I was writing a Python program which includes printing a array created from user input in the order the user inputed each item of the array. Unfortunately, I have had few problems with that; Once it repeated the first item twice with one of the set, and then in another set it put the last 2 items at the beginning.
I checked the array in the shell and the array contained the right amount of items in the right order, so I don't know what is going on. My script looks something like this:
i = 1
lines = []
for i in range (1, (leng + 1)):
lines.append(input())
input() # The data stripped is not used, the input is a wait for the user to be ready.
i = 0
for i in range (0, (leng + 1)):
print(lines[i - len(lines)])
I searches found me nothing for my purposes (but then again, I could have not used the correct search term like in my last question).
Please answer or find a duplicate if existing. I'd like an answer.
Don't you just want this?
for line in lines:
print(line)
EDIT
As an explanation of what's wrong with your code... you're looping one too many times (leng+1 instead of leng). Then you're using i - len(lines), which should probably be okay but is just the equivalent of i. Another fix for your code could be:
for i in range(len(lines)):
print(lines[i])
SECOND EDIT
Rewriting your full code to what I think is the simplest, most idiomatic version:
# store leng lines
lines = [input() for _ in range(leng)]
# wait for user to be ready
input()
# print all the lines
for line in lines:
print(line)
Related
Link to question: https://www.spoj.com/UTPEST22/problems/UTP_Q2/
From what I understand, the question is divided into 2 parts:
Input
The first input is an integer that limits the number of time the user can provide a set of integers.
From the second line onwards, the user provides the sequence of integers up until the specified limit.
The set of integers are arranged in ascending order, separated only by a space each.
Output
For each sequence of integers, the integers in it are looped over. Only those that are even are printed as outputs horizontally.
from sys import stdin
for x in range(1, 1+ int(input())):
# number of cases, number of times the user is allowed to provide input
for line in stdin:
num_list = line.split()
# remove the space in between the integers
num = [eval(i) for i in num_list]
# change the list of numbers into integers each
for numbers in range(num[0], num[-1] + 1):
# the first integer is the lower bound
# the second the upper bound
if numbers % 2 == 0:
# modulo operation to check whether are the integers fully divisible
print(numbers, end = ' ')
# print only the even numbers, horizantally
Can anyone please provide some insights on how to make changes to my code, specifically the loop. I felt so messed up with it. Screenshot of the result.
Any help will be appreciated.
You can use restructure the code into the following steps:
Read each case. You can use the input function here. A list comprehension can be used to read each line, split it into the lower and upper bound and then convert these to integers.
Process each case. Use the lower and upper bounds to display the even numbers in that range.
Using loops: Here is an example solution that is similar to your attempt:
n = int(input())
cases = []
for case in range(n):
cases.append([int(x) for x in input().split()])
for case in cases:
for val in range(case[0], case[1] + 1):
if val % 2 == 0:
print(val, end=' ')
print()
This will produce the following desired output:
4 6 8 10 12 14 16 18 20
2 4 6 8 10 12 14 16
-4 -2 0 2 4 6
100 102 104 106 108
Simplify using unpacking: You can simplify this further by unpacking range. You can learn more about unpacking here.
n = int(input())
cases = []
for case in range(n):
cases.append([int(x) for x in input().split()])
for case in cases:
lower = case[0] if case[0] % 2 == 0 else case[0]
print(*range(lower, case[1] + 1, 2))
Simplify using bit-wise operators: You can simplify this further using the bit-wise & operator. You can learn more about this operator here.
n = int(input())
cases = []
for case in range(n):
cases.append([int(x) for x in input().split()])
for case in cases:
print(*range(case[0] + (case[0] & 1), case[1] + 1, 2))
So first of obviously ask user to input the range however many times they specified, you can just split the input and then just get the first and second item of that list that split will return, by using tuple unpacking, then append to the ranges list the range user inputted but as a Python range object so that you can later easier iterate over it.
After everything's inputted, iterate over that ranges list and then over each range and only print out the even numbers, then call print again to move to a new line in console and done.
ranges = []
for _ in range(int(input())):
start, end = input().split()
ranges.append(range(int(start), int(end) + 1))
for r in ranges:
for number in r:
if number % 2 == 0:
print(number, end="")
print()
Here's my solution:
n = int(input())
my_list = []
for i in range(n):
new_line = input().split()
new_line = [int(x) for x in new_line]
my_list.append(new_line)
for i in my_list:
new_string = ""
for j in range(i[0], i[1]+1):
if (not(j % 2)): new_string += f"{j} "
print(new_string)
Read the first value from stdin using input(). Convert to an integer and create a for loop based on that value.
Read a line from stdin using input(). Assumption is that there will be two whitespace delimited tokens per line each of which represents an integer.
Which gives us:
N = int(input()) # number of inputs
for _ in range(N):
line = input()
lo, hi = map(int, line.split())
print(*range(lo+(lo&1), hi+1, 2))
There are a few issues here but I'm guessing this is what's happening: you run the code, you enter the first two lines of input (4, followed by 3 20) and the code doesn't print anything so you press Enter again and then you get the results printed, but you also get the error.
Here is what's actually happening:
You enter the input and the program prints everything as you expect but, you can't see it. Because for some reason when you use sys.stdin then print without a new line, stdout does not flush. I found this similar issue with this (Doing print("Enter text: ", end="") sys.stdin.readline() does not work properly in Python-3).
Then when you hit Enter again, you're basically sending your program a new input line which contains nothing (equivalent to string of ""). Then you try to split that string which is fine (it will just give you an empty list) and then try to get the first element of that list by calling num[0] but there are no elements in the list so it raises the error you see.
So you can fix that issue by changing your print statement to print(numbers, end = ' ', flush=True). This will force Python to show you what you have printed in terminal. If you still try to Enter and send more empty lines, however, you will still get the same error. You can fix that by putting an if inside your for loop and check if line == "" then do nothing.
There is still an issue with your program though. You are not printing new lines after each line of output. You print all of the numbers then you should go to the newline and print the answer for the next line of input. That can be fixed by putting a print() outside the for loop for numbers in range(num[0], num[-1] + 1):.
That brings us to the more important part of this answer: how could you have figured this out by yourself? Here's how:
Put logs in your code. This is especially important when solving this type of problems on SPOJ, Codeforces, etc. So when your program is doing that weird thing, the first thing you should do is to print your variables before the line of the error to see what their value is. That would probably give you a clue. Equally important: when your program didn't show you your output and you pressed Enter again out of confusion, you should've gotten curious about why it didn't print it. Because according to your program logic it should have; so there already was a problem there.
And finally some side notes:
I wouldn't use eval like that. What you want there is int not eval and it's just by accident that it's working in the same way.
We usually put comments above the line not below.
Since it appears you're doing competitive programming, I would suggest using input() and print() instead of stdin and stdout to avoid the confusions like this one.
SPOJ and other competitive programming websites read your stdout completely independent of the output. That means, if you forget to put that empty print() statement and don't print new lines, your program would look fine in your terminal because you would press Enter before giving the next input line but in reality, you are sending the new line to the stdin and SPOJ will only read stdout section, which does not have a new line. I would suggest actually submitting this code without the new line to see what I mean, then add the new line.
In my opinion, the variable numbers does not have a good name in your code. numbers imply a list of values but it's only holding one number.
Your first if does not need to start from 1 and go to the number does it? It only needs to iterate that many times so you may as well save yourself some code and write range(int(input())).
In the same for loop, you don't really care about the value of variable x - it's just a counter. A standard practice in these situations is that you put _ as your variable. That will imply that the value of this variable doesn't really matter, it's just a counter. So it would look like this: for _ in range(int(input())).
I know some of these are really extra to what you asked for, but I figured you're learning programming and trying to compete in contests so thought give some more suggestions. I hope it helped.
Steps for simple solution
# taking input (number of rows) inside outer loop
# l = lower limit, u = upper limit, taking from user, then converting into integer using map function
# applying logic for even number
# finally printing the even number in single line
for j in range(int(input())):
l, u = map(int, input('lower limit , upper limit').split())
for i in range(l, u+1):
if i%2 == 0: # logic for even number
print(i, end=' ')
I was currently finishing up my project that concerned ciphering a sentence using a key matrix.
As of now, all the calculations are done and correct, the only thing left is for me to print the output to the screen and voila.
What you can see above is my current output.
The Key matrix is printed just how I want it to be printed and all is good with Encrypted message as well, except that my print prints one space more than what is needed. This is quite problematic because of the fact that the project is going to be verified with a bot, so even though it changes nothing on the screen (except when piping into cat -e) the bot is still going to pick it up.
My print function looks like the following:
def the_output_printer(key_matrix, encrypted_matrix, matrix_size):
length = (len(sys.argv[1]));
if (length == 0):
exit(84);
lines = round(length / matrix_size, 0);
if (length % matrix_size != 0):
lines += 1
lines = int(lines);
print("Key matrix:");
for line_index_key in range(0, matrix_size):
for col_index_key in range(0, matrix_size):
if (col_index_key != matrix_size - 1):
print("{}".format(key_matrix[line_index_key][col_index_key]), end="\t");
if (col_index_key == matrix_size - 1):
print("{}".format(key_matrix[line_index_key][col_index_key]), end="\n");
print("\n", end="");
print("Encrypted message:")
for line_index in range(0, lines):
for col_index in range(0, matrix_size):
print("{}".format(encrypted_matrix[line_index][col_index]), end=" ");
print();
I tried something simillar to what I've done for Key Matrix but it didn't really work out.
Any ideas as how to not print that last " "?
Thank you all for reading!
As I'm still new to python please excuse my horrible coding style, I'm still working on it.
Your problem is that each iteration of your nested for loop prints your end argument, one space. That's fine assuming you want one between all elements, but it doesn't know to skip it on the last iteration of the nested loop.
There's more than one way to solve this, but because you mentioned being new to Python I'll stick to a simple one - instead of printing each number, collect up the numbers in a single list and then pass that list to print(). print() defaults to adding a separator between its arguments but not after the final one.
message_elements = []
for line_index in range(0, lines):
for col_index in range(0, matrix_size):
message_elements.add("{}".format(encrypted_matrix[line_index][col_index]))
print(*message_elements)
The * operator in the final print() unpacks the list, as if you'd specified each of its elements as an argument to print(). It's equivalent to:
print(message_elements[0], message_elements[1], ...)
Once you're more experienced with Python there are ways to more concisely collect up the matrix elements into a list, or to avoid an intermediate list at all and use a single expression to do it. But this should work and changes as little as I can from your existing code.
Alright, I figured it out :)!
The problem was that as I'm still new to Python, I once again messed up how
range() functioned.
My previous attempt at fixing this resembled:
if (line_index == lines and col_index == matrix_size):
print("{}".format(encrypted_matrix[line_index][col_index]));
else:
print("{}".format(encrypted_matrix[line_index][col_index]), end=" ");
I ommited the fact that while using
in range(foo)
the value stops at foo - 1, or quite simply while it is strictly inferior to foo.
The fix was quite simply to add -1 to my if statement, EXACTLY the same thing I forgot when i was doing my key_matrix printing part. The fixed part of the function now looks lice this:
if (line_index == lines - 1 and col_index == matrix_size - 1):
print("{}".format(encrypted_matrix[line_index][col_index]));
else:
print("{}".format(encrypted_matrix[line_index][col_index]), end=" ");
Which gives me the correct output :). Thank you everyone but I figured it out after re-reading the code few times.
I've got a txt which first line include the good answers of a test, and the other lines include the ID of the participants and they answers (' ' between). If the user give an input (call it n) its means the number of the question, and I have to count how many of them are good (similar which is in the [0] line n's)
The txt's like:
BCCCDBBBBCDAAA
AB123 BXCDBBACACADBC
AD995 BABCDABCBCBBBA
AH97 BCACDBDDBCBBCA
AK260 DCDCBDDAACDBDB
AL580 AACCDBBCDCAACA
AN562 BAABBDCACCBDBB
And my code is:
person=[]
with open('answers.txt', 'r') as v:
pcs=sum(1 for line in open('answers.txt'))
for i in range(0, pcs):
person.extend(v.read().strip().split())
result=0
jnum=input('which exesises result are you interested in? ')
jnum=int(jnum)
good=person[0]
good=good[jnum]
for i in range(0, pcs):
letter=person[i*2]
letter=letter[jnum]
if good==letter:
result+=1
print(result)
else:
result=result
Yes, it will freeze, once you fix enough problems to get that far: your final two lines are an infinite loop. You don't change either good or letter within the loop -- as soon as they match, you're stuck inside.
Insert print statements to trace your execution and data values.
Also, I strongly recommend that you adopt incremental programming. Your code has multiple problems; you should write just a few lines, make sure that they work, and then go on to the next small group.
I know this is probably something incredibly simple, but I seem to be stumped.
Anyways for an assignment I have to have the user enter the number of data points(N) followed by the data points themselves. They must then be printed in the same manner in which they were entered (one data point/line) and then put into a single list for later use. Here's what I have so far
N = int(input("Enter number of data points: "))
lines = ''
for i in range(N):
lines += input()+"\n"
print(lines)
output for n = 4 (user enters 1 (enter) 2 (enter)...4 and the following is printed:
1
2
3
4
So this works and looks perfect however I now need to convert these values into a list to do some statistics work later in the program. I have tried making a empty list and bringing lines into it however the /n formating seems to mess things up. Or I get list index out of range error.
Any and all help is greatly appreciated!
How about adding every new input directly to a list and then just printing it.
Like this:
N = int(input("Enter number of data points: "))
lines = []
for i in range(N):
new_data = input("Next?")
lines.append(new_data)
for i in lines:
print(i)
Now every item was printed in a new line and you have a list to manipulate.
You could just add all the inputs to the list and use the join function like this:
'\n'.join(inputs)
when you want to print it. This gives you a string with each members of the list separated with the delimiter of your choice, newline in this case.
This way you don't need to add anything to the values you get from the user.
You could try to append all the data into a list first, and then print every item in it line by line, using a for loop to print every line, so there is no need to concatenate it with "\n"
N = int(input("Enter number of data points: "))
data = []
for i in range(N):
item = data.append(input())
for i in data:
print(i)
I have a sample file that looks like this:
#XXXXXXXXX
VXVXVXVXVX
+
ZZZZZZZZZZZ
#AAAAAA
YBYBYBYBYBYBYB
ZZZZZZZZZZZZ
...
I wish to only read the lines that fall on the index 4i+2, where i starts at 0. So I should read the VXVXV (4*0+2 = 2)... line and the YBYB...(4*1 +2 = 6)line in the snippet above. I need to count the number of 'V's, 'X's,'Y's and 'B's and store in a pre-existing dict.
fp = open(fileName, "r")
lines = fp.readlines()
for i in xrange(1, len(lines),4):
for c in str(lines(i)):
if c == 'V':
some_dict['V'] +=1
Can someone explain how do I avoid going off index and only read in the lines at the 4*i+2 index of the lines list?
Can't you just slice the list of lines?
lines = fp.readlines()
interesting_lines = lines[2::4]
Edit for others questioning how it works:
The "full" slice syntax is three parts: start:end:step
The start is the starting index, or 0 by default. Thus, for a 4 * i + 2, when i == 0, that is index #2.
The end is the ending index, or len(sequence) by default. Slices go up to but not including the last index.
The step is the increment between chosen items, 1 by default. Normally, a slice like 3:7 would return elements 3,4,5,6 (and not 7). But when you add a step parameter, you can do things like "step by 4".
Doing "step by 4" means start+0, start+4, start+8, start+12, ... which is what the OP wants, so long as the start parameter is chosen correctly.
You can do one of the following:
Start xrange at 0 then add 2 onto i in secondary loop
for i in xrange(0, len(lines), 4):
for c in str(lines(i+2))
if c == 'V':
some_dict['V'] += 1
Start xrange at 2, then access i the way specified in your original program
for i in xrange(2, len(lines), 4):
for c in str(lines(i))
if c == 'V':
some_dict['V'] += 1
I'm not quite clear on what you're trying to do here--- are you actually just trying to only read the lines you want from disk? (In which case you've gone wrong from the start, because readlines() reads the whole file.) Or are you just trying to filter the list of lines to pick out the ones you want?
I'll assume the latter. In which case, the easiest thing to do would be to just use a listcomp to filter the line by indices. e.g. something simple like:
indices = [x[0] * 4 + 2 for x in enumerate(lines)]
filtered_lines = [lines[i] for i in indices if len(lines) > i]
and there you go, you've got just the lines you want, no index errors or anything silly like that. Then you can separate out and simplify the rest of your code to do the counting, just operating on the filtered list.
(just slightly edited the first list comp to be a little more idiomatic)
I already gave a similar answer to another question: How would I do this in a file?
A better solution (avoiding unnecessary for loops) would be
fp = open(fileName, "r")
def addToDict(letter):
someDict[letter] += 1;
[addToDict('V') for 'V' in str(a) for a in fp.readlines()[2::4]];
I tried to make this an anonymous function without success, if someone can do that it would be excellent.