Using Dispatch from win32com.client 'SAPI.Spvoice' - python-3.x

I'm trying to use Python code to change WIN10 text-to-speech voice from Windows Default to English.
There are mentions of using SetVoice commands with SAPI.Spvoice, but cannot find the expample
from win32com.client import Dispatch
Windows_Speak = Dispatch('SAPI.Spvoice')
Windows_Speak.Speak('Tomato')
The above code would use the Windows default language settings, but I need to be able to change languages using in-Python commands. Any ideas?

Try this:
from win32com.client import Dispatch
Windows_Speak = Dispatch('SAPI.Spvoice')
Windows_Speak.Voice = speak.GetVoices().Item(2)
Windows_Speak.Rate = 3
print(speak.GetVoices().Item(2).GetDescription()) #just to see what voice is used
Windows_Speak.Speak('Tomato')
Play around if the voice id

One alternative could be using 'pyttsx3.
If you are trying to change voice from your Window's default one, then you can use try this:
engine = pyttsx3.init('sapi5')
#with given method you will get the list of voices available
voices = engine.getProperty('voices')
#in engine I am setting 0th indexed voice as my custom
engine.setProperty('voice', voices[0].id)

Related

How to copy-paste data from an OS-running application with Python?

I need to write an application that basically focuses on a given Windows window title and copy-pastes data in a notepad. I've managed to achieve it with pygetwindow and pyautogui, but it's buggy:
import pygetwindow as gw
import pyautogui
# extract all titles and filter to specific one
all_titles = gw.getAllTitles()
titles = [title for title in all_titles if 'title' in title]
window = gw.getWindowsWithTitle(titles[0])[0].activate()
pyautogui.hotkey('ctrl', 'a')
pyautogui.hotkey('ctrl', 'c')
Using Spyder, I ocasionally get the following error when activating:
PyGetWindowException: Error code from Windows: 126 - The specified module could not be found.
Additionally, I would be interested in doing this process without affecting the user working on the machine. Activate basically makes the window pop to front. Moreover, it would be better to not be OS dependant, but I haven't found anything yet.
I've tried pywinauto but the SetFocus() method doesn't work (it's buggy, documented).
Is there any other method which would make the whole process invisible and easier?
Not sure if this will help
I am using pywinauto to set_focus
import pywinauto
import pygetwindow as gw
def focus_to_window(window_title=None):
window = gw.getWindowsWithTitle(window_title)[0]
if not window.isActive:
pywinauto.application.Application().connect(handle=window._hWnd).top_window().set_focus()

debug python code and change variables at runtime in pyCharm

I am using pycharm to 2018.3.4 to develop python scripts and I am still pretty new in this language, I normally write PowerShell code. I have a question concerning debugging. Take this unfinished code as an example.
#! python3
# phoneAndEmail.py - Finds phone numbers and email addresses on the clipboard.
import pyperclip, re, sys
phoneRegex = re.compile(r'''(
(\(?([\d \-\)\–\+\/\(]+)\)?([ .-–\/]?)([\d]+))
)''', re.VERBOSE)
mailRegex = re.compile(r'''(
\w+#\w+\.\w+
)''', re.VERBOSE)
text = pyperclip.paste()
def getMatches(text, regex) :
return regex.findall(text)
Emails = getMatches(text,mailRegex) #I want to play with this variable at runtime
phone = getMatches(text,phoneRegex)
I am at the stage where I want to analyze the variable Emails at runtime. So I set a breakpoint and can view the contents of the varieble just fine. However I also want to run some methods and play with their input parameters at runtime. Does someone know how this is possible? If this is possible with another IDE then this would be fine too.
In Pycharm 2018.3.4 you simply do this by clicking on the console tab and then on the show command prompt button.
Now you can type in Emails or Emails.pop() for example in order to manipulate variables:
You can also refer to this post, where this was discussed for an older version: change variable in Pycharm debugger

How to convert text to speech in python 3.5 on windows 10?

I tried espeak but didn't succeed and some functionalities only supported in python 2.
For offline use in Windows, use SAPI directly.
You can use SpVoice.
import win32com.client
speaker = win32com.client.Dispatch("SAPI.SpVoice")
speaker.Speak("Jumpman Jumpman Jumpman Them boys up to something!")
Have you tried using Google Text-to-Speech via gTTS?
The syntax for using it in Python 3.x is as follows:
from gtts import gTTS
my_tts = "Text you want to process"
tts = gTTS(text=my_tts, lang='en')
tts.save("Absolute/path/to/file.mp3")
Here is the github repo of gTTS.

Preventing jedi to complete everything after space

I am trying to use jedi to complete python code inside a PyQt application, using QCompleter and QStringListModel to store the possible completion.
Here's a simple working demo:
#!/usr/bin/env python3
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import jedi
import sys
class JediEdit(QLineEdit):
def __init__(self, parent=None):
super().__init__(parent)
self._model = QStringListModel()
self._compl = QCompleter()
self._compl.setModel(self._model)
self.setCompleter(self._compl)
self.textEdited.connect(self.update_model)
def update_model(self, cur_text):
script = jedi.Script(cur_text)
compl = script.completions()
strings = list(cur_text + c.complete for c in compl)
self._model.setStringList(strings)
if __name__ == '__main__':
app = QApplication(sys.argv)
line = JediEdit()
line.show()
sys.exit(app.exec_())
If you run the application and write a code which is not completing anything (e.g. or foo =), the completion will actually show all the possible tokens that can go in that position.
So, if I run and write a space in the field, lots of things pops up, from abs to __version__.
I would like to prevent this: is it possible to query jedi.Script to understand if the token is being completed or if a completely new token is starting?
EDIT: another little question: say that I am running an interpreter which is detached from jedi current state. How can I provide local and global variables to jedi.Script so that it will take into account those, instead of its own completions?
Autocompletion
Jedi's autocompletion will always show all possible tokens in a place. That's the whole point in autocompletion.
If you don't want that behavior just scan the last few characters for whitespace and certain other characters like = or :, it would be a very simple regex command. (You could also try to look up Jedi's internals and use the way how Jedi knows about this context. However I'm not going to tell you, because it's not a public API and IMHO regex calls suffice.)
In the future something like that might be possible. (See https://github.com/davidhalter/jedi/issues/253).
Now that I think about it, there might be another way that you could experiment with this: You can try to play with Completion.name and Completion.complete. The latter only gives you what could come after the current token, while the name would be the full thing. So you can compare and if they are equal than you might not want to display anything.
Have fun playing with the API :-)
Interpreter
If you're running an interpreter, you can use jedi.Interpreter to combine code with actual Python objects. It's pretty flexible. But please note that the current Interpreter (0.8.1) is very buggy. Please use the master branch from Github (0.9.0).

