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.

What is wrong in the loop ?

Help for those learning Tcl or writing their own scripts.
Post Reply
j
juanamores
Master
Posts: 317
Joined: Sun Mar 15, 2015 9:59 am

What is wrong in the loop ?

Post by juanamores »

The file (listaDJS) contains the name, date and time of transmission (broadcast ) of my Radio DJs.
Example lines files:
Juan Miércoles 7 de Setiembre a las 04:06:38
Pedro Jueves 8 de Setiembre a las 05:08:54
Maria Viernes 9 de Setiembre a las 15:11:49
Jack Viernes 9 de Setiembre a las 16:50:42
Axel Viernes 9 de Setiembre a las 18:22:02
When you run it seems that the bot is in an infinite loop.
I want to solve this bug .
In addition , I wish to show me the list in reverse order to what the show now .
I wish that first show last broadcast date and time.
Axel Viernes 9 de Setiembre a las 18:22:02
Jack Viernes 9 de Setiembre a las 16:50:42
Maria Viernes 9 de Setiembre a las 15:11:49
Pedro Jueves 8 de Setiembre a las 05:08:54
Juan Miércoles 7 de Setiembre a las 04:06:38
Today I list the order of emissions , in the order they are lines.
The code:

Code: Select all

proc pub:brodcasting {nick uhost hand chan text} {
global canal_admin
if { $chan == $canal_admin } {
	if {[file exist listaDJS]} {
         set file [open listaDJS "r"]
		 set data [read $file]
		 set first [lindex $data 0]
		if {$first == ""} {
		set line_to_delete 0 
		set data [lreplace $data $line_to_delete $line_to_delete]  
		set fp [open $fname "w"]
		puts $fp [join $data "\n"]
		close $fp
		} 
		set data [split $data "\n"]
         set x 0
         	 while {[llength $data] > 0} {
		      if {([llength $data] == 0) && ($x == 0)} { putquick "PRIVMSG $canal_admin :The list is empty."; return }
               if {$data == ""} { continue }
			    putquick "PRIVMSG $canal_admin :\0032Dj \011 \011 \011 \011 \011 \011 \011 \011 \011 \011 \011 \011 \011 \011 \011 \011 \011 \011  Date \011 \011 \011 \011 \011 \011 \011 \011 \011 \011 \011 \011 \011 \011 \011 \011\011 \011 \011 \011 \011 \011 \011 \011 \011   Time" 
				 putquick "PRIVMSG $canal_admin :[lindex $data $x]"
                  set x [expr {$x + 1}]
			}
         close $file
		 putquick "PRIVMSG $canal_admin :\0032____End of List____"
    } else {
    putmsg $canal_admin "Data Base is missing!"
    } 
} else {
return
	}
}
If you do not understand my ideas is because I can not think in English, I help me with Google Translate. I only speak Spanish. Bear with me. Thanks :)
w
willyw
Revered One
Posts: 1196
Joined: Thu Jan 15, 2009 12:55 am

Re: What is wrong in the loop ?

Post by willyw »

This line should be generating an error:

Code: Select all

set fp [open $fname "w"] 
because the varialbe $fname has never been set.

I have not tried to run your code at all. But the
while
loop looks to me like it will just go forever, as you said.
That's because:

Code: Select all

while {[llength $data] > 0} { 
there is nothing to shorten the length of $data. It will always be greater than 0.

If it were me, I wouldn't use a while loop anyway, if possible.
See if you can use a
foreach
loop. http://www.tcl.tk/man/tcl8.6/TclCmd/foreach.htm

While you are there, at the TCL site, check out:
http://www.tcl.tk/man/tcl8.6/TclCmd/lreverse.htm
as it might do what you want, for outputting the lines, last to first.

I hope this helps.
For a fun (and popular) Trivia game, visit us at: irc.librairc.net #science-fiction . Over 300K Q & A to play in BogusTrivia !
j
juanamores
Master
Posts: 317
Joined: Sun Mar 15, 2015 9:59 am

Post by juanamores »

Thanks for the help of willyw.
In the end I decided for the for command.

Code: Select all

for {set i 0} {$i < [llength $data]} {incr i} {
putquick "PRIVMSG $canal_admin :[lindex $data $i]"
}
Before , I modified what was wrong ($fname) and I used lreverse, did not know that command.

Code: Select all

set fp [open listaDJS "w"]
      puts $fp [join $data "\n"]
      close $fp
      }
     set data1 [split $data "\n"]
	  set data [lreverse $data1] 
Thanks for the ideas, it worked perfect! :D
Turning to another matter ...

The list contains two items (DJ and date-hour).
I wish not to allow stored emissions of the same DJ to get together if they have not yet passed 4 hours of its previous issues.

