How to fix " '=' expected near '. .' " error in Lua - for-loop

This error occurs on line 3 of my code and I don't know why.
I'm trying to create multiple variables with x..q, but it doesn't work.
for i=1,3 do
for q=1,3 do
x..q=i+1
print(x..q)
end
end
The output should be:
2
2
2
3
3
3
4
4
4
But instead it returns the error in the title.

If you want to create multiple global variables, use code like this:
for i=1,3 do
for q=1,3 do
_G["x"..q]=i+1
print(_G["x"..q])
end
end
This code will create globals x1, x2, and x3.
But I think you'd be better off using a table:
x={}
for i=1,3 do
for q=1,3 do
x[q]=i+1
print(x[q])
end
end

I believe you are using the operator .. unintentionally.
When accessing a value of a table, the syntax is x.q. Programming in Lua: 2.5 – Tables
To represent records, you use the field name as an index. Lua supports this representation by providing a.name as syntactic sugar for a["name"]. So, we could write the last lines of the previous example in a cleanlier manner as
a.x = 10 -- same as a["x"] = 10
print(a.x) -- same as print(a["x"])
print(a.y) -- same as print(a["y"])
When concatenating a string the syntax is x .. q.
Programming in Lua: 3.4 – Concatenation
Lua denotes the string concatenation operator by ".." (two dots). If any of its operands is a number, Lua converts that number to a string.
print("Hello " .. "World") --> Hello World
print(0 .. 1) --> 01

Related

Checking if a text file is formatted in a specific way

I have a text file which contains instructions. I'm reading it using File.readlines(filename). I want to check that the file is formatted as follows:
Has 3 lines
Line 1: two integers (including negatives) separated by a space
Line 2: two integers (including negatives) separated by a space and 1 capitalised letter of the alphabet also separated by a space.
Line 3: capitalised letters of the alphabet without any spaces (or punctuation).
This is what the file should look like:
8 10
1 2 E
MMLMRMMRRMML
So far I have calculated the number of lines using File.readlines(filename).length. How do I check the format of each line, do I need to loop through the file?
EDIT:
I solved the problem by creating three methods containing regular expressions, then I passed each line into it's function and created a conditional statement to check if the out put was true.
Suppose IO::read is used to return the following string str.
str = <<~END
8 10
1 2 E
MMLMRMMRRMML
END
#=> "8 10\n1 2 E\nMMLMRMMRRMML\n"
You can then test the string with a single regular expression:
r = /\A(-?\d+) \g<1>\n\g<1> \g<1> [A-Z]\n[A-Z]+\n\z/
str.match?(r)
#=> true
I could have written
r = /\A-?\d+ -?\d+\n-?\d+ -?\d+ [A-Z]\n[A-Z]+\n\z/
but matching an integer (-?\d+) is done three times. It's slightly shorter, and reduces the chance of error, to put the first of the three in capture group 1, and then treat that as a subexpression by calling it with \g<1> (not to be confused with a back-reference, which is written \k<1>). Alternatively, I could have use named capture groups:
r = /\A(?<int>-?\d+) \g<int>\n\g<int> \g<int> (?<cap>[A-Z])\n\g<cap>+\n\z/

Find a specific character in a string

I want to find a specific character in a given string of number for example if my input is:
1 4 5 7 9 12
Then for 4 the answer should be 1. My code is as follows:
secarr = second.split(" ")
answer = secarr.index(number) #here number is a variable which gets the character
puts answer
The above method works if I write "4" instead of number or any other specific character but does not work if I write a variable. Is there a method in ruby to do the same?
This is probably your variable number is an Integer, and secarr is an Array of Strings. Try to cast the number to string:
answer = secarr.index(number.to_s)

What does the dot mean in this line of code: 65.+rand(10)

I came across this line of code and could not understand the purposed of the dot. Could someone explain what the dot in 65 . + rand(10) is doing and how this is different from 65 + rand(10)?
For full context I saw this code within this 8 char random string generator:
(0...8).map{65.+(rand(25)).chr}.join => "QSILUSPP"
(0...8).map{65.+(rand(25)).chr}.join => "BJIIBQEE"
(0...8).map{65.+(rand(25)).chr}.join => "XORWVKDV"
You can notice, that in original code there are 2 method calls - + and chr. I can show it by equivalent code:
65.send(:+, rand(10)).send(:chr) # is the equal to following line:
65.+(rand(10)).chr
This trick produces method chain, that allows to skip parentheses. With parentheses, 65.+(rand(10)).chr could be written like this:
(65 + rand(10)).chr
Without this trick, chr will apply on rand(10) and the result string will try to be added to 65. It'll produce TypeError:
65+(rand(25)).chr
TypeError: String can't be coerced into Fixnum
It is not any different. As numbers are objects in Ruby, + is actually a method call and can therefore be using the dot syntax like any other method. The form you're used to seeing, 65 + rand(10), is "syntax sugar" and is equivalent to 65.+(rand(10)).
Why anyone would write code using .+, I have no idea.

