Python: Display all even numbers between two integers inclusive, with a limit the number of times the code accepts input

Question:

Link to question: https://www.spoj.com/UTPEST22/problems/UTP_Q2/
From what I understand, the question is divided into 2 parts:

  1. 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.
  1. 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.

Asked By: brucey

||

Answers:

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()
Answered By: Matiiss

You can use restructure the code into the following steps:

  1. 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.

  2. 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))
Answered By: Prins

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))
Answered By: Vlad

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)
Answered By: Schnitte

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=' ')
Answered By: Abhishek Kumar

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.

Answered By: ARKhoshghalb
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.