The main aim of the code is to take n lines of input and add this data to dictionary and then perform n queries on dictionary. however only the last query is working correctly.
from sys import stdin
n = int(input())
mydict={}
for i in range(0,n):
pairs=input().split(' ')
key=pairs[0]
value=pairs[1]
mydict[key]=value
print (mydict)
for a in stdin:
print(a)
if(a in mydict):
print(a+'='+mydict[a])
else:
print("Not Found")
The input obtained from stdin includes the new line character(s), however, due to the use of input() the keys in the dictionary do not, hence the lookup fails. It works on the final iteration because the line is terminated by end of file rather than new line.
You could fix it by stripping whitespace at the end of the line in the second loop:
for a in stdin:
a = a.rstrip()
print(a)
if a in mydict:
print(a+'='+mydict[a])
else:
print("Not Found")
The content read from stdin is original stream.
So when you hit the enter key, the '\n' is add to the stream.
Solution 1: use input method.
Solution 2: read from stdin, and use rstrip() method before query from the dict.
Related
Imagine unlimited multiline input with some URL addresses, for example:
How would you get that addresses from the input separately?
Following was close, but actually not helping:
lines = []
while True:
line = input()
if line:
lines.append(line)
else:
break
text = '\n'.join(lines)
source: How to get multiline input from user
And other advices I consider completely useless: https://python.plainenglish.io/taking-multiple-inputs-from-user-in-python-3-6cbe02d03a95
If I understand the problem correctly, this may help:
lines = []
try:
while line := input():
lines.append(line)
except EOFError:
pass
print(lines)
This will handle both interactive and redirected input (stdin)
There is a function you could use:
import sys
sys.stdin.read()
But I'm not sure this is a great idea because it won't know when to stop reading. The traditional input() function will detect a \n symbol via the return key, then end input.
I think looping would be the best way forward.
Like:
urls = ''
while True:
url = input()
if url:
urls += url + '\n'
else:
break
Have a nice day.
EDIT of entire post, in order to be more clear of the problem:
s = "GATATATGCATATACTT"
t = "ATAT"
for i in range(len(s)):
if t == s[i:i+len(t)]:
print i+1,
So the purpose of the program above is to scan through the long line of DNA (s) with the short line of DNA (t), in order to find at which positions on s, that t matches. The output of the above code is:
2 4 10 #This are basically the index numbers of string s that string t matches. but as can be seen in the code above, it's i+1 to give a 1-based numbering output.
The problem I'm having is that when i try to change the code, in order to make it receive the values for s and t through a file, the readline() function is not working for me. The motif.txt file contains two strings of DNA, one on each line.
with open('txt/motif.txt', 'r') as f:
s = f.readline()
t = f.readline()
for i in range(len(s)):
if t == s[i:i+len(t)]:
print i+1,
So this code, on the other hand will output nothing at all. But when I change t to:
t = f.readline().strip()
Then the program outputs the same result as the first example did.
So i hope this has made things more clear. My question is thus, if readline() returns a string, why isn't my program in example 2 working in the same way as in the very first example?
your problem statement is wrong, there's no way s or t has more content (and len(s) > 0 or len(t) > 0) in the first example than in the second.
basically with:
s = f.readline()
then s will contain a string like "foobar \n", and thus len(s) will be 9.
Then with:
s = f.readline().strip()
with the same string, len(s) will be 6 because the stripped string is "foobar".
so if you line is full of spaces like s = " \n", s.strip() will be the empty string "", with len(s) == 0.
Then in that case your loop won't start and will never print anything.
in almost all the other cases I can think of, you should get an execption raised, not silent exit.
But to be honest, your code is bad because nobody can understand what you want to do from reading it (including you in six months).
I'm a beginner with Python.
I tried to solve the problem: "If we have a file containing <1000 lines, how to print only the odd-numbered lines? ". That's my code:
with open(r'C:\Users\Savina\Desktop\rosalind_ini5.txt')as f:
n=1
num_lines=sum(1 for line in f)
while n<num_lines:
if n/2!=0:
a=f.readlines()[n]
print(a)
break
n=n+2
where n is a counter and num_lines calculates how many lines the file contains.
But when I try to execute the code, it says:
"a=f.readlines()[n]
IndexError: list index out of range"
Why it doesn't recognize n as a counter?
You have the call to readlines into a loop, but this is not its intended use,
because readlines ingests the whole of the file at once, returning you a LIST
of newline terminated strings.
You may want to save such a list and operate on it
list_of_lines = open(filename).readlines() # no need for closing, python will do it for you
odd = 1
for line in list_of_lines:
if odd : print(line, end='')
odd = 1-odd
Two remarks:
odd is alternating between 1 (hence true when argument of an if) or 0 (hence false when argument of an if),
the optional argument end='' to the print function is required because each line in list_of_lines is terminated by a new line character, if you omit the optional argument the print function will output a SECOND new line character at the end of each line.
Coming back to your code, you can fix its behavior using a
f.seek(0)
before the loop to rewind the file to its beginning position and using the
f.readline() (look, it's NOT readline**S**) method inside the loop,
but rest assured that proceding like this is. let's say, a bit unconventional...
Eventually, it is possible to do everything you want with a one-liner
print(''.join(open(filename).readlines()[::2]))
that uses the slice notation for lists and the string method .join()
Well, I'd personally do it like this:
def print_odd_lines(some_file):
with open(some_file) as my_file:
for index, each_line in enumerate(my_file): # keep track of the index of each line
if index % 2 == 1: # check if index is odd
print(each_line) # if it does, print it
if __name__ == '__main__':
print_odd_lines('C:\Users\Savina\Desktop\rosalind_ini5.txt')
Be aware that this will leave a blank line instead of the even number. I'm sure you figure how to get rid of it.
This code will do exactly as you asked:
with open(r'C:\Users\Savina\Desktop\rosalind_ini5.txt')as f:
for i, line in enumerate(f.readlines()): # Iterate over each line and add an index (i) to it.
if i % 2 == 0: # i starts at 0 in python, so if i is even, the line is odd
print(line)
To explain what happens in your code:
A file can only be read through once. After that is has to be closed and reopened again.
You first iterate over the entire file in num_lines=sum(1 for line in f). Now the object f is empty.
If n is odd however, you call f.readlines(). This will go through all the lines again, but none are left in f. So every time n is odd, you go through the entire file. It is faster to go through it once (as in the solutions offered to your question).
As a fix, you need to type
f.close()
f = open(r'C:\Users\Savina\Desktop\rosalind_ini5.txt')
everytime after you read through the file, in order to get back to the start.
As a side note, you should look up modolus % for finding odd numbers.
This question already has answers here:
How to read multiple lines of raw input?
(16 answers)
Closed 6 years ago.
I want to write a program that gets multiple line input and work with it line by line. Why isn't there any function like raw_input in Python 3?
input does not allow the user to put lines separated by newline (Enter). It prints back only the first line.
Can it be stored in a variable or even read it to a list?
raw_input can correctly handle the EOF, so we can write a loop, read till we have received an EOF (Ctrl-D) from user:
Python 3
print("Enter/Paste your content. Ctrl-D or Ctrl-Z ( windows ) to save it.")
contents = []
while True:
try:
line = input()
except EOFError:
break
contents.append(line)
Python 2
print "Enter/Paste your content. Ctrl-D or Ctrl-Z ( windows ) to save it."
contents = []
while True:
try:
line = raw_input("")
except EOFError:
break
contents.append(line)
In Python 3.x the raw_input() of Python 2.x has been replaced by input() function. However in both the cases you cannot input multi-line strings, for that purpose you would need to get input from the user line by line and then .join() them using \n, or you can also take various lines and concatenate them using + operator separated by \n
To get multi-line input from the user you can go like:
no_of_lines = 5
lines = ""
for i in xrange(no_of_lines):
lines+=input()+"\n"
print(lines)
Or
lines = []
while True:
line = input()
if line:
lines.append(line)
else:
break
text = '\n'.join(lines)
input(prompt) is basically equivalent to
def input(prompt):
print(prompt, end='', file=sys.stderr, flush=True)
return sys.stdin.readline()
You can read directly from sys.stdin if you like.
lines = sys.stdin.readlines()
lines = [line for line in sys.stdin]
five_lines = list(itertools.islice(sys.stdin, 5))
The first two require that the input end somehow, either by reaching the end of a file or by the user typing Control-D (or Control-Z in Windows) to signal the end. The last one will return after five lines have been read, whether from a file or from the terminal/keyboard.
Use the input() built-in function to get a input line from the user.
You can read the help here.
You can use the following code to get several line at once (finishing by an empty one):
while input() != '':
do_thing
no_of_lines = 5
lines = ""
for i in xrange(5):
lines+=input()+"\n"
a=raw_input("if u want to continue (Y/n)")
""
if(a=='y'):
continue
else:
break
print lines
My current code reads user input until line-break.
But I am trying to change that to a format, where the user can write input until strg+d to end his input.
I currently do it like this:
input = raw_input ("Input: ")
But how can I change that to an EOF-Ready version?
In Python 3 you can iterate over the lines of standard input, the loop will stop when EOF is reached:
from sys import stdin
for line in stdin:
print(line, end='')
line includes the trailing \n character
Run this example online: https://ideone.com/rUXCIe
This might be what most people are looking for, however if you want to just read the whole input until EOF into a single variable (like OP), then you might want to look at this other answer.
Use file.read:
input_str = sys.stdin.read()
According to the documentation:
file.read([size])
Read at most size bytes from the file (less if the read hits EOF
before obtaining size bytes). If the size argument is negative or
omitted, read all data until EOF is reached.
>>> import sys
>>> isinstance(sys.stdin, file)
True
BTW, dont' use input as a variable name. It shadows builtin function input.
You could also do the following:
acc = []
out = ''
while True:
try:
acc.append(raw_input('> ')) # Or whatever prompt you prefer to use.
except EOFError:
out = '\n'.join(acc)
break
With sys.stdin.readline() you could write like this:
import sys
while True:
input_ = sys.stdin.readline()
if input_ == '':
break
print type(input_)
sys.stdout.write(input_)
Remember, whatever your input is, it is a string.
For raw_input or input version, write like this:
while True:
try:
input_ = input("Enter:\t")
#or
_input = raw_input("Enter:\t")
except EOFError:
break
print type(input_)
print type(_input)
print input_
print _input