TCL – nested NOT – error

Clovertech Forums Read Only Archives Cloverleaf Cloverleaf TCL – nested NOT – error

  • Creator
    Topic
  • #52682
    Peter Heggie
    Participant

      Can a TCL combine three IF tests into one larger test? What is wrong with this syntax:

      “if { ! {[cequal $hsv “CWP”] && ![cequal $prevloc “”] && [cequal $MSH10 “CHPFXFER”] } } {

                     echo $title “KILL message if Hospital Service…” }

      }

      I’m getting error: can’t use non-numeric string as operand of “!”

      Peter

      Peter Heggie
      PeterHeggie@crouse.org

    Viewing 15 reply threads
    • Author
      Replies
      • #75101
        Jim Kosloskey
        Participant

          Peter,

          Try this:

          if { ! ([cequal $hsv “CWP”] && ![cequal $prevloc “”] && [cequal $MSH10 “CHPFXFER”] ) } {

                        echo $title “KILL message if Hospital Service…” }

          }

          Note the parenthesis instead of curly braces.

          email: jim.kosloskey@jim-kosloskey.com 30+ years Cloverleaf, 61 years IT – old fart.

        • #75102
          Charlie Bursell
          Participant

            You don’t need either parenthesis or curly braces here

            I would not use cequal

            if {$hsv ne “CWP” && $prevloc ne “” && $MSH10 eq “CHPFXFER”} {

                         echo $title “KILL message if Hospital Service…” }

            }

            Since the compare is inside braces you can even pretty it up like:

            if {$hsv ne “CWP” &&

                   $prevloc ne “” &&

                   $MSH10 eq “CHPFXFER”} {

                         echo $title “KILL message if Hospital Service…” }

            }

          • #75103
            Jeff Dinsmore
            Participant

              Agreed. I’d use the eq and ne operators rather than cequal and you don’t need any grouping. Negating the result of the comparisons just adds confusion to the code.

              And, assuming that the the intent of the original code was to negate the result of the three comparisons as a group, it should look like this, I believe.

              if { $hsv ne “CWP” && $prevloc eq “” && $MSH10 ne “CHPFXFER” } {

                 echo $title “KILL message if Hospital Service…”

              }

              Jeff Dinsmore
              Chesapeake Regional Healthcare

            • #75104
              Peter Heggie
              Participant

                Thank you Jim, the parenthesis solved that problem, and added to my understanding of TCL – the curly braces contain the entire condition for the IF, and then within that, standard use of parenthesis for indicating the order of processing parts of the condition.

                Thank you Charlie and Jeff; I need to fine tune the logic even more to get the exact condition I want – a hospital service of CWP is grounds for rejecting the message unless both the prior patient location is not null and the (Invision) function name is CHPFXFER. But certainly I can replace the cequal command with a simple string comparison. Maybe this:

                if { ! ($hsv eq “CWP” && $prevloc ne “” && $MSH10 eq “CHPFXFER” ) } {

                echo $title “KILL message if Hospital Service…” }

                }

                Peter

                Peter Heggie
                PeterHeggie@crouse.org

              • #75105
                Peter Heggie
                Participant

                  Maybe it would help if I posted more of the code:

                  # Set Not Allowed Hospital Service List      

                        set HospServNotAllowed {CAN SGA CWP}

                  # KILL message if Hospital Service is Not Allowed

                          if {[lcontain $HospServNotAllowed $hsv]} {

                               if { ! ($hsv eq “CWP” && $prevloc ne “” && $MSH10 eq “CHPFXFER” ) } {

                                 echo $title “KILL message if Hospital Service is Not Allowed” n

                                 lappend dispList “KILL $mh”

                               }

                          } else {

                  This works now. I’m too lazy to work out the logic without using the outer NOT (!). And I don’t want to put in an ELSE branch with a CONTINUE, because I’ve got another eight logic tests further down for other conditions which the message must pass through if it passes the Hospital Service test.

                  Peter

                  Peter Heggie
                  PeterHeggie@crouse.org

                • #75106
                  Terry Kellum
                  Participant

                    I’ve never used the eq and ne operators.  Been doing [string equal $a $b] == 1.

                    Thanks for another Perl of wisdom Charlie!!!

                  • #75107
                    David Barr
                    Participant

                      Peter Heggie wrote:

                      if { ! ($hsv eq “CWP” && $prevloc ne “” && $MSH10 eq “CHPFXFER” ) } {

                      echo $title “KILL message if Hospital Service…” }

                      }

                      Peter

                      If you want to get rid of the parens, you have to negate the comparisons individually and change the “ands” to “ors”. For example “!(a && !b && c)” is the same as “!a || b || !c”. So, in your case you could write it as:

                      Code:

                      if { $hsv ne “CWP” || $prevloc eq “” || $MSH10 ne “CHPFXFER” } {
                       echo $title “KILL message if Hospital Service…” }
                      }

                    • #75108
                      Gene Salay
                      Participant

                        Terry Kellum wrote

                        Quote:

                        Been doing [string equal $a $b] == 1

                        Terry, is there an advantage to using the ==1?

                      • #75109
                        Chris Williams
                        Participant

                          There is a caveat when using the string comparison operators eq and ne. Both operands should be surrounded by quotes.

                          Code:

                          if {$hsv ne “CWP”}

                          will create a syntax error if hsv is empty because the interpreter evaluates it as

                          Code:

                          if { ne “CWP”}

                          With the quotes

                          Code:

                          if {”$hsv” ne “CWP”}

                          it will evaluate as

                          Code:

                          if {”” ne “CWP”}

                        • #75110
                          David Barr
                          Participant

                            Actually, you don’t have to quote the variables, but you do have to quote the string literals.

                            Code:

                            tcl>set x “”
                            tcl>if { $x eq “whatever” } { echo yes } else { echo no }
                            no
                            tcl>if { $x eq whatever } { echo yes } else { echo no }
                            Error: syntax error in expression ” $x eq whatever “: variable references require preceding $
                            tcl>

                          • #75111
                            Kevin Scantlan
                            Participant

                              I understand why it’s better to use the string equal in lieu of cequal, but what advantage does using the “eq” have over the string equal?

                            • #75112
                              David Barr
                              Participant

                                Less characters to type, faster execution, more readable. Everything within an “if” condition is already being passed through “expr” automatically, and “eq” is an operator that is interpreted by “expr” without having to call an additional function.

                              • #75113
                                Charlie Bursell
                                Participant

                                  Very close in time of executions.

                                  See: http://wiki.tcl.tk/15322

                                  I use it cause I am lazy!  😀

                                  Less characters to type

                                  However I will say I was told by Jeff Hobbs (Keeper of Tcl) that the string command are *MUCH* more optonized than the old TCLX “C” commands

                                • #75114
                                  David Barr
                                  Participant

                                    The timings on the TCLers Wiki page don’t take the “if” condition into account. “if” is automatically calling “expr”, so “if{[string equal]}” is calling one extra command.

                                    Code:

                                    proc 1 {a b} {if {$a eq $b} {return 1}}
                                    proc 2 {a b} {if {[string equal $a $b]} {return 1}}
                                    set a “t1.e0”
                                    set b “0x001n”
                                    puts [time {1 $a $b} 1000000] ;# 1.101801 microseconds per iteration
                                    puts [time {2 $a $b} 1000000] ;# 1.230454 microseconds per iteration

                                    Using this pattern, “eq” is about 10% faster.

                                    However, I agree that performance isn’t the main criteria you should use when choosing which one to use.

                                  • #75115
                                    Jeff Dinsmore
                                    Participant

                                      The primary reason for using string comparisons is that the “==” operator is for numeric comparisons and sometimes evaluates “true” for strings that are not equal.

                                      I use the eq and ne operators because they’re core Tcl operators and they’re easier to read – and are better for us lazy typists ;o)

                                      Back to the original problem…

                                      Now that I re-read the description of the condition…

                                      Quote:


                                      “…a hospital service of CWP is grounds for rejecting the message unless both the prior patient location is not null and the (Invision) function name is CHPFXFER”

                                      …I think the logic has to look like this:

                                      Code:


                                      if { $hsv eq “CWP” && ( $prevloc eq “” || $MSH10 ne “CHPFXFER” ) } {
                                        puts delete
                                      } else {
                                        puts “do not delete”
                                      }

                                      Testing…

                                      Code:

                                      () 25 % set MSH10 “CHPFXFER”
                                      CHPFXFER
                                      () 26 % set prevloc “notnull”
                                      notnull
                                      () 27 % if { $hsv eq “CWP” && ( $prevloc eq “” || $MSH10 ne “CHPFXFER” ) } { puts delete } else { puts “do not delete” }
                                      do not delete

                                      () 28 % set MSH10 “XYZ”
                                      XYZ
                                      () 29 % set prevloc “notnull”
                                      notnull
                                      () 30 % if { $hsv eq “CWP” && ( $prevloc eq “” || $MSH10 ne “CHPFXFER” ) } { puts delete } else { puts “do not delete” }
                                      delete

                                      () 31 % set MSH10 “CHPFXFER”
                                      CHPFXFER
                                      () 32 % set prevloc “”
                                      () 33 % if { $hsv eq “CWP” && ( $prevloc eq “” || $MSH10 ne “CHPFXFER” ) } { puts delete } else { puts “do not delete” }
                                      delete

                                      Jeff Dinsmore
                                      Chesapeake Regional Healthcare

                                    • #75116
                                      Peter Heggie
                                      Participant

                                        Yes – thanks Jeff; that does meet the logic requirements.

                                        Peter

                                        Peter Heggie
                                        PeterHeggie@crouse.org

                                    Viewing 15 reply threads
                                    • The forum ‘Cloverleaf’ is closed to new topics and replies.