Problem in reading till EOF in python - python

i have a python code which should read in 2 integers from standard input till user presses Ctrl+D (i.e EOF)
and do some processing .I tried the following code :
n,k=map(int,[a for a in sys.stdin.read().split()])
Here , when i enter two integers the programme accepts it and when i press Ctrl+D it shows the correct output , like:
6 3
but when i put in 2 pairs in intergers like:
6 3
12 2 and then press Ctrl+D then instead of the desired result i get error that:
[i]ValueError: Too many values to upack[/i]
So how do i correct the code for it to work properly?
I intend to have the shortest possible code for that
Thanks.

>>> x=map(int,[a for a in sys.stdin.read().split()])
2 3 4 5
>>> x
[2, 3, 4, 5]
and work against the list; this so you will accept a variable number of ints if required to do so

The problem is not in how you read from stdin. Entering 6 3 essentially makes your code equivalent to
n, k = [6, 3]
which will work fine. Entering 6 3 12 2 though will result in
n, k = [6, 3, 12, 2]
which does not work, since you try to unpack a sequence of four values to only two targets. If you want to ignore everything beyond the first two numbers, try
n, k = [int(a) for a in sys.stdin.read().split()][:2]
If you want to iterate through the numbers read from stdin in pairs, you can use
numbers = (int(a) for a in sys.stdin.read().split())
for n, k in zip(numbers, numbers):
# whatever

Related

Сyclic shift of all array elements

A list of integers is entered from the keyboard. Write a program that will cycle through all the elements of an array one position to the right (the last element is moved to the beginning of the list).
Input data
The first line contains the number of elements in the list. After that, the list elements themselves are entered - one per line.
Output
Output the list resulting from the shift.
Example
Input data
6
8
12
3
4
5
1
Output
1 8 12 3 4 5
I don't understand what's wrong with this code. It works, but the teacher said that the task was not solved correctly.
h = []
k = int(input())
for i in range(k):
o = int(input())
h.append(o)
h = h[len(h) - 1:] + h[:len(h)-1]
print(h)
I think there is a typo in the example, the 1 is missing. Did you mean:
Input 6 8 12 3 4 5 1
Output 1 6 8 12 3 4 5
EDIT: There is no typo here, the 6 represents how many numbers the user will input, and they are typed line by line. So the following doesn't make sense :)
Did you actually try to run your code with the example? Because it doesn't work :)
First, line 2:
You cannot convert a string like "6 8 12 3 4 5 1" directly to an integer because the int() function doesn't know how to deal with the spaces.
Then, line 3:
for i in range(k) doesn't make sense for python, because k is a list.
The range function takes (at least) an integer and returns a "list" with all the numbers between 0 and this number (excluded). With a quick google search you can find some examples like this one.
The correct way to loop over a string, by character would be:
s = "hello"
for letter in s:
print(s)
or
s = "hello"
for i in range(len(s)):
print(s[i])
Both will output:
h
e
l
l
o
Finally, line 4:
You try to convert the character (I assume) to an integer.
But what if the character is a space? (it will crash)
And what about a number like 12? You will then add 1 and 2 but not 12 to your final list.
To summarize, you need a function that split the string on spaces. The split function does exactly this! It takes a character and splits a string regarding this character, returning a list of substrings.
Again, you can google it to find examples
Here is a solution for you problem, I tried to comment it to make it easier to understand:
inp = input("Please enter several numbers: ") # read the numbers
inp = inp.split(" ") # split the input on spaces
h = []
for element in inp:
h.append(int(element)) # Convert each element to int
# rotate the list
# you don't need the len(h) here, python handles negative indices
rot = h[-1:] + h[:-1]
print(rot)

foobar please-pass-the-coded-messages hidden test case not passing

