7
\$\begingroup\$

I made a translator for the English language. As of now it only translates from Spanish, Russian, and Arabic (will be adding more languages).

The program pulls the input from a yaml file with a list of words and phrases inside of it. It searches the users input and if it finds a match it returns with the English translation of the word or phrase!

require 'yaml'

def welcome
    puts "Welcome to the Translation Center! Please enter the language you would like to translate to English or you can choose from the list below:  
    1. Spanish
    2. Russian
    3. Arabic"
    input = language = gets.chomp!
    case language
    when /spanish/i
        spanish_translate
    when "1"
        spanish_translate
    when /russian/i
        russian_translate
    when "2"
        russian_translate
    when /arabic/i
        arabic_translate
    when "3"
        arabic_translate
    else
        puts "Language is not yet supported within Translation Center."
        exit
    end
end

def spanish_translate
    translations = YAML.load_file 'spanish.yml'
    puts "Enter word or phrase to be translated to English, press 'Q' to quit:"
    input = gets.chomp
    case
    when translations[input]
        puts "The translation from Spanish to English is: #{translations[input]}"
    when input =~ /q/i
        exit
    else
        puts "Invalid word or phrase redirecting..."
        spanish_translate
    end
end

def russian_translate
    translation = YAML.load_file 'russian.yml'
    puts "Enter word or phrase you would like translated to English, press 'Q' to quit:"
    input = gets.chomp!
    case
    when translations[input]
        puts "The translation from Russian to English is: #{translations[input]}"
    when input =~ /q/i
        exit
    else
        puts "Invalid word or phrase redirecting..."
        russian_translate
    end
end

def arabic_translate
    translation = YAML.load_file 'arabic.yml'
    puts "Enter word or phrase you woukd like translated to English, press 'Q' to quit:"
        input = gets.chomp!
        input = gets.chomp!
    case
    when translations[input]
        puts "The translation from Arabic to English is: #{translations[input]}"
    when input =~ /q/i
        exit
    else
        puts "Invalid word or phrase redirecting..."
        arabic_translate
    end
end
welcome

Here's the Spanish yaml file:

a: to
abajo: down
el abancio: fan
buenos dias: good morning
buenos tardes: good afternoon
como se llama usted: what is your name
como esta usted: how are you
estoy bien: i am fine
mucho gusto: nice to meet you
perdoname: excuse me
por favor: please
gracias: thank you
lo siento: i'm sorry
salud: bless you
de nada: you are welcome
hay muchos: there are many
si: 'yes'
no: 'no'
yo no comprendo: i do not understand
yo quiero una tortilla: i want a tortilla

Russian yaml file:

и: and, though
в: in, at
не: not
он: he
на: on, it, at, to
я: I
что: what, that, why
тот: that 
быть: to be
с: with and, from, of
а: while, and, but 
весь: all, everything
это: that, this, it 
как: how, what, as, like

Arabic yaml file:

salam: hi
سلام: hi
Sabah el kheer: good morning
صباح الخير: good morning 
massa el kheer: good evening
مساء الخير: good evening
marhaban: welcome
مرحبا: welcome
Kaifa haloka: how are you(male)
kaifa haloki: how are you(female)
كيف حالك؟: how are you
ana bekhair shokran: i'm fine thanks
أنا بخير شكر: im fine thanks
wa ant: and you(male)
wa anti: and you (female)
و أنت؟: and you
jayed: good
'aadee: so-so
عادي: good
جيد: so-so

It now has the ability to translate to three different languages.

How's this looking as an OOP language overall? What can I do differently next time?