EXAMPLE:
John issued at 00 hours and do it again to 01:30 a.m. .
What I want is the bot does not store this information for 01:30 a.m. .
I want to prevent the same DJ climb to broadcast many times in a short space of time, to have a greater number of emissions covered.
If the same DJ reissues, I wish to save the data only if it has been 4 hours of their previous issue .

The database is formed this way:

Code: Select all

proc addjss { } {
global canal_admin
	if {![file exists djnick]} { return }
		set fname0 "djnick"
		set fp [open $fname0 "r"]
		set data [read -nonewline $fp]
		close $fp
		set lines [split $data " "]  
		set addjs [lindex $lines 0]
		set datehour [lrange $lines 3 end]
 
	if {![file exists listaDJS]} {
		set fs [open listaDJS "w"]
		puts $fs ""
		close $fs
	}  else {
	set fname "listaDJS"
	set fp [open $fname "a"]
	puts $fp "$addjs $datehour"
	close $fp 
	}
}
The variable addjs keep nick DJ and the variable datehour saves the date and time of issue.
Something like that:

Code: Select all

if {($addjs == "previous DJ") && ([expr { [clock seconds] - $your previous DJ time}] < "4 hours")} { return }
else {puts $fp "$addjs $datehour"}
Last edited by juanamores on Sun Sep 11, 2016 12:01 pm, edited 1 time in total.
If you do not understand my ideas is because I can not think in English, I help me with Google Translate. I only speak Spanish. Bear with me. Thanks :)
w
willyw
Revered One
Posts: 1196
Joined: Thu Jan 15, 2009 12:55 am

Post by willyw »

juanamores wrote:....
it worked perfect! :D
Good to hear ! :)


You're welcome.
For a fun (and popular) Trivia game, visit us at: irc.librairc.net #science-fiction . Over 300K Q & A to play in BogusTrivia !
j
juanamores
Master
Posts: 317
Joined: Sun Mar 15, 2015 9:59 am

Post by juanamores »

willyw wrote:
juanamores wrote:....
it worked perfect! :D
Good to hear ! :)


You're welcome.
I edited post, please see it :oops:
If you do not understand my ideas is because I can not think in English, I help me with Google Translate. I only speak Spanish. Bear with me. Thanks :)
w
willyw
Revered One
Posts: 1196
Joined: Thu Jan 15, 2009 12:55 am

Post by willyw »

juanamores wrote: ...
I edited post, please see it :oops:

There might be a few ways to accomplish it.
It sounds like you need to do some math with time measurements.

But trying to do this without seeing the -COMPLETE- script might be a waste of time.

Please either post the script here in this thread, or
http://paste.tclhelp.net/
whichever suits you best.
For a fun (and popular) Trivia game, visit us at: irc.librairc.net #science-fiction . Over 300K Q & A to play in BogusTrivia !
j
juanamores
Master
Posts: 317
Joined: Sun Mar 15, 2015 9:59 am

Post by juanamores »

willyw wrote:....
But trying to do this without seeing the -COMPLETE- script might be a waste of time.
....
I understand.
It is that the entire scropt has more than 10 thousand lines .
My idea was to include the conditional when the database ( listaDJS file) is modified.
I'll see what I can fix like .
Thank you very much for your kind help. :)
If you do not understand my ideas is because I can not think in English, I help me with Google Translate. I only speak Spanish. Bear with me. Thanks :)
w
willyw
Revered One
Posts: 1196
Joined: Thu Jan 15, 2009 12:55 am

Post by willyw »

juanamores wrote: ...
I understand.
It is that the entire scropt has more than 10 thousand lines .
That's huge.

They all cannot apply to this one issue.
Post all the lines that do.
My idea was to include the conditional when the database ( listaDJS file) is modified.
...
I was wondering about how lines like this are created:
Juan Miércoles 7 de Setiembre a las 04:06:38
suspecting that something like [unixtime] command is used to get the current time, at that time.
Then something else comes along and uses that to create what is saved in the file.
With that original [unixtime], you could do some math and conditional checking.
Perhaps you could have the script save that original [unixtime]. That would make it easier.

If you must work with it, exactly as quoted above, then here is something to experiment with:

Code: Select all

clock scan [lindex [split "7 de Setiembre a las 04:06:38" ] end ] -format %H:%M:%S
and

Code: Select all

ctime [clock scan [lindex [split "7 de Setiembre a las 04:06:38" ] end ] -format %H:%M:%S ]
(so you can see what is actually returned)

I'm not very good with the
clock
command. I don't know how to deal with it, in various languages.
http://www.tcl.tk/man/tcl8.6/TclCmd/clock.htm

