egghelp.org community Forum Index
[ egghelp.org home | forum home ]
egghelp.org community
Discussion of eggdrop bots, shell accounts and tcl scripts.
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[SOLVED] Set Variable to Line in File / Write Variable

 
Post new topic   Reply to topic    egghelp.org community Forum Index -> Scripting Help
View previous topic :: View next topic  
Author Message
Seka
Voice


Joined: 19 Apr 2011
Posts: 18

PostPosted: Fri Apr 22, 2011 9:36 am    Post subject: [SOLVED] Set Variable to Line in File / Write Variable Reply with quote

I am pretty sure I know how to write a variable to a line in a file. My goal here is to use an outside file to "record" the state of a variable, so that if the bot resets it doesn't forget what the variable was set to the last time it accessed the script.

Let me explain.

I need to increment the value of a variable, in order for the bot to know what change to make on which day, in the course of eleven days. I just realized that by initializing the variable the way I do in the script, that if the bot dies or resets the CONF, it will start the variable from scratch.

So, every time I increment the variable, I want to write the value to a file. Then, pull that value from that file, each time the bot needs it for the script. Thus, avoiding repeating the same action two or more days in a row.

What I need:

I can't quite figure out the code to set a variable to a line in a file, then after the variable is increased an increment, overwrite that file line with the new value.

I'd really appreciated some help with this!

Thank you.


Last edited by Seka on Tue Apr 26, 2011 1:49 pm; edited 1 time in total
Back to top
View user's profile Send private message
willyw
Revered One


Joined: 15 Jan 2009
Posts: 1175

PostPosted: Fri Apr 22, 2011 10:52 am    Post subject: Reply with quote

There is some very helpful info on file operations, here:

http://forum.egghelp.org/viewtopic.php?t=6885


Probably more than what you need.... it sounds like you need to write only one line, with one number on it, to the file.

You might also find some useful info here:
http://www.tcl.tk/man/tcl8.5/TclCmd/open.htm#M7
or close to there.
http://www.tcl.tk/man/tcl8.5/TclCmd/open.htm


The main page is:
http://www.tcl.tk/man/tcl8.5/TclCmd/contents.htm

I hope this helps.
Back to top
View user's profile Send private message
nml375
Revered One


Joined: 04 Aug 2006
Posts: 2857

PostPosted: Fri Apr 22, 2011 11:01 am    Post subject: Reply with quote

There are a few ways of doing this..
However, I'd probably settle with restoring the value when your eggdrop is restarted, rather than everytime the variable is read.

One of the simplest ways of doing this, is actually to have your code write a script that sets the value.. then all you need to do is add a "source restore.tcl" to your config-file

Code:
...
#assuming variable is named "state"
set fd [open "restore.tcl" "WRONLY CREAT TRUNC"]
puts $fd [list set state $state]
close $fd
...

The above code writes a single line to the file restore.tcl, containing a (safe) set command to restore the value of "state". It should be fairly trivial to embed in your current code.

Other ways would be to just write the value to the file, and restore it by opening the file with read-access, reading the line, and restoring the value of the variable using the read value..

Code:
...
#assuming variable is named "state"
set fd [open "restore" "WRONLY CREAT TRUNC"]
puts $fd $state
close $fd
...
if {[catch {open "restore" "RDONLY"} fd]} {
  #unable to open file, does not exist?
  putlog "Error restoring state: $fd"
  return
} else {
  set ::state [gets $fd]
  close $fd
}
...

_________________
NML_375, idling at #eggdrop@IrcNET
Back to top
View user's profile Send private message
Seka
Voice


Joined: 19 Apr 2011
Posts: 18

PostPosted: Fri Apr 22, 2011 11:38 am    Post subject: Reply with quote

Thank you both for the quick responses. I was able to rig something together, using the documentation.

nml375,

It looks like what you're suggesting could significantly lower the amount of code in my primary script.

My question is this, though. If I need to increment the value of the variable and store it in several different scenarios, would I need to repeat that code snippet throughout the script?

Example:

Code:
pub example{nick host channel text} {
if {$state == 1} {
putserv "TOPIC $channel :It is day 1!"
incr $state
} elseif {$state == 2} {
putserv "TOPIC $channel :It is day 2!"
set $state 1
}
}


