Ruby skips a section of script - ruby

Ruby noob here, and I am having an infuriating issue.
Something in my script is making Ruby skip a section of it.
#Main_block_begins_here
if __FILE__ == $0
#Open_the_file_with_values_and_weights
File.open(getFileName, 'r') do |f|
#Intial_data...
$totalNumber=f.gets.chomp!.to_i
$totalCapacity=f.gets.chomp!.to_i
$currentItemWeight=0
$currentItemValue=0
$spaceLeft=0
$spaceLeft=$totalCapacity
$takenWeight=0
$takenValue=0
#Make_a_heap_for_the_data
$prioQ = Heap.new do
#reads_values,_computes_them,_and_enqueues_them
until i==$totalNumber
total=0
value=f.gets.chomp!.to_i
weight=f.gets.chomp!.to_i
total=value/weight
puts "#{total}=t, #{value}=v, #{weight}=w. Correct?"
check=gets.chomp!
it=Obj.new(total, value, weight) do
prioQ.enqueue(it)
end
i+=1
end
end
#dequeueIt
puts "total weight taken was #{$takenWeight} and total value taken was #{$takenValue}."
end
end
The commented line #dequeueIt is a method earlier on that when I let run, it gives me an infinite loop with all values that were supposed to be read in from the text file as zeros.
The puts line and the check declaration line inside the until loop are for debugging purposes, and of course they never print out.
Commented out, when I run the program it just prints out the last line as if the until loop never ran. If more code for context is necessary, just let me know and I'll put it up.
My hair's starting to fall out over this one, so any help is appreciated!
EDIT:: Yes, it should have been i==$totalnumber. I fixed it in my code and it still doesn't execute the script inside that loop.

This is one oversight:
until i=$totalNumber
This assigns a number to i; it is always true. Try
until i==$totalNumber

Related

I keep getting a comparison between number and nil when trying to sort a table by myself

taula = {};
function randomNumber()
return math.random(100);
end
function startArray()
for x=0, 10 do
taula[x]=randomNumber();
end
end
function printArray()
for i=0,#taula do
print(taula[i]);
end
end
function organizeArray()
for i=0,#taula do
for j=1,#taula do
if taula[i]>taula[j] then
tmp = taula[j];
taula[j]=taula[i];
taula[i]=taula[tmp];
end
end
end
end
startArray()
organizeArray()
printArray()
This is not working! The initial idea is to have printed the table declared as 'taula' but in the function organizeArray() there is a problem in the if, it says I compare a number with a nil value when I have both j and i variables declared. I need help.
You're referencing tala[tmp] instead of tmp (at line 27) when you're shuffling the array around. That's what's causing the bug.
A few pointers:
You're using globals for everything. This can cause headaches later on, when globals collide (i.e tmp could be set to something, and you do something with it). See: Local Variables and Blocks
Using randomNumber() makes your code kind of obscure, since randomNumber is just an alias for math.random(100).
Lua starts at 1, not 0. You can start at 0, but this is just something to keep in mind. #table will not count the index 0.
When asking questions, please give the full error message -- this'll let us look at the code without having to run it ourselves :)
You can put print(x) in your code, so you can see what's happening. This'll help you find bugs, since you know whats going on.

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.

Ruby negated-if statements

I have a statement checking if a string contains another; if it doesn't, it runs some code. I don't think I'm doing it in a very optimised way. Here is a code snippet:
if blocks_in_progress.include? ('|' + blocks[i])
else
block = blocks[i]
break
end
Bit of a Ruby newbie here, but as far as I understand it, the following is the preferred way:
unless blocks_in_progress.include? ('|' + blocks[i])
block = blocks[i]
break
end
Source: https://github.com/bbatsov/ruby-style-guide (syntax section)
A one liner:
break block = blocks[i] unless blocks_in_progress.include? ('|' + blocks[i])

Ruby, how should I design a parser?

I'm writing a small parser for Google and I'm not sure what's the best way to design it. The main problem is the way it will remember the position it stopped at.
During parsing it's going to append new searches to the end of a file and go through the file startig with the first line. Now I want to do it so, that if for some reason the execution is interrupted, the script knows the last search it has accomplished successfully.
One way is to delete a line in a file after fetching it, but in this case I have to handle order that threads access file and deleting first line in a file afaik can't be done processor-effectively.
Another way is to write the number of used line to a text file and skip the lines whose numbers are in that file. Or maybe I should use some database instead? TIA
There's nothing wrong with using a state file. The only catch will be that you need to ensure you have fully committed your changes to the state file before your program enters a section where it may be interrupted. Typically this is done with an IO#flush call.
For example, here's a simple state-tracking class that works on a line-by-line basis:
class ProgressTracker
def initialize(filename)
#filename = filename
#file = open(#filename)
#state_filename = File.expand_path(".#{File.basename(#filename)}.position", File.dirname(#filename))
if (File.exist?(#state_filename))
#state_file = open(#state_filename, File::RDWR)
resume!
else
#state_file = open(#state_filename, File::RDWR | File::CREAT)
end
end
def each_line
#file.each_line do |line|
mark_position!
yield(line) if (block_given?)
end
end
protected
def mark_position!
#state_file.rewind
#state_file.puts(#file.pos)
#state_file.flush
end
def resume!
if (position = #state_file.readline)
#file.seek(position.to_i)
end
end
end
You use it with an IO-like block call:
test = ProgressTracker.new(__FILE__)
n = 0
test.each_line do |line|
n += 1
puts "%3d %s" % [ n, line ]
if (n == 10)
raise 'terminate'
end
end
In this case, the program reads itself and will stop after ten lines due to a simulated error. On the second run it should display the next ten lines, if there are that many, or simply exit if there's no additional data to retrieve.
One caveat is that you need to remove the .position file associated with the input data if you want the file to be reprocessed, or if the file has been reset. It's also not possible to edit the file and remove earlier lines or it will throw off the offset tracking. So long as you're simply appending data to the file, or restarting it, everything will be fine.

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