formatting strings for stdin.write() in python 3.x - string

I'm having a problem where I get errors when I try to execute this code with python 3.2.2
working_file = subprocess.Popen(["/pyRoot/iAmAProgram"], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
working_file.stdin.write('message')
I understand that python 3 changed the way it handles strings but I dont understand how to format the 'message'. Does anyone know how I'd change this code to be valid?
many thanks
jon
update: heres the error message i get
Traceback (most recent call last):
File "/pyRoot/goRender.py", line 18, in <module>
working_file.stdin.write('3')
TypeError: 'str' does not support the buffer interface

If you have a string variable that you want to write to a pipe (and not a bytes object), you have two choices:
Encode the string first before you write it to the pipe:
working_file.stdin.write('message'.encode('utf-8'))
Wrap the pipe into a buffered text interface that will do the encoding:
stdin_wrapper = io.TextIOWrapper(working_file.stdin, 'utf-8')
stdin_wrapper.write('message')
(Notice that the I/O is now buffered, so you may need to call stdin_wrapper.flush().)

Is your error message "TypeError: 'str' does not support the buffer interface"? That error message tells you pretty much exactly what is wrong. You don't write string objects to that sdtin. So what do you write? Well, anything supporting the buffer interface. Typically this is bytes objects.
Like:
working_file.stdin.write(b'message')

Related

Read a dtoverlay controlled device via Python3?

How to read a dtoverlay controlled device, i.e. sensor via pyhon3?
I can read the device via a simple cat, for example...
# cat /sys/bus/i2c/devices/1-0077/iio\:device0/in_temp_input
27130
So I know the basic setup and such is good, sensor is at address 0x77, it is a BME280 sensor, etc.
I can also read the sensor via the various python3 libraries for such sensors, say the python library from Adafruit.
But I want to use the dtoverlay method of sensor control, i.e. read, and read the sensor from python3. This seemed obvious and straight forward, but apparently not, tried the following code and got the following error.
#!/usr/bin/python3
#
#
import os
#
theSensor=os.open('/sys/bus/i2c/devices/1-0077/iio\:device0/in_temp_input', os.O_RDONLY)
os.lseek(theSensor, 0, os.SEEK_SET)
print(os.read(theSensor, 2))
theSensor.close()
And the error...
# python3 BME280-OverLay.py
Traceback (most recent call last):
File "/root/BME280-OverLay.py", line 17, in <module>
theSensor=os.open('/sys/bus/i2c/devices/1-0077/iio\:device0/in_temp_input', os.O_RDONLY)
FileNotFoundError: [Errno 2] No such file or directory: '/sys/bus/i2c/devices/1-0077/iio\\:device0/in_temp_input'
Is there some trick to reading this specific device path via python3? The simple cat works.
In your initial cat command, you noticed that there's a \ inside the URL. That's an escape character. It might be there because you used autocompletion with the Tab key ; in this case bash adds it automatically, even though in fact cat doesn't need it, but deals with it.
python doesn't (deal with it). You'll have to feed open() with the clear path syntax.
By the way you can use a plain open() call and the with syntax :
with open('/sys/bus/i2c/devices/1-0077/iio:device0/in_temp_input', 'r') as fd:
temp = fd.read()
print(temp)
This way, the file gets closed before the print() call.
PS: the fact that the file you are trying to read is on a virtual filesystem would have no impact.

Getting user input data using sys.stdin

import sys
data = []
for line in sys.stdin:
data.append(line)
I did not use .read() or .readline()
but this code works reading the data. It read the data line by line. Input data is separated by '\n'. data is typed by user. like 'input()' .
My Question:
Is .read() or .readline() not necessary?
I wonder why for loop works on sys.stdin and how it reads data line by line?
If you look at the documentation for sys, you'll see that sys.stdin (and sys.stdout / sys.stderr) are just file objects.
These streams are regular text files like those returned by the open() function.
The documentation about open() says:
The type of file object returned by the open() function depends on the mode. When open() is used to open a file in a text mode ('w', 'r', 'wt', 'rt', etc.), it returns a subclass of io.TextIOBase (specifically io.TextIOWrapper).
TextIOWrapper inherits from IOBase, which has an __iter__ method. This __iter__ method allows looping over lines in the file. I can't find where this is noted in the Python documentation, but it is given in the source code for IOBase.
IOBase (and its subclasses) support the iterator protocol, meaning that an IOBase object can be iterated over yielding the lines in a stream.

How to write to stdout like a file object in python

Working on python script that uses stdin and stdout. The default
behaviour is the script will write to a file, so I have this function
that is called to handle writing to a file:
def run_loop(data,name):
with open(name, 'w') as fo:
fo.write("webstat output "+t) # t is a date str created in global scope
for x in data:
fo.write(processer(x))
fo.write('\n')
I have a few places in the script where I use this function, so it
would be less convenient to have to rewrite it or write a substituent
of it to work with stdout. When I try using stdout with open,
sys.stdout says its a type _io.TextIOWrapper. I get an error when
tying to call run_loop(same_data,sys.stdout) I get this error:
TypeError: expected str, bytes or os.PathLike object, not _io.TextIOWrapper
I'm wondering if there is away to use open() with stdout? I would
guess that since stdout is file io, I should be able to write to it as
a file. Ideally there would be a way to change _io.TextIOWrapper into
an object that open() can use, but I've been looking at types of the
methods inside of sys.stdout and they don't seem to provide this
facility. I'm not sure why the fo object from open() couldn't be
set to stdout?
The behaviour I'm trying to achieve is
cat input-data.txt | myscript.py > out.txt
I've been able to get the stdin portion to work, but I'm still at a
loss for how to write to stdout with open().
Supposedly, I could forego open(), if I could keep compatibility with
the other places I call this function: data being a list and name
usually being a string of the file name where the output should be saved.
Python 3.7.5rc1

Python : Geting issue on OCR while using python tesseract API interface

I used Pytesseract module for OCR. It seems slow process. So I followed
Pytesseract is too slow. How can I make it process images faster? .
I used code mentioned in https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/tesseract-ocr/xvTFjYCDRQU/rCEwjZL3BQAJ . But getting error
!strcmp(locale, "C"):Error:Assert failed:in file baseapi.cpp, line 201
Segmentation fault (core dumped),
Then i check some post and get reference to add in my code locale.setlocale(locale.LC_ALL, "C").
So after added this in my code I got another error
Traceback (most recent call last):
File "master_doc_test3.py", line 107, in <module>
tess = Tesseract()
File "master_doc_test3.py", line 67, in __init__
if self._lib.TessBaseAPIInit3(self._api, datapath, language):
ctypes.ArgumentError: argument 3: <class 'TypeError'>: wrong type`
Can anyone give idea about this error? OR If anyone have idea about best way to make OCR in fastest way using python.
You should try to convert to bytes every parameter you pass to ctypes lib calls:
self._lib.TessBaseAPIInit3(self._api, datapath, language)
Something like this is working for me:
self._lib.TessBaseAPIInit3(self._api, bytes(datapath, encoding='utf-8'), bytes(language, encoding='utf-8'))
I have got the clue here.
Please, take into consideration that the code you are using needs more fine tuning in other lib calls as the next ones:
tess.set_variable(bytes("tessedit_pageseg_mode", encoding='utf-8'), bytes(str(frame_piece.psm), encoding='utf-8'))
tess.set_variable(bytes("preserve_interword_spaces", encoding='utf-8'), bytes(str(1), encoding='utf-8'))

Python 3.1 server-side can't output Unicode string to client

I'm using a free web host but choosing not to work with any Python framework, and am stuck trying to print Chinese characters saved in the source file (using emacs to save file encoded in utf-8) to the resulting HTML page. I thought Unicode "just works" in Python 3.1 so I am baffled. I found three solutions that aren't working. I might just be missing a detail or two.
The host is Alwaysdata, and it has been straightforward to use, so I have little clue about details of how they put together the parts. All I do is upload or edit (with ssh) Python files to a www folder, change permissions, point a browser to the right URL, and it works.
My first attempt, which works on local IDLE (and also the server's Python command line interactive shell, which makes me even more confused why it won't work when it's passed to a browser)
#!/usr/bin/python3.1
mystr = "世界好"
print("Content-Type: text/html\n\n")
print("""<!DOCTYPE html>
<html><head><meta charset="utf-8"></head>
<body>""")
print(mystr)
The error is:
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3:
ordinal not in range(128)
Then I tried
print(mystr.encode("utf-8"))
resulting in no error, but the following undesired output to the browser:
b'\xe4\xbd\xa0\xe5\xa5\xbd\xe4\xb8\x96\xe7\x95\x8c'
Third, the following lines were added but got an error:
import sys
sys.setdefaultencoding("utf-8")
AttributeError: 'module' object has no attribute 'setdefaultencoding'
Finally, replacing print with f.write:
import codecs
f = codecs.open(sys.stdout, "w", "utf-8")
mystr = "你好世界"
...
f.write(mystr)
error:
TypeError: invalid file: <_io.TextIOWrapper name='<stdout>'
encoding='ANSI_X3.4-1968'>
How do I get the output to work? Do I need to use a framework for a quick fix?
It sounds like you are using CGI, which is a stupid API as it's using stdout, made for output to humans, to output to your browser. This is the basic source of your problems.
You need to encode it in UTF-8, and then write to sys.stdout.buffer instead of sys.stdout.
And after that, get yourself a webframework. Really, you'll be a lot happier.

Resources