Python Forum
Saving text file with a click: valueerror i/o operation on closed file
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Saving text file with a click: valueerror i/o operation on closed file
#3
(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.
Reply


Messages In This Thread
RE: Saving text file with a click: valueerror i/o operation on closed file - by vizier87 - Nov-13-2020, 08:09 AM

Possibly Related Threads…
Thread Author Replies Views Last Post
  [closed] check whether an integer is 32 or 64 bits paul18fr 4 250 May-27-2024, 04:55 PM
Last Post: deanhystad
  How to Randomly Print a Quote From a Text File When User Types a Command on Main Menu BillKochman 13 1,390 Apr-24-2024, 05:47 AM
Last Post: Bronjer
  very newbie problem on text file zapad 2 368 Apr-12-2024, 06:50 PM
Last Post: zapad
  This result object does not return rows. It has been closed automatically dawid294 6 1,531 Mar-30-2024, 03:08 AM
Last Post: NolaCuriel
  file open "file not found error" shanoger 8 1,419 Dec-14-2023, 08:03 AM
Last Post: shanoger
  Replace a text/word in docx file using Python Devan 4 4,140 Oct-17-2023, 06:03 PM
Last Post: Devan
  Need to replace a string with a file (HTML file) tester_V 1 856 Aug-30-2023, 03:42 AM
Last Post: Larz60+
  How can I change the uuid name of a file to his original file? MaddoxMB 2 1,065 Jul-17-2023, 10:15 PM
Last Post: Pedroski55
  save values permanently in python (perhaps not in a text file)? flash77 8 1,382 Jul-07-2023, 05:44 PM
Last Post: flash77
  Reading data from excel file –> process it >>then write to another excel output file Jennifer_Jone 0 1,220 Mar-14-2023, 07:59 PM
Last Post: Jennifer_Jone

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020