Author Topic: Boolean AND/OR in IF statements  (Read 8398 times)

0 Members and 1 Guest are viewing this topic.

Haddood

  • $upporter
  • Hero Member
  • *****
  • Posts: 688
  • Karma: 22
    • View Profile
Boolean AND/OR in IF statements
« on: April 28, 2014, 06:43:25 PM »
I searched the form and the wiki if there is a way to add and/or to the if statements  ... no lock

anybody with ideas on how this can be accomplished ?
When Voice command gets tough, use hand gestures

jitterjames

  • Administrator
  • Hero Member
  • *****
  • Posts: 7714
  • Karma: 116
    • View Profile
    • VoxCommando
Re: Boolean AND/OR in IF statements
« Reply #1 on: April 28, 2014, 06:47:48 PM »
No it can't be done, but if you give an example of what you are trying to do I think there is probably a way to do it with the existing tools.

Of course if the simple logic available in the LCB is not good enough you can always use python.

jitterjames

  • Administrator
  • Hero Member
  • *****
  • Posts: 7714
  • Karma: 116
    • View Profile
    • VoxCommando
Re: Boolean AND/OR in IF statements
« Reply #2 on: April 28, 2014, 06:50:52 PM »
Anything can be broken down into an "or" by splitting it into two if statements.

Code: [Select]
if ((a equals 5) or (a equals 9)) then print "a is either 5 or 9"
can be broken down into

Code: [Select]
if (a equals 5) then print "a is either 5 or 9"

if (a equals 9)  then print "a is either 5 or 9"
This may not be the ideal solution but it is one option.

Haddood

  • $upporter
  • Hero Member
  • *****
  • Posts: 688
  • Karma: 22
    • View Profile
Re: Boolean AND/OR in IF statements
« Reply #3 on: April 28, 2014, 07:17:40 PM »
In fact I am looking into simplfying multiple conditions statemts ...
for example:

If temp > 0 and temp < 10 tts: it is pretty cold
If temp > 10 and temp < 20 tts: it is chilly
If temp > 20 and temp < 30 tts: it is perfect weather

without using multiple action and stop macro etc ...

I think the solution will be python ... or you can you consider it as a feature request? :)
When Voice command gets tough, use hand gestures

Kalle

  • $upporter
  • Hero Member
  • *****
  • Posts: 2320
  • Karma: 47
    • View Profile
Re: Boolean AND/OR in IF statements
« Reply #4 on: April 28, 2014, 08:25:51 PM »
This logic is available in the LCB

http://voxcommando.com/mediawiki/index.php?title=Logic_Block#.28A.29.3C.28B.29

You can test this as example: IF (A)contains(B) with 3 logic blocks

IF (- 0 1 2 3 4 5 6 7 8 9 10) contains {LastResult}
THEN tts.speak "it's pretty cold"

IF (11 12 13 14 ...) contains {LastResult}

IF (21 22 23 24 ...) ....

I'm not sure if it will work, but you can try it.
« Last Edit: April 28, 2014, 09:09:43 PM by Kalle »
***********  get excited and make things  **********

jitterjames

  • Administrator
  • Hero Member
  • *****
  • Posts: 7714
  • Karma: 116
    • View Profile
    • VoxCommando
Re: Boolean AND/OR in IF statements
« Reply #5 on: April 28, 2014, 10:23:06 PM »
You need to be careful if you do it this way.  If the temp is 2 then all of your examples will be true.

So you need to do something like

Code: [Select]
if   ,1,2,3,4,5,6,7,8,9,10,11,    contains   ,{temp},

Haddood

  • $upporter
  • Hero Member
  • *****
  • Posts: 688
  • Karma: 22
    • View Profile
Re: Boolean AND/OR in IF statements
« Reply #6 on: April 29, 2014, 12:12:51 AM »
It feels like a mines land ... The risk of many conditions becoming true is pretty high. As well, say if the temp coming from a sensor, then it won't be integer most of the times and these examples if they work they work only with integers, I think.

It feels like the solution will be passing temp to Python ... Python will figure to which range it belongs then return an integer, so it returns 1,2 or 3 ...
So the IFs will be

If 1 = (LastResult)  tts: it is pretty cold
If 2 = (LastResult)  tts: it is chilly
If 3 = (LastResult)  tts: it is perfect weather ...


Now I have to figure how to pass temp to Python and read back from
Learn some basic ifs in Python
Figure a way to make the script a generic function that I pass a long the temp the various ranges

Seems gonna be a bumby ride   ::) ::)



When Voice command gets tough, use hand gestures

Kalle

  • $upporter
  • Hero Member
  • *****
  • Posts: 2320
  • Karma: 47
    • View Profile
