Autoit GUI, Variables not being declared on button press - variables

I am still in the process of learning how to script my own GUIs. Koda has been a big help, I have been messing around with it, learning little bits at a time. However, I have encountered an error that I can not seem to get around. The current GUI I am working on is a simple tool to change bot settings for a game. This gui should have 5 buttons for difficulty setting, and a list of check boxes for the number of bots.
BUT, when I select a difficulty level, bot number, and hit save I get this error:
'Variable used without being declared'
The error is occuring on this line (botSAVE button at the end):
FileWriteLine($file2, "aiSettings.setMaxNBots " & $botnum)
I thought the button functions 'Func numClick()' set this variable based on the button that was pressed, but obviously I have overlooked something. Hopefully it is an easy fix. Does anybody see what might be causing this error? I have posted this question on autoitcsript forums but they seem to shy away from game automation scripts so I didn't really get much help over there.
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <TabConstants.au3>
#include <WindowsConstants.au3>
Opt("GUIOnEventMode", 1)
#Region ### START Koda GUI section ### Form=c:\users\admin\desktop\form1.kxf
$Form1 = GUICreate("Battlefield 2 Bot-Tool", 418, 499, 759, 83)
GUISetOnEvent($GUI_EVENT_CLOSE, "Form1Close")
GUISetOnEvent($GUI_EVENT_MINIMIZE, "Form1Minimize")
GUISetOnEvent($GUI_EVENT_MAXIMIZE, "Form1Maximize")
GUISetOnEvent($GUI_EVENT_RESTORE, "Form1Restore")
$Pic1 = GUICtrlCreatePic("C:\Users\admin\Desktop\bflogo.jpg", 0, 0, 417, 233)
$Settings = GUICtrlCreateTab(8, 240, 401, 249)
GUICtrlSetOnEvent(-1, "SettingsChange")
$Bot = GUICtrlCreateTabItem("Bots")
$botSAVE = GUICtrlCreateButton("Save these changes", 220, 433, 169, 33)
GUICtrlSetOnEvent(-1, "botSAVEClick")
$botDEFAULT = GUICtrlCreateButton("Restore default settings", 28, 433, 169, 33)
GUICtrlSetOnEvent(-1, "botDEFAULTClick")
$botskill = GUICtrlCreateGroup(" Bot skill level", 28, 265, 169, 145)
$skill1 = GUICtrlCreateRadio(" RECRUIT", 44, 289, 113, 17)
GUICtrlSetTip(-1, "Easy opposition, a damn turkey shoot")
GUICtrlSetOnEvent(-1, "skill1Click")
$skill2 = GUICtrlCreateRadio(" TRAINED", 44, 313, 113, 17)
GUICtrlSetTip(-1, "Default setting, opponents are deadly at close range")
GUICtrlSetOnEvent(-1, "skill2Click")
$skill3 = GUICtrlCreateRadio(" HARDENED", 44, 337, 113, 17)
GUICtrlSetTip(-1, "Enemies are a force to be reckoned with")
GUICtrlSetOnEvent(-1, "skill3Click")
$skill4 = GUICtrlCreateRadio(" VETERAN", 44, 361, 113, 17)
GUICtrlSetTip(-1, "Enemies are experienced, and dangerous")
GUICtrlSetOnEvent(-1, "skill4Click")
$skill5 = GUICtrlCreateRadio(" ELITE", 44, 385, 113, 17)
GUICtrlSetTip(-1, "Crack shot opponents will strategize against you. You will not survive")
GUICtrlSetOnEvent(-1, "skill5Click")
GUICtrlCreateGroup("", -99, -99, 1, 1)
$botnumber = GUICtrlCreateGroup(" Number of bots ", 220, 265, 169, 145)
$num1 = GUICtrlCreateRadio("2", 236, 289, 25, 17)
GUICtrlSetOnEvent(-1, "num1Click")
$num2 = GUICtrlCreateRadio("4", 236, 313, 25, 17)
GUICtrlSetOnEvent(-1, "num2Click")
$num3 = GUICtrlCreateRadio("6", 236, 337, 25, 17)
GUICtrlSetOnEvent(-1, "num3Click")
$num4 = GUICtrlCreateRadio("8", 236, 361, 25, 17)
GUICtrlSetOnEvent(-1, "num4Click")
$num5 = GUICtrlCreateRadio("10", 236, 385, 33, 17)
GUICtrlSetOnEvent(-1, "num5Click")
$num6 = GUICtrlCreateRadio("12", 284, 289, 33, 17)
GUICtrlSetOnEvent(-1, "num6Click")
$num7 = GUICtrlCreateRadio("14", 284, 313, 33, 17)
GUICtrlSetOnEvent(-1, "num7Click")
$num8 = GUICtrlCreateRadio("16", 284, 337, 33, 17)
GUICtrlSetOnEvent(-1, "num8Click")
$num9 = GUICtrlCreateRadio("18", 284, 361, 33, 17)
GUICtrlSetOnEvent(-1, "num9Click")
$num10 = GUICtrlCreateRadio("20", 284, 385, 33, 17)
GUICtrlSetOnEvent(-1, "num10Click")
$num11 = GUICtrlCreateRadio("24", 340, 289, 33, 17)
GUICtrlSetOnEvent(-1, "num11Click")
$num12 = GUICtrlCreateRadio("28", 340, 313, 33, 17)
GUICtrlSetOnEvent(-1, "num12Click")
$num13 = GUICtrlCreateRadio("32", 340, 337, 33, 17)
GUICtrlSetOnEvent(-1, "num13Click")
$num14 = GUICtrlCreateRadio("36", 340, 361, 33, 17)
GUICtrlSetOnEvent(-1, "num14Click")
$num15 = GUICtrlCreateRadio("40", 340, 385, 33, 17)
GUICtrlSetOnEvent(-1, "num15Click")
GUICtrlCreateGroup("", -99, -99, 1, 1)
$Server = GUICtrlCreateTabItem("Server")
$serverDEFAULT = GUICtrlCreateButton("Restore default settings", 28, 433, 169, 33)
$serverSAVE = GUICtrlCreateButton("Save these changes", 220, 433, 169, 33)
GUICtrlCreateTabItem("")
GUISetState(#SW_SHOW)
Opt("MustDeclareVars",1)
#EndRegion ### END Koda GUI section ###
While 1
Sleep(100)
WEnd
Func Form1Close()
If #GUI_WINHANDLE = $Form1 Then
Exit
EndIf
EndFunc
Func Form1Maximize()
EndFunc
Func Form1Minimize()
EndFunc
Func Form1Restore()
EndFunc
Func num1Click()
$botnum = "2"
EndFunc
Func num2Click()
$botnum = "4"
EndFunc
Func num3Click()
$botnum = "6"
EndFunc
Func num4Click()
$botnum = "8"
EndFunc
Func num5Click()
$botnum = "10"
EndFunc
Func num6Click()
$botnum = "12"
EndFunc
Func num7Click()
$botnum = "14"
EndFunc
Func num8Click()
$botnum = "16"
EndFunc
Func num9Click()
$botnum = "18"
EndFunc
Func num10Click()
$botnum = "20"
EndFunc
Func num11Click()
$botnum = "24"
EndFunc
Func num12Click()
$botnum = "28"
EndFunc
Func num13Click()
$botnum = "32"
EndFunc
Func num14Click()
$botnum = "36"
EndFunc
Func num15Click()
$botnum = "40"
EndFunc
Func SettingsChange()
EndFunc
Func skill1Click()
$skillset = "0.1"
EndFunc
Func skill2Click()
$skillset = "0.3"
EndFunc
Func skill3Click()
$skillset = "0.6"
EndFunc
Func skill4Click()
$skillset = "0.8"
EndFunc
Func skill5Click()
$skillset = "1.0"
EndFunc
Func botDEFAULTClick()
EndFunc
Func botSAVEClick()
Local $file = FileOpen("AIDefault.ai", 1)
If $file = -1 Then
MsgBox(0, "Protected file", "Please ensure that the file 'AIDefault.ai' is not set to Read Only.")
exit
EndIf
FileWriteLine($file, "aiSettings.setNSides 2 ")
FileWriteLine($file, "aiSettings.setAutoSpawnBots 1 ")
FileWriteLine($file, "aiSettings.setMaxNBots 64 ")
FileWriteLine($file, "aiSettings.maxBotsIncludeHumans 1")
FileWriteLine($file, "aiSettings.setBotSkill 0.4 ")
FileWriteLine($file, "run BotNames.ai ")
FileWriteLine($file, "aiSettings.setInformationGridDimension 32")
FileWriteLine($file, "run AIPathFinding.ai")
FileWriteLine($file, "run AIBotChanger.ai ")
FileClose($file)
$file2 = FileOpen("AIBotChanger.ai", 1)
If $file2 = -1 Then
MsgBox(0, "Protected file", "Please ensure that the file 'AIBotChanger.ai' is not set to Read Only.")
Exit
EndIf
FileWriteLine($file2, "aiSettings.overrideMenuSettings 1")
FileWriteLine($file2, "aiSettings.setMaxNBots " & $botnum)
FileWriteLine($file2, "aiSettings.setBotSkill " & $skillset)
FileWriteLine($file2, "aiSettings.maxBotsIncludeHumans 0")
FileClose($file2)
EndFunc
-If anybody sees what I have done wrong, OR has a link to a topic that covers declaring variables with a button click, Help is always appreciated. The only topics I have found are incredibly vague, or differ slightly from what I am look for

When you want to use a variable value outside of a function as well, you must declare its scope to be global. So just add a line Global $botnum (probably with a default value) before your many function declarations...
And obviously the same with $skillset.
The error is raised because you used Opt("MustDeclareVars", 1). But it wouldn't work anyways when you wouldn't declare these variables as global, because the value is set in the function but discarded again as soon as the function ends. So when you'd use them uninitialized in another function then, you would always receive the default value of an uninitialized variable.

Related

Scrypto: how to write test passing bucket as a function argument

In my blueprint, I have a function for the admin to deposit tokens back into the blueprint token vault.
pub fn deposit(&mut self, amount: Decimal, mut bucket: Bucket) {
assert!(amount <= bucket.amount(), "not enough amount in your bucket");
self.token_vault.put(bucket.take(amount))
}
I know how to generate a new account in my test file, and how to make a method call with badge protected access...
And I have learned from Scrypto-example/nft/magic-card:
https://github.com/radixdlt/scrypto-examples
let (public_key, private_key, account_component) = test_runner.new_allocated_account();
...
let manifest = ManifestBuilder::new(&NetworkDefinition::simulator())
.create_proof_from_account_by_amount(account_component, badge_amount, badge_addr)
.withdraw_from_account_by_amount(account_component, amount, token_addr)
.take_from_worktop(token_addr, |builder, bucket_id| {
builder.call_method(component, func_name, args!(amount, Bucket(bucket_id)))
})
.call_method(
account_component,
"deposit_batch",
args!(Expression::entire_worktop()),
)
.build();
let receipt = test_runner.execute_manifest_ignoring_fee(
manifest,
vec![NonFungibleAddress::from_public_key(&public_key)],
);
println!("{} receipt: {:?}\n", func_name, receipt);
receipt.expect_commit_success();
Then I got this error:
COMMITTED FAILURE: KernelError(InvalidDropNodeVisibility { mode: Application, actor:
Method(Scrypto { package_address: NormalPackage[011784f2e3c4b3dc9d14c850484fc4962f59ea68271e917d2f075c],
blueprint_name: "StableCoin", ident: "deposit" }, ResolvedReceiver { derefed_from:
Some((Global(Component(NormalComponent[02fd2e738e08b33e7d19001684043cd24fe35fda1ddc9429f7051e])), 36)),
receiver: Component([252, 13, 40, 104, 140, 209, 211, 110, 141, 213, 197, 200, 172, 195, 190, 178, 219, 47, 174, 17, 52, 209, 75, 207, 106, 97, 105, 21, 213, 159, 52, 25, 15, 4, 0, 0]) }),
node_id: Bucket(1027) })
But how can I make the bucket variable from my account_component as a function argument?
I solved it... my blueprint function should not include the amount, which has been represented in bucket argument...
pub fn deposit_to_vault(&mut self, bucket: Bucket) {
self.token_vault.put(bucket)
}
then use take_from_worktop_by_amount to get the bucket_id:
.withdraw_from_account_by_amount(user.compo_addr, amount, token_addr)
.take_from_worktop_by_amount(amount, token_addr, |builder, bucket_id| {
builder.call_method(component, func_name, args!(Bucket(bucket_id)))
})
.call_method(
user.compo_addr,
"deposit_batch",
args!(Expression::entire_worktop()),
)
.build();

Kotlin: Applicatives with Extension Functions

From what I understood, Applicatives are classes which implement the method apply, but I've seen a version with functions too. This is what it should look like:
fun <T, R> List<T>.ap(fab: List<(T) -> R>): List<R> = fab.flatMap { f -> this.map(f) }
And, when I am testing it with:
fun main(){
val numbers = listOf(75, 454, 7, 45, 45, 56, 75)
val functions = listOf<(Int) -> Int>({ i -> i * 2 }, { i -> i + 3 })
val result = numbers.ap(functions).joinToString()
println(result)
}
The output is:
150, 908, 14, 90, 90, 112, 150, 78, 457, 10, 48, 48, 59, 78
But the expected output is:
153, 911, 17, 93, 93, 115, 153, 81, 460, 13, 51, 51, 62, 81
Basically, I am applying a list of functions to a normal list, that's what it should do. From what I observed, my applicative did his job only for the first function, but for the other, it didn't... How can I get the expected result, using applicatives? I would like to keep my list of functions the way it is already, or at least to keep it similar at most.

The picture can't display in the google colab

python, pyecharts, google colab
It seems get the picture, but why can's see anything
enter image description here
from pyecharts.globals import CurrentConfig, NotebookType
CurrentConfig.NOTEBOOK_TYPE = NotebookType.JUPYTER_LAB
from pyecharts.charts import Bar
from pyecharts import options as opts
# V1 版本开始支持链式调用
bar = (
Bar()
.add_xaxis(["衬衫", "毛衣", "领带", "裤子", "风衣", "高跟鞋", "袜子"])
.add_yaxis("商家A", [114, 55, 27, 101, 125, 27, 105])
.add_yaxis("商家B", [57, 134, 137, 129, 145, 60, 49])
.set_global_opts(title_opts=opts.TitleOpts(title="某商场销售情况"))
)
bar.render()
# 不习惯链式调用的开发者依旧可以单独调用方法
bar = Bar()
bar.add_xaxis(["衬衫", "毛衣", "领带", "裤子", "风衣", "高跟鞋", "袜子"])
bar.add_yaxis("商家A", [114, 55, 27, 101, 125, 27, 105])
bar.add_yaxis("商家B", [57, 134, 137, 129, 145, 60, 49])
bar.set_global_opts(title_opts=opts.TitleOpts(title="某商场销售情况"))
# bar.load_javascript()
# bar.render()
bar.render_notebook()

Why won't my code store ints into my temps array?

System.out.print("What would you like to decode? ");
String fileName1 = console.next();
System.out.print("Save the results as: ");
resultFileName = console.next();
int token1;
Scanner inFile1 = new Scanner(new
File(fileName1)).useDelimiter("[" + "," + " ]");
List<Integer> temps = new ArrayList<Integer>();
while (inFile1.hasNext()) {
token1 = inFile1.nextInt();
temps.add(token1);
}
for(int i = 0; i <= temps.size() - 1; i++) {
int x = temps.get(i);
System.out.print((char) x);
}
when i run this it says there is a error on "token1 = inFile1.nextInt();"
this is what is in the file: [89, 111, 117, 39, 114, 101, 32, 97, 108, 109, 111, 115, 116, 32, 116, 104, 101, 114, 101, 46, 32, 75, 101, 101, 112, 32, 117, 112, 32, 116, 104, 101, 32, 103, 111, 111, 100, 32, 119, 111, 114, 107, 33]
Use the inFile1.hasNextInt() opposed to the inFile1.hasNext(). This way you can make sure the next value can be interpreted as an int.
I think the inFile1.hasNext() is resolving as true because you still have the character ] left in the file.
The useDelimiter is only used to seperate your ints. So you have to manually parse the [ and ] and call Scanner inFile1 = new Scanner(new
File(fileName1)).useDelimiter(","); for parsing the ints.
Edit: for parsing the '[' for example you can use:
Pattern p = Pattern.compile("[");
scanner.next(p);

