qWait analogue in PySide? - pyqt

I've written a series of unit tests in PyQt using QTest and unittest. My code passes signals around, so to ensure that sufficient time has gone by after an operation before testing, I throw in some qWaits.
APP.ui.serverPortEdit.setText('1234')
QTest.mouseClick(APP.ui.userConnectButton, Qt.LeftButton)
QTest.qWait(2000) #wait for the server to connect
self.checkOnline()
I'd like to run the same tests in PySide, but I can find no analogue to qWait. Have I overlooked something? The PySide qTest docs make no mention of it.

For others that come across this (my first Google hit) time.sleep() does not process QEvents. I came across this PyQt4/PySide wrapper that defines qWait to use with PySide:
from datetime import datetime as datetime_, timedelta
#staticmethod
def qWait(t):
end = datetime_.now() + timedelta(milliseconds=t)
while datetime_.now() < end:
QtGui.QApplication.processEvents()
QtTest.QTest.qWait = qWait

Can't you use python's time.sleep()?

Related

How to write a Python code for downloading an abstract from PubMed?

This is the code I have as of now and I have tried multiple different ways to get the correct code but to no avail.
I am using the Biopython module for this.
from Bio.Entrez import efetch
def print_abstract(pmid):
handle = efetch(db='pubmed', id=pmid, retmode='text', rettype='abstract')
print handle.read()
I tried the code as listed above along with a few tweaks here and there but nothing seems to be working for a simple query.
Step 1: When using python3, use print() as such:
from Bio.Entrez import efetch
def print_abstract(pmid):
handle = efetch(db='pubmed', id=pmid, retmode='text', rettype='abstract')
print(handle.read())
Step 2: To make use of NCBI's E-utilities, NCBI requires you to specify your email address with each request. So, specify any email (it doesn't have to be real) as follows:
from Bio import Entrez
Entrez.email = 'some#example.com'
Step 3: Now you can retrieve an abstract programmatically, for example by running
print_abstract(35312860)
This gives me:
1. Acta Diabetol. 2022 Mar 21. doi: 10.1007/s00592-022-01878-z. [Epub ahead of
print]
Significant and persistent improvements in time in range and positive emotions in
children and adolescents with type 1 diabetes using a closed-loop control system
after attending a virtual educational camp.
...
OBJECTIVE: To evaluate the six-month impact of the advanced automated functions...

How do I run other python separate inside of kivy program

Coming from Arduino to python I am use to everything running in a loop more or less.
I am trying to understand how python interacts with kivy.
I understand that in order to make a segment of code run over and over I need a while statement for example. However if I use code that loops before it gets to the kivy code it will never get to the kivy code. But if I make a loop after the kivy code it will not run till I close the program.
I have google around and I see examples of simple projects of python/kivy projects that all the code pertains to the UI glue logic to make it actually do something. But I have not seen anything show python code running independent of the kivy project.
In other words if I made a project in Arduino I would have a main loop and I could call out to functions and then return from them. However I don't understand what is the best way to do this with kivy/python.
The sample code I have posted below is not a loop however I would expect it to run everything in one go. But It will run the first print statements and then when I close the app the last print statement will run.
I understand that loops are not recommended with object oriented programing, this is just a simple example as reference of what I'm use to.
For those that will say I don't understand what your asking and what are you trying to do or ask?
I am trying to ask where do I put python code that dose not pertain immediately to the kivy code but needs to run in loops or whatever while kivy is running. So that I can make things happen on the python side while not blocking kivy.
Dose this require multiple python programs? And leave the kivy program by itself almost like a .kv file.
Or dose it require everything to be put in classes?
Thanks for any clarification, best practices or examples.
from kivy.app import App
from kivy.uix.button import Button
print("test")
class FirstKivy(App):
def build(self):
return Button(text="Test text")
print("test2")
FirstKivy().run()
print("test3")
You would need to add Threading to your code
from kivy.app import App
from kivy.uix.button import Button
import threading
print("test")
class FirstKivy(App):
def build(self):
return Button(text="Test text")
print("test2")
def run():
FirstKivy().run()
def print_stuff():
print("test3")
kivy_thread = threading.Thread(target=run)
print_thread = threading.Thread(target=print_stuff)
kivy_thread.start()
print_thread.start()

restart python (or reload modules) in py.test tests

I have a (python3) package that has completely different behaviour depending on how it's init()ed (perhaps not the best design, but rewriting is not an option). The module can only be init()ed once, a second time gives an error. I want to test this package (both behaviours) using py.test.
Note: the nature of the package makes the two behaviours mutually exclusive, there is no possible reason to ever want both in a singular program.
I have serveral test_xxx.py modules in my test directory. Each module will init the package in the way in needs (using fixtures). Since py.test starts the python interpreter once, running all test-modules in one py.test run fails.
Monkey-patching the package to allow a second init() is not something I want to do, since there is internal caching etc that might result in unexplained behaviour.
Is it possible to tell py.test to run each test module in a separate python process (thereby not being influenced by inits in another test-module)
Is there a way to reliably reload a package (including all sub-dependencies, etc)?
Is there another solution (I'm thinking of importing and then unimporting the package in a fixture, but this seems excessive)?
To reload a module, try using the reload() from library importlib
Example:
from importlib import reload
import some_lib
#do something
reload(some_lib)
Also, launching each test in a new process is viable, but multiprocessed code is kind of painful to debug.
Example
import some_test
from multiprocessing import Manager, Process
#create new return value holder, in this case a list
manager = Manager()
return_value = manager.list()
#create new process
process = Process(target=some_test.some_function, args=(arg, return_value))
#execute process
process.start()
#finish and return process
process.join()
#you can now use your return value as if it were a normal list,
#as long as it was assigned in your subprocess
Delete all your module imports and also your tests import that also import your modules:
import sys
for key in list(sys.modules.keys()):
if key.startswith("your_package_name") or key.startswith("test"):
del sys.modules[key]
you can use this as a fixture by configuring on your conftest.py file a fixture using the #pytest.fixture decorator.
Once I had similar problem, quite bad design though..
#pytest.fixture()
def module_type1():
mod = importlib.import_module('example')
mod._init(10)
yield mod
del sys.modules['example']
#pytest.fixture()
def module_type2():
mod = importlib.import_module('example')
mod._init(20)
yield mod
del sys.modules['example']
def test1(module_type1)
pass
def test2(module_type2)
pass
The example/init.py had something like this
def _init(val):
if 'sample' in globals():
logger.info(f'example already imported, val{sample}' )
else:
globals()['sample'] = val
logger.info(f'importing example with val : {val}')
output:
importing example with val : 10
importing example with val : 20
No clue as to how complex your package is, but if its just global variables, then this probably helps.
I have the same problem, and found three solutions:
reload(some_lib)
patch SUT, as the imported method is a key and value in SUT, you can patch the
SUT. Example, if you use f2 of m2 in m1, you can patch m1.f2 instead of m2.f2
import module, and use module.function.

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