<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Fausto Tapia</title>
    <description>The latest articles on DEV Community by Fausto Tapia (@ftapiaa27).</description>
    <link>https://dev.to/ftapiaa27</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F978158%2Fd0242624-dd0c-46fd-900d-ad1af6d2a17d.jpeg</url>
      <title>DEV Community: Fausto Tapia</title>
      <link>https://dev.to/ftapiaa27</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ftapiaa27"/>
    <language>en</language>
    <item>
      <title>Calisthenics exercises recommendation software</title>
      <dc:creator>Fausto Tapia</dc:creator>
      <pubDate>Fri, 17 Feb 2023 04:20:25 +0000</pubDate>
      <link>https://dev.to/ftapiaa27/calisthenics-exercises-recommendation-software-2672</link>
      <guid>https://dev.to/ftapiaa27/calisthenics-exercises-recommendation-software-2672</guid>
      <description>&lt;p&gt;This is de Codecademy CS102 final project.&lt;br&gt;
This program is a recommendations program for calisthenics enthusiasts looking for progressions to train for some of the most popular calisthenics skills.&lt;br&gt;
As a fitness enthusiast myself, I decided to make a recommendation program (although basic) of something I would actually find useful, probably as I learn more skills I'll turn this into a full blown app.&lt;br&gt;
Anyways...&lt;/p&gt;

&lt;p&gt;This project has a few files:&lt;/p&gt;
&lt;h2&gt;
  
  
  data.py
&lt;/h2&gt;

&lt;p&gt;This has all the data used in the project, a dictionary with key-value pairs of the names of the skills and a list containing the details, these lists contain two elements: the description of the movement and another list containing all the progressions for each skill, and finally this list contains tuples with three parameters, the level of difficulty, name of the progression and details on how to perform it.&lt;/p&gt;

&lt;p&gt;Here's a snippet of that data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;planche_progressions = [
    (1, 'Tuck Planche', 'Start in a push-up position with your hands shoulder-width apart and your fingers pointing forward. Lower your hips and raise your feet, keeping your back straight. Try to hold this position for as long as possible.'),
    (2, 'Advanced Tuck Planche', 'From a tucked position, straighten your legs and lift your hips to create a horizontal line with your body.'),
    (3, 'Straddle Planche', 'Open your legs into a straddle position, keeping your hips high and your back straight.'),
    (4, 'Half-Lay Planche', 'Lower one leg to create a half lay position while keeping the other leg straight and high.'),
    (5, 'Full Planche', 'Straighten both legs and lower your body until it is parallel to the ground.'),
    (6, 'Planche Push-Ups', 'From a full planche position, lower your body until your chest touches the ground, then push back up to the starting position.')
]

front_lever_progressions = [
    (1, 'Tuck Front Lever', 'Start by hanging from a bar with your knees tucked to your chest. Keep your arms straight and engage your lats to hold your body in a horizontal position.'),
    (2, 'Advanced Tuck Front Lever', 'Straighten your legs out in front of you while maintaining a horizontal position.'),
    (3, 'Straddle Front Lever', 'Open your legs into a straddle position while keeping your body horizontal.'),
    (4, 'Half-Lay Front Lever', 'Lower one leg to create a half lay position while keeping the other leg straight and high.'),
    (5, 'Full Front Lever', 'Straighten both legs and hold your body in a horizontal position.'),
    (6, 'Front Lever Pull-Ups', 'From a full front lever position, pull your body up to the bar while maintaining a horizontal position.')
]