How to pass a comma-separated list to a mixin as a single argument

I made a multi-stop gradient mix-in that simply puts #arguments for all the vendor prefixes for *-linear-gradient. It works, put I'm annoyed when I define a gradient with many stops, I have to put everything on one line when using the mixin, like this:
.gradientMultiple(~'top, rgba(255, 255, 255, 1) 0%, rgba(254, 254, 254, 1) 16%, rgba(252, 252, 252, 1) 36%, rgba(239, 239, 239, 1) 66%, rgba(18, 34, 106, 1) 66%, rgba(13, 31, 136, 1) 84%');
I'd like to put the function parameter on multiple lines like this for readability, but it generates a parse error:
.gradientMultiple(~'top,
rgba(255, 255, 255, 1) 0%,
rgba(254, 254, 254, 1) 16%,
rgba(252, 252, 252, 1) 36%,
rgba(239, 239, 239, 1) 66%,
rgba(18, 34, 106, 1) 66%,
rgba(13, 31, 136, 1) 84%
');
Here's the mixin definition:
.gradientMultiple ( ... ) {
background-image: -webkit-linear-gradient(#arguments);
background-image: -moz-linear-gradient(#arguments);
background-image: -ms-linear-gradient(#arguments);
background-image: -o-linear-gradient(#arguments);
background-image: linear-gradient(#arguments);
}
.gradientMultiple(top,
rgba(255, 255, 255, 1) 0%,
rgba(254, 254, 254, 1) 16%,
rgba(252, 252, 252, 1) 36%,
rgba(239, 239, 239, 1) 66%,
rgba( 18, 34, 106, 1) 66%,
rgba( 13, 31, 136, 1) 84%;);
Also see:
0
1
2
and finally the lead remark of 3
For use cases when the mixin forces you to supply a string, or you don't want LESS to compute the argument value, you can use a bit of javascript:
(disclaimer: JS evaluation is now deprecated and possibly will be removed in LESS 3/4, so use this only when working with legacy code where no other alternative is available)
.keyframes(~`
"translate, " +
"50% { transform: translateX(calc(50% - 25px)) } " +
"100% { transform: translateX(0px) } "
`);