Write Multiline Arithmetic in Ruby

How to write multiline arithmetic properly in Ruby? Previously, i have tried something like y, then i realized there is something wrong with that code. I need to write multiline arithmetic due to my very long equation.
a = 5
b = 5
x = (a + b) / 2
puts x # 5, as expected
y = (
a
+ b
) /
2
puts y # 2, what happened?
The Ruby parser will assume a statement has ended if it looks like it has ended at an end of the line.
What you can to do prevent that is to leave the arithmetic operator just before a new line, like this:
a = 1
b = 2
c = a +
b
And you'll get the result you expect.
(
expr1
expr2
)
is actually, in Ruby, the same as
(expr1; expr2)
which just executes the first expression (for side effects) and returns the second one (also after evaluating it)
Try thinking about the "expectations" of the interpreter, and remember that in ruby EVERYTHING is an expression (which means that everything evaluates to some value, even constructs that in other languages are considered "special", like if-then-elses, loops, etcettera).
So:
y = ( #1
a #2
+ b #3
) / #4
2 #5
At line 1 we start the declaration of a variable, and the line ends with an open (pending) parenthesis. The interpreter expects the rest of the definition, so it proceeds to the next line looking for a VALUE to assign to the var y.
At line 2, the interpreter finds the variable a, but no enclosing parenthesis. It evaluates a, which has value 5, and since the line 2 is a perfectly-valid expression, the interpreter understands that this expression is finished (since in Ruby a newline OFTEN means end-of-expression indicator).
So up to now it has produced a value 5, but the only expectation it still has is that it must match the enclosing parenthesis.
If after that the interpreter had found the enclosing parenthesis, it would have assigned the value of a (i.e. 5) to the parenthesis expression (because everything must have a value, and the last value produced will be used).
When the interpreter reaches line 3, it finds another perfectly-valid ruby expression, + b. Since + 5 (5 being the value of variable b) is a VALID integer declaration in ruby, the interpreter sees it as standalone, not at all related to the previous 5 evaluated for the variable a (remember, it had no other expectation, except the one for the parenthesis).
In short, it throws away the value obtained for a, and uses only the value obtained with + b. In the next line it finds the enclosing parenthesis, and so the parenthesis-expression gets assigned the last produced value, which is a 5 produced by the expression + b.
Since on line 4 the interpreter finds a /, it (correctly) understands it as the division method of an integer, since it has produced an integer up to now (the int 5)! This creates the expectation for possible arguments of the method, which it finds on line 5. The resulting evaluated expression is y = 5 / 2, which equals 2 in integer division. So, basicaly, here is what the interpreter did:
y = ( # Ok, i'm waiting for the rest of the parenthesis expression
a # cool, a has value 5, if the parenthesis ends here, this is the value of the expr.
+ b # Oh, but now I found + b, which has value + 5, which evaluates to 5. So now this is the last value I have evaluated.
) / # Ok, the parenthesis have been closed, and the last value I had was a 5. Uow, wait, there is a slash / there! I should now wait for another argument for the / method of the 5 I have!
2 # Found, let's make y = 5 / 2 = 2!
The problem here is that on line #2, you should have left an expectation for the interpreter (exactly as you left on line 4 with the / method), which you did not!
The answer of #Maurício Linhares suggests exactly this:
y = (
a +
b
) /
2
By moving the + method to the end of the line 2, you tell the interpreter that your expression is still not complete! So it keeps the expectation and proceeds to line #3 to find the right operand of the expression (or, more precisely in Ruby, an argument for the + method :D).
The same works with string concatenation:
# WRONG, SINCE + "somestring" is not a valid stand-alone expression in ruby
str = "I like to"
+ " move it!"
# NoMethodError: undefined method `+#' for " move it!":String
# CORRECT, by leaving the + sign as last statement of the first line, you
# keep the 'expectation' of the interpreter for the next
# argument of the + method of the string object "I like to"
str = "I like to" +
" move it!"
# => "I like to move it!"
The difference is that in your code there were no error thrown, since + b is actually a valid expression.
I hope my answer was useful on giving you some intuition on WHY it was not working as expected, sorry if I'm not concise :)

How convert a number in letter in smarty?

I want to put letters instead of numbers.For example, if I have the following statement:
{for $node=1 to {$nr_nods}}
{$nod}<br>
{/for}
where {$nr_nods}=3, will show
1
2
3
,but Y want display
A
B
C
how make this?
In php, assign an array to the template with the equivalences:
$smarty->assign('nums'=>array(1=>'A',2=>'B',3=>'C'));
and then just output the values by key:
{$nums.$nod}

Resources