Forum: Ruby Simulation of a dictionary

Posted by Joao Silva (rubyforum)
on 2012-10-09 20:17
Hi all.

What I'm trying to do, is a program that has a hash with predefined
words and its corresponding meaning, then when I enter a word that is
found in the hash, I must return its meaning, and if not found in the
hash, should return the most similar word.

This is the code that was doing:

#######################################################################

words={
"computer" => "an electronic device ...",
"cat" => "a small domesticated carnivorous ...",
"home" => "the place where one lives permanently ...",
"dog" => "a domesticated carnivorous mammal ... "
}

like=""
print "Enter word to search: "
w=gets.chomp.to_s

word.each{|k,v|
if k==w
    puts v
else
    for i in 0..10
  if k[i]==w[i]
             like[i]=w[i]
  end
     end
end
}
################################################################

for example if I enter the word home, returns me its meaning:

home => "the place where one lives permanently ..."

and if such entry hom, meaning me back home with any word and thus
similar to those found in the hash.

Thanks.
Posted by Eric Christopherson (echristopherson)
on 2012-10-09 21:10
(Received via mailing list)
On Tue, Oct 9, 2012 at 1:17 PM, Joao Silva <lists@ruby-forum.com> wrote:
> Hi all.
>
> What I'm trying to do, is a program that has a hash with predefined
> words and its corresponding meaning, then when I enter a word that is
> found in the hash, I must return its meaning, and if not found in the
> hash, should return the most similar word.

Maybe use something like Levenshtein distance.

Some links to look at:
http://stackoverflow.com/questions/2158851/groupin...
http://stackoverflow.com/questions/2531502/detect-...
Posted by Damián M. González (igorjorobus)
on 2012-10-10 15:46
Hi Joao, firs of all, it's not necessary put .to_s() in w, since gets()
means "get string", so everything inputted for the user will be a
string. Second, I recommend you .downcase() the w variable, because the
user may input "CAT", if you will have personal nouns in the dictionary
you'll have to do something like the next showed. I also though a way to
find which is the closest word to what is tipped. Take a look, I tested
it a bit and worked.

#encoding: utf-8

words={
"computer" => "an electronic device ...",
"cat" => "a small domesticated carnivorous ...",
"home" => "the place where one lives permanently ...",
"dog" => "a domesticated carnivorous mammal ... "
}

loop do

print "Enter word to search: "
w=gets.strip

#you can tipe 'exit' to go out
if w == 'exit' then exit end

  resultado = \
  if words.has_key?(w) then words[w]
  elsif words.has_key?(w.downcase) then words[w]
  elsif words.has_key?(w.downcase.capitalize) then words[w]
  else nil end


  unless resultado
        words[w] = "erase after.."
  place = nil
  words_in_array = words.sort
  words_in_array.each_with_index do |value, index|
    if value[0] == w then place = index end
    break if place != nil
  end
  possible_words = [words_in_array[place.-(1)][0], \
  words_in_array[place.+(1)][0]]
  resultado = \
  "The word doesn't match, meaby did you mean: #{possible_words.join('
or ')}. Try again"
  words.delete(w)
  end

  puts resultado

end
Posted by "Jesús Gabriel y Galán" <jgabrielygalan@gmail.com> (Guest)
on 2012-10-10 16:25
(Received via mailing list)
On Tue, Oct 9, 2012 at 9:10 PM, Eric Christopherson
<echristopherson@gmail.com> wrote:
> Some links to look at:
> http://stackoverflow.com/questions/2158851/groupin...
> http://stackoverflow.com/questions/2531502/detect-...
>

The text gem has an implementation of the Levenshtein distance:

require 'text'

words={
"computer" => "an electronic device ...",
"cat" => "a small domesticated carnivorous ...",
"home" => "the place where one lives permanently ...",
"dog" => "a domesticated carnivorous mammal ... "
}

puts "Enter a word: "
s = gets.chomp

if words.has_key?(s)
  puts words[s]
else
  distances = Hash.new {|h,k| h[k] = []}
  words.keys.each {|word| distances[Text::Levenshtein.distance(word,s)] 
<< word}
  # puts "All words sorted by distance"
  # distances.each {|distance, words| puts "#{distance} => 
#{words.join(",")}
  puts "nearest words: #{distances[distances.keys.sort.first]}"
end

Jesus.
Posted by "Jesús Gabriel y Galán" <jgabrielygalan@gmail.com> (Guest)
on 2012-10-10 16:26
(Received via mailing list)
On Wed, Oct 10, 2012 at 4:24 PM, Jess Gabriel y Galn
<jgabrielygalan@gmail.com> wrote:
>> Maybe use something like Levenshtein distance.
> words={
>   puts words[s]
> else
>   distances = Hash.new {|h,k| h[k] = []}
>   words.keys.each {|word| distances[Text::Levenshtein.distance(word,s)] << word}
>   # puts "All words sorted by distance"
>   # distances.each {|distance, words| puts "#{distance} => #{words.join(",")}

There's a typo in this line. Should be

distances.each {|distance, words| puts "#{distance} => 
#{words.join(",")}"}
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.