I have been attempting google foobar and in the second level i got the task named please-pass-the-coded-messages. below is the task
==============================
You need to pass a message to the bunny workers, but to avoid detection, the code you agreed to use is... obscure, to say the least. The bunnies are given food on standard-issue plates that are stamped with the numbers 0-9 for easier sorting, and you need to combine sets of plates to create the numbers in the code. The signal that a number is part of the code is that it is divisible by 3. You can do smaller numbers like 15 and 45 easily, but bigger numbers like 144 and 414 are a little trickier. Write a program to help yourself quickly create large numbers for use in the code, given a limited number of plates to work with.
You have L, a list containing some digits (0 to 9). Write a function solution(L) which finds the largest number that can be made from some or all of these digits and is divisible by 3. If it is not possible to make such a number, return 0 as the solution. L will contain anywhere from 1 to 9 digits. The same digit may appear multiple times in the list, but each element in the list may only be used once.
Languages
=========
To provide a Java solution, edit Solution.java
To provide a Python solution, edit solution.py
Test cases
==========
Your code should pass the following test cases.
Note that it may also be run against hidden test cases not shown here.
-- Java cases --
Input:
Solution.solution({3, 1, 4, 1})
Output:
4311
Input:
Solution.solution({3, 1, 4, 1, 5, 9})
Output:
94311
-- Python cases --
Input:
solution.solution([3, 1, 4, 1])
Output:
4311
Input:
solution.solution([3, 1, 4, 1, 5, 9])
Output:
94311
Use verify [file] to test your solution and see how it does. When you are finished editing your code, use submit [file] to submit your answer. If your solution passes the test cases, it will be removed from your home folder.
i have tried a solution which is working very correct in my ide(note i wanted a solution without any library)
def solution(l):
# Your code here
if (len(l) == 1 and l[0] % 3 != 0) or (len(l) == 0):
return 0
number = formGreatestNumber(l)
remainder = number % 3
if remainder == 0:
result = formGreatestNumber(l)
return result
result = removeUnwanted(l, remainder)
return result
def formGreatestNumber(li):
li.sort(reverse=True) # descending order
li = [str(d) for d in li] # each digit in string
number = 0
if len(li) > 0:
number = int("".join(li)) # result
return number
def removeUnwanted(l, remainder):
possibleRemovals = [i for i in l if i % 3 == remainder]
if len(possibleRemovals) > 0:
l.remove(min(possibleRemovals))
result = formGreatestNumber(l)
return result
pairs = checkForTwo(l, remainder)
if len(pairs) > 0:
for ind in pairs:
l.remove(ind)
result = formGreatestNumber(l)
return result
else:
divisibleDigits = [d for d in l if d % 3 == 0]
if len(divisibleDigits) > 0:
result = formGreatestNumber(divisibleDigits)
return result
else:
return 0
def checkForTwo(l, remainder): # check of (sum of any two pairs - remainder) is divisible by 3
result = []
for i in range(len(l)):
for j in range(i+1, len(l)):
if ((l[i]+l[j])-remainder) % 3 == 0:
result.append(l[i])
result.append(l[j])
return result
return []
print(solution([]))
print(solution([1]))
print(solution([9]))
print(solution([3, 1, 4, 1, 9, 2, 5, 7]))
however it is on verifying showing-
Verifying solution...
Test 1 passed!
Test 2 passed!
Test 3 failed [Hidden]
Test 4 passed! [Hidden]
Test 5 passed! [Hidden]
so where is the error i am not noticing and is there any other way without any library like itertools?
I won't give away the code and spoil the fun for you, I'll perhaps try to explain the intuition.
About your code, I think the (2nd part of) the function removeUnwanted() is problematic here.
Let's see.
So first off, you'd arrange the input digits into a single number, in order from largest to smallest, which you've already done.
Then if the number formed isn't divisible by 3, try removing the smallest digit.
If that doesn't work, reinsert the smallest digit and remove the 2nd smallest digit, and so on.
Once you're done with removing all possible digits one at a time, try removing digits two at a time, starting with the two smallest.
If any of these result in a number that is divisible by 3, you're done.
Observe that you'll never need to remove more than 2 digits for this problem. The only way it's impossible to form the required number is if there are 2 or lesser digits and they are both either in the set {1,4,7} or {2,5,8}.
Edit: More about your code -
The initial part of your removeUnwanted() looks okay where you check if there's a single digit in the number which can be removed, removing the minimum from the choice of single digits and getting the answer.
I reckon the problem lies in your function checkForTwo(), which you call subsequently in removeUnwanted.
When you're passing the list to checkForTwo(), observe that the list is actually sorted in the decreasing order. This is because li.sort(reverse=True) in your function formGreatestNumber() sorted the list in place, which means the content of list l was sorted in descending order too.
And then in checkForTwo(), you try to find a pair that satisfies the required condition, but you're looping from the biggest 2 pairs that can possibly be removed. i starts from 0 and j starts from i+1 which is 1, and since your list is in descending order, you're trying to remove the biggest 2 elements possible.
A quick fix would be to sort the list in ascending order and then proceed further iterate through the list in reverse order, because since the list is sorted in descending order already, reverse iteration gives you the list in ascending order and saves us from re-sorting which would normally cost an additional O(NlogN) time.