back_lever_progressions = [ ...

calisthenics_skills = {
    "Planche": ["A gymnastics move where the body is held parallel to the ground in a horizontal position, supported only by the hands.", planche_progressions],
    "Front Lever": ["A gymnastics move where the body is held parallel to the ground in a horizontal position, supported only by the arms., ", front_lever_progressions],
    "Back Lever": ["A gymnastics move where the body is held parallel to the ground in a horizontal position, supported only by the arms.", back_lever_progressions], ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This data was generated with ChatGPT so some of the descriptions are a little bit off.&lt;/p&gt;

&lt;h2&gt;
  
  
  LinkedList.py
&lt;/h2&gt;

&lt;p&gt;The data of the dictionary was introduced into a linked list in the actual program (More details on this later), so this file has the Node and LinkedList classes:&lt;br&gt;
THE NODE CLASS&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Node:
    def __init__(self, value, next_node=None):
        self.value = value
        self.next_node = next_node

    def get_value(self):
        return self.value

    def get_next_node(self):
        return self.next_node

    def set_next_node(self, next_node):
        self.next_node = next_node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This class only has the constructor and three methods that serve to get the value of a node, get the next node and set the next node&lt;br&gt;
THE LINKED LIST CLASS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class LinkedList:
    def __init__(self, value=None):
        self.head_node = Node(value)

    def get_head_node(self):
        return self.head_node

    def insert_beginning(self, new_value):
        new_node = Node(new_value)
        new_node.set_next_node(self.head_node)
        self.head_node = new_node

    def __iter__(self):
        current_node = self.head_node
        while(current_node):
            yield current_node.get_value()
            current_node = current_node.get_next_node()

    def stringify_list(self):
        string_list = ""
        current_node = self.get_head_node()
        while current_node:
            if current_node.get_value() != None:
                string_list += str(current_node.get_value()) + "\n"
            current_node = current_node.get_next_node()
        return string_list

    def remove_node(self, value_to_remove):
        current_node = self.get_head_node()
        if current_node.get_value() == value_to_remove:
            self.head_node = self.head_node.get_next_node()
        else:
            while current_node:
                current_next_node = current_node.get_next_node()
                if current_next_node.get_value() == value_to_remove:
                    current_node.set_next_node(current_next_node.get_next_node())
                    current_node = None
                else:
                    current_node = current_next_node

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This class has several more methods:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get the head node of the linked list.&lt;/li&gt;
&lt;li&gt;Insert a node at the beginning of the linked list with a specified value.&lt;/li&gt;
&lt;li&gt;Iterator, in order to iterate through the linked list using a for loop.&lt;/li&gt;
&lt;li&gt;Stringify, although not used here, this can be used to display the contents of the linked list.&lt;/li&gt;
&lt;li&gt;Remove a node by it's value, again, not used here.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  UI
&lt;/h2&gt;

&lt;p&gt;This only has a function to display the welcome message&lt;/p&gt;

&lt;h2&gt;
  
  
  The main script file
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from heapq import heappop, heappush
from ui import *
from data import *
from LinkedList import LinkedList



skill_names = LinkedList()

class recommendation_system:
    def __init__(self):
        self.skills = LinkedList()

    def load_data(self):
        for name, details in calisthenics_skills.items():
            self.skills.insert_beginning([name, details])
            print(f"{name} added")

    def get_skill(self):
        while True:
            print("What calisthenics skill are you interested in?", 
            "Type the beggining of of the name and press enter to see if it's here:",
            "(Or type 0 to exit)", sep = "\n")
            answer = input()
            if answer == "0":
                break
            answer = answer.lower()
            coincidences = []
            for skill in self.skills:
                if skill:
                    skill_name = skill[0].lower()
                    if answer == skill_name[:len(answer)]:
                        coincidences.append(skill)
            if len(coincidences) == 0:
                print("No matches were found for " + answer)
                print("Try again: ")
                self.get_skill()
            elif len(coincidences) == 1:
                print("The only match for your search is {0}".format(coincidences[0][0]))
                continue_or_not = input("Do you want to continue with this skill?\n[Y or N]: ")
                if continue_or_not.lower() == "y":
                    self.get_choice_between_description_and_progressions(coincidences[0])
                else:
                    continue
            else:
                print("Here are the matches to your search: ")
                for match in coincidences:
                    print(match[0])
                print("Try again: ")
                self.get_skill()

    def get_choice_between_description_and_progressions(self, skill):
        try:
            current_skill = skill.copy()
            choice = int(input(f"What do you want to learn about the {current_skill[0]}?\nDescription [1], progressions [2], exit[3]: "))
            if choice == 1:
                print(current_skill[1][0])
                self.get_choice_between_description_and_progressions(current_skill)
            elif choice == 2:
                while (True):
                    current_progression = heappop(current_skill[1][1])
                    print("Progression #{0}: {1}.\nDescription: {2}".format(current_progression[0], current_progression[1], current_progression[2]))
                    choice = int(input("Do you want to see the next progression [1] or exit to main menu [2]? "))
                    if choice == 1:
                        continue
                    elif choice == 2:
                        break
            elif choice == 3:
                exit
            else:
                print("Please select a valid option.")
                self.get_choice_between_description_and_progressions()
        except:
            print("There are no more progressions to display, returning to main menu")

    def main(self):
        welcome()
        self.get_skill()


cal_skills = recommendation_system()
cal_skills.load_data()
cal_skills.main()

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This program has a class named recommendation system which has the following methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The constructor: It creates an empty linked list
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def __init__(self):
        self.skills = LinkedList()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;LOAD_DATA
This loads the data from data.py into the linked list created in the constructor, it adds every key-value pair of the dictionary into lists in a Node at the beginning of the linked list.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def load_data(self):
        for name, details in calisthenics_skills.items():
            self.skills.insert_beginning([name, details])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;GET_SKILL
This method basically takes the user input in order to identify the calisthenics skill the user wants to learn about, it does it by comparing the user input to the beginning letters of the name of the skills, if there's a match the skill is added to a temporary list. The user is prompted to input the name of the desired skill until there's only one option, after the user is asked whether or not they would like to continue with that skill, if so the next method is called, otherwise the user returns to the main menu.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def get_skill(self):
        while True:
            print("What calisthenics skill are you interested in?", 
            "Type the beggining of of the name and press enter to see if it's here:",
            "(Or type 0 to exit)", sep = "\n")
            answer = input()
            if answer == "0":
                break
            answer = answer.lower()
            coincidences = []
            for skill in self.skills:
                if skill:
                    skill_name = skill[0].lower()
                    if answer == skill_name[:len(answer)]:
                        coincidences.append(skill)
            if len(coincidences) == 0:
                print("No matches were found for " + answer)
                print("Try again: ")
                self.get_skill()
            elif len(coincidences) == 1:
                print("The only match for your search is {0}".format(coincidences[0][0]))
                continue_or_not = input("Do you want to continue with this skill?\n[Y or N]: ")
                if continue_or_not.lower() == "y":
                    self.get_choice_between_description_and_progressions(coincidences[0])
                else:
                    continue
            else:
                print("Here are the matches to your search: ")
                for match in coincidences:
                    print(match[0])
                print("Try again: ")
                self.get_skill()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;GET_CHOICE_BETWEEN_DESCRIPTION_AND_PROGRESSIONS
In this code the user is propted to choose between displaying the details of the skill or the progressions.
If the user chooses to display the description they are prompted to choose again, if they choose to see the progressions they are displayed one by one from easiest to hardest using the heappop function.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def get_choice_between_description_and_progressions(self, skill):
        try:
            current_skill = skill.copy()
            choice = int(input(f"What do you want to learn about the {current_skill[0]}?\nDescription [1], progressions [2], exit[3]: "))
            if choice == 1:
                print(current_skill[1][0])
                self.get_choice_between_description_and_progressions(current_skill)
            elif choice == 2:
                while (True):
                    current_progression = heappop(current_skill[1][1])
                    print("Progression #{0}: {1}.\nDescription: {2}".format(current_progression[0], current_progression[1], current_progression[2]))
                    choice = int(input("Do you want to see the next progression [1] or exit to main menu [2]? "))
                    if choice == 1:
                        continue
                    elif choice == 2:
                        break
            elif choice == 3:
                exit
            else:
                print("Please select a valid option.")
                self.get_choice_between_description_and_progressions()
        except:
            print("There are no more progressions to display, returning to main menu")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's the full code:&lt;br&gt;
&lt;a href="https://github.com/ftapiaa27/Recommendation-Software.git" rel="noopener noreferrer"&gt;https://github.com/ftapiaa27/Recommendation-Software.git&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>tooling</category>
      <category>productivity</category>
      <category>github</category>
    </item>
    <item>
      <title>Python Terminal Game: Minesweeper</title>
      <dc:creator>Fausto Tapia</dc:creator>
      <pubDate>Thu, 24 Nov 2022 04:31:36 +0000</pubDate>
      <link>https://dev.to/ftapiaa27/python-terminal-game-minesweeper-4bn8</link>
      <guid>https://dev.to/ftapiaa27/python-terminal-game-minesweeper-4bn8</guid>
      <description>&lt;p&gt;As a part of the codecademy course on Computer Science I came up with this approach to code the game "Minesweeper" as a game interactible through the terminal.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Game class
&lt;/h2&gt;

&lt;p&gt;`class Game:&lt;br&gt;
    alive = 1&lt;br&gt;
    board_back = [[" " for i in range(9)] for j in range(9)]&lt;br&gt;
    board_front = [["#" for i in range(9)] for j in range(9)]&lt;br&gt;
    bomb_coor = []&lt;br&gt;
    def &lt;strong&gt;init&lt;/strong&gt;(self):&lt;br&gt;
        x_coor = [0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8]&lt;br&gt;
        y_coor = [0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8]&lt;br&gt;
        for i in range(10):&lt;br&gt;
            temp = []&lt;br&gt;
            temp.append(x_coor.pop(random.choice(x_coor)))&lt;br&gt;
            temp.append(y_coor.pop(random.choice(y_coor)))&lt;br&gt;
            self.bomb_coor.append(temp)&lt;br&gt;
            self.board_back[temp[0]][temp[1]] = "B"&lt;br&gt;
        for i in range(9):&lt;br&gt;
            for j in range(9):&lt;br&gt;
                if self.board_back[i][j] == "B":&lt;br&gt;
                    continue&lt;br&gt;
                else:&lt;br&gt;
                    self.board_back[i][j] = str(self.count_bombs(i, j))&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def count_bombs(self, x, y):
    count = 0
    for i in range(x-1,x+2):
        for j in range(y-1,y+2):
            if i == x and j == y:
                continue
            elif i &amp;lt; 0 or i &amp;gt; 8 or j &amp;lt; 0 or j &amp;gt; 8:
                continue
            elif self.board_back[i][j] == "B":
                count += 1
            else:
                continue
    return count

def print_board(self, board):
    for i in range(9):
        print(board[i])

def set_flag(self):
    x = int(input("Type horizontal coordinate to flag: "))
    y = int(input("Type vertical coordinate to flag: "))
    self.board_front[y][x] = "F"

def uncover(self):
    x = int(input("Type horizontal coordinate to uncover: "))
    y = int(input("Type vertical coordinate to uncover: "))
    if self.board_back[y][x] == "0":
        self.clear_empty(y, x)
    else:
        self.board_front[y][x] = self.board_back[y][x]

    if self.board_back[y][x] == "B":
        print("You lost")
        self.alive = 0

def clear_empty(self, x, y):
    if self.board_front[x][y] != " " and self.board_back[x][y] == "0":
        self.board_front[x][y] = " "
        for i in range(y-1, y+2, 2):
            if i &amp;lt; 0 or i &amp;gt; 8:
                continue
            self.clear_empty(x, i)
        for j in range(x-1, x+ 2, 2):
            if j &amp;lt; 0 or j &amp;gt; 8:
                continue
            self.clear_empty(j, y)
def verify_game(self):
    if self.alive == 0:
        print("Game Over")
        return 0
    else:
        user_wins = True
        for i in self.bomb_coor:
            if self.board_front[i[0]][i[1]] != "F":
                user_wins = False
                break
        for i in self.board_front:
            if "#" in i:
                user_wins = False
                break
        if user_wins:
            print("You Won!")
            return 0
        else:
            return 1`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This class contains 4 attributes and 7 methods&lt;/p&gt;

&lt;p&gt;THE ATTRIBUTES&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;alive: This value indicates whether the player is alive or dead&lt;/li&gt;
&lt;li&gt;board_back: this isn't visible to the player, it is a 8x8 matrix (list of 8 lists of 8 values) or board containig all the info of the board including bomb locations and the number of bombs in surrounding squares.&lt;/li&gt;
&lt;li&gt;board_front: this is visible to the player, "#" means the squared hasn't been uncovered.&lt;/li&gt;
&lt;li&gt;bomb_coor: a list of pair values indicating the coordinates of all bombs&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;THE METHODS&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;init&lt;/strong&gt;: the constructor of the class defines the bomb_coor array and sets up the board_back matrix.&lt;/li&gt;
&lt;li&gt;count_bombs: this method is used in the constructor to count the number of bumbs surrounding a certain square assuming it doesn't have a bomb itself.&lt;/li&gt;
&lt;li&gt;print_board: prints a board in the terminal.&lt;/li&gt;
&lt;li&gt;set_flag: used to "flag" a certain square when we believe it to have a bomb in board_front.&lt;/li&gt;
&lt;li&gt;uncover: used to uncover a obscured square in board_front and reveal its corresponding value in board_back.&lt;/li&gt;
&lt;li&gt;clear_empty: used to clear all empty contiguous squares in board_front that correspond to a "0" in board_back.&lt;/li&gt;
&lt;li&gt;verify_game: used to check if the game is still going or if it has ended in a Win or a Loss&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example of object usage:&lt;br&gt;
&lt;code&gt;game = Game()&lt;br&gt;
while game.alive:&lt;br&gt;
    game.print_board(game.board_back)&lt;br&gt;
    print()&lt;br&gt;
    game.print_board(game.board_front)&lt;br&gt;
    if game.verify_game() == 0:&lt;br&gt;
        break&lt;br&gt;
    choice = int(input("""&lt;br&gt;
    Select one optione:&lt;br&gt;
    1.- Flag&lt;br&gt;
    2.- Uncover&lt;br&gt;
    """))&lt;br&gt;
    if choice == 1:&lt;br&gt;
        game.set_flag()&lt;br&gt;
    else:&lt;br&gt;
        game.uncover()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Code on github: &lt;a href="https://github.com/ftapiaa27/MineSweeper.git"&gt;https://github.com/ftapiaa27/MineSweeper.git&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CONCLUSION:&lt;br&gt;
This little project serves as a general practice of OOP in python, it's not much but it's hones work&lt;/p&gt;

</description>
      <category>python</category>
      <category>computerscience</category>
      <category>gamedev</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