Perhaps someone else will jump in here, with better ideas for you.
For a fun (and popular) Trivia game, visit us at: irc.librairc.net #science-fiction . Over 300K Q & A to play in BogusTrivia !
j
juanamores
Master
Posts: 317
Joined: Sun Mar 15, 2015 9:59 am

Post by juanamores »

willyw wrote: ...
I was wondering about how lines like this are created:
Juan Miércoles 7 de Setiembre a las 04:06:38
....
I do not like long explanations, because my English is very bad.
But I will try... :)

There are several databases (files).
When a DJ goes up to emission, its nick and start time is stored in this way:

Code: Select all

set horadjstart [clock seconds]

set temp [open "dj" w+]
puts $temp "$djnickname $horadjstart"
close $temp 
When the DJ ends its emission, the values are stored in another file:

Code: Select all

set horadjend [clock seconds]
set hespad [clock format [clock scan "0 day" -base [clock seconds]] -format " %A %d de %B a las %H:%M:%S"]

set temp [open "djnick" w+]
puts $temp "$bajardj $horadjend $hespad"
close $temp
bajardj variable == DJ Nick has completed its issuance (emission)
horadjend variable == time of DJ used the command to get off emission
hespad variable == end time with clock format

As you have seen in previous post, listaDJs data base is formed with the nick of DJ and the time they ended broadcasting (emission).
These data are extracted from the "djnick" file.
In this file only the last DJ issued is stored and the final time of his emission.
When a new DJ goes up to emission, and he ends, the "djnick" file is deleted and a new file "djnick" is created with the name of this last DJ and the time off end the emission.

This is the current contents of the "djnick" file:
Juan 1473590937 Domingo 11 de Setiembre a las 12:48:57
This data
1473590937
represents the time that culminated issue Juan.
I use it to perform mathematical operations


I'm so sorry for the quantity of data I'm given to you.
I understand is difficult without haven't seen the full script.
If you do not understand my ideas is because I can not think in English, I help me with Google Translate. I only speak Spanish. Bear with me. Thanks :)
w
willyw
Revered One
Posts: 1196
Joined: Thu Jan 15, 2009 12:55 am

Post by willyw »

juanamores wrote:
...
This data
1473590937
represents the time that culminated issue Juan.
I use it to perform mathematical operations

...
Then you are all set.
You have the time saved. Just get the difference compared to current time, and if it is less than four hours, don't save new info.

What you have described is something very similar to what I was thinking of.

:)

Good luck with it.
For a fun (and popular) Trivia game, visit us at: irc.librairc.net #science-fiction . Over 300K Q & A to play in BogusTrivia !
j
juanamores
Master
Posts: 317
Joined: Sun Mar 15, 2015 9:59 am

Post by juanamores »

willyw wrote: Just get the difference compared to current time, and if it is less than four hours, don't save new info.
The question I have is like comparing it the same nickname and corresponding to the same day , with the difference of 4 hours . :oops:
This comparison have to do at the time that the database is formed , not in that extract data.

The variable that gives me trouble to compare is:

Code: Select all

set hespad [clock format [clock scan "0 day" -base [clock seconds]] -format " %A %d de %B a las %H:%M:%S"] 
proc addjss { } {
global canal_admin
if {![file exists djnick]} { return }
set fname0 "djnick"
set fp [open $fname0 "r"]
set data [read -nonewline $fp]
close $fp
set lines [split $data " "]
set addjs [lindex $lines 0]
set datehour [lrange $lines 3 end]

if {![file exists listaDJS]} {
set fs [open listaDJS "w"]
puts $fs ""
close $fs
} else {
set fname "listaDJS"
set fp [open $fname "a"]
COMPARISON would go here
puts $fp "$addjs $datehour"
close $fp
}
}
Can you help me with the line that I'm missing ? :oops:
If you do not understand my ideas is because I can not think in English, I help me with Google Translate. I only speak Spanish. Bear with me. Thanks :)
w
willyw
Revered One
Posts: 1196
Joined: Thu Jan 15, 2009 12:55 am

Post by willyw »

juanamores wrote: ...
The variable that gives me trouble to compare is:

Code: Select all

set hespad [clock format [clock scan "0 day" -base [clock seconds]] -format " %A %d de %B a las %H:%M:%S"] 
...
You want to compare the time stored in $hespad to the current time, correct?

But the value stored in $hespad is in text. So you need to convert the time stored in text in $hespad, to a numerical value so you can do math on it to compare it to the current time. Is this correct?

( I may have done this differently, by storing the original numerical time value... rather than convert back and forth.... but no matter )

Try this command:

Code: Select all

