Building a Tarot Dictionary in Ruby
Published: 2020-11-12 22:57:08

I spent the last week building my first ever program using Ruby. 

I built a simple program for looking up tarot cards, specifically the meanings associated with the cards in the popular Rider-Waite tarot deck. Seasoned Tarot readers learn how to interpret cards by personal association, but most beginners rely on books to look up each card as they do a reading, or spread. I had a friend in mind when I came up with the idea for the program. She relies on a book to check the meanings of cards; the type is very small and it can take a while to find one card. My goal for this program was to make it so a person is only a few keystrokes away from the information they are after, avoiding the hassle of flipping through pages. 

![program welcome screen](https://dev-to-uploads.s3.amazonaws.com/i/5m6sw50kjyzx12rl85s2.png)

## Loops on loops

To achieve the goal of having easy accessibility within the program I had to build many navigational loops within my methods. I decided to go with simple keystrokes for input, going off my own experience of interacting with similar CLI styles. I also thought of beginners to Tarot, who might get confused by the suit they need or the common mistake of hitting the wrong button. The case of the input shouldn't have mattered - why frustrate a user who put in 'b' instead of 'B'? Originally I found myself doing a lot of ` input == "E" || or input == "e"` before I remembered to take a look at the methods available for me and swapped out for a much simpler `input.case`. I also wanted to get back to the previous list or starting a new search to be accessible inside the program, and this was mostly achievable thanks to the relatively small size of the information that was being provided. 

```
new_input = gets.chomp
            if new_input.upcase == "B"
                major_arcana
            elsif new_input.upcase == "M"
                main_menu_display
            elsif new_input.upcase == "E"
                exit_program
            else
                puts "Invalid selection"
                major_arcana
            end
```
######*I avoided having invalid input shoot users all the way back to the main menu by instead redirecting back to the start of the method they were already in*


Another big hurdle was around the concept of making sure every method I wrote was handling one specific job. There were more than a few hours spent taking methods apart and writing new classes, new methods, new modules, worried that I needed to spread the load out, only to realize what I was actually doing was undoing the good work I had done. But the process made me understand my code and how parts of my code related to each other even more. I certainly would have been done writing my program a lot sooner if I had more confidence and second-guessed myself less, but I think it was worth it, in the end, to spend that much more time understanding what exactly was going on step by step.

```
def self.card_display(array, index)
        puts "------------------"
        puts "  Name: #{array[index].name}"
        puts "  Type: #{array[index].type}"
        puts "  Suit: #{array[index].suit}"
        puts "  Meaning: #{array[index].meaning_up}"
        puts "  Meaning reversed: #{array[index].meaning_rev}"
    end
```
######*I created a method for the code to display the information in an easy to read format so that I could reuse it anywhere in the program without repeating the same 8 lines of code over and over.*

When I first started planning the program I set a very simple goal: just have the code return the basic information when requested. I also wrote down a few extra functions that would be fun, if I had the time. A mistake I made was laying the groundwork for some of those early, telling myself I would go back and actually build them. In the future, I would rather only write the code I actually plan on working with at that time, and when it comes time to add in extra stuff then add it. I ended up having to do a lot more cleanup when I later decided that certain functions were either beyond my capabilities or just unnecessary for the scope of the project. 

![program example](https://dev-to-uploads.s3.amazonaws.com/i/ke1k6g8pinf4qrbv836r.png)

Overall, I absolutely love my program. It may be simple but it does exactly what I set out for it to do. At some point, when I have a larger skill set, I think it would be fun to revisit and add in some of the things I came up with but had to set aside. For now, I am excited to show it to my friends who read Tarot