Problem from CodeWars It returns 5 instead of 23 . Can someone help me understand my code?

Problem:
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Finish the solution so that it returns the sum of all the multiples of 3 or 5 below the number passed in.
Note: If the number is a multiple of both 3 and 5, only count it once.
Code:
def solution(number):
return sum( (i%3==0 or i%5==0) for i in range (number))
solution(10)
The problem asks you to sum the numbers which are multiples of 3 or 5, but here you're summing the result of (i%3==0 or i%5==0), which is a boolean (which in Python is equal to the integers 0 and 1).
Meaning you're just counting the number of multiples of 3 and 5, not summing them. This can trivially be checked by just running the function locally in a Python shell: you'll get 5 (because range starts at 0 inclusive, so while 0 does not matter to the sum it matters to the counting).
A generator comprension is "value returned [for] value [in] producer [if] condition". Your test needs to go at the end, as a condition.
Basically you are summing the boolean values that's why your answer is not correct please try following code
Code:
def solution(number):
return sum( i for i in range (number) if (i%3==0 or i%5==0))
solution(10)
In each iteration of the loop, you are evaluating the condition
(i%3==0 or i%5==0)
which is True exactly five times when number is 10. Each True counts as a 1, hence you get 5 for the sum.
To get the correct answer, you need to rearrange the statement so that you evaluate i whenever your condition is true. For more details, see list comprehensions.

How to get n variables in one line?

I have a number n and I need to get from a user n variables in one line.
As far as i know, it's pretty easy to do if you know exactly how many variables you have.
*variables* = map(int, input().split())
But if I don't know how many variables there are, what should I do?
Also, I'm asked to put the result in array.
Unfortunately, I've just started learning Python, so I have absolutely no idea how to do it and can't show any code I've tried.
User input being taken as a space separated string:
1 2 3 4 5
This being the code you are dealing with:
map(int, input().split())
Stating you need a list, then just store it in a single variable:
inputs = map(int, input().split())
However, dealing with Python 3, you will end up with map object. So if you actually need a list type, then just call list on the map function:
inputs = list(map(int, input().split()))
Demo:
>>> inputs = list(map(int, input().split()))
1 2 3 4 5
>>> type(inputs)
<class 'list'>
>>> inputs
[1, 2, 3, 4, 5]

Check if an element in one list has the same index as another element in another list

I am making the mastermind game on python with numbers. I have a problem with checking the elements if they are in an incorrect place.
So basically, if the code generated by the computer has no duplicates but the user used some in their input like (COMP: 1 2 3 4 & USER: 1 2 2 3). I can't check the positions of only one '2' and not both of them. Please help.
Code:
def incorrect_place():
incorrect_place = 0
if len(set(user_code)) != 4: #There are duplicates in the user's input
for index, num in enumerate(set(user_code)):
#I don't know how to check it now
incorrect_place += 1
return incorrect_place
I would like it if someone also finds a solution where the computer has chosen a duplicate and so has the user like (COMP: 1, 2, 2, 3 & USER: 2, 3, 4, 4)
Based on a little bit of research into what Mastermind is and the fact that the function in your OP returns an integer, my guess is that you want to compare a computer-generated list to a user-generated list of the same size and see how many positions have different values.
Example:
Computer: 1 2 3 4
User: 1 2 2 3
S S D D # S=Same, D=Different
So the answer above would be 2.
I propose the following:
def incorrect_places(comp_list, user_list):
return sum(1 if a != b else 0 for a, b in zip(comp_list, user_list))
How it works:
zip(comp_list, user_list) gives us a list of 2-tuples, pairing the corresponding values in each list by the position in which they occur. For the above example, we'd get: [(1, 1), (2, 2), (3, 2), (4, 3)]
1 if a != b else 0 for a, b in that_list -- returns a 1 if each number in the pair is the same, otherwise a 0. Thus, we get [0, 0, 1, 1]
Finally we sum it all to get our answer. Hope this helps.
Edit: Commenters have pointed out that this is the same as doing sum(a != b for a, b in zip(comp_list, user_list)). I prefer the longer and more readable version, but they work the same way. This difference is purely stylistic. Choose whichever version you like.
I understood your question after reading Two-Bit Alchemist's answer.
Here's my try:
def list_differences(list_a, list_b):
# Subtract list_b from list_a, element by element. The subtraction
# will result in non-zero values for elements that were different.
return [bool(list_a[i]-list_b[i]) for i in range(len(list_a))].count(True)

Categories

Resources