Playing a sound in a ipython notebook

I would like to be able to play a sound file in a ipython notebook.
My aim is to be able to listen to the results of different treatments applied to a sound directly from within the notebook.
Is this possible? If yes, what is the best solution to do so?
The previous answer is pretty old. You can use IPython.display.Audio now. Like this:
import IPython
IPython.display.Audio("my_audio_file.mp3")
Note that you can also process any type of audio content, and pass it to this function as a numpy array.
If you want to display multiple audio files, use the following:
IPython.display.display(IPython.display.Audio("my_audio_file.mp3"))
IPython.display.display(IPython.display.Audio("my_audio_file.mp3"))
A small example that might be relevant : http://nbviewer.ipython.org/5507501/the%20sound%20of%20hydrogen.ipynb
it should be possible to avoid gooing through external files by base64 encoding as for PNG/jpg...
The code:
import IPython
IPython.display.Audio("my_audio_file.mp3")
may give an error of "Invalid Source" in IE11, try in other browsers it should work fine.
The other available answers added an HTML element which I disliked, so I created the ringbell, which gets you both play a custom sound as such:
from ringbell import RingBell
RingBell(
sample = "path/to/sample.wav",
minimum_execution_time = 0,
verbose = True
)
and it also gets you a one-lines to play a bell when a cell execution takes more than 1 minute (or a custom amount of time for that matter) or is fails with an exception:
import ringbell.auto
You can install this package from PyPI:
pip install ringbell
If the sound you are looking for could be also a "Text-to-Speech", I would like to mention that every time a start some long process in the background, I queue the execution of a cell like this too:
from IPython.display import clear_output, display, HTML, Javascript
display(Javascript("""
var msg = new SpeechSynthesisUtterance();
msg.text = "Process completed!";
window.speechSynthesis.speak(msg);
"""))
You can change the text you want to hear with msg.text.

Resources