The undefined name in the loop? - pylint

I was misleded by Pymodelint and asked an embarrassing quesiton today here.
TL;DR:
def test():
a = 0
for i in range(5):
if i == 2:
a = b # an alert appears here saying that [Pymode] E0602 undefined name 'b' [pyflakes]
b = a + 1
print(b)
The pymodelint is compilted for python3. I have tested the above code to reproduce the error alert.
Why there should be an alert?

Related

Undefined Method Error - Modifying a Hash in a Case Statement After

So, I made a hash called "facing". I call a case statement after, where I want to subtract 1 from the value if the user types L, or (I didn't get here yet) add 1 if the input = 'R'.
class Rover
attr_accessor :orientation
end
#facing = Hash.new
facing = {
0 => 0
}
bot = Rover.new
bot.orientation = "N"
puts "Bot's current orientation is: " + bot.orientation
puts "What direction to turn ('L' or 'R')?"
input = gets.chomp.to_s.capitalize
case input
when input = 'L'
facing do |key, value|
value - 1
end
end
The problem is that I get a method undefined (facing) error message. What am I doing wrong?
Have a look at the documentation for case.
This statement: input = 'L' means "give the variable input the value 'L'", not "check if it equals 'L'".
But that's not where your error is coming from. With facing do... You're giving a block to a hash, which is confusing the compiler and causing it to look for a facing method.
What exactly are you trying to do with the hash?

Ruby does not recognize times method

I wrote a program to simulate the rolling of polyhedral dice but every time I run it I get the error shown below. It displays my prompts and lets me input my numbers, but after that it screws up. I've been trying to find a fix online but I only find people talking about different problems with the times method being undefined. I'm new to Ruby, so any help would be appreciated.
My program:
p = 0
while p < 1
puts "Choose your die type"
die_type = gets.chomp
puts "Choose your number of die"
die_number = gets.chomp
total = 0
i = 1
die_number.times do
random_int = 1 + rand(die_type)
total += random_int
i += 1
end
puts total
end
The error I get:
/dieroll.rb:13: undefined method 'times' for "5":String (NoMethodError)
Change die_number = gets.chomp to die_number = gets.to_i. die_number = gets.chomp, assigns a string to the local variable die_number( Because Kernel#gets gives us a string object). String don't have any method called #times, rather Fixnum class has that method.
Change also die_type = gets.chomp to die_type = gets.to_i, to avoid the next error waiting for you, once you will fix the first one.
1.respond_to?(:times) # => true
"1".respond_to?(:times) # => false
In you case die_number was "5", thus your attempt "5".times raised the error as undefined method 'times' for "5":String (NoMethodError).

Getting (NoMethodError) as if object has not been created

I'm having difficulty running the following. I get the following error
"': undefined method `name' for nil:NilClass (NoMethodError)"
at the
puts shopper[i].name
line
As if sometimes the object hasn't been created by the time it gets to that line
(0 .. 9).each do |i|
shopper[i] = Shopper.new("Shopper Number-#{i}")
(0 .. 19).each do |j|
r = rand(0 .. (k-1))
if shopper[i].unsuccessful_shopping_trip == true
puts "#{shopper[i].name} has failed to buy 3 times and has decided to go home"
i += 1
break
else
if shopper[i].add_product(shop.remove_product_bought_by_shopper(r)) == false
puts "#{shopper[i].name} has tried to buy #{(shop.products[r]).name} but it is sold out"
j -= 1
else
puts "#{shopper[i].name} has bought #{(shop.products[r]).name}"
end
end
end
puts shopper[i].name
puts shopper[i].shopping_list
total_shopper_net += shopper[i].total_net_value
total_shopper_gross += shopper[i].how_much_spent
total_shopper_product_count += shopper[i].total_product_count
end
Can anyone explain this?
You are manually incrementing i within the each iterator. Any subsequent reference to shopper[i] does not yet exist, since shoppers are created only at the top of the loop.

Why don't the following Ruby methods work? I've written a couple of methods that are supposed to give the sum of an entered array

This is what's up:
It seem I've got a syntax problem. Both of the following methods, which are similar to one another, load to irb fine. When I go to use them, though, they produce errors. Since I'm just learning this, I'm not only looking for a fix, I'm looking to understand why both return errors and how any fix works to solve the issues.
Thanks for the help,
TJ
First method:
def sum(*)
i = 1
total = sum[0]
until sum[i] == nil
total = total + sum[i]
i += 1
end
puts total
end
Upon loading this file irb returns => nil, no errors. However, an attempt to use the method looks like:
sum 3, 58, 298, 2
Unknown error.
Writing the method directly in irb vs loading .rb file produces this error after line 3:
def sum(*)
.. i = 1
.. total = sum[0]
(eval):2: (eval):2: compile error (SyntaxError)
(eval):2: syntax error, unexpected $end, expecting kEND
total = sum[0]
^
Now, I see that it says SyntaxError but I do not know what the rest of the feedback means nor what proper syntax for this would be.
Second method:
def sum(*)
i = 1
total = sum[0]
until i == sum.count
total = total + sum[i]
i += 1
end
puts total
end
This one produces all the same errors in the same ways as the first.
Try this instead:
def sum(*nums)
sum = 0
nums.each { |num| sum += num }
sum
end
sum(1, 2, 3)
I don't think `def sum(*) is valid Ruby syntax; you have to give your vararg a name.
Also, see this Stackoverflow question for an even shorter way to sum an array of numbers.

NoMethodError: undefined method `+#' for "some sting":String

My rails app just started receiving this error today. Here is the code context. It is throwing the error on the line that starts with new_host_id
while #host_ids.include?(new_host_id)
i++
new_host_id = duplicate_host_id + i.to_s
end
Ruby does not have a ++ operator.
The idiom in Ruby is i += 1, which is the abbreviated form of i = i + 1.
Initially I thought that the posted code was incorrect and had to be ++i to generate that error. However, as Jörg W Mittag explains in a comment, this is not the case:
[..] Ruby allows whitespace (including line breaks) between an operator and the operand(s), so the entire thing is interpreted as i + (+(new_host_id = duplicate_host_id + i.to_s)) [.. which is] why the NoMethodError refers to String.
Here is a simplified example showing the issue (the posted code refers to the first case):
> x = "hello"
> +x
undefined method `+#' for "hello":String (NoMethodError)
> x+
syntax error, unexpected $end
I used + and not ++ above to simplify the example: Ruby treats ++i and i++ as the productions +(+i) and [roughly] i+(+) ..
It turns out the error was caused by the previous line i++
I changed i++ to i = i + 1 and it's working now.
Here's the working code
while #host_ids.include?(new_host_id)
i = i + 1
new_host_id = duplicate_host_id + i.to_s
end
If you had warnings on, you'd probably have got a warning about that line.
$VERBOSE = true
def foo
i = 2
i++
j = 5
j + i
end
warning: possibly useless use of + in void context

Resources