Python outputs string with newline character from external C program call - python

This is my first question, any feedback would be amazing.
I am calling a C program from Python3 and the string captured by my variable
prints out the newline characters instead of processing a newline character.
Want this:
hello
world
I get:
b'hello\nworld'
I have this c program called find.c:
int main(int argc, char *argv[]){
printf("%s:\n%s\n\n",argv[1],argv[2]);
return 0;
}
Executed/Ran/Processed by Python3:
import sys
import subprocess
user = sys.argv[1]
item = sys.argv[2]
out = subprocess.check_output(["./find", user, item])
print(out)
Once again, the string "out" contains the "\n" instead of treating it like
a new line.
I've tried adding: universal_newlines=True and end="" to check_out() with no luck.
I've tried using Popen() and call() and they both still keep the "\n".
As a last note: I am outputting this string to a textarea in html. And yes I know the b'' is not actually part of the string.
Cheers!

EHHHH, I figured it out. For anyone interested I did the following:
print(subprocess.check_output(["./find",user,item],universal_newlines=True))
I didn't actually try using universal_newlines=True exclusively.
Look at that my first accepted answer as well!

In your out you need to strip the carriage return and new lines.
import sys
import subprocess
user = sys.argv[1]
item = sys.argv[2]
out = check_output(["./find", user, item]).strip()
print(out)

try this. subprocess is returning a byte string, you want to print it as ascii characters.
print(out.decode('ascii'))

Related

output of os.system in variable python

I am making a server that asks for you IP address and I want to make an option that says (leave blank for __your ip__) but I'm having trouble with it. I tried doing this
import subprocess
output = subprocess.check_output("ipconfig getifaddr en0", shell=True)
but it returns
b'***.***.***.***\n' is there a way to remove the '', b and \n or another way to get an IP that doesn't return 127.0.0.1?
What you're seeing is the bytestring output and the following newline.
You'll want
output = subprocess.check_output("ipconfig getifaddr en0", shell=True).decode().strip()
to first decode the bytes as UTF-8, then strip whitespace from the start and the end.

Python TypeError: expected a string or other character buffer object when importing text file

I am pretty new to python. For this task, I am trying to import a text file, add and to id, and remove punctuation from the text. I tried this method How to strip punctuation from a text file.
import string
def readFile():
translate_table = dict((ord(char), None) for char in string.punctuation)
with open('out_file.txt', 'w') as out_file:
with open('moviereview.txt') as file:
for line in file:
line = ' '.join(line.split(' '))
line = line.translate(translate_table)
out_file.write("<s>" + line.rstrip('\n') + "</s>" + '\n')
return out_file
However, I get an error saying:
TypeError: expected a string or other character buffer object
My thought is that after I split and join the line, I get a list of strings, so I cannot use str.translate() to process it. But it seems like everyone else have the same thing and it works,
ex. https://appliedmachinelearning.blog/2017/04/30/language-identification-from-texts-using-bi-gram-model-pythonnltk/ in example code from line 13.
So I am really confused, can anyone help? Thanks!
On Python 2, only unicode types have a translate method that takes a dict. If you intend to work with arbitrary text, the simplest solution here is to just use the Python 3 version of open on Py2; it will seamlessly decode your inputs and produce unicode instead of str.
As of Python 2.6+, replacing the normal built-in open with the Python 3 version is simple. Just add:
from io import open
to the imports at the top of your file. You can also remove line = ' '.join(line.split(' ')); that's definitionally a no-op (it splits on single spaces to make a list, then rejoins on single spaces). You may also want to add:
from __future__ import unicode_literals
to the very top of your file (before all of your code); that will make all of your uses of plain quotes automatically unicode literals, not str literals (prefix actual binary data with b to make it a str literal on Py2, bytes literal on Py3).
The above solution is best if you can swing it, because it will make your code work correctly on both Python 2 and Python 3. If you can't do it for whatever reason, then you need to change your translate call to use the API Python 2's str.translate expects, which means removing the definition of translate_table entirely (it's not needed) and just doing:
line = line.translate(None, string.punctuation)
For Python 2's str.translate, the arguments are a one-to-one mapping table for all values from 0 to 255 inclusive as the first argument (None if no mapping needed), and the second argument is a string of characters to delete (which string.punctuation already provides).
Answering here because a comment doesn't let me format code properly:
def r():
translate_table = dict((ord(char), None) for char in string.punctuation)
a = []
with open('out.txt', 'w') as of:
with open('test.txt' ,'r') as f:
for l in f:
l = l.translate(translate_table)
a.append(l)
of.write(l)
return a
This code runs fine for me with no errors. Can you try running that, and responding with a screenshot of the code you ran?

sys.stdin in for loop is not grabbing user input

I have this code (test.py) below:
import sys
for str in sys.stdin.readline():
print ('Got here')
print(str)
For some reason when I run the program python test.py and then I type in abc into my terminal I get this output:
>>abc
THIS IS THE OUTPUT:
Got here
a
Got here
b
Got here
c
Got here
It prints out Got here five times and it also prints out each character a, b, c individually rather than one string like abc. I am doing sys.stdin.readline() to get the entire line but that doesn't seem to work either. Does anyone know what I am doing wrong?
I am new to python and couldn't find this anywhere else on stackoverflow so sorry if this is a obvious question.
readline() reads a single line. Then you iterate over it. Iterating a string gives you the characters, so you are running your loop once for each character in the first line of input.
Use .readlines(), or better, just iterate over the file:
for line in sys.stdin:
But the best way to get interactive input from stdin is to use input() (or raw_input() in Python 2).
You are looping through each character in the string that you got inputted.
import sys
s = sys.stdin.readline()
print ('Got here')
print(s)
# Now I can use string `s` for whatever I want
print(s + "!")
In your original code you got a string from stdin and then you looped through ever character in that input string and printed it out (along with "Got here").
EDIT:
import sys
while True:
s = sys.stdin.readline()
# Now I can do whatever I want with string `s`
print(s + "!")

Delete last printed character python

I am writing a program in Python and want to replace the last character printed in the terminal with another character.
Pseudo code is:
print "Ofen",
print "\b", # NOT NECCESARILY \b, BUT the wanted print statement that will erase the last character printed
print "r"
I'm using Windows8 OS, Python 2.7, and the regular interpreter.
All of the options I saw so far didn't work for me. (such as: \010, '\033[#D' (# is 1), '\r').
These options were suggested in other Stack Overflow questions or other resources and don't seem to work for me.
EDIT: also using sys.stdout.write doesn't change the affect. It just doesn't erase the last printed character. Instead, when using sys.stdout.write, my output is:
Ofenr # with a square before 'r'
My questions:
Why don't these options work?
How do I achieve the desired output?
Is this related to Windows OS or Python 2.7?
When I find how to do it, is it possible to erase manually (using the wanted eraser), delete the '\n' that is printed in python's print statement?
When using print in python a line feed (aka '\n') is added. You should use sys.stdout.write() instead.
import sys
sys.stdout.write("Ofen")
sys.stdout.write("\b")
sys.stdout.write("r")
sys.stdout.flush()
Output: Ofer
You can also import the print function from Python 3. The optional end argument can be any string that will be added. In your case it is just an empty string.
from __future__ import print_function # Only needed in Python 2.X
print("Ofen",end="")
print("\b",end="") # NOT NECCESARILY \b, BUT the wanted print statement that will erase the last character printed
print("r")
Output
Ofer
I think string stripping would help you. Save the input and just print the string upto the length of string -1 .
Instance
x = "Ofen"
print (x[:-1] + "r")
would give you the result
Ofer
Hope this helps. :)

Prevent python from printing newline

I have this code in Python
inputted = input("Enter in something: ")
print("Input is {0}, including the return".format(inputted))
that outputs
Enter in something: something
Input is something
, including the return
I am not sure what is happening; if I use variables that don't depend on user input, I do not get the newline after formatting with the variable. I suspect Python might be taking in the newline as input when I hit return.
How can I make it so that the input does not include any newlines so that I may compare it to other strings/characters? (e.g. something == 'a')
You are correct - a newline is included in inputted. To remove it, you can just call strip("\r\n") to remove the newline from the end:
print("Input is {0}, including the return".format(inputted.strip("\r\n")))
This won't cause any issues if inputted does not have a newline at the end, but will remove any that are there, so you can use this whether inputted is user input or not.
If you don't want any newlines in the text at all, you can use inputted.replace("\r\n", "") to remove all newlines.
Your problem is actually Eclipse. Assuming that you use PyDev, I was able to reproduce the problem. When entering something in the Eclipse console, the problem occurs as described in your question. But when directly executing the very same script with the Python 3.1.1 interpreter, inputted does not include a newline character.
I investigated the Python source code and found out input() uses GNU readline if stdin is interactive (i.e. a TTY or prompt, however you want to call it), but falls back to the .readline() method of the stdin object if necessary. Then, if the result of readline ends with \n, that character is removed. Note: No CR-LF or LF-CR handling here (in the fallback case)!
So I wrote this little script to see what actually happens:
import sys
from io import StringIO
for stdin in [sys.stdin, StringIO("test\r\ntest\r\n")]:
sys.stdin = stdin
print("readline returns this: " + repr(sys.stdin.readline()))
inputted = input("Enter in something: ")
print("inputted: " + repr(inputted))
print("inputted is printed like this: --> {0} <--".format(inputted))
It first executes the code with the normal stdin (console or Eclipse console) and then with a prepared stdin containing the text test\r\ntest\r\n.
Try and run the script in Eclipse - you must enter a string twice. The conclusion: Pressing Enter in the Eclipse console will produce CR-LF ("\r\n"). Printing "\r" in the Eclipse console will jump to the next line.
On the other side, running it in the Windows console will produce the expected output: input() returns a string without a newline at the end because (I guess) GNU readline is used. With the prepared stdin StringIO("test\r\n"), the input() result is "test\r" as in Eclipse (although not printed as newline).
Hope this all makes sense... but what I still don't know is if that is expected behavior of Eclipse.
If you only want to stript the last line endings, you could use rstrip.
inputted.rstrip ("\r\n")
inputted = inputted.strip()
Edit: As noted, this will kill all whitespace at the start and end. A way to get rid of only the trailing newline is:
import re
inputted = re.sub("[\n\r]+$", "", inputted)

Categories

Resources