Would your snippet be repeated after the "incr $state" in each expression?

Edit:

The proc is actually a time bind, but I just used the above code as an example.
Back to top
View user's profile Send private message
nml375
Revered One


Joined: 04 Aug 2006
Posts: 2857

PostPosted: Fri Apr 22, 2011 6:50 pm    Post subject: Reply with quote

The first problem with the code you posted, is that state is a local variable. The script-solution I mentioned "only" works with global variables (it could be made to work with local variables as well, but the hazzle really isn't worth it.. just use a global variable instead..)

Assuming we use a globalspace variable ::state instead; the posted code would only need one instance of the "save-code", provided that we add it at the end of the "example" proc, that we place the code at the end of the proc, and that we do not exit the proc prematurely (no return statements, etc).

Code:
pub example {nick host handle channel text} {
  if {$::state == 1} {
    putserv "TOPIC $channel :It is day 1!"
    incr ::state
  } elseif {$::state == 2} {
    putserv "TOPIC $channel :It is day 2!"
    set ::state 1
  }
  set fd [open "restore.tcl" "WRONLY CREAT TRUNC"]
  puts $fd [list set state $::state]
  close $fd
}

Btw, I fixed the issues where you use variable substitutions unintentinally: set $state 1 =>set state 1; incr $state => incr state
_________________
NML_375, idling at #eggdrop@IrcNET
Back to top
View user's profile Send private message
Seka
Voice


Joined: 19 Apr 2011
Posts: 18

PostPosted: Sun Apr 24, 2011 11:46 am    Post subject: Reply with quote

Ok. So, here's what I've got. It is untested, so far.

Let me know if I need to change anything, please:

Code:
set channel "#Bot_Test"

# Open the TCL with the variable?
set fd [open "restore" "WRONLY CREAT TRUNC"]
puts $fd $rpday
close $fd

# Execute every day at midnight?
bind time - "00 00 * * *" tchange

# Execute the proc.
proc tchange {min hour day month year} {
global channel
if {$::rpday == 1} {
putquick "TOPIC $channel :It is Day 1!"
incr ::rpday
} elseif {$::rpday == 2} {
putquick "TOPIC $channel :It is Day 2!"
incr ::rpday
} elseif {$::rpday == 3} {
putquick "TOPIC $channel :It is Day 3!"
incr ::rpday
} elseif {$::rpday == 4} {
putquick "TOPIC $channel :It is Day 4!"
incr ::rpday
} elseif {$::rpday == 5} {
putquick "TOPIC $channel :It is Day 5!"
incr ::rpday
} elseif {$::rpday == 6} {
putquick "TOPIC $channel :It is Day 6!"
incr ::rpday
} elseif {$::rpday == 7} {
putquick "TOPIC $channel :It is Day 7!"
incr ::rpday
} elseif {$::rpday == 8} {
putquick "TOPIC $channel :It is Day 8!"
incr ::rpday
} elseif {$::rpday == 9} {
putquick "TOPIC $channel :It is Day 9!"
incr ::rpday
} elseif {$::rpday == 10} {
putquick "TOPIC $channel :It is Day 10!"
incr ::rpday
} elseif {$::rpday == 11} {
putquick "TOPIC $channel :It is Day 11!"
set ::rpday 1
}
  set fd [open "rpday.tcl" "WRONLY CREAT TRUNC"]
  puts $fd [list set state $::rpday]
  close $fd
}
}


Also, do I need to create the "rpday.tcl" script in advance, or just enter the "source/rpday.tcl" entry in the bots conf?
what should the contents of that script look like, so that the variable can be read properly?
Back to top
View user's profile Send private message
nml375
Revered One


Joined: 04 Aug 2006
Posts: 2857

PostPosted: Sun Apr 24, 2011 12:28 pm    Post subject: Reply with quote

Please indent your code properly when posting, it makes spotting issues such as the extra } in your code that much easier to spot... not to mention reading the code.