\$\endgroup\$
  • 1
    \$\begingroup\$ Just a little FYI, we won't add features to your code for you on request, otherwise your question may be closed as off-topic. \$\endgroup\$ – Ethan Bierlein Oct 28 '15 at 17:28
  • 1
    \$\begingroup\$ Somehow unrelated note: the Spanish translation of "fan" is "abanico", not "abancio" :) \$\endgroup\$ – varocarbas Oct 28 '15 at 21:25
  • \$\begingroup\$ Well, there's no explicit question here, though it's obvious you'd like to find a way to add new languages easier. How about moving it into a class, let it be a 'Translator' one? Moreover, all these 'translate' methods share a lot of code and can be easily merged into one generic method. Recursion is redundant and might be replaced with a simple while loop. What about words containing 'q' letter that don't exist in your dictionary? \$\endgroup\$ – cafe_ Oct 28 '15 at 23:23
  • \$\begingroup\$ @xrthdsf would you mind elaborating what you mean a little more? The dictionary hash isn't finished yet, those where just some test runs that I needed to throw in. And I can't necessarily say it requires yaml without a couple yaml files lol \$\endgroup\$ – 13aal Oct 29 '15 at 3:09
  • 2
    \$\begingroup\$ I rolled this back because it invalidates my answer. What you may and may not do after receiving answers \$\endgroup\$ – Peilonrayz Oct 29 '15 at 19:32
1
\$\begingroup\$

How's this looking as an OOP language overall?

Ruby is actually multi-paradigm. It allows you to use OO, and it gives you the option not to.
For example you didn't use any objects, so you didn't actually employ OOP.

For improvements:

  • Your {lang}_translate code is very repetitive, you can change it to a class to reduce repetitiveness.

  • You load the YAML file on each word translated (or incorrectly inputted), and so you should load it once.

  • You have to add multiple things when you add a new language.

    • Both the index and language in the case.

    • Both the index and language in the puts

    • The language file in the new {lang}_translate function.

    You can remove this all if you use a list and a class.


First, to remove the first two points, I would make a class that lazily loads the translations. And implements the translation.
Also I personally think your case statement in {lang}_translate is better as if elsif else.
exit seems like a bad design here, if you were to want to allow the user to change language by entering 'q', you will have to remove the exit.

class Translate
    def initialize(file_name)
        @file_name = file_name
    end

    def set_translation
        @translations = YAML.load_file @file_name
    end

    def translate
        puts "Enter word or phrase to be translated to English, press 'Q' to quit:"
        input = gets.chomp
        if (@translations || set_translation)[input]?
            puts "The translation from Spanish to English is: #{@translations[input]}"
        elsif input =~ /q/i
            return
        else
            puts "Invalid word or phrase redirecting..."
            translate
        end
    end
end

spanish = Translate.new('spanish.yaml')
spanish.translate

This can then be expanded easily to allow any language, by just passing a different file path.


As for welcome, I would recommend using an Array so you have control over the order. And so you can specify languages by only name and file.

languages = [
    ["Spanish", Translate.new('spanish.yaml')],
    ["Russian", Translate.new('russian.yaml')],
    ["Arabic", Translate.new('arabic.yaml')]
]

Being able to use this in the output is a simple each_with_index.

For the program to automatically call translate you need to get the index of the language in the languages Array. Where you get the index either via a regex or .index. Finally you then check if it's valid input, and output correctly.

def welcome
    languages = [
        ["Spanish", Translate.new('spanish.yaml')],
        ["Russian", Translate.new('russian.yaml')],
        ["Arabic", Translate.new('arabic.yaml')]
    ]

    puts "Welcome to the Translation Center! Please enter the language you would like to translate to English or you can choose from the list below:"
    languages.each_with_index { |item, index| puts String(index + 1) + '. ' + item[0] }
    language = gets.chomp!.downcase

    index = if /^\d+$/.match(language) then
        Integer(language) - 1
    else
        languages.index { |x| x[0].downcase == language }
    end

    if index.nil? or (language = languages[index][1]).nil?
        puts "Language is not yet supported within Translation Center."
    else
        language.translate
    end
end

Finally, I think that you should allow users to input more than one word or phrase at a time. This would be adding a simple infinite loop to Translate.translate, and changing it to not be recursive.

\$\endgroup\$
  • \$\begingroup\$ I was actually in the process of working on making it able to translate more then one word or phrase haha. I'll try out making it into more of an OOP and see what I can do with it, thanks for the advice! \$\endgroup\$ – 13aal Oct 29 '15 at 14:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.