Re: Boolean AND/OR in IF statements
« Reply #7 on: April 29, 2014, 02:19:28 AM »
Quote
You need to be careful if you do it this way.  If the temp is 2 then all of your examples will be true.

 :bonk Thanks for the hint.
***********  get excited and make things  **********

nime5ter

  • Administrator
  • Hero Member
  • *****
  • Posts: 1999
  • Karma: 61
    • View Profile
    • Getting Started with VoxCommando
Re: Boolean AND/OR in IF statements
« Reply #8 on: April 30, 2014, 12:19:48 PM »
Now I have to figure how to pass temp to Python and read back from
Learn some basic ifs in Python
Figure a way to make the script a generic function that I pass a long the temp the various ranges

Seems gonna be a bumby ride   ::) ::)

Not to discourage you from doing any of this independently, as I think it's very worthwhile/fun, and I suspect it won't be as challenging for you as you think. But here is one of many different ways you could do this using Python in VC.

I think it's a nice example of something that many VC users -- with varying backgrounds and levels of technical know-how -- might want to experiment with.

(Maybe others can follow up with other suggested solutions, to give everyone an idea of the many ways to tackle the same problem?  ::) ...)

Within my VC command I check the temperature using the WUnder plugin, and then execute the Python file, checkTemp.py (attached), which handles the rest.

To figure out how to get my LastResult (temperature) data from VC for my Python script, I referred to the wiki documentation on using Python. http://voxcommando.com/mediawiki/index.php?title=Python

I also directly stole from the "Actions" example on that page, as you will see.

As per the documentation, LastResult returns a string, and we don't want a string for our purposes.

As you mention above, we also don't necessarily want to restrict ourselves to integers, since WUnder data sometimes returns decimal temp values. I begin by converting the string to a floating point value.

Python makes this kind of string to int or string to float conversion very easy, and a quick Google search usually retrieves the correct syntax without a lot of hunting.

Here is my VC command.

Code: [Select]
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 1.9.3.1-->
<command id="1155" name="checktemp" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
  <action>
    <cmdType>WUnder.GetCustom</cmdType>
    <params>
      <param>{C.temp_c}</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>PY.ExecFile</cmdType>
    <params>
      <param>PY\checkTemp.py</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <phrase>What's the temperature, How warm is it, How cold is it</phrase>
  <phrase optional="true">outside, out there</phrase>
</command>

I've attached the Python file; I usually place my Python files in the PY folder of my VC directory, but whatever floats your boat.

I'm pasting the Python code from my checkTemp.py file here below (this is the same as what is in the attachment), just for those who want to see the code without having to download the attachment and try it for themselves.

The main thing to be careful of with Python is indentation levels. I write my code in Notepad++. (Update: there is now a decent editor/script tester in the Python plugin window itself: http://voxcommando.com/mediawiki/index.php?title=Python#Testing_Code)

Code: [Select]
tempC=float(vc.getObject("LastResult",""))

if 0 <= tempC <= 10:   
    vc.callAction("TTS.Speak","It is pretty cold. You might want a hat.", None)
    vc.callAction("OSD.ShowText","It is pretty cold.", None)

elif 10 <= tempC <= 19:   
    vc.callAction("TTS.Speak","It is chilly. You'll want a light jacket.", None)
    vc.callAction("OSD.ShowText","It is chilly out.", None)
   
elif 19 <= tempC < 30:   
    vc.callAction("TTS.Speak","It is perfect weather. You should find a patio and knock back a cold one.", None)
    vc.callAction("OSD.ShowText","It is perfect weather.", None)
   
else:
    vc.callAction("TTS.Speak","It is %s degrees Celsius"%tempC, None)
    vc.callAction("OSD.ShowText","It is %s degrees Celsius."%tempC, None)

As you can see, I've used your range of temps from 0 to 30 degrees Celsius, with my "else" covering the exceptions.

Follow up discussion, alternative solutions are encouraged! :)
« Last Edit: August 22, 2015, 09:52:39 AM by nime5ter »
TIPS: POST VC VERSION #. Explain what you want VC to do. Say what you've tried & what happened, or post a video demo. Attach VC log. Link to instructions followed.  Post your command (xml)

Kalle

  • $upporter
  • Hero Member
  • *****
  • Posts: 2320
  • Karma: 47
    • View Profile
Re: Boolean AND/OR in IF statements
« Reply #9 on: April 30, 2014, 12:42:40 PM »
Wow, great!!!  ::bow
***********  get excited and make things  **********

vulcanjedi

  • $upporter
  • Sr. Member
  • *****
  • Posts: 213
  • Karma: 8
    • View Profile
