What am I doing wrong with this simple If function in ruby - ruby

I have been trying to teach myself to code and have gravitated towards Ruby.
Upon working on if functions I have come across this problem where even if the user input is == to the answer variable it still comes back as false in the if function. It will not come back as true
I can get it to work if it is an Integer, but for some reason it always returns false when having a string. Tried to convert is as well but can not figure it out.
Thank you for any help.
puts("For each question select A, B, or C")
puts("What is the capital of Kentucky?")
puts()
puts("A. Louisville")
puts("B. Frankfort")
puts("C. Bardstown")
puts()
answer = String("B")
text = gets()
puts()
if text == answer
puts("correct")
else
puts("incorrect")
puts("The correct answer was " + answer + ".")
end

There is an additional method you can call when declaring the "text" variable that will solve this.
The method you used preserves a line break at the end when you press enter to submit an answer so it will never actually correspond to the answer. To remove the line break use the "chomp" method.
text = gets.chomp
Hope this helped. Good luck.

Related

Detecting bad syntax in a string [duplicate]

This question already has answers here:
Better way to write "matching balanced parenthesis" program in Ruby
(8 answers)
Closed 8 years ago.
I just went through those interview coding quizzes for the first time and I'm somewhere between submerging myself in a tub of dran-o and investing in No Tears bubble bath products along with a bunch of toasters.
The problem was as follows:
If you're given a string like "zx(c)abcde[z{x]}", write a function that returns true if the syntax is correct and false if the syntax is incorrect: for example, in that string the brackets and braces are messed up. In other words "{hello}mot[o]" will pass but "{hello}mo{[t}" would not.
My throught process went like: keep a list of opening and closing bracket/brace/parens positions, then see if there is overlap. But that wasn't an optimal solution so I bombed it.
I'd like some help understanding how to solve this problem.
Thanks in advance.
[Edit: I've incorporated both of #sawa's excellent suggestions.]
One way you can do this is with a stack.
MATCH = { '['=>']', '('=>')', '{'=>'}' }
OPENING = MATCH.keys
CLOSING = MATCH.values
def check_for_match(str)
str.chars.each_with_object([]) do |c, arr|
case c
when *OPENING
arr << c
when *CLOSING
return false unless c.eql?(MATCH[arr.pop])
end
end.empty?
end
check_for_match("zx(c)abcde[z{x]}") #=> false
check_for_match("zx(c)abcde[z{x}]") #=> true
[Edit: I thought this question seemed familiar. I and several others answered it a while ago.]
Another way to do this is to first strip out the irrelevant characters, then sequentially remove adjacent matching pairs until either the string is empty (return true) or the string is not empty and there are no more matching adjacent pairs (return false).
def check_for_match(str)
str = str.gsub(/[^\(\)\[\]\{\}]/, '')
while str.gsub!(/\(\)|\[\]|\{\}/, ''); end
str.empty?
end
check_for_match("zx(c)abcde[z{x]}") #=> false
check_for_match("zx(c)abcde[z{x}]") #=> true
Reader challenge: provide a proof that the syntax is incorrect when false is returned.
I would replace each bracket with an XML tag, and just run it through an XML validator. It'll pick out weird stuff like this:
<bracket>stuff<curly>morestuff</bracket></curly>
This will fail XML validation, so you can just return that.

Ruby String/Array Write program

For a project that I am working on for school, one of the parts of the project asks us to take a collection of all the Federalist papers and run it through a program that essentially splits up the text and writes new files (per different Federalist paper).
The logic I decided to go with is to run a search, and every time the search is positive for "Federalist No." it would save into a new file everything until the next "Federalist No".
This is the algorithm that I have so far:
file_name = "Federalist"
section_number = "1"
new_text = File.open(file_name + section_number, 'w')
i = 0
n= 1
while i < l.length
if (l[i]!= "federalist") and (l[i+1]!= "No")
new_text.puts l[i]
i = i + i
else
new_text.close
section_number = (section_number.to_i +1).to_s
new_text = File.open(file_name + section_number, "w")
new_text.puts(l[i])
new_text.puts(l[i+1])
i=i+2
end
end
After debugging the code as much as I could (I am a beginner at Ruby), the problem that I run into now is that because the while function always holds true, it never proceeds to the else command.
In terms of going about this in a different way, my TA suggested the following:
Put the entire text in one string by looping through the array(l) and adding each line to the one big string each time.
Split the string using the split method and the key word "FEDERALIST No." This will create an array with each element being one section of the text:
arrayName = bigString.split("FEDERALIST No.")
You can then loop through this new array to create files for each element using a similar method you use in your program.
But as simple as it may sound, I'm having an extremely difficult time putting even that code together.
i = i + i
i starts at 0, and 0 gets added to it, which gives 0, which will always be less than l, whatever that value is/means.
Since this is a school assignment, I hesitate to give you a straight-up answer. That's really not what SO is for, and I'm glad that you haven't solicited a full solution either.
So I'll direct you to some useful methods in Ruby instead that could help.
In Array: .join, .each or .map
In String: .split
Fyi, your TA's suggestion is far simpler than the algorithm you've decided to embark on... although technically, it is not wrong. Merely more complex.

Need help breaking up Ruby code into methods

