This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

linsert and something else

Help for those learning Tcl or writing their own scripts.
User avatar
ultralord
Master
Posts: 255
Joined: Mon Nov 06, 2006 6:52 pm

linsert and something else

Post by ultralord »

i can insert one variable into one file like this:


set g_stats [linsert $g_stats end $admin]
set fileio [open /home/ul/public_html/ircstats/g_stats.txt "w"]
puts $fileio $g_stats
flush $fileio
close $fileio

can i remove one variable from the file like linsert other command? i search but nothing..

thanks in adv
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

To remove a list item from a list, use the lreplace command with no "element" parameters.
NML_375
User avatar
ultralord
Master
Posts: 255
Joined: Mon Nov 06, 2006 6:52 pm

Post by ultralord »

like that?


set g_stats [lreplace $g_stats end $admin]
set fileio [open /home/ul/public_html/ircstats/g_stats.txt "w"]
puts $fileio $g_stats
flush $fileio
close $fileio

thanks for the help i want to remove $admin value from the $g_stats file
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

Not quite...

lreplace expects a list, a start index, an end index, and optionally one or more elements to replace the range with (no elements obviously means don't add anything, simply remove the range).
NML_375
User avatar
ultralord
Master
Posts: 255
Joined: Mon Nov 06, 2006 6:52 pm

Post by ultralord »

can you make me one expample to underestand? or to make that "easy" script for me but you must move it to request this topic.. and i think i underestand how it works if i saw something

i want to remove one $admin from one specific .txt file only that..
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

A good start would be to read the manpage for lsearch and lreplace, as these comes with some rather good examples.
NML_375
User avatar
ultralord
Master
Posts: 255
Joined: Mon Nov 06, 2006 6:52 pm

Post by ultralord »

set stats2 [lsearch -exact $g_stats $admin ]
set g_stats2 [lreplace $g_stats $admin 0 0]


like that?> replace the $admin with 0 ?


thanks
User avatar
arfer
Master
Posts: 436
Joined: Fri Nov 26, 2004 8:45 pm
Location: Manchester, UK

Post by arfer »

The command lsearch returns the index of the first match or -1 if no match is found

set idx [lsearch $testlist $pattern]

So, in the above example, the value of the variable named idx has been assigned the index of the first match of $pattern in $testlist OR -1 if $pattern is not found in $testlist.

To remove the first occurance of $pattern from the list :-

if {$idx != -1} {
set testlist [lreplace $testlist $idx $idx]
}

Or, to replace the first occurance of $pattern in $testlist with 0 :-

if {$idx != -1} {
set testlist [lreplace $testlist $idx $idx 0]
}

If you are having trouble understanding the commands as described in the reference documents (perhaps English is not your first language) then I recommend you install a Tcl distro on your desktop and use the provided Tclsh to experiment with core Tcl statements. Alternatively, you could enable Tcl commands in your bot's partyline (this has the benefit of understanding both core Tcl and Eggdrop Tcl). These are examples from my bot's partyline :-

[23:12] <arfer> .tcl set testlist {one two three four}
[23:12] <Baal> Tcl: one two three four
[23:12] <arfer> .tcl set pattern three
[23:12] <Baal> Tcl: three
[23:13] <arfer> .tcl set idx [lsearch $testlist $pattern]
[23:13] <Baal> Tcl: 2
[23:13] <arfer> .tcl set testlist [lreplace $testlist $idx $idx 0]
[23:13] <Baal> Tcl: one two 0 four

Experiment! It is unlikely you will break anything.
User avatar
ultralord
Master
Posts: 255
Joined: Mon Nov 06, 2006 6:52 pm

Post by ultralord »

nice thnx for all explanation .. i underestand somethings better..
so for my script i must put that:

testlist is my path for .txt and pattern is my $admin


set idx [lsearch $testlist $pattern]
if {$idx != -1} {
set testlist [lreplace $testlist $idx $idx]
}

because i want to remove the $admin from the txt file..

variable $admin have one nick on his value

thanks for all help
User avatar
ultralord
Master
Posts: 255
Joined: Mon Nov 06, 2006 6:52 pm

Post by ultralord »

so? my previus post is mistake?
User avatar
speechles
Revered One
Posts: 1398
Joined: Sat Aug 26, 2006 10:19 pm
Location: emerald triangle, california (coastal redwoods)

Post by speechles »

ultralord wrote:so? my previus post is mistake?

Code: Select all

WRONG...
set stats2 [lsearch -exact $g_stats $admin ]
set g_stats2 [lreplace $g_stats $admin 0 0] 

CORRECT..
set stats2 [lsearch -exact $g_stats $admin ]
set g_stats2 [lreplace $g_stats $stats2 $stats2]
lsearch is the lindex position, so use $stats2 to lreplace it...:roll:
If $stats2 happens to be negative (the lsearch failed) then there will be an error setting g_stats2. We aren't testing for failed conditions before setting that variable as we are assuming it will never fail because you haven't given any indication as to why it ever would. This isn't rocket science. If you make a mistake it doesn't kill anyone or cost millions of dollars. It just means you learn, try to experiment on your own at times...

Also, for clarification, the above assumes a proper tcl list is present. So the biggest question of all becomes something only you can answer for us, "Is $g_stats a list or a string?" If it's a list, how are the elements composed? You might need to use "-glob" with wildcards within your lsearching. If it's a string then there are more problems with your script than you've shown. Perhaps revealing more of the code would yield the answer? :?
User avatar
ultralord
Master
Posts: 255
Joined: Mon Nov 06, 2006 6:52 pm

Post by ultralord »

yes thnx and i underestand is so big fault and nothing costs :/

also look what i want.. i have this

set g_stats [linsert $g_stats end $admin]
set fileio [open /home/ul/public_html/ircstats/g_stats.txt "w"]
puts $fileio $g_stats
flush $fileio
close $fileio

with that i put $admin on $g_stats .. $admin = Ultralord (had value one nick)
on then the nick is added to a list on /home/ul/public_html/ircstats/g_stats.txt like nick1 nick2 nick3 nick4.. then i want to make one lsearch/lreplace to remove the $admin from that list on txt when i want.. on my script.. sorry for my english ;/ do you underestand better now?
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

Ultralord: In response to your query a few posts back;
  • testelist: This would be the variable holding the list of nicknames, not the file. I believe you called this g_stat.
  • pattern: this would be a pattern to find the list item (nickname) to be removed. lsearch uses "glob"-style matching by default, allowing the use of wildcards (*?) aswell as character ranger ([a-z]). Matching is case sensitive. Assuming the same layout as in your other function, this would be admin.
In your case, it might be a better idea to use the "exact"-style matching of lsearch. This would be accomplished by altering the lsearch-command like below (once again adjusting variable names):

Code: Select all

set idx [lsearch -exact $testelist $pattern]
NML_375
User avatar
arfer
Master
Posts: 436
Joined: Fri Nov 26, 2004 8:45 pm
Location: Manchester, UK

Post by arfer »

I'm not sure I agree entirely with the last posting. If there are no wildcards or character ranges in the pattern, which seems to be the case here, then the pattern is specific in which case the -glob AND -exact options are superfluous. An exact match IS required without actually specifying a -exact option.

[15:52] <@arfer> % return [lsearch {one two three} th]
[15:52] <@Baal> -1
[15:52] <@arfer> % return [lsearch {one two three} ree]
[15:52] <@Baal> -1
[15:52] <@arfer> % return [lsearch {one two three} threes]
[15:52] <@Baal> -1
[15:52] <@arfer> % return [lsearch {one two three} three]
[15:52] <@Baal> 2
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

The issue at hand would be in cases where the nickname would contain \[]. The point of -exact is to explicitly disallow wildcard and range matching done in a glob-style matching.

Regardless of what kind of matching-mechanism is chosen, the pattern must match the whole entity, a partial match is never sufficient.
arfer wrote:An exact match IS required without actually specifying a -exact option.
This is incorrect, as the default mechanism of lsearch is glob-style matching. For exact-style matching, you explicitly need to add the -exact option. The examples posted does not support your statement. Remember that a trivial glob-pattern would appear to be an exact-match, yet with non-trivial data you will see a difference in matching...
NML_375
Post Reply