Re: Boolean AND/OR in IF statements
« Reply #10 on: April 30, 2014, 01:29:12 PM »
Very neat indeed, thanks for sharing nime5ter.

Haddood

  • $upporter
  • Hero Member
  • *****
  • Posts: 688
  • Karma: 22
    • View Profile
Re: Boolean AND/OR in IF statements
« Reply #11 on: April 30, 2014, 04:19:12 PM »
I second Kalle

Wow !!!!   :yay
When Voice command gets tough, use hand gestures

Haddood

  • $upporter
  • Hero Member
  • *****
  • Posts: 688
  • Karma: 22
    • View Profile
Re: Boolean AND/OR in IF statements
« Reply #12 on: April 30, 2014, 07:52:45 PM »
Started to test with Python, I did not figure how to pass multiple parameters and I need help with that. I still need to pass start, end and step

the script I am working on as explained before is a generic function that detect the value within which range. if lest then start then it returns 0, then returns 1,2,3 ...etc.

then it will be easy to deal with inside VC with multiple if A==B ... like that there will be no multiple true (unless we are dealing with fuzzy logic) ....

Code: [Select]
x = float(vc.getObject("LastResult",""))
start = -20
end = 40
step = 10

y = -1
for i in xrange (start, end+step+1, step):
  y = y + 1;
  if x < i:
      break
result = y;
When Voice command gets tough, use hand gestures

nime5ter

  • Administrator
  • Hero Member
  • *****
  • Posts: 1999
  • Karma: 61
    • View Profile
    • Getting Started with VoxCommando
Re: Boolean AND/OR in IF statements
« Reply #13 on: April 30, 2014, 09:35:39 PM »
You need to define a function in Python, and then you can pass your parameters to the function from your VC command.

Python (tempConditions.py):
Code: [Select]
def conditions(x,start,end,step):
    myTemp = float(x)
    y = -1
    for i in range (start, end+step+1, step):
        y = y + 1
        if myTemp < i:
            break
    return y

Example of your VC command (your parameters could be payloads {1},{2},{3},{4} or whatever you need to do -- I just defined the variables below to try to make clear what is what):
Code: [Select]
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 1.9.3.1-->
<command id="1164" name="What's it like out there?" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
  <action>
    <cmdType>PY.ExecFile</cmdType>
    <params>
      <param>PY\tempConditions.py</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>Results.SetVar</cmdType>
    <params>
      <param>x</param>
      <param>5</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>Results.SetVar</cmdType>
    <params>
      <param>start</param>
      <param>-20</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>Results.SetVar</cmdType>
    <params>
      <param>end</param>
      <param>40</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>Results.SetVar</cmdType>
    <params>
      <param>step</param>
      <param>10</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>PY.ExecString</cmdType>
    <params>
      <param>result=conditions({var.x},{var.start},{var.end},{var.step})</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>OSD.ShowText</cmdType>
    <params>
      <param>{LastResult}</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <phrase>What's it like out there?</phrase>
</command>

The important lines of my VC command example, for your purposes, are that you need to:

1. Load your python file, either in the same command or when you first launch VC using a VC.Loaded event. (Usually best to load it on launch rather than every time you issue the command; once it is loaded it will continue to work unless you reinitialize Python.)

2. You need to call *the Python function* in your command using "result=..." so that the returned value becomes your {LastResult}. At the same point, you're passing your function the parameters from VC.

Code: [Select]
PY.ExecString     result=conditions(x,start,end,step)

... Hope that makes sense.  ???
« Last Edit: August 22, 2015, 09:46:33 AM by nime5ter »
TIPS: POST VC VERSION #. Explain what you want VC to do. Say what you've tried & what happened, or post a video demo. Attach VC log. Link to instructions followed.  Post your command (xml)

Haddood

  • $upporter
  • Hero Member
  • *****
  • Posts: 688
  • Karma: 22
    • View Profile
Re: Boolean AND/OR in IF statements
« Reply #14 on: April 30, 2014, 11:45:37 PM »
 Thank you, thank you ... Your feed back is really appreciated

It is implemented and working like a charm...
First application to check when I ask to set volume and based on which range VC will give feed back:

If required volume:

Less than 25 set it then engage a command to verify it is loud enough then on single to increase / decrease
Between 25 and 50 ... Just do it
50 and 75 set it then engage a command to verify if it is too loud then on single to decrease the volume if needed
More than 75 refuse to do it  :-\ and tts it will be too loud

Next step is to change these limits to global vars and change them based on the time of day



Next work on the temperature recommendations
When Voice command gets tough, use hand gestures