python read output - python

Write a program that outputs the first number within a file specified by the user. It should behave like:
Enter a file name: l11-1.txt
The first number is 20.
You will need to use the file object method .read(1) to read 1 character at a time, and a string object method to check if it is a number. If there is no number, the expected behaviour is:
Enter a file name: l11-2.txt
There is no number in l11-2.txt.
Why is reading 1 character at a time a better algorithm than calling .read() once and then processing the resulting string using a loop?
I have the files and it does correspond to the answers above but im not sure how to make it output properly.
The code i have so far is below:
filenm = raw_input("Enter a file name: ")
datain=file(filenm,"r")
try:
c=datain.read(1)
result = []
while int(c) >= 0:
result.append(c)
c = datain.read(1)
except:
pass
if len(result) > 0:
print "The first number is",(" ".join(result))+" . "
else:
print "There is no number in" , filenm + "."
so far this opens the file and reads it but the output is always no number even if there is one. Can anyone help me ?

OK, you've been given some instructions:
read a string input from the user
open the file given by that string
.read(1) a character at a time until you get the first number or EOF
print the number
You've got the first and second parts here (although you should use open instead of file to open a file), what next? The first thing to do is to work out your algorithm: what do you want the computer to do?

Your last line starts looping over the lines in the file, which sounds like not what your teacher wants -- they want you to read a single character. File objects have a .read() method that lets you specify how many bytes to read, so:
c = datain.read(1)
will read a single character into a string. You can then call .isdigit() on that to determine if it's a digit or not:
c.isdigit()
It sounds like you're supposed to keep reading a digit until you run out, and then concatenate them all together; if the first thing you read isn't a digit (c.isdigit() is False) you should just error out

Your datain variable is a file object. Use its .read(1) method to read 1 character at a time. Take a look at the string methods and find one that will tell you if a string is a number.

Why is reading 1 character at a time a better algorithm than calling .read() once and then processing the resulting string using a loop?
Define "better".
In this case, it's "better" because it makes you think.
In some cases, it's "better" because it can save reading an entire line when reading the first few bytes is enough.
In some cases, it's "better" because the entire line may not be sitting around in the input buffer.

You could use regex like (searching for an integer or a float):
import re
with open(filename, 'r') as fd:
match = re.match('([-]?\d+(\.\d+|))', fd.read())
if match:
print 'My first number is', match.groups()[0]
This with with anything like: "Hello 111." => will output 111.

Related

Best regex pattern to replace input function from a separate python file