First, since you named your variable rpday, not state, you'll have to change that in the save-code as well..
Also, if you go with the script-solution, you don't need to write the value to "restore"; I'd suggest you only use one or the other to avoid confusion, not both..

Also a hint, since you're building such many states on a single expression (variable), I'd considder using switch instead of those stacked if/elseif/else's...

Finally, as for reading the generated rpday.tcl upon startup; I'd use a catch-statement - just so I wouldn't have to bother making sure the file is always created (yes, I'm lazy). I'll even add a default value in case there was an error loading the file...

Code:
if {[catch {source rpday.tcl} err]} {
  set ::rpday 1
}

set ::rpchan "#Bot_Test"

bind time - "00 00 * * *" tchange
proc tchange {min hour day month year} {
  global rpchan

  switch -exact -- $::rpday {
    1 {putquick "TOPIC $::rpchan :It is Day One!"}
    2 {putquick "TOPIC $::rpchan :It is Day Two!"}

    #... and so on...
    #until the default case, which maches if none of the above does...
    default {
      putquick "TOPIC $::rpchan :It is Day Eleven!"
      set ::rpday 0
    }
  }
  incr ::rpday
  set fd [open "rpday.tcl" "WRONLY CREAT TRUNC"]
  puts $fd [list set ::rpday $::rpday]
  close $fd
}


Edit: Corrected missing "incr ::rpday"
Edit: Corrected missing edit note...
_________________
NML_375, idling at #eggdrop@IrcNET


Last edited by nml375 on Fri Apr 29, 2011 10:00 am; edited 2 times in total
Back to top
View user's profile Send private message
Seka
Voice


Joined: 19 Apr 2011
Posts: 18

PostPosted: Tue Apr 26, 2011 1:18 pm    Post subject: Reply with quote

Looks like that is going to do it. I just need to format my topic a little better. I can't figure out how to keep the script from thinking that the brackets in the topic are code.

Thanks for your help, NML!
Back to top
View user's profile Send private message
nml375
Revered One


Joined: 04 Aug 2006
Posts: 2857

PostPosted: Tue Apr 26, 2011 1:35 pm    Post subject: Reply with quote

Escape them as \[ \]
_________________
NML_375, idling at #eggdrop@IrcNET
Back to top
View user's profile Send private message
Seka
Voice


Joined: 19 Apr 2011
Posts: 18

PostPosted: Tue Apr 26, 2011 1:48 pm    Post subject: Reply with quote

Awesome.

Solved.

Thanks again!
Back to top
View user's profile Send private message
Seka
Voice


Joined: 19 Apr 2011
Posts: 18

PostPosted: Fri Apr 29, 2011 9:43 am    Post subject: Reply with quote

Quote:
Code:
if {[catch {source rpday.tcl} err]} {
  set ::rpday 1
}

set ::rpchan "#Bot_Test"

bind time - "00 00 * * *" tchange
proc tchange {min hour day month year} {
  global rpchan

  switch -exact -- $::rpday {
    1 {putquick "TOPIC $::rpchan :It is Day One!"}
    2 {putquick "TOPIC $::rpchan :It is Day Two!"}

    #... and so on...
    #until the default case, which maches if none of the above does...
    default {
      putquick "TOPIC $::rpchan :It is Day Eleven!"
      set ::rpday 0
    }
  }
  set fd [open "rpday.tcl" "WRONLY CREAT TRUNC"]
  puts $fd [list set ::rpday $::rpday]
  close $fd
}


It looks like the above script is stuck on the first entry in the "switch" statement. As it stands, at midnight, the topic is always changed to "It is Day One!" and never anything else in the list.
Back to top
View user's profile Send private message
nml375
Revered One


Joined: 04 Aug 2006
Posts: 2857

PostPosted: Fri Apr 29, 2011 9:58 am    Post subject: Reply with quote

Sorry, seems I forgot to increase the value of rpday at the end of the proc.. I'll update my previous post to correct the issue in a sec..
_________________
NML_375, idling at #eggdrop@IrcNET
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    egghelp.org community Forum Index -> Scripting Help All times are GMT - 4 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Forum hosting provided by Reverse.net

Powered by phpBB © 2001, 2005 phpBB Group
subGreen style by ktauber