For loop with flexible stop variable - ruby

I need to write a loop
for x in (1..y)
where the y variable can be changed somehow. How can I do that?
For example:
for x in (1..y/x)
But it does not work.

Normally we'd use a loop do with a guard clause:
x = 1
loop do
break if x >= y
x += 1
...
end
Make sure y is larger than x or it'll never do anything. y can change if necessary and as long as it's greater than x the loop will continue. As soon as y drops below x the loop will terminate on the next iteration.
Note: I use >= because testing for equality is a bug-in-waiting. Sometimes we try to compare where x starts out greater than y or we are incrementing a float and comparing it to an integer or another float and using == and never hit the magic "equal" causing the loop to run away. Instead always check for a greater-than-or-equal to end the loop.

I think you might be confused about return values. This actually works fine, it's just that the return value is equal to the original range.
y = 4
for x in (1..y)
puts x
end
# 1
# 2
# 3
# 4
#=> 1..4
Here's a code snippet to prove it.

Related

Check if numeral within bounds in one statement

Is there a way to check if a number x is greater than a number a and less than a number b, without specifying x twice?
I can do this:
x = 4
a = 1
b = 10
x > a && x < b
...but is there a way to do something like this:
# not valid ruby, is there another way?
a < x < b
This does not answer the question exactly, please read the Edit part of the answer.
Tested this to work for x being an Integer and a Float.
(a..b).include? x
Edit:
As #spickermann pointed out in comments the original question excludes the beginning and the end of the interval.
To exclude the end is easy, this is what ... is for. Therefore
(a...b).include? x # is the same as `a <= x && x < b`
To exclude the start of the interval is not that easy. One could use next_float:
(a.to_f.next_float...b).include? x
However even the (a...b) is something I would not use because it is not so common literal and in my opinion decreases readability of the code. With a.to_f.next_float we are making some really awkward code that may work for Integers and Floats but I would be afraid of other Numeric data types.
Unless someone brings completely different approach I would stick with x > a && x < b

What is wrong with my if statement 'if x + y = z'

I am trying to evaluate if a selected item meats a requirement. I am trying to evaluate the result of nominal + x against required.
I am using the following code:
if #weight.nominal + x = required
weights << #weight.id
end
However, it adds nominal + x together. Why is that, and how do I do what I want?
As #Pavan said in the comment, your conditional might be wrong. It should be == instead of =. = is the assignment.
if #weight.nominal + x == required ... end
Here what happens "behind the scene" with your original code:
required is assigned to x.
Add x to #weight.nominal (#weight.nominal + x)
Evaluate the result from step 2, which is always true.
Execute the code within if block, which is weights << #weight.id
Eventually, your x's value is lost, it will take required value instead and your conditional is useless since it always true.

Does VBScript have increment operator?

For y = 1 to 10
y = y+1
print(y)
Next
For the above code the output which I get is 2,4,6,8,10. Shouldn't the o/p be 2,3,4,5,6,7,8,9,10
Can I consider y = y+1 as y++
The default step increment for a vbscript for loop is 1. By adding in y=y+1, you are effectively increasing your increment by 2 each cycle:
For y = 2 to 10 step 2
Wscript.echo y
Next
There is no "increment operator" as such; However you could consider step an increment operator in this context (both positive and negative).
y = y + 1 is similar as the intended concept y++.
You would probably be best using that type of operation inside a do/while loop where there are no auto increments eg:
y = 0
do while y < 10
y = y + 1
wscript.echo y
Loop
See this previous post:
Does VBScript have Increment Operators
in a For...Next loop, you won'T need to increase the counter value manualy.
You are increasing the value that is increased by the For loop:
For y = 1 to 10 ' starts at 1, next is 3
y = y+1 ' but you increase it to 2, increased to 4
print(y) ' prints 2, 4
Next ' Increases to 3, 5, up to 11, then stops because it's greater than 10
No, VB Script doesn't have an increment operator. VB script is based on BASIC which is a language meant for learning and the increment operator is considered to be confusing by many so it was never added on purpose.
As for your second question, to get the output you want remove y = y+1 line and change loop to For y = 2 to 10. Also, yes, y=y+1 is the same as y++ in most languages.

IF condition is met, start loop at beginning (Ruby)

Using ruby 1.9.3, I need to do the following:
test_ids.each do |x|
if x == 1
y = x+1
elsif x == 2
y = x+2
elsif x == 3
(end loop here, start over with next test_id)
else
y = x+4
end
end
I just need the loop to continue with the next object in the array if a condition is met instead of continuing throughout the script. How is this possible?
EDIT:
The end goal is something like this:
case x
when 1
abort
when 2
...
else
...
end
puts x+2
So as you can see, x is being used after the if case statement. I need to not run the puts statement if x = 1. I don't want to abort the script and terminate it altogether, I just want to skip that array object and go to the next one. Any suggestions?
= assigns a value to x so your code only executes x = 1 inside the loop.
Instead you need a comparison using == in your if statements.
You could have avoided this using a case statement:
case x
when 1
...
when 2
...
when 3
...
else
...
end
In my experience using case tends to clarify code compared to multiple if/else/elsif.
You are looking for the next command.
test_ids.each do |x|
if x == 1
y = x+1
elsif x == 2
y = x+2
elsif x == 3
next
else
y = x+4
end
end

Python Matrix Neighbor Checking

I have a 7*7 matrix containing 0s and 1s in which each (x,y) will be checked for how many of its neighbors are a 1. I am a beginner to python, and will only be using basic programming procedures.
I have:
for x in range(rows):
for y in range(cols):
lives = 0
lives = neighbors(matrix, rows, cols)
def neighbors(matrix, rows, cols):
if matrix[x][y+1] == 1:
lives += 1
if matrix[x-1][y+1] == 1:
lives += 1
#All 8 positions are checked like this
return lives
I am getting the ol indexing error. This seems like a very simple problem I just can't seem to figure out how to fix it.
First of all, the index error occurs when you do y+1. Since you are going in the range of the amount of cols, this will end up being cols+1, which is out of range.
What you can do is use a try-except block, or make sure it doesn't get out of range through only looping to cols-1.
Additionally your function definition is redundant, since you don't use all your input parameters, and you access the x and y variables in the global scope.
The easiest thing to do is probably just to remove the definition and the return-statement.
This should work:
for x in range(rows):
for y in range(cols-1): #Loop until the second to last element.
lives = 0
if matrix[x][y+1] == 1:
lives += 1
if x == 0: #You probably don't want to check x-1 = -1
continue
if matrix[x-1][y+1] == 1:
lives += 1

Resources