Lua: Doing arithmetic in for k,v in pairs(tbl) loops - math

I have a table such as the following:
mafiadb:{"Etzli":{"alive":50,"mafia":60,"vigilante":3,"doctor":4,"citizen":78,"police":40},"Charneus":{"alive":29,"mafia":42,"vigilante":6,"doctor":14,"citizen":53,"police":33}}
There are more nested tables, but I'm just trying to keep it simple for now.
I run the following code to extract certain values (I'm making an ordered list based on those values):
sortmaf={}
for k,v in pairs(mafiadb) do
sortmaf[k]=v["mafia"]
end
That's one of the codes I run. The problem I'm running into is that it doesn't appear you can do arithmetic in a table loop. I tried:
sortpct={}
for k,v in pairs(mafiadb) do
sortpct[k]=(v["alive"]*100)/(v["mafia"]+v["vigilante"]+v["doctor"]+v["citizen"]+v["police"])
end
It returns that I'm attempting to do arithmetic on field "alive." What am I missing here? As usual, I appreciate any consideration in answering this question!
Editing:
Instead of commenting on the comment, I'm going to add additional information here.
The mafiadb database I've posted IS the real database. It's just stripped down to two players instead of the current 150+ players I have listed in it. It's simply structured as such:
mafiadb = {
Playername = {
alive = 0
mafia = 0
vigilante = 0
doctor = 0
police = 0
citizen = 0
}
}
Add a few hundred more playernames, and there you have it.
As for the error message, the exact message is:
attempt to perform arithmetic on field 'alive' (nil value)
So... I'm not sure what the problem is. In my first code, the one with sortmaf, it works perfectly, but suddenly, it can't find v["alive"] as a value when I'm trying to do arithmetic? If I just put v["alive"] by itself, it's suddenly found and isn't nil any longer. I hope this clarifies a bit more.

This looks like a simple typo to me.
Some of your 150 characters is not well written - probably they don't have an "alive" property, or it's written incorrectly, or it's not a number. Try this:
for k,v in pairs(mafiadb) do
if type(v.alive) ~= 'number' then
print(k, "doesn't have a correct alive property")
end
end
This should print the names of the "bad" characters.

Related

Sabre Scribe Scripting Specifically Looping

Anybody have any tips for looping, and continue? For example, I placed about 2500 pnrs on a queue, and I need to add a remark to each of them. Is it possible for a script to add the remark then move to the next pnr?
For example, I placed about 2500 pnrs on a queue, and I need to add a remark to each of them. Is it possible for a script to add the remark then move to the next pnr?
Loops are supported in Scribe but have to be built manually by creating your own iteration variables and breaking the loop manually when you know the work is complete.
What you are describing is definitely possible, but working in queues can be difficult as there are many possible responses when you try to end the PNRs. You'll have to capture the response to detect whether you need to do something else to get out of the error condition (e.g. if a PNR warning indicates you have to double-end the record).
If possible, its likely simpler to work off the queue by collecting all PNR locators and then looping through that list, adding your remarks, and then ending the PNRs. You'll still have to capture the response to determine if the PNR is actually ended properly, but you won't have to deal with the buggy queue behavior. A basic Scribe loop sample is below. Note that I haven't been a Scribe developer for a while and I did this in Notepad so there might be some errors in here, but hopefully it's a good starting point.
DEFINE [ROW=N:8] ;iteration variable/counter
DEFINE [LOCATOR_FILE=*:60] ;File Path
DEFINE [TEMP_LOCATOR=*:6] ;pnr locator variable, read from the temp file
DEFINE [BREAK=*:1] ;loop breaking variable
OPEN F=[TEMP_LOCATOR] L=0 ;open the file of locators
[BREAK] = ""
[ROW] = 0
REPEAT
[ROW] = [ROW] + 1
[TEMP_LOCATOR] = "" ;Reset temp locator variable, this will break our loop
READ F=[LOCATOR_FILE] R=[ROW] C=1 [TEMP_LOCATOR]
IF $[TEMP_LOCATOR] = 6 THEN ;test length of locator, if this is 6 chars, you have a good one, pull it up and add your remark
»"5YOUR REMARK HERE"{ENTER}«
»ER{ENTER}«
;trap errors
READ F="EMUFIND:" R=0 C=0 [TEMP_LOCATOR] ;read for the locator being present on this screen, which should indicate that the ER was successful - you'll have to trap other errors here though
IF [#SYSTEM_ERROR] = 0 THEN ;this locator was found, ER appears successful
»I{ENTER}« ;Ignore this PNR and move to the next one
ELSE
[BREAK] = "Y" ;error found afeter ER, break loop. Maybe show a popup box or something, up to you
ENDIF
ELSE ;No locator found in file, break the loop
[BREAK] = "Y"
ENDIF
UNTIL [BREAK] = "Y"
CLOSE [LOCATOR_FILE]

I need help for gamemaker 2.3

Pls help me
A few weeks ago it came out of gamemaker 2.3, practically in the gamemaker language they changed the scripts into functions, but now after converting the files to be able to reopen them, I double-checked all the scripts and etc but anyway when I start it it remains a black screen, however it doesn't give me any compilation errors or whatever, what could be the problem?
Ps.
I might sound stupid, but if someone has the same program as me I can pass the project to them so they can see the scripts for themselves, so basically it's just the base and there is only the script to make the player walk and for collisions, I know that no one would want to waste time, but I ask the same
Its possible that your code is stuck in an infinite loop, here's an example of what that might look like:
var doloop = true
while(doloop == true){
x += 1
y += 1
}
the "doloop" variable is never changed within the while loop, so it is always equal to true and the loop never ends. Because the code never finishes looping, it can never get around to drawing anything, so you end up with a black screen. The easiest way to check for these is to put a breakpoint/debugging point at the beginning and just after every while/for/do/ect loop and debug it. e.g. (I am using asterisks "*" to represent breakpoints)
var doloop = true
* while(doloop == true){
x += 1
y += 1
}
*
When you get to one of the loops remove the first breakpoint and hit the "continue" button in the debugger. If it (it being the computer) takes an longer than it should to hit the second breakpoint (as in, you wait for a ten seconds to or two minutes (depends on how complex the code is) and it still hasn't hit the second breakpoint), then you should replace the breakpoint at the beginning of the loop to check and make sure it is still in there. If it is still in the loop, then that is likely where the code is getting stuck. Review the loop and everywhere any associated variables are set/changed, and you should be able to find the problem (even if it takes a while).
Majestic_Monkey_ and the commentors are correct: use the debugger. It's easy and it's your friend. Just place a red circle on the very first line of code that runs, and click the little bug icon and you can step through your code easily.
But to address your specific issue (or if anyone in the future has this issue): scripts have changed into files that can have many functions. Where you used to have
//script_name
var num = argument0 + argument1;
return num;
You would now have
function script_name(a, b) {
var num = a + b;
return num;
}
All you have to do is create a decleration for your new function:
function my_function_name(argument_names, etc...)
Then wrap all your old code in { }, and replace all those ugly "argument0" things with actual names. It's that easy. Plus you can have more than one function per script!

Sage TypeError positive characteristics not allowed in symbolic computations

I am new to sage and have got a code (link to code) which should run.
I am still getting an error message in the decoding part. The error trace looks like this:
in decode(y)
--> sigma[i+1+1] = sigma[i+1]*(z)\
-(delta[i+1]/delta[mu+1])*z^(i-mu)*sigma[mu+1]*(z);
in sage.structure.element.Element.__mul__
if BOTH_ARE_ELEMNT(cl):
--> return coercion_model.bin_op(left, right, mul)
in sage.structure.coerce.CoercionModel_cache_maps.bin_op
--> action = self.get_action(xp,yp,op,x,y)
...... some more traces (don't actually know if they are important)
TypeError: positive characteristics not allowed in symbolic computations
Does anybody know if there is something wrong in this code snipped? Due to previous errors, I changed the following to get to where I am at the moment:
.coeffs() changed to .coefficients(sparse=False) due to a warning message.
in the code line sigma[i+1+1] = sigma[i+1](z)\
-(delta[i+1]/delta[mu+1])*z^(i-mu)*sigma[mu+1](z); where the error occurs, i needed to insert * eg. sigma[i+1]*(z)
I would be grateful for any guess what could be wrong!
Your issue is that you are multiplying things not of characteristic zero (like elements related to Phi.<x> = GF(2^m)) with elements of symbolic computation like z which you have explicitly defined as a symbolic variable
Phi.<x> = GF(2^m)
PR = PolynomialRing(Phi,'z')
z = var('z')
Basically, the z you get from PR is not the same one as from var('z'). I recommend naming it something else. You should be able to access this with PR.gen() or maybe PR(z).
I'd be able to be more detailed, but I encourage you next time to paste a fully (non-)working example; trying to slog through a big worksheet is not the easiest thing to track all this down. Finally, good luck, hope Sage ends up being useful for you!

Use input variable in assert or specify the data to assert

I have a unit test for a function that adds data (untransformed) to the database. The data to insert is given to the create function.
Do I use the input data in my asserts or is it better to specify the data that I’m asserting?
For eample:
$personRequest = [
'name'=>'John',
'age'=>21,
];
$id = savePerson($personRequest);
$personFromDb = getPersonById($id);
$this->assertEquals($personRequest['name'], $personFromDb['name']);
$this->assertEquals($personRequest['age'], $personFromDb['age']);
Or
$id = savePerson([
'name'=>'John',
'age'=>21,
]);
$personFromDb = getPersonById($id);
$this->assertEquals('John', $personFromDb['name']);
$this->assertEquals(21, $personFromDb['age']);
I think 1st option is better. Your input data may change in future and if you go by 2nd option, you will have to change assertion data everytime.
2nd option is useful, when your output is going to be same irrespective of your input data.
I got an answer from Adam Wathan by e-mail. (i took his test driven laravel course and noticed he uses the 'specify' option)
I think it's just personal preference, I like to be able to visually
skim and see "ok this specific string appears here in the output and
here in the input", vs. trying to avoid duplication by storing things
in variables." Nothing wrong with either approach in my opinion!
So i can't choose a correct answer.

Vendors black box function can only be called successfully once

(first question here, sorry if I am breaking a piece of etiquette)
My site is running on an eCommerce back end provider that I subscribe to. They have everything in classic ASP. They have a black box function called import_products that I use to import a given text file into my site's database.
The problem is that if I call the function more than once, something breaks. Here is my example code:
for blah = 1 to 20
thisfilename = "fullcatalog_" & blah & ".csv"
Response.Write thisfilename & "<br>"
Response.Flush
Call Import_Products(3,thisfilename,1)
Next
Response.End
The first execution of the Import_Products function works fine. The second time I get:
Microsoft VBScript runtime error '800a0009'
Subscript out of range: 'i'
The filenames all exist. That part is fine. There are no bugs in my calling code. I have tried checking the value of "i" before each execution. The first time the value is blank, and before the second execution the value is "2". So I tried setting it to null during each loop iteration, but that didn't change the results at all.
I assume that the function is setting a variable or opening a connection during its execution, but not cleaning it up, and then not expecting it to already be set the second time. Is there any way to find out what this would be? Or somehow reset the condition back to nothing so that the function will be 'fresh'?
The function is in an unreadable include file so I can't see the code. Obviously a better solution would be to go with the company support, and I have a ticket it in with them, but it is like pulling teeth to get them to even acknowledge that there is a problem. Let alone solve it.
Thanks!
EDIT: Here is a further simplified example of calling the function. The first call works. The second call fails with the same error as above.
thisfilename = "fullcatalog_testfile.csv"
Call Import_Products(3,thisfilename,1)
Call Import_Products(3,thisfilename,1)
Response.End
The likely cause of the error are the two numeric parameters for the Import_Products subroutine.
Import_Products(???, FileName, ???)
The values are 3 and 1 in your example but you never explain what they do or what they are documented to do.
EDIT Since correcting the vender subroutine is impossible, but it always works for the first time it's called lets use an HTTP REDIRECT instead of a FOR LOOP so that it technically only gets called once per page execution.
www.mysite.tld/import.asp?current=1&end=20
curr = CInt(Request.QueryString("current"))
end = CInt(Request.QueryString("end"))
If curr <= end Then
thisfilename = "fullcatalog_" & curr & ".csv"
Call Import_Products(3,thisfilename,1)
Response.Redirect("www.mysite.tld/import.asp?current=" & (curr + 1) & "&end=" & end)
End If
note the above was written inside my browser and is untested so syntax errors may exist.

Resources