I am writing a program to better learn to program and I wish to use RSpec so that I can learn that as well. However, as is, the code isn't particularly RSpec friendly, so I need to break it up into methods so that I can test it.
I don't need anyone to write the code for me, but perhaps explain how I can break it up. I am new to programming and this kind of thing (breaking things up into methods) is a really difficult concept for me.
Here's what I have:
if params[:url] != ''
url = params[:url] #line created so I can return url more easily (or, in general)
words = params[:word].gsub("\n", ",").delete("\r").split(",") #.delete redundant?
words.reject!(&:empty?)
words.each(&:lstrip!)
return "#{words}", "#{url}" #so that I can return url, not sure how to do that yet
end
The code is a SERP checker, it takes a url and keywords and checks their location in the search engines.
For url, it'll just be the url of the website the user wishes to check... for word, it would be the keywords they wish to check their site against in Google.. a user may fill out the input form like so:
Corn on the cob,
Fibonacci,
StackOverflow
Chat, Meta, About
Badges
Tags,,
Unanswered
Ask Question
Your code takes a sloppy string and turns it into a clean array. You first clean up the string, then you polish the array. You could define methods for these actions.
def clean_up_words(str)
#code to clean str
str
end
def clean_up_list(arr)
#code to clean arr
arr
end
dirty_list = clean_up_words( params[:word]).split(',')
clean_list = clean_up_list( dirty_list )
def foo params
url = params[:url]
url.empty? ? nil : [params[:word].scan(/[^\s\r,]+/), url]
end
You are assigning url = params[:url]. If you are going to do that, you should do it before other places where you refer to the same thing to reduce the amount of calling [] on param.
You have several conditions on the words to be extracted. (a) Either split by "\n", ",", "\r", (b) the word should not be of 0 length, (c) white characters should be stripped off. All of this can be put together as scan(/[^\s\r,]+/).
You want to return two variables when url is not empty. Use an array in that case.

Return popupmenu selection in MATLAB using one line of code

I have a GUI which uses a selection from a popupmenu in another callback. Is there a way to return the selected value of the popupmenu in only one line without creating any temporary variables? I've tried several solutions, but I've only managed two lines with one temporary variable:
Three lines:
list=get(handles.popupmenu1,'String');
val=get(handles.popupmenu1,'Value');
str=list{val};
Two lines:
temp=get(handles.popupmenu1,{'String','Value'});
str=temp{1}{temp{2}};
Can anyone shave it down to one?
PS, It's a dynamic menu, so I can't just use get(handles.popupmenu1,'Value') and ignore the string component altogether.
Here's a one-liner:
str = getCurrentPopupString(handles.popupmenu1);
And here's the definition of getCurrentPopupString
function str = getCurrentPopupString(hh)
%# getCurrentPopupString returns the currently selected string in the popupmenu with handle hh
%# could test input here
if ~ishandle(hh) || strcmp(get(hh,'Type'),'popupmenu')
error('getCurrentPopupString needs a handle to a popupmenu as input')
end
%# get the string - do it the readable way
list = get(hh,'String');
val = get(hh,'Value');
if iscell(list)
str = list{val};
else
str = list(val,:);
end
I know that's not the answer you were looking for, but it does answer the question you asked :)
I know this is stupid, but I couldn't resist:
list=get(handles.popupmenu1,'String'); str=list{get(handles.popupmenu1,'Value')};
I know that's not what you meant, but like the other answers above, it does answer your question... :-)
To make it a one-liner, I would simply create my own function (i.e. getMenuSelection) like Jonas illustrates in his answer. If you really want a true one-liner, here's one using CELLFUN:
str = cellfun(#(a,b) a{b},{get(handles.popupmenu1,'String')},{get(handles.popupmenu1,'Value')});
Very ugly and hard to read. I'd definitely go with writing my own function.
EDIT: And here's a slightly shorter (yet still equally ugly) one-liner using FEVAL:
str = feval(#(x) x{1}{x{2}},get(handles.popupmenu1,{'String','Value'}));

Ruby gets function won't accept empty line more than once

I'm trying to write a simple ruby function that can prompt the user for a value and if the user presses ENTER by itself, then a default value is used.
In the following example, the first call to the Prompt function can be handled by pressing ENTER by itself and the default value will be used. However, the second time I call Prompt and press ENTER, nothing happens, and it turns out I have to press some other character before ENTER to return from the 'gets' call.
There must be some way to flush the input buffer to avoid this problem. Anyone know what to do?
Thanks,
David
def BlankString(aString)
return (aString == nil) ||
(aString.strip.length == 0)
end
#Display a message and accept the input
def Prompt(aMessage, defaultReponse = "")
found = false
result = ""
showDefault = BlankString(defaultReponse) ? "" : "(#{defaultReponse})"
while not found
puts "#{aMessage}#{showDefault}"
result = gets.chomp
result.strip!
found = result.length > 0
if !found
then if !BlankString(showDefault)
then
result = defaultReponse
found = true
end
end
end
return result
end
foo = Prompt("Prompt>", "sdfsdf")
puts foo
foo = Prompt("Prompt>", "default")
puts foo
This isn't technically an answer, but it'll help you anyways: use Highline (http://highline.rubyforge.org/), it'll save you a lot of grief if you're making a command-line interactive interface like this
I tried your code (under Windows) and it seemed to work fine.
What OS are you using?
I also tried your code (under OSX) with ruby 1.8.6 and it worked fine:
:! ruby prompt.rb
Prompt>(sdfsdf)
sdfsdf
Prompt>(default)
default
What do you get when you run the following?
c = gets
b = gets
a = gets
p [ a, b, c ]
I just hit 'Enter' 3x and get
["\n", "\n", "\n"]
I'm guessing what's wrong is that you're entering an infinite loop in your while statement by not passing it a defaultResponse (in some code that you're actually runinng that's not in your example).
I have confirmed (by running the program outside of Komodo) that the problem is in fact solely happening inside Komodo. I thank everyone for the feedback and taking the time to do the independent test (which I hadn't though of) to help narrow down the problem.

Resources