Nov-13-2020, 08:09 AM
(Nov-12-2020, 04:46 PM)Gribouillis Wrote: You can redirect sys.stdout by defining your own context. The following code prints 'Hello there!' in file 'foo.txt' and then 'Done' to standard output. Don't close files explicitly when using the 'with' statement. They are closed automatically when the context exits
from contextlib import contextmanager import sys @contextmanager def redirect_stdout(file): old, sys.stdout = sys.stdout, file try: yield finally: sys.stdout = old def main(): with open('foo.txt', 'w') as file, redirect_stdout(file): print('Hello there!') print('Done') if __name__ == '__main__': main()That said, I don't know how the HeartRateMonitor class works, but you could consider injecting a file argument in this class instead of redirecting the global stdout.
Hi there. Thanks a bunch.
It works nicely if I'm making a simple Python script, but currently I'm running PyQt and I have to admit, the whole thing about structures of the programming are a bit hazy for me so please bear with me for a while.
So I've been modifying it a bit:
@contextmanager def redirect_stdout(file): old, sys.stdout = sys.stdout, file try: yield finally: sys.stdout = old def on_click(self): clear = lambda: os.system('cls') clear() print("Beginning measurement...") now = datetime.now() current_time = now.strftime("%Y%m%d-%H%M%S") parser = argparse.ArgumentParser(description="Read and print data from MAX30102") parser.add_argument("-r", "--raw", action="store_true", help="print raw data instead of calculation result") parser.add_argument("-t", "--time", type=int, default=30, help="duration in seconds to read from sensor, default 30") args = parser.parse_args() with open("/home/pi/Desktop/Output data - " + current_time + self.textbox.text() + ".txt", 'w') as file, redirect_stdout(file): hrm = HeartRateMonitor(print_raw=args.raw, print_result=(not args.raw)) hrm.start_sensor() try: time.sleep(args.time) except KeyboardInterrupt: print('keyboard interrupt detected, exiting...') hrm.stop_sensor()And got this error:
NameError: name 'redirect_stdout' is not defined
And as for your suggestion on injecting something in the class, I'm not sure where I should put it, but here it is :
from max30102 import MAX30102 import hrcalc import threading import time import numpy as np class HeartRateMonitor(object): """ A class that encapsulates the max30102 device into a thread """ LOOP_TIME = 0.01 def __init__(self, print_raw=False, print_result=False): self.bpm = 0 if print_raw is True: print('IR, Red') self.print_raw = print_raw self.print_result = print_result def run_sensor(self): sensor = MAX30102() ir_data = [] red_data = [] bpms = [] # run until told to stop while not self._thread.stopped: # check if any data is available num_bytes = sensor.get_data_present() if num_bytes > 0: # grab all the data and stash it into arrays while num_bytes > 0: red, ir = sensor.read_fifo() num_bytes -= 1 ir_data.append(ir) red_data.append(red) if self.print_raw: print("{0}, {1}".format(ir, red)) while len(ir_data) > 100: ir_data.pop(0) red_data.pop(0) if len(ir_data) == 100: bpm, valid_bpm, spo2, valid_spo2 = hrcalc.calc_hr_and_spo2(ir_data, red_data) if valid_bpm: bpms.append(bpm) while len(bpms) > 4: bpms.pop(0) self.bpm = np.mean(bpms) if (np.mean(ir_data) < 50000 and np.mean(red_data) < 50000): self.bpm = 0 if self.print_result: print("Finger not detected") if self.print_result: print("BPM: {0}, SpO2: {1}".format(self.bpm, spo2)) time.sleep(self.LOOP_TIME) sensor.shutdown() def start_sensor(self): self._thread = threading.Thread(target=self.run_sensor) self._thread.stopped = False self._thread.start() def stop_sensor(self, timeout=2.0): self._thread.stopped = True self.bpm = 0 self._thread.join(timeout)It was code made available anyway, but I haven't changed anything here because I'll just mess it up.
And, if it is not too much, is it possible that the saving of the text occurs after the console is done loading the texts, and so that I can also see in both the console AND immediately in the text?
I'm doing some data collection with the GUI I'm making, so I'd like to make it as efficient as possible.
Sorry if PyQt is not supposed to be discussed here.
Thanks.