clock scan $hespad -format " %A %d de %B a las %H:%M:%S"
I tried it and it works. It returns a number. If you want to see what that number represents, then do:

Code: Select all

 ctime [clock scan $hespad -format " %A %d de %B a las %H:%M:%S"]
And you already know that
[clock seconds]
returns a number that represents the current time.

Four hours is 14400 seconds.

So something like:

Code: Select all

set now [clock seconds]
set then [clock scan $hespad -format " %A %d de %B a las %H:%M:%S"]

if {[expr $now - $then] > 14400 } {
       puts $fp "$addjs $datehour" 
    }
might do what you want.

I think I've got the picture now.
For a fun (and popular) Trivia game, visit us at: irc.librairc.net #science-fiction . Over 300K Q & A to play in BogusTrivia !
j
juanamores
Master
Posts: 317
Joined: Sun Mar 15, 2015 9:59 am

Post by juanamores »

With added lines do not work ..
Something is wrong....
Tcl error [pub_setdj]: input string does not match supplied format

I tried it in two different ways:
1) Invoking the addjss process with the hespad variable in the pub_setdj process, in the latter process it is where the variable hespad sets and where invoked before making changes and it worked.

Code: Select all

addjss $hespad
Then

Code: Select all

proc addjss { hespad } {
global canal_admin
	if {![file exists djnick]} { return }
	set fname0 "djnick"
	set fp [open $fname0 "r"]
	set data [read -nonewline $fp]
	close $fp
	set lines [split $data " "]
	set addjs [lindex $lines 0]
	set datehour [lrange $lines 3 end]

	if {![file exists listaDJS]} {
	set fs [open listaDJS "w"]
	puts $fs ""
	close $fs
	} else {
	set now [clock seconds]
	set then [clock scan $hespad -format " %A %d de %B a las %H:%M:%S"]
	if {[expr $now - $then] > 14400 } { 
		set fname "listaDJS"
		set fp [open $fname "a"] 
		puts $fp "$addjs $datehour"
		close $fp 
	} else { putquick "PRIVMSG $canal_admin :this issue is not stored";return }
	}
}
2) As seen above, the variable $hespa was stored on the djnick file in the pub_setdj process.
Thus:

Code: Select all

set horadjend [clock seconds]
set hespad [clock format [clock scan "0 day" -base [clock seconds]] -format " %A %d de %B a las %H:%M:%S"]

set temp [open "djnick" w+]
puts $temp "$bajardj $horadjend $hespad"
close $temp
Given this, it takes the value of the variable directly from djnick file ($datehour) and invoke the process without the variable (as he had done before and it worked).

Code: Select all

addjss

Code: Select all

proc addjss {  } {
global canal_admin
	if {![file exists djnick]} { return }
	set fname0 "djnick"
	set fp [open $fname0 "r"]
	set data [read -nonewline $fp]
	close $fp
	set lines [split $data " "]
	set addjs [lindex $lines 0]
	set datehour [lrange $lines 3 end]

	if {![file exists listaDJS]} {
	set fs [open listaDJS "w"]
	puts $fs ""
	close $fs
	} else {
	set now [clock seconds]
	set then [clock scan $datehour -format " %A %d de %B a las %H:%M:%S"]
	if {[expr $now - $then] > 14400 } { 
		set fname "listaDJS"
		set fp [open $fname "a"] 
		puts $fp "$addjs $datehour"
		close $fp 
	} else { putquick "PRIVMSG $canal_admin :this issue is not stored";return }
	}
}
Of the two ways gave me the same error:
Tcl error [pub_setdj]: input string does not match supplied format
If you do not understand my ideas is because I can not think in English, I help me with Google Translate. I only speak Spanish. Bear with me. Thanks :)
w
willyw
Revered One
Posts: 1196
Joined: Thu Jan 15, 2009 12:55 am

Post by willyw »

Ok.

I'm not understanding you very well.

That, in combination with not having the script to see what you are actually doing, is causing this to be much more difficult than it should be.

I wish you the best of luck with it.
For a fun (and popular) Trivia game, visit us at: irc.librairc.net #science-fiction . Over 300K Q & A to play in BogusTrivia !
j
juanamores
Master
Posts: 317
Joined: Sun Mar 15, 2015 9:59 am

Post by juanamores »

willyw wrote:Ok.

I'm not understanding you very well.

That, in combination with not having the script to see what you are actually doing, is causing this to be much more difficult than it should be.

I wish you the best of luck with it.
Ok, thanks.

According to what I read, the error that arises is due to format of clock command, the way you suggested me.
Info Info2

I'll see what I can fix it.
If you do not understand my ideas is because I can not think in English, I help me with Google Translate. I only speak Spanish. Bear with me. Thanks :)
Post Reply