I am new to regex so please explain how you got to the answer. Anyway I want to know the best way to match input function from a separate python file.
For example:
match.py
a = input("Enter a number")
b = input()
print(a+b)
Now I want to match ONLY the input statement and replace it with a random number. I will do this in a separate file main.py. So my aim is to replace input function in the match.py with a random numbers so I can check the output will come as expected. You can think of match.py like a coding exercise where he writes the code in that file and main.py will be the file where it evaluates if the users code is right. And to do that I need to replace the input myself and check if it works for all kinds of inputs. I looked for "regex patterns for python input function" but the search did not work right. I have a current way of doing it but I don't think it works in all kinds of cases. I need a perfect pattern which works in all kinds of cases referring to the python syntax. Here is the current main.py I have (It doesn't work for all cases I mean when you write a string with single quote, it does not replace but here is the problem I can just add single quote in pattern but I also need to detect if both are used):
# Evaluating python file checking if input 2 numbers and print sum is correct
import re
import subprocess
input_pattern = re.compile(r"input\s?\([\"]?[\w]*[\"]?\)")
file = open("match.py", 'r')
read = file.read()
file.close()
code = read
matches = input_pattern.findall(code)
for match in matches:
code = code.replace(match, '8')
file = open("match.py", 'w')
file.write(code)
file.close()
process = subprocess.Popen('python3 match.py', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
out = process.communicate()[0]
print(out == b"16\n")
file = open("match.py", 'w')
file.write(read)
file.close()
Please let me know if you don't understand this question.
The following regex statement is very close to what you need:
input\s?\((?(?=[\"\'])[\"\'].*[\"\']\)|\))
I am using a conditional regex statement. However, I think it may need a nested conditional to avoid the situation that the user enters something like:
input(' text ")
But hopefully this gets you on the right track.

What is the purpose of readline().strip()?

What is the purpose of readline().strip() (especially in the below code)?
Context:
I was taking a look at the following code:
op = open('encyin.txt', 'r')
n, q = op.readline().split()
n = int(n)
q = int(q)
dic = {}
for i in range(1, n + 1):
dic[str(i)]=(op.readline().strip())
And trying to interpret it.
My Interpretation:
The start is simple enough - it opens a file encyin.txt in read mode. It takes input - n & p - from the line, the .split() separating the two inputs. They are then classified as integers, and an empty list dict is created?
From there, a for loop is utilised.
But what does the last line mean? I am not familiar with (a) readline().strip() and (b) how this affects list dict and the values of the input:
For Example
If ency.txt was the following:
6 5
1151
723
1321
815
780
931
What happens to the other numbers from the 2nd line downwards? Does the readline().split assign them a line number? Does it add it to the list dict, a bit like .append?
What does the last line mean of the top code do? I am not familiar with (a) readline().strip() and (b) how this affects list dict and the values of the input:
In your text file, you have these things called whitespace characters. Often, these are spaces or enters ('\n') that you want to get rid of. The strip() helps you remove these whitespace characters.
If you were to print the numbers after reading them and without stripping, you would get:
number1
number2
number3
...
Because you haven't removed the hidden 'enter' character.
When reading a python script and you come across some function that you don't know, your goal should first to be understand the function out of context, and then you can figure out what they are doing in context.
The first port of call for understanding builtin/standard library functions (as opposed to functions from some extra library) should be the python docs. When the docs fail you, move on to other sources (there are plenty).
In this case, you want to know what op.readline() does. Well, what is op? I would go to open, and see that it creates a file object, which tells you that the actual implementation used is in io. Here we can search the page for readline.
What do the docs have to say about readline?
Read and return one line from the stream.
Here, I would assume, since it's a text file, "a line from the stream" is a string object (but you could always open a python interpreter to check), and look up string.strip(), which says:
Return a copy of the string with the leading and trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace.
Now put them together. They call (op.readline().strip()).
We know op is a "file object" using io
io's readline reads a single line from the stream
some_string.strip() called without parameters removes all whitespace from the start and end of some_string
Although python uses duck-typing, objects still have types/behaviours and understanding code often involves knowing what kind of object you are dealing with at any point so you can look into how it should work.
For example, if you know something is a dictionary, but you don't know what a dictionary is, you should search the docs for some info and try to understand what it does out of context first.
op = open('encyin.txt', 'r')
n, q = op.readline().split()
n = int(n)
q = int(q)
dic = {}
for i in range(1, n + 1):
# Here you're creating a key-value pair using the str value of the loop variable
# i as the dictionary key i.e. key dic[str(i)] creates the key, and the value is
# op.readline().strip(). strip() is a str method that removes trailing characters.
# the default is to remove whitespace at the beginning and ends of the string.
# These spaces get trimmed off if the method is called
dic[str(i)]=(op.readline().strip())
https://docs.python.org/3/library/stdtypes.html?highlight=str#str.strip
readline() returning a single line as string from your file.
ex: for the given txt file info:
Danni Loss
Shani Amari
Michele favarotti
readline() will return the first line:
Danni Loss\n
then there is a use of strip() removes all empty chars from the start and end of the string, so you will get:
Danni Loss
.readline() reads a line from a file. The result includes a trailing '\n'.
.strip() removes all leading & trailing whitespace (e.g. the above-mentioned '\n') from a string.
Thus, the last line of code dic[str(i)]=(op.readline().strip()) does the following:
Reads line from the open file
Strips whitespace from the line
Stores the stripped line in the dictionary using the index (converted to string) as a key

How does raw_input treat ENTER or \n

I have a long list of numbers that I would like to input into my code through a raw_input. It includes numbers that are spaced out through SPACES and ENTER/RETURN. The list looks like this . When I try to use the function raw_input, and copy paste the long list of numbers, my variable only retains the first row of numbers. This is my code so far:
def main(*arg):
for i in arg:
print arg
if __name__ == "__main__": main(raw_input("The large array of numbers"))
How can I make my code continue to read the rest of the numbers?
Or if that's not possible, can I make my code acknowledge the ENTER in any way?
P.s. While this is a project euler problem I don't want code that answers the project euler question, or a suggestion to hard code the numbers in. Just suggestions for inputting the numbers into my code.
If I understood your question correctly, I think this code should work (assuming it's in python 2.7):
sentinel = '' # ends when this string is seen
rawinputtext = ''
for line in iter(raw_input, sentinel):
rawinputtext += line + '\n' #or delete \n if you want it all in a single line
print rawinputtext
(code taken from: Raw input across multiple lines in Python )
PS: or even better, you can do the same in just one line!
rawinputtext = '\n'.join(iter(raw_input, '') #replace '\n' for '' if you want the input in one single line
(code taken from: Input a multiline string in python )
I think what you are actually looking for is to directly read from stdin via sys.stdin. But you need to accept the fact that there should be a mechanism to stop accepting any data from stdin, which in this case is feasible by passing an EOF character. An EOF character is passed via the key combination [CNTRL]+d
>>> data=''.join(sys.stdin)
Hello
World
as
a
single stream
>>> print data
Hello
World
as
a
single stream

Exact number of characters in a JSON

I have a file with several JSON objects in each line. And, I need to know the length of each object, I mean the each number of characters. But when I run the code below, it provides a number of characters less than expected.
jsonFile = open(File, 'r')
line = jsonFile.readline()
len(line)
It considers some elements like "/n" as a one character but I want it to say there are two. Do you have any idea please ?
print os.path.getsize('myfile.json')
http://devdocs.io/python/library/os.path#os.path.getsize

Python command Line - multiple Line Input

I'm trying to solve a Krypto Problem on https://www.spoj.pl in Python, which involves console input.
My Problem is, that the Input String has multiple Lines but is needed as one single String in the Programm.
If I just use raw_input() and paste (for testing) the text in the console, Python threats it like I pressed enter after every Line -> I need to call raw_input() multiple times in a loop.
The Problem is, that I cannot modify the Input String in any way, it doesn't have any Symbol thats marks the End and I don't know how many Lines there are.
So what do I do?
Upon reaching end of stream on input, raw_input will return an empty string. So if you really need to accumulate entire input (which you probably should be avoiding given SPOJ constraints), then do:
buffer = ''
while True:
line = raw_input()
if not line: break
buffer += line
# process input
Since the end-of-line on Windows is marked as '\r\n' or '\n' on Unix system it is straight forward to replace those strings using
your_input.replace('\r\n', '')
Since raw_input() is designed to read a single line, you may have trouble this way.
A simple solution would be to put the input string in a text file and parse from there.
Assuming you have input.txt you can take values as
f = open(r'input.txt','rU')
for line in f:
print line,
Using the best answer here, you will still have an EOF error that should be handled. So, I just added exception handling here
buffer = ''
while True:
try:
line = raw_input()
except EOFError:
break
if not line:
break
buffer += line

Categories