FS Blog #2: Tech Skills Bot - My CLI Data Gem Project
Tags: ruby
Published: 2021-05-28 02:49:52

# FS Blog #2: Tech Skills Bot - My CLI Data Gem Project

![https://images.unsplash.com/photo-1485827404703-89b55fcc595e?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb](https://images.unsplash.com/photo-1485827404703-89b55fcc595e?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb)

*Photo Credit: Unsplash - [Alex Knight](https://unsplash.com/photos/2EJCSULRwC8)*

## Tech Skills Bot

For my CLI Data Gem project, I'm building a Tech Skills Bot, Al (a smaller, newer upgraded version of Hal9000:)) to help students to plan their tech careers by learning more about the most in-demand tech skills. 

The idea is that students would interact with Al via CLI (Command Line Interface), and at Al's prompt, could enter input to see a list of in-demand tech skills, and then if they want to learn more, enter input to learn more about the skills including average salary, growth potential, and opportunities at top tech companies.  

Tech Skills Bot is a very simple MVP, as this is my very first project: first time using VS Code for an actual/live project, first time programming with Ruby (or any actual programming language for that matter), first time publishing "committing/pushing" to GitHub(!), ...etc. Even though the app is super simple, it was still a lot of work. I learned a lot through the process, and was able to use a lot of the concepts that I learned from lessons and labs I've done so far, which I detailed below. As I learn more through out the program, I would love to add more functionalities and features!

### **Building Tech Skills Bot:**

- To build my app using Ruby, I first setup my local environment, including setting up and connecting my local and remote repos, creating project file structure and files, and adding gems, dependencies, and the requirements in my app and files.
- I then code a Scraper to get the data from a public website about the top in-demand tech skills and their detailed information, using a Ruby Gem Nokogiri to parse the HTML of the website with specific CSS Selectors, then code a Skill class to store these data, and finally, code a CLI that incorporates the Scraper and the Skill classes to sequence out the potential interactions with the student, including different methods for different input scenarios.
- The Ruby gems I used for the app are: **Nokogiri**, **Open-URI**, and **Pry**.

Below is the details behind the tech in my building process:

## The Tech Behind The Tech Skills Bot:

### Part 1: The Environment (& app's main files):

- **bundler -** handles the app's code dependencies & keeps all requirements in one place (in gemfile), keeps environment consistent by tracking and installing the exact gems & versions needed.
- **gems** - the app's ****Ruby external code libraries, installed by running gem install (gem name).
- **config**
    - **environment.rb**  - specifies load information including gems and database dependencies to configure load path/load order so that nothing breaks in the app.
- **bin**
    - **run.rb** - file that will start the app, requires the config/environment.rb file.
- **lib**
    - **scraper.rb**  - where the app's Scraper class codes live.
    - **skill.rb** - where the app's Skill class codes live.
    - **CLI.rb** - where the app's CLI codes live.
    - **version.rb** - keeps track of the version of the app.
- **gemfile** - file inside of the app that lists all of the gems the app uses
- **gemfile.lock** - keeps track of all of the app's path, gems, platforms, dependencies and their versions.
- **README** - a brief documentation of the app, with a short description of the app, install instructions, contributor's guide, and a link to the license of the app's code
- **LICENSE** - the app is under The MIT License (with free copyright and "AS IS" statements with warranty and liability waiver).

*While setting up my file structure and files, here are some things I've learned:* 

- ***Version matters!:** the correct versions and the consistency of your Ruby and Ruby Gems and dependencies matter.*
- ***Load order matters!:** load gems, dependencies and requirements first before your codes.*
- ***require  -** absolute path for the filename (in the directory from which the app is being run)*
- ***require_relative**  - relative path to the file in which the require statement is called (relative to the file being run)*

### Part 2: The Programming & Concepts:

- **General:**
    - **HTML** - **"Hyper Text Markup Language",** is the standard markup language for documents or contents to be displayed in a web browser. The app uses a scraper to parse the HTML data from the website.
    - **CSS - "Cascading Style Sheets"** is language for the presentation or styling of web pages, with rules that define how browsers present HTML, customizing for the content's look and feel, including margins, colors, layout, etc. The app uses a scraper with the help of the CSS Selectors to select the relevant HTML data of the website.
        - **CSS Selectors** - used to select (or find) elements from the HTML that matches elements by name, type, attribute, etc., including element, id, class.
    - **CLI** - **"Command Line Interface"** are programs that users can interact with entirely through a computer/system's terminal and shell. There is no graphics or visual interfaces and can only interact with the user through accepting ASCII entered into a prompt and communicate via ASCII output. The app only uses CLI for its user interface.
- **Ruby Essentials:**
    - **Basic control flow - "if" statements** - "if" statements (and its associated "else", "elsif" and "end" statements) are a type of control flows that tell the app what code to execute conditionally. They are one of the most common ways to enact control flow (along with "while" and "case" statements and "loops") - the codes that follow the "if" statement get evaluated, or read and enacted by the computer, and if the statement results in "true", then the codes through to the associated end statement will run, if the statement results in "false", then the computer goes to the "else" or "elsif" statement, and evaluate the codes follow those statements, and depends on the results of those statement are "true" or "false", the computer either runs the codes that follow those statements or is redirected to the next statements. The app uses "if" statements and "while" statement for the CLI's menu method, where student's inputs were made into "if" statements based on different scenarios, and the Bot's responses.
    - **Variables & variable scopes**
        - **Variables** - variables stores information, and has a value, type  (starts with a lowercase letter, variable with an uppercase letter is known as a constant and has different characteristics). Can be created with "=" (assignment operator)
            - **Local variables** - can only be accessed in a specific, local environment. A local variable that is defined inside one method can not be accessed by another method. (We can use instance variable to get around this limitation)
            - **Instance variables** - can be accessible in any instance method in a particular instance of a class. A variable that has an instance scope, or instance variable is responsible for holding information regarding and instance of a class and is accessible only to that instance of the class.
            - **Class variables -** A variable that has a class scope  class variable
    - **Object instantiation**: **new** and **Initialize** - *All Ruby objects are bundles of data and logic, or attributes and behavior.* A Ruby class can create new instances of an object in that class via the **.new** method, whether or not that class has an initialize method. However if we want each instance of the class to be created with certain attributes, there must be a defined initialized method. (An initialize method is called automatically whenever .new is used.) The **initialize** method instantiates an object and can be used to assign a new object and assign a new object with certain attributes upon it being called. The app uses the initialize method for the Skill class, where each of the new skill scraped from the website is instantiated with name and info, and saved into the Skill class.
    - **The meaning of the "self"** - In Object-Oriented Programming, there is a concept of "self": when we create a class, each new instance of the class is considered to be an object, and the object is aware of itself and can refer to its methods as self.methods. In another word, the object can operate on itself and is aware of its attributes, behaviors, etc. The app uses the concept of self in its Scraper and Skill classes.
    - **Method Types - Class vs. Instance Methods:**
        - **Classe Methods** - classes act as a factory for objects, capable of instantiating new instances.  Class Methods are methods that live inside of the object class, with behaviors and functions that can be accessed by objects in that class. The app has three classes: Skills, Scraper, CLI, each with its own **Class Methods** for each to operate.
        - **Instance Methods** - instances are instances of behaviors or objects. Instance Methods are methods that belong to any instance of a class. The app uses both Class Methods and Instance Methods that creates instances, behaviors, functionalities for each class and class objects.
    - **Method Return Types** - what methods return - the app uses both explicit return and implicit return for the methods uses
        - **Explicit return** - puts (short for "out"puts"tring") and print commands tell the program to display specific information explicitly;
            - puts adds a new line after executing, and print does not
        - **Implicit return** - Ruby is an implicit language, if there are no explicit return, the program will return the last code executed.
    - **Iterating Through Collections - .each with a block** - .each with a block is a Ruby method that calls block with two arguments, the item and its index, for each item in enum, and given arguments are passed through to each(). the app's scraper uses ".each_with_index" to iterate through scraped data from the website to create new Skill objects with the skill names and skill info as attributes, and return each Skill object with an index number.
- **Gems:**
    - **Pry** - a Ruby Gem and a type of REPL (Read, Evaluate, Print, Loop) that is used for debugging the app (by calling binding.pry in the app's code, that line gets interpreted at runtime as the program is executed, and when the interpreter hits that line, the program freezes and the terminal of the program turns into a REPL in the middle of the program for checking if the codes are working)
    - **Nokogiri** - a Ruby Gem that the app uses to parse and read the website's HTML in Ruby.
    - **Open URI** - a Ruby module that the app uses to programmatically make HTTP requests of the website.

And that's my Tech Skills Bot app in a nutshell! Hope this helps anyone who is interested in building a CLI app. I really enjoyed building my first app and learning every step along the way. I look forward to learning more so I can add more to the app and/or build more fun and complex apps! 

Also, aside from the project, It really amazes me that anyone can open up any webpage and see all of their HTML and CSS data. The internet is a pretty amazing place! :)