Lua: alternative to goto operator in Lua 5.1 - loops

Since World of Warcraft runs Lua 5.1, I'd like to know if there is a way to get what I need without using the goto operator. This is my code: this code reads the contents of a tooltip line by line, as if it were a text file
-- _G["UniScan_wpnTooltipTextLeft"..n]:GetText() return the text at n line
local line, n = nil, 1
while (_G["UniScan_wpnTooltipTextLeft"..n]:GetText()) do ::redo:: --As long as there are lines of text
if string.find("Durability", _G["UniScan_wpnTooltipTextLeft"..n]:GetText()) then
line = n - 1
break
end
n = n + 1
end
if not line then goto redo end
If, due to a UI loading bug, at the end of the loop the line variable is equal to nil , just repeat the loop so the line variable has a finite value. How can I achieve this in Lua 5.1?

How about:
while ((not line) or _G["UniScan_wpnTooltipTextLeft"..n]:GetText()) do
...

Related

Using lua script to read thousand keys from file and deleting key in redis

I am using this file, but its not working. What am I doing wrong
function lines_from(file)
if not file_exists(file) then return {} end
local lines = {}
for line in io.lines(file) do
lines[#lines + 1] = line
end
return lines
end
-- tests the functions above
local file = 'a.txt'
local lines = lines_from(file)
-- iterate all line numbers and delete key
for k,v in pairs(lines) do
redis.call('DEL', v)
end
Is file iteration wrong or keys always needs to be passed in argument.
I have 1000 keys to delete
Keys dont have any prefix and cant regex as no pattern
I'd assume the line count being 0 has something to do with it "not working". If it's not passing an error, it could potentially contain no values at all.
if #lines == 0 then
return error("An error occurred opening the file: Missing lines")
end

Reading a specific line in Julia

Since I'm new in Julia I have sometimes obvious for you problems.
This time I do not know how to read the certain piece of data from the file i.e.:
...
stencil: half/bin/3d/newton
bin: intel
Per MPI rank memory allocation (min/avg/max) = 12.41 | 12.5 | 12.6 Mbytes
Step TotEng PotEng Temp Press Pxx Pyy Pzz Density Lx Ly Lz c_Tr
200000 261360.25 261349.16 413.63193 2032.9855 -8486.073 4108.1669
200010 261360.45 261349.36 413.53903 22.925126 -29.762605 132.03134
200020 261360.25 261349.17 413.46495 20.373081 -30.088775 129.6742
Loop
What I want is to read this file from third row after "Step" (the one which starts at 200010 which can be a different number - I have many files which stars at the same place but from different integer) until the program will reach the "Loop". Could you help me please? I'm stacked - I don't know how to combine the different options of julia to do it...
Here is one solution. It uses eachline to iterate over the lines. The loop skips the header, and any empty lines, and breaks when the Loop line is found. The lines to keep are returned in a vector. You might have to modify the detection of the header and/or the end token depending on the exact file format you have.
julia> function f(file)
result = String[]
for line in eachline(file)
if startswith(line, "Step") || isempty(line)
continue # skip the header and any empty lines
elseif startswith(line, "Loop")
break # stop reading completely
end
push!(result, line)
end
return result
end
f (generic function with 2 methods)
julia> f("file.txt")
3-element Array{String,1}:
"200000 261360.25 261349.16 413.63193 2032.9855 -8486.073 4108.1669"
"200010 261360.45 261349.36 413.53903 22.925126 -29.762605 132.03134"
"200020 261360.25 261349.17 413.46495 20.373081 -30.088775 129.6742"

Fortran, write 2d array into excel file

Hello I am having trouble writing a 2d array into an excel file.
I would like to have the values in a 10 x 10 format in excel, but this error keeps popping up I am not sure how to fix it.
code3.f90:40:12:
write(10, (b(i,j), j = 1,10)
1
Error: Syntax error in WRITE statement at (1)
x-10-104-223-3:cht
Here is my initial code
do i = 1, 10
do j = 1, 10
b(i, j) = 1
end do
end do
do i = 1,10
open( unit = 10, file = "test.csv")
write(10, (b(i,j), j = 1,10)
end do
You have the writesyntax wrong. You need to specify the format as a second part in the parenthesis, the output items go outside:
write(10,*) (b(i,j), j = 1,10)
Here, the format * is used to indicate list-directed output to "let the compiler decide on the exact output format" (depending on the output items).
As remarked by#cars10 in a comment: opening the file inside the loop is a bad idea. The code will probably exit with an error in the second iteration. Put the statement in front of the loop body.

Csh adding strings to an array, whitespace troubles

I’m having trouble doing something basic with csh. I have a string:
set newCmd = "$expansionCmd –option1 –option2 …"
And I’m creating an array of these strings, which I later want to execute:
set expansionCmdList = ($expansionCmdList[*] "$newCmd")
#I also tried without quotes, e.g. just $newCmd
Finally I try to iterate over and execute these commands:
foreach exCmd ($expansionCmdList)
`exCmd` #execute it in the shell
end
However the problem is that the array entries are not the full string, but every part of the string separated by whitespace, i.e. the first entry is just “$expansionCmd”, the next entry would be “—option1” etc.
Apologies in advance for using c shell, my company's code base is stuck with it.
Any time you are expanding an entire array and want to keep its individual elements' identities intact, you need the :q (for "quoted") modifier on the expansion. Otherwise, as soon as you do something like set expansionCmdList=($expansionCmdList[*] "$newCmd"), all previous commands in the list are split out into their component words, each of which is now its own array element. Simple demonstration:
% set a = ( a "b c" d )
% echo $a[2]
b c
% set a = ( $a[*] e )
% echo $a[2]
b
Oops, you've messed up the array before you even get to your execution loop. Things go much better with :q:
% set a = ( a "b c" d )
% set a = ( $a:q e )
% echo $a[2]
b c
You need to use the same modifier in the for loop:
foreach exCmd ($expansionCmdList:q)
Finally, `exCmd` tries to run a command literally named "exCmd", and then take its output and run that as a command. What you probably want to do is simply execute a command equal to the value of the variable. You will likely run into more whitespace woes here, and you can't solve them by making each command an array since csh doesn't support arrays of arrays. Fair warning. But if the commands don't have any quotation needs, this will work:
$exCmd
Mark's solution is clearly superior for most applications, but there is another option. Instead of using foreach directly, get the size of the array and iterate through the sequence:
set BUILD_MATRIX = ( "makefile.make:make --jobs --makefile=makefile.make" \
"Makefile:make --jobs --makefile=Makefile" \
"build.xml:ant" )
foreach i ( `seq ${#BUILD_MATRIX}` )
echo $i
echo $BUILD_MATRIX[$i]
end
(copied from Accessing array elements with spaces in TCSH)

Using a Do-Loop, to read a column of data (numerical & string) and filter the numbers as output into another file

I have an output file, single column, where each 7th line is a string and the others numerical (something like below)
998.69733
377.29340
142.22397
53.198547
19.743515
7.5493960
timestep: 1
998.69733
377.29340
142.22047
53.188023
19.755905
7.5060229
timestep: 2
998.69733
377.29337
I need to read this data into another file, omitting the text and keeping only the numbers and tried a loop to allocate a dummy for my string but I get an error as it does not recognize (AI).
DO 10 I = 1, 1000
IF (MOD(I,7) == 0) THEN
READ (8, FMT= '(AI)') dummy
END IF
READ (8,*) val
WRITE (9,*) val
10 CONTINUE
(8 - input file and 9 - output file allocation)
I am quite new to Fortran and spent a lot of time surfing for a solution or at least a similar problem but did not find anything. I would really appreciate some help.
Thank you very much in advance.
If you just want to skip the seventh lines, you could do "read (8, '(A)' ) dummy" where dummy is declared as a character string (i.e., "character (len=80) :: dummy"). It won't matter than some of the characters are letters and others numbers.
P.S. The modern was to write loops is "do", "end do" ... no need for line numbers and continue statements.
Simply use list-directed input with an empty input item list.
Also, the seventh line gets read twice in your loop. Put the read and write of val in an ELSE section, or, alternatively, us the CYCLE statement:
DO I = 1, 1000
IF(MOD(I,7) == 0) THEN
READ(8,*)
CYCLE
END IF
READ(8,*) val
WRITE(9,*) val
END DO

Resources