• Re: Set a group of blank vars to a reset value.

    From Arjen Markus@21:1/5 to snosniv on Fri Feb 3 03:10:33 2023
    On Friday, February 3, 2023 at 11:40:48 AM UTC+1, snosniv wrote:
    I have some time entry data as mins0, secs0, mins1, secs1 etc etc, my script detects if both are unset and raises a warning, but if say mins is set but secs is blank, I set the secs to 0 (and vice-versa):

    if {($mins0 == "")} { set mins0 0}
    but rather than doing all the mins individually, I'd prefer a loop, but something like;
    for {set i 0} {$i < $max} {incr i} {
    {if $mins$i == ""} {set $mins$i 0}
    }
    obviously won't work.
    How do I do get a loop method to work please? (history means I can't really convert to an array easily).

    One way to achieve this is vIa [set]:
    set value0 0
    set oldi 0
    for {set i 1} { $i < 100} {incr i} {
    set value$i [expr {1 + [set value$oldi]}]
    set oldi $i
    }
    puts [set value99]

    Regards,

    Arjen

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From snosniv@21:1/5 to All on Fri Feb 3 02:40:45 2023
    I have some time entry data as mins0, secs0, mins1, secs1 etc etc, my script detects if both are unset and raises a warning, but if say mins is set but secs is blank, I set the secs to 0 (and vice-versa):

    if {($mins0 == "")} { set mins0 0}
    but rather than doing all the mins individually, I'd prefer a loop, but something like;
    for {set i 0} {$i < $max} {incr i} {
    {if $mins$i == ""} {set $mins$i 0}
    }
    obviously won't work.
    How do I do get a loop method to work please? (history means I can't really convert to an array easily).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From snosniv@21:1/5 to All on Fri Feb 3 04:12:36 2023
    I need to set ALL times that are blank i.e. entry widget has been left empty, to value 0.
    i.e. mins0, mins1, mins2 etc all need to be set to 0 if they are seen as "".

    Sorry for the confusion.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Arjen Markus@21:1/5 to snosniv on Fri Feb 3 04:20:55 2023
    On Friday, February 3, 2023 at 1:12:39 PM UTC+1, snosniv wrote:
    I need to set ALL times that are blank i.e. entry widget has been left empty, to value 0.
    i.e. mins0, mins1, mins2 etc all need to be set to 0 if they are seen as "".

    Sorry for the confusion.
    Well, I assumed you meant you did not know how to get the value of a variable whose name is constructed. You should adapt the loop I showed ;). It merely illustrates the principle, not the solution.

    Regards,

    Arjen

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From snosniv@21:1/5 to All on Fri Feb 3 04:38:56 2023
    It's the IF part I'm struggling with.
    I can set all to 0 with your method, but that overwrites valid times as well. I'm not that conversant with Tcl, or software in general, being a hardware engineer, not software.

    if {($mins0 == "")} { set mins0 0}
    if {($mins1 == "")} { set mins1 0}
    if {($mins2 == "")} { set mins2 0} ## i.e. set to zero only if entry widget is left empty.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ralf Fassel@21:1/5 to All on Fri Feb 3 14:03:06 2023
    * snosniv <[email protected]>
    | I have some time entry data as mins0, secs0, mins1, secs1 etc etc, my
    | script detects if both are unset and raises a warning, but if say mins
    | is set but secs is blank, I set the secs to 0 (and vice-versa):

    | if {($mins0 == "")} { set mins0 0}
    | but rather than doing all the mins individually, I'd prefer a loop, but
    | something like;
    | for {set i 0} {$i < $max} {incr i} {
    | {if $mins$i == ""} {set $mins$i 0}
    | }
    | obviously won't work.
    | How do I do get a loop method to work please? (history means I can't
    | really convert to an array easily).

    If you need to stick with the individual variable approach: the key is to
    use 'set' to do the lookup (and the proper TCL syntax to start with ;-)
    as in:

    for {set i 0} {$i < $max} {incr i} {
    if {[set mins$i] eq ""} {
    set mins$i 0
    }
    }

    HTH
    R'

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From snosniv@21:1/5 to All on Fri Feb 3 05:25:32 2023
    Sorted, thanks all for the help.
    I haven't dabbled in Tcl much since I retired over 5 years ago, so forgotten quite a lot,
    well, that's my excuse anyway. 😃

    Thanks again, Kev P.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to snosniv on Fri Feb 3 14:11:22 2023
    snosniv <[email protected]> wrote:
    Sorted, thanks all for the help.
    I haven't dabbled in Tcl much since I retired over 5 years ago, so
    forgotten quite a lot, well, that's my excuse anyway. ?

    The key to solving these sorts of questions yourself is to remember two
    things:

    1) Tcl is not Perl, the variable is not named with the sigil. $xyz is
    a variable named "xyz" and $ is shorthand for "retreive contents of
    the given named variable".

    2) That "set" does double duty of creating/changing variable contents
    *and* of retreiving the contents of named variables.

    3) That expansions (both "$" and "[]") occur before the command named
    in the first parameter is called

    What #1 and #2 above mean is that "$" plus a variable name is the
    equivalent of single parameter set, i.e.:

    $varname

    performs the same operation as (note the lack of $ below)

    set varname

    What #3 means is that you can create named variables using the contents
    of other variables by using "$" or "[set varname]":

    If you have this:

    set varname qwerty

    Then both of these:

    set $varname 123
    set [set varname] 123

    Create a variable named "qwerty" and make it contain the string "123".

    And this retreives "123" as the contents of the variable "qwerty":

    set qwerty

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From saitology9@21:1/5 to snosniv on Fri Feb 3 13:31:23 2023
    On 2/3/2023 5:40 AM, snosniv wrote:
    I have some time entry data as mins0, secs0, mins1, secs1 etc etc, my script detects if both are unset and raises a warning, but if say mins is set but secs is blank, I set the secs to 0 (and vice-versa):

    if {($mins0 == "")} { set mins0 0}
    but rather than doing all the mins individually, I'd prefer a loop, but something like;
    for {set i 0} {$i < $max} {incr i} {
    {if $mins$i == ""} {set $mins$i 0}
    }
    obviously won't work.
    How do I do get a loop method to work please? (history means I can't really convert to an array easily).


    Here is a slightly different solution, especially if you have a large
    number of these variables.

    Here is how you use it, with an optional third argument which is the
    reset value:

    test_reset mins0 secs0
    test_reset mins1 secs1
    ...
    test_reset mins100 secs100


    This is the implementation:

    proc test_reset {minvar secvar {def 0}} {
    upvar \#0 $minvar mins
    upvar \#0 $secvar secs

    if {[string trim $mins] eq ""} { set mins $def }
    if {[string trim $secs] eq ""} { set secs $def }

    return
    }

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Andreas Leitgeb@21:1/5 to [email protected] on Fri Feb 3 19:09:01 2023
    saitology9 <[email protected]> wrote:
    On 2/3/2023 5:40 AM, snosniv wrote:
    I have some time entry data as mins0, secs0, mins1, secs1 etc etc, my script detects if both are unset and raises a warning, but if say mins is set but secs is blank, I set the secs to 0 (and vice-versa):

    if {($mins0 == "")} { set mins0 0}
    but rather than doing all the mins individually, I'd prefer a loop, but
    something like;
    for {set i 0} {$i < $max} {incr i} {
    {if $mins$i == ""} {set $mins$i 0}
    }
    obviously won't work.
    How do I do get a loop method to work please? (history means I can't really convert to an array easily).


    Here is a slightly different solution, especially if you have a large
    number of these variables.

    Here is how you use it, with an optional third argument which is the
    reset value:

    test_reset mins0 secs0
    test_reset mins1 secs1
    ...
    test_reset mins100 secs100

    My suggestion:
    for {set i 0} {$i <= 100} {incr i} {
    test_reset mins$i secs$i
    }


    This is the implementation:

    proc test_reset {minvar secvar {def 0}} {
    upvar \#0 $minvar mins
    upvar \#0 $secvar secs

    My suggestion:
    In your specific case, where all the mins# and secs# variables
    are global, this is fine as it is, but more generally, I'd
    advise to use level 1 instead of \#0, because then you could
    use the helper to also reset local variables in other procedures,
    while still being able to reset global variables, by calling
    the test_reset from global level. If mins# and secs# are
    always global and you want to call test_reset even from
    within other procedures and still reset the global ones,
    then forget the paragraph, as in that case the "#0" is just right.

    One more thing: the # for upvar doesn't really need escaping,
    unless you use a syntax-highlighting editor that doesn't know tcl
    well - then escaping the # is harmless for tcl, but may be neeeded
    to get the coloring right.

    In Tcl, # only starts a comment, when it appears where the start
    of a command is expected, and that isn't the case after "upvar".

    if {[string trim $mins] eq ""} { set mins $def }
    if {[string trim $secs] eq ""} { set secs $def }

    return
    }


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From saitology9@21:1/5 to Andreas Leitgeb on Fri Feb 3 14:22:51 2023
    On 2/3/2023 2:09 PM, Andreas Leitgeb wrote:

    test_reset mins0 secs0
    test_reset mins1 secs1
    ...
    test_reset mins100 secs100

    My suggestion:
    for {set i 0} {$i <= 100} {incr i} {
    test_reset mins$i secs$i
    }


    True, more so if they need are named uniformly and the call to reset
    them happens for all at the same time. If you imagine a GUI where the
    mins/secs are placed, that is probably one or two at a time.




    This is the implementation:

    proc test_reset {minvar secvar {def 0}} {
    upvar \#0 $minvar mins
    upvar \#0 $secvar secs

    My suggestion:
    In your specific case, where all the mins# and secs# variables
    are global, this is fine as it is, but more generally, I'd
    advise to use level 1 instead of \#0, because then you could
    use the helper to also reset local variables in other procedures,
    while still being able to reset global variables, by calling

    Good point. I need to revisit the man page for upvar about these magic
    level numbers :-)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)