capitalization - Why does my ruby pig latin translator not capitalize the first word of a string properly? -
i trying write program translates string capitalized words , punctuation pig latin. here conditions:
1) words beginning vowel should tack on "ay".
2) words beginning single phoneme "sch" or "qu" or "squ" or "ch" should move of characters end, not first letter, , tack on "ay".
3) regular pig latin rules word beginning 1 consonant (i.e., "well," => 'ellway,").
4) capitalization , punctuation should preserved, initial letter change if letter doesn't begin vowel. "well," become "ellway,".
everything works, except first word of string. fourth condition never met first word of string. so, example, "well," becomes "ellway,". punctuation works, capitalization isn't working properly.
edit: have realized issue occurs when word not begin vowel. so, "actually," becomes "actuallyay," (which should), "quaint," becomes "aintquay,", when should "aintquay,". so, here code pass pig latin array named pig_latin:
string = string.split(' ') pig_latin = [] string.each |word| if vowels.include?(word[0]) pig_latin << word + "ay" elsif (consonants.include?(word[0]) && consonants.include?(word[1]) && consonants.include?(word[2])) || word[1..2].include?('qu') pig_latin << (word[3..-1] + word[0..2] + "ay") elsif (consonants.include?(word[0]) && consonants.include?(word[1])) || word[0..1].include?('qu') pig_latin << (word[2..-1] + word[0..1] + "ay") else pig_latin << (word[1..-1] + word[0] + "ay") end end
here part of code handles capitalization , punctuation. clarify, pig_latin array pig-latinized phrase passed it. uppercase_alphabet array created include uppercase letters:
idx1 = 0 while idx1 < pig_latin.count word = pig_latin[idx1] idx2 = 0 while idx2 < word.length if uppercase_alphabet.include?(word[idx2]) word[idx2] = word[idx2].downcase word[0] = word[0].upcase end if punctuation.include?(word[idx2]) word[word.length], word[idx2] = word[idx2], '' end idx2 += 1 end idx1 += 1 end pig_latin.join(' ')
edit: here code outlining various arrays i'm using:
vowels = ['a', 'e', 'i', 'o', 'u', 'a', 'e', 'i', 'o', 'u'] lowercase_alphabet = ('a'..'z').to_a uppercase_alphabet = ('a'..'z').to_a alphabet = lowercase_alphabet + uppercase_alphabet punctuation = ['.', ',', ';', '?', '!', ':'] consonants = [] alphabet.each |letter| consonants << letter unless vowels.include?(letter) end
and, here errors i'm getting when run test following string: "well, have, not even. seen movie." (i understand punctuation makes no sense).
1) #translate retains punctuation original phrase failure/error: s.should == "ellway, iay avehay, otnay evenay. eensay atthay oviemay." expected: "ellway, iay avehay, otnay evenay. eensay atthay oviemay." got: "ellway, iay avehay, otnay evenay. eensay atthay oviemay." (using ==) # ./spec/04_pig_latin_spec.rb:83:in `block (2 levels) in <top (required)>
it hard debug imaginary code. asking people why code doesn't work without providing values of key variables.
her tips:
1) string works array, don't have create array of individual letters, forces type commas , quote marks:
vowels = 'aeiou' vowels.include?('a') #=>true
2) don't have include caps in arrays of consonants , vowels, instead can downcase before calling include?():
ch = 'a' vowels.include?(ch.downcase) #=> true
3) when debugging, puts
, p
(for arrays, hashes) friend. can find out elsif branches executing adding puts/p statements:
if vowels.include?(word[0]) puts 'x' pig_latin << word + "ay" elsif (consonants.include?(word[0]) && consonants.include?(word[1]) && consonants.include?(word[2])) || word[1..2].include?('qu') puts 'a' pig_latin << (word[3..-1] + word[0..2] + "ay") elsif (consonants.include?(word[0]) && consonants.include?(word[1])) || word[0..1].include?('qu') puts 'b' pig_latin << (word[2..-1] + word[0..1] + "ay") else puts 'c' pig_latin << (word[1..-1] + word[0] + "ay") end end
4) when comparing strings, can use ==
. instead of this:
word[0..1].include?('qu')
...you can write:
if word[0..1].downcase == 'qu'
it's more efficient use ==
when can.
5) if conditionals complex. if know regexes are, can simplify things extracting consonants @ beginning of word, , using if statements test consonants are:
words = %w{ schlepp quail squall checkers } consonants = ('a'..'z').to_a.join.tr('aeiou', '') words.each |word| md = word.match(/ \a #match start of string, followed by... [#{consonants}]+ #a consonant, 1 or more times /x) if md starting_consonants = md[0] #test starting_consonants here, e.g. #if starting_consonants == 'q' , word[1] == 'u' # else #then word starts vowel ... end end --output:-- schl q sq ch
you can limit number of consonants extracted 3 this:
[#{consonants}]{1,3}
6) handle capitalization @ same time change words--then won't have search through letters in every word. first thing, check capitalization of first letter (then set flag variable, e.g. capitalized = true). downcase first letter. after change word, if there capital, upcase first letter(you can call capitalize(), result can different calling upcase() on first letter). way don't have search through whole word in complicated nested loop. sure set flag variable false.
7) in ruby, use while loops , increment counter:
while idx2 < word.length char = word[idx2] ... ... idx2 += 1 end
instead, use each() loops:
word.each_char |char| #do char end
Comments
Post a Comment