Anticipating User Input When Building a CLI App
Tags: ruby, logic, cliapp
Published: 2019-10-30 03:12:41

###Getting Started###

My project partner and I recently completed our first ever coding project, a CLI App built using Ruby. As a novice in coding, it was really exciting and rewarding to build something other people could interact with. Besides overall concerns about the app working, our biggest challenge was anticipating a user's input, and accounting for variations. 

###Will users follow directions?###

The app consists of a database of planets in our solar system, which the user is able to get information on by entering the name of their current location, and picking a planet from a presented list. Here is the code for the method that asks the user where they're from, and compares their answer to existing planets in the database: 

   ```ruby
def user_planet
        puts "What planet in the Solar System do you currently reside on?"
        user_location = gets.chomp.capitalize
        solar_planets = Planet.find_by(name: user_location)
        if solar_planets
            puts ""
            user_location
        else 
            puts ""
            puts "Please enter a planet in the Solar System.".colorize(:red)
            user_planet
        end
    end
```
Because our database only has the 8 major planets in the Solar System, we had to make sure the user could only pick one of those for their current location. We based later methods and calculations on this answer, so had to create air-tight logic around the input. The use of an `if...else` statement was imperative here, as it allowed us to guide the user to the correct answer. If they picked one of the 8 planets, their answer was recorded. If they tried something funny, like Pluto, or Gallifrey, they got a red message redirecting them to give another answer, and were sent back to the beginning of the method. This way, they had infinite chances to get this right (or at least make the rest of our methods happy).

###Y/N Complications###

At a different point in the app, the user is asked a series of yes or no questions. While the prompt offers Y and N as answer options, we still had to make sure the logic would stand up to testing. 

```ruby
def distance_from_selection
        puts ""
        puts "Would you like to see the distance to your selection? Y/N"
        user_input = gets.chomp.downcase
        if user_input == "y" || user_input == "yes"
            distance
            print_distance
            puts ""
            display_travel_time
        elsif user_input == "n" || user_input == "no"
            display_travel_time
        else
            puts "Please enter Y or N."
            distance_from_selection
        end
    end
```
Above, we take in the user's input and convert it to lower case letters using `.downcase` in order to account for users with a love for capitals, and ones who never use them. In our `if...elsif...else` statement, we make sure to anticipate multiple options for yes and no, the requested answers, as well as something else that could be entered. The `else` option prompts the user for a correct answer and returns them to the beginning of the method. Each option has its own internal path of methods that are followed depending on the user's selection.

###Multiple Interesting Options###

```ruby
def ending_options
        puts ""
        puts "*---*---o---*---~---o---~---*---o---*---*"
        puts "--*---*---o---*---~---o---~---*---o---*--"
        puts "What would you like to do now? Please select 1, 2, or 3.".colorize(:yellow)
        puts "1. Go back to Planet Menu."
        puts "2. View your Favorite Planets."
        puts "3. Exit Travel Agency."
        user_input = gets.chomp
        if user_input == "1"
            system("clear")
            main_menu
        elsif user_input == "2"
            display_favorites
        elsif user_input == "3"
            puts ""
            puts ""
            puts "Thank you for visiting the Milky Way Travel Agency. Good Bye!".colorize(:magenta)
            system("imgcat ./lib/images/purple_solarsystem.jpg")   
        else
            puts "Please make another selection."
        ending_options
        end
    end
```

This is the code for the ending of our app. We had to make sure the user had multiple options, and would clearly know what each one did. Each option has a number, and the user was asked to input the number of their selection to proceed. While the `if...elsif...elsif` part of the logic covers the presented options, the `else` is there in case of typos or general messing around. It returns the user to the option menu to remind them of the app's desired input. It also gives them another chance to see the adorable star ribbon we coded, of which I'm very proud. 

Here's a link to the project's repo: [Milky Way Travel Agency](https://github.com/mezzolite/milky_way_travel_agency)

**Sources**: planet image from [Jenny Mottar via NASA](https://solarsystem.nasa.gov/resources/545/artists-concept-our-solar-system/)