Python Virtual Assistant not continuing after a block of code. while 1: - function

I will provide the code for a portion. It doesn't continue after using commands within a while block. I think it is the code block text = get_audio().lower() that is giving me the error.
def process_text():
pass
if __name__ == "__main__":
assistant_speaks('''Hello, I am a Virtual Assistant.
I am here to make your life easier. You can command me to perform
various tasks such as calculating sums or opening applications.
Please tell me who you are.''')
name = 'are'
name = get_audio()
assistant_speaks("Hello, " + name + '.')
while 1:
assistant_speaks("What can i do for you?" + name + '.')
text = get_audio().lower()
if text == 0:
continue
if "exit" in str(text) or "bye" in str(text) or "sleep" in str(text):
assistant_speaks("Ok bye, " + name + '.')
break
# calling process text to process the query
process_text()
def process_text():
try:
if 'search' in input or 'play' in input:
# a basic web crawler using selenium
search_web(input)
return
elif "who are you" in input or "define yourself" in input:
speak = '''Hello, I am a virtual assistant.
I am here to make your life easier. You can command me to perform
various tasks such as calculating sums or opening applications.'''
assistant_speaks(speak)
return
Basically, it doesn't answer any questions when I ask the elifs. Past the try:
Does anyone have any ideas?

There are at least three mistakes you should correct in order to get the behavior you want from your program:
Replace input with text inside the try block. In Python, input is a built-in function, not a string. You already assigned the user's answer to the variable text, so why not use that one? :)
Define your process_text function before you call it. Practically, you should move the line where you call process_text() somewhere after the definition of that function.
There are also a couple of indentation errors, and the most important happens when you call the process_text() function: you should un-indent that line back one level, otherwise it will be executed inside the if "exit" in ... block.
You should also define process_text before the while loop, because you just need to define it once.

Related

In Jupyter Notebook, how to show output within function without using print

I want the code to show "123" without using built-in print function, but it does not. What should I do?
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
def myf():
"123"
myf()
If I got right, you just want to print the "123", right?
def myf():
print("123")
myf()
If you want to receive the "123" as a result of your def, would be something like this :
def myf():
x = "123"
return x
Z = myf()
print (Z)
"123"
You can use the display function:
Although, I don't think that's what you want. The settings you're enabling:
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
Only apply to returned values; that's why you don't see it printed. If you return the value and call the function a few times, you'll see them:
I don't have a direct answer to this, but I have some pointers to the problem.
Normal output is written either in stdout or stderr by some Python provided method. However, when utilizing the IPython feature of checking a value by using either direct value ("123") or variable (first line a = "123", second line a). This output stream can not be captured with simple %%capture magic in Jupyter; the output vanishes in the scope of the function definition.
I do agree that this would be useful; in machine learning we sometimes use dependency inversion like structures, where we modify functions instead of line-by-line code, where debugging gets hard since we can not capture some of the outputs without injecting a print or display. However, not using display might have unwanted and hard to predict consequences as some of the models can be rather verbose in what they write. However, capturing some outputs without extra prints and displays from user defined cells might be nice feature.
Notice that sometimes print doesn't work, but display does. Print might not always understand how our utilities in pandas or matplotlib works.

How do I debug lua functions called from conky?

I'm trying to add some lua functionality to my existing conky setup so that repetitive "code" in my conky text can be cleaned up. For example, I have information for each mounted FS, each core, etc. where each row displayed in my panel differs ONLY by one parameter.
My first skeletal, attempt at using lua functions for this seems to run but displays nothing in my panel. I've only found very simple examples to base this on, so I may have made a simple error, but I don't even know how to diagnose it. My code here is modeled after what I HAVE been able to find regarding writing functions, such as this How to implement a basic Lua function in Conky? , but that's about all the depth I've found on the topic except for drawing and cairo examples.
Here's the code added to my conky config, as well as the contents of my functions.lua file
conky.config = {
...
lua_load = '/home/conky-manager/MyConky/functions.lua',
};
conky.text = [[
...
${voffset 5}${lua conky_test 'test'}
...
]]
file - functions.lua
function conky_test(parm1)
return 'result text'
end
What I would expect is to see is "result text" displayed in my panel at the location where that function call appears, but nothing shows.
Is there a log created by conky as it runs, or a way to provide some debug output? Even if I'd made a simple error here, I'd still like to have the ability to diagnose things as my code gets more complex.
Success!
After cobbling info from several articles together, I figured out my basic flaws -
1. Missing a 'conky_main' function,
2. Missing a 'lua_draw_hook_post' to invoke it, and
3. Realizing that if I invoke conky from a terminal, print statements in lua would appear there.
So, for anyone who sees this question and has the same issues, here's the corrected code.
conky.config = {
...
lua_load = '/home/conky-manager/MyConky/functions.lua',
lua_draw_hook_post = "main",
};
conky.text = [[
...
${lua conky_test 'test'}
...
]]
and the proper basics in my functions.lua file
function conky_test(parm1)
return 'result text'
end
function conky_main()
if conky_window == nil then
return
end
end
A few notes:
I still haven't determined if using 'lua_draw_hook_pre' instead of 'lua_draw_hook_post' makes any difference, but it doesn't seem to in this example.
Also, some examples showed actually calling this 'test' function instead of writing a 'main', but the 'main' seemed to have value in checking to see if conky_window existed.
Some examples seemed to state that naming functions with the prefix 'conky_' was required, but then showed examples of calling those functions without the prefix, so I assume the prefix is inferred during the call.
a major note: you should run conky from the directory containing the lua scripts.

how to use the recognized text with Google Assistant's hotword.py code

How do I get the spoken text from the hotword.py code & do my own actions on the recognised text rather than Google going off and reacting to the text?
I've installed GA on the Pi3 & after some initial issues with usb mic/analogue audio settings and certain Python files missing this got me going:
When installing Google Assistant, I an error "...googlesamples.assistant' is a package and cannot be directly executed..."
I then followed the Google Next steps : https://developers.google.com/assistant/sdk/prototype/getting-started-pi-python/run-sample and created a new project "myga/" with a hotword.py file that contains:
def process_event(event):
"""Pretty prints events.
Prints all events that occur with two spaces between each new
conversation and a single space between turns of a conversation.
Args:
event(event.Event): The current event to process.
"""
if event.type == EventType.ON_CONVERSATION_TURN_STARTED:
print()
#GPIO.output(25,True) see https://stackoverflow.com/questions/44219740/how-can-i-get-an-led-to-light-on-google-assistant-listening
if event.type == EventType.ON_RECOGNIZING_SPEECH_FINISHED:
print("got some work to do here with the phrase or text spoken!")
print(event)
if (event.type == EventType.ON_CONVERSATION_TURN_FINISHED and
event.args and not event.args['with_follow_on_turn']):
print()
#GPIO.output(25,False) or also see https://blog.arevindh.com/2017/05/20/voice-activated-google-assistant-on-raspberry-pi-with-visual-feedback/
I'd like code to react to the ON_RECOGNIZING_SPEECH_FINISHED event I think and at either do my own action by matching simple requests or if the phrase is not in my list then let Google handle it. How do I do that?
Eventually I'd be asking "OK Google, turn BBC1 on" or "OK Google, play my playlist" or "OK Google, show traffic" and hotword.py would run other applications to do those tasks.
Thanks, Steve
See the documentation here for all available methods -
https://developers.google.com/assistant/sdk/reference/library/python/
You can use the stop_conversation() method to stop Google Assistant handling that request and act on your own.
Here's what you need to do at a high level -
Build your own dictionary of commands that you'd like to handle -
"turn BBC1 on", "play my playlist" etc.
On EventType.ON_RECOGNIZING_SPEECH_FINISHED event check if the
recognized command exists in your dictionary.
If the recognized command exists in your dictionary call the assistant.stop_conversation() method and handle the command on your own. If not do nothing (let google handle it)
pseudo code -
local_commands = ['turnBBCOn', 'playLocalPlaylist']
function turnBBCOn() :
#handle locally
function playLocalPlaylist() :
#handle locally
def process_event(event):
if event.type == EventType.ON_CONVERSATION_TURN_STARTED:
print()
if event.type == EventType.ON_RECOGNIZING_SPEECH_FINISHED:
print(event.args['text'])
if event.args['text'] in local_commands:
assistant.stop_conversation()
if(event.args['text']='turn BBC1 on')
turnBBCOn()
elif(event.args['text']='play my playlist')
playLocalPlaylist()
if (event.type == EventType.ON_CONVERSATION_TURN_FINISHED and
event.args and not event.args['with_follow_on_turn']):
print()
I have recently integrated google assistant SDK with Raspberry Pi 3. I have taken reference from below git repository and created action.py and actionbase.py classes can handle my custom command. I found it very clean and flexible way to create your own custom commands.
You can register your custom command in action.py file like below
actor = actionbase.Actor()
actor.add_keyword(
_('ip address'), SpeakShellCommandOutput(
say, "ip -4 route get 1 | head -1 | cut -d' ' -f8",
_('I do not have an ip address assigned to me.')))
return actor
action.py
Write your custom code in action.py
"""Speaks out the output of a shell command."""
def __init__(self, say, shell_command, failure_text):
self.say = say
self.shell_command = shell_command
self.failure_text = failure_text
def run(self, voice_command):
output = subprocess.check_output(self.shell_command, shell=True).strip()
if output:
self.say(output.decode('utf-8'))
elif self.failure_text:
self.say(self.failure_text)
You can full source code here. https://github.com/aycgit/google-assistant-hotword
The text is contained within the event arguments. By calling event.args you can make use of the text. Here is an example.
https://github.com/shivasiddharth/GassistPi/blob/master/src/main.py

Using loops to automate functions-Python 3

Is there a way to use a for loop to automate a function? e.g
if i write..
def foo (a number):
return (a number)
for i in range(10):
print(foo('1{}').format(str(i))
Comes out with AttributeError: 'NoneType' object has no attribute 'format'
Well, I am changing this because it didn't really answer your question, but its a lot simpler than you are trying to make it. Really all it is, is a function that is called and updated by a loop. So, let's try that:
def foo(num):
print(num)
num = 0
for i in range(1,10,1):
foo(num + i)
So, what I've done here is taken your script and changed it. To start with, "a number" as a parameter will cause syntax errors while trying to define them. So I changed it to "num".
Then, I've used a simple print statement to print out the number that is coming in. This could be removed if you just wanted a loop with it cycling it through numbers. And of course changing "foo(num + i)" to "print(num + i)".
The "num = 0" sets a variable so we can use it later.
Regards,
Jerry

Connecting output of script to extract performance

When I use the Execute Script operator, where there is one input arc and this input is of type ExampleSet and I run, for example, the one-line script return operator.getInput(ExampleSet.class), and then connect the output to an Extract Performance operator, which takes an ExampleSet as input, I get an error: Mandatory input missing at port Performance.example set.
My goal is to check a Petri-net for soundness via the Analyse soundness operator that comes with the RapidProm extension, and to take and change the first attribute on the first line to either 0 or 1 depending on whether this string matches "is sound", so I can then use Extract Performance and combine it with other performances using Average.
Is doing this with Execute Script the right way to do it, and if so, how should I fix this error?
Firstly: Don't bother about the error Mandatory input missing at port Performance.example set
It will be resolved when you run the model.
Secondly: It is indeed a bit ugly, the output of the operator that checks
the soundness of the model, since it is a very long string that looks like
Woflan diagnosis of net "d1cf46bd-15a9-4801-9f02-946a8f125eaf" - The net is sound End of Woflan diagnosis
You can indeed use the execute script to resolve this :)
See the script below!
The output is an example set that returns 1 if the model is sound, and 0 otherwise. Furthermore, I like to use some log operators to translate this to a nice table useful for documentation purposes.
ExampleSet input = operator.getInput(ExampleSet.class);
for (Example example : input) {
String uglyResult = example["att1"];
String soundResult = "The net is sound";
Boolean soundnessCheck = uglyResult.toLowerCase().contains(soundResult.toLowerCase());
if (soundnessCheck){
example["att1"] = "1"; //the net is sound :)
} else {
example["att1"] = "0"; //the net is not sound!
}
}
return input;
See also the attached example model I created.
RapidMiner Setup