How to achieve the output of the input array? - python

Given an array of integers, process each array element and return the resultant array.
If the element is an even no., add 2 to it.
If the element is an odd no., add 1 to it.
The array will not contain any negative integers.
for eg.,
Input 1 : {1,2,3,4,5}
Input 2 : 5 (no. of elements in input 1 array)
Output : {2,4,4,6,6}
My code :
def EvenOddSum(a, n):
even = 0
odd = 0
for i in range(n):
if i % 2 == 0:
even += a[i]
else:
odd += a[i]
print("Even index positions sum ", even )
print ("Odd index positions sum ", odd )
arr=input("Enter array : ")
n = int(input("Enter number of elements in arr : "))
print(EvenOddSum(arr, n) )
I tried this but this . But code is showing unsupported operand type error. Plus I can't achieve the logic stated in problem.
How to achieve the solution for my problem . Please help.

This line:
arr=input("Enter array : ")
gives you a str, not a list. You might want something more like:
arr = list(map(int, input("Enter array : ").split()))
which takes the str input, splits it into a List[str], and then maps it to a List[int].
Note that this assumes you're entering the array as "1 2 3 4", not some tricky syntax like "{1,2,3,4}" (which you could write more code to handle, but if it's not part of the assignment I wouldn't recommend deliberately making your life more difficult).
You should also define your function to just take the array, rather than the array plus the count (since the array already contains the length). Then to test it you can simply get the array from stdin and invoke the function all in one step:
>>> def even_odd_sum(a):
... return [i + (2 - i % 2) for i in a]
...
>>> even_odd_sum(list(map(int, input("Enter array: ").split())))
Enter array: 1 2 3 4 5
[2, 4, 4, 6, 6]
If you wanted to exactly match the funky formatting given in the original question, that's significantly more work than implementing the actual function, but it might look like:
from typing import Any, List
def even_odd_sum(a: List[int]) -> List[int]:
return [i + (2 - i % 2) for i in a]
def input_funky_formatted_list(funk: str) -> List[str]:
if funk[0] != "{" or funk[-1] != "}":
raise ValueError("this formatting is insufficiently funky")
return funk[1:-1].split(",")
def output_funky_formatted_list(arr: List[Any]) -> str:
return "{" + ",".join(map(str, arr)) + "}"
arr = list(map(int, input_funky_formatted_list(input("Input 1 : "))))
input("Input 2 : ") # discard this, it serves no purpose
print(f"Output : {output_funky_formatted_list(even_odd_sum(arr))}")

The first problem of the code is that the result of input() is a string independent of what you actually type.
To get arr to eventually contain an array of numbers (possibly into a list), you should parse the string resulting from input() or adopt another input strategy (see below on third issue).
Python libraries are incredibly helpful with this, and you could consider using ast.literal_eval() for the job, e.g.:
import ast
s = '{1,2,3,4,5}'
items = ast.literal_eval('[' + s[1:-1] + ']')
print(items)
# [1, 2, 3, 4, 5]
If you have some freedom over the input, you could spare yourself some work or even take a more direct approach.
The second problem is that EvenOddSum() (which incidentally is not named according to typical Python coding style conventions) is not implementing the logic to fulfill your expectations.
One way would be:
# offsets=(even_offset, odd_offset)
def odd_even_sum(items, offsets=(2, 1)):
return [item + offsets[item % 2] for item in items]
The third issue is that if you input a string containing all the array, the information about its length is redundant, unless you make some use of it.
For example, you could use it to check if the array is of the desired length:
assert(len(items) == n)
or use it to simplify your input:
def odd_even_sum(items, offsets=(2, 1)):
return [item + offsets[item % 2] for item in items]
n = int(input('Array length?'))
items = []
for i in range(n):
item = int(input(f'Item[{i}]?'))
items.append(item)
Putting all this together:
def odd_even_sum(items, offsets=(2, 1)):
return [item + offsets[item % 2] for item in items]
n = int(input('Array length?'))
items = []
for i in range(n):
item = int(input(f'Item[{i}]?'))
items.append(item)
new_items = odd_even_sum(items)
print(f' Input: {items}')
print(f'Output: {new_items}')

Related

Why does the `eval` function seemingly take so long in Python?

TL;DR why is Python's eval function slow?
Hi. I was solving a coding exercise and noticed that the eval function was causing timeouts for some test cases and was wondering why this is the case as I don't particularly recall reading that the function is slow.
Here's the exercise:
You are given a list of n nonnegative integers and a target integer. Find out how many possible ways there are to add '+' or '-' in between the provided integers in order to obtain the target. For example, the input [1, 1, 1, 1, 1] and 3 would return 5 since there are five total ways to insert + or - to obtain 3: -1+1+1+1+1, +1-1+1+1+1, +1+1-1+1+1, +1+1+1-1+1, +1+1+1+1-1.
The solution I initially came up with used eval as follows:
from itertools import product
from typing import List
def solution(numbers: List[int], target: int) -> int:
numbers = [str(x) for x in numbers]
length = len(numbers)
all_operations = list(map(''.join, product('+-', repeat=length)))
answer = 0
for operation in all_operations:
eval_string = ''.join([''.join(x) for x in zip(operation, numbers)])
if eval(eval_string) == target:
answer += 1
return answer
The second solution that passes all test cases doesn't use eval and simply performs the arithmetic step by step:
from itertools import product
from typing import List
def solution(numbers: List[int], target: int) -> int:
numbers = [str(x) for x in numbers]
length = len(numbers)
all_signs = list(map(''.join, product('+-', repeat=length)))
answer = 0
for operation in all_signs:
value = 0
for op, number in zip(operation, numbers):
if op == '+':
value += int(number)
elif op == '-':
value -= int(number)
if value == target:
answer += 1
return answer
Converting your values to strings then running eval is not going to be efficient. This will be faster although it may be possible to improve this even further:
import itertools
INTS = [1, 1, 1, 1, 1]
CONST = 3
# build a new list comprised of the original INTS plus their negative values
P = list(map(lambda x: -x, INTS)) + INTS
# work out the unique permutations
s = set(itertools.permutations(P, len(INTS)))
# iterate over (map) each unique permutations to see if its sum matches CONST
print(list(map(lambda x: sum(x) == CONST, s)).count(True))

IQ test function in Python not working as intended

I'm having trouble with this code below.
My task is to create a function, that among the given numbers finds one that is different in evenness, and returns a position of that number. The numbers are given as a string. So far I have managed to convert the string into an integer list, then using for loop to iterate through each number.
The problem I'm encountering is that I've managed to return only the position of an odd number among the even numbers, and I can't continue on with the code for vice versa action, because it only returns the position of the odd number.
Here is the code:
def iq_test(numbers):
# Splitting the "numbers" string
num_split = numbers.split()
# converting the splitted strings into int
num_map = map(int, num_split)
# converting the object into list
list_num = list(num_map)
for n in list_num:
if not n%2 == 0:
return list_num.index(n) + 1
Your problem is, that you are assuming, that you are searching for the first even number. What you have to do, is to first decide, what you are searching for. You could for example simply first count the number of even numbers. If it is one, then you are looking for an even number, otherwise, you are looking for an odd. As you don't care for the actual numbers, I would map all of them to their value mod 2 as so:
num_map = list(map(lambda x: int(x) % 2, num_split))
Then, the rest is simple. For example like this:
def iq_test(numbers):
# Splitting the "numbers" string
num_split = numbers.split()
# converting the splitted strings into even (0) or odd (1)
num_map = list(map(lambda x: int(x) % 2, num_split))
# return the correct position based on if even or odd is in search
evens = num_map.count(0)
if evens == 1:
return num_map.index(0) + 1
else:
return num_map.index(1) + 1
I came up with a similar and a little bit shorter solution
def iq_test(numbers):
# first check what im looking for "even" or "odd", map a lambda function that basically does it for me, using the numbers argument as a list type and afterwards cast it into a list so i can iterate later on
num_map = list(map(lambda x: 'e' if int(x) % 2 == 0 else 'o', numbers.split()))
# search for even numbers numbers
if num_map.count('e') == 1:
return num_map.index('e') + 1
# search for odd numbers numbers
return num_map.index('o') + 1
def iq_test(numbers):
# Splitting the "numbers" string
num_split = numbers.split()
# converting the splitted strings into int
num_map = map(int, num_split)
# converting the object into list
list_num = list(num_map)
for n in list_num:
if not n%2 == 0:
return list_num.index(n) + 1

Python Count Unique Elements for Multidimensional List

I've written a function to count unique elements in a 2d list in Python, and I'm wondering how to make it more general for lists of any number of dimensions. Answers I've seen so far about finding the dimension by testing if the first instance is a list don't seem robust. Please note I want to avoid using NumPy.
Any suggestions please?
def count_unique_elements_2d_list(list_2d):
flat_list = []
for sublist in list_2d:
for item in sublist:
flat_list.append(item)
unique_recipes = set(flat_list)
return len(unique_recipes)
This will return on the unique elements, which you can then call len on.
def get_unique(some_array, seen=None):
if seen is None:
seen = set()
for i in some_array:
if isinstance(i, list):
seen.union(get_unique(i, seen))
else:
seen.add(i)
return seen
What is happening?
This is a recursive problem. If the level is not a list, then assume it's an item and add it to the set of seen items. if it is a list, then run the function on it again.
You can avoid the extra space you have used by running two for loops and adding unique elements to the set only.
def count_unique_elements_2d_list(list_2d):
unique=set()
for sublist in list_2d:
for item in sublist:
unique.add(item)
return len(unique)
If the element is already present it would not be added to the set. And you will get the unique count of elements.
Here is my quick hack. It's a little unclean with the except but it's short and relatively efficient.
def get_dimensions(lut):
dim = 0
test = lut
try:
while test[0]:
dim = dim + 1
test = test[0]
except TypeError:
return dim
def to_onedimensional(lut, dim, output, counter):
if(counter == dim - 1):
for x in lut:
output.append(x)
else:
for x in lut:
to_onedimensional(x, dim, output, counter + 1)
This is how to use it:
lut = [[[3],[4]], [[2],[3]]]
print(get_dimensions(lut))
output = []
to_onedimensional(lut, get_dimensions(lut), output, 0)
res = set(output)
print(len(res))
Output:
3
3

Python: Find Every Fibonacci Sequence in a Given List of Numbers

a program that takes a list of numbers separated with "," from the user and extracts and prints every fibonacci sequence from the list.
like this:
In: 5,6,9,3,0,1,1,2,3,8,2,9,3,0,1,1,2,3,5,98
Out:
[0,1,1,2,3]
[0,1,1,2,3,5]
i tried to use "for" loops to find the first 0 and process the program after it. like it checks and follows the list for the fibonacci sequence until it's out of the sequence, prints the list, and then looks for the next 0.
i wrote the part of the code that gets the input, but i don't know how to do the rest
numbers = input("Enter your numbers list and use comma to seperate them: ")
numlist = numbers.split(",")
numlist = [int(x) for x in numlist]
result = []
"result" is the output list (or lists).
i hope my explanations were clear. anyone can help?
Below program should work, it will check for the fibbonaci series in the list of numbers
numbers = [5,6,9,3,0,1,1,2,3,8,2,9,3,0,1,1,2,3,5,98]
first = numbers[0]
second = numbers[1]
fibbonacci = []
result = []
for number in numbers[2:]:
if first + second == number:
if not fibbonacci:
fibbonacci.extend([first, second, number])
else:
fibbonacci.append(number)
elif fibbonacci:
result.append(fibbonacci)
fibbonacci = []
first = second
second = number
print(result)
Idea is very similar to #Vuplex but can use os.path.commonprefix to remove extra code to compare two series
import os
numlist = list(map(int,input.split(',')))
answer = []
fib_series = [0,1,1,2,3,5,8,13]
answer = []
i = 0
while i < len(numlist):
if not numlist[i]:
answer.append(os.path.commonprefix([fib_series,numlist[i:]]))
i += 1
print(answer) #[[0, 1, 1, 2, 3], [0, 1, 1, 2, 3, 5]]
FIB = [0,1,1,2,3,5,8,13]
def checkSequence(numArr):
i = 0
while i < len(numArr):
if FIB[i] == int(numArr[i]):
i += 1
else:
return i
numbers = input("Enter your numbers list and use comma to seperate them: ")
numlist = numbers.split(",")
answer = list()
i = 0
while i < len(numlist):
if int(numlist[i]) == 0:
ret = checkSequence(numlist[i:])
answer.append(numlist[i:i+ret])
i += 1
As you can see, you can quite easily make a CheckSquence method to check the array splice for a squence and return the amount of entries you've found. With the answer from the checkSequence you then can create a splice for your answer list. This produces the results you've specified in your question.
EDIT: You'll need to define the Fibunacci sequence before. You can either use a static sequence like I did, or compute till a certain point and then compair against that result.

Writing a custom sum function that sums a list of numbers

I am new to Python and need some help writing a function that takes a list as an argument.
I want a user to be able to enter a list of numbers (e.g., [1,2,3,4,5]), and then have my program sum the elements of the list. However, I want to sum the elements using a for loop, not just by using the built in sum function.
My problem is that I don't know how to tell the interpreter that the user is entering a list. When I use this code:
def sum(list):
It doesn't work because the interpreter wants just ONE element that is taken from sum, but I want to enter a list, not just one element. I tried using list.append(..), but couldn't get that to work the way I want.
Thanks in anticipation!
EDIT: I am looking for something like this (thanks, "irrenhaus"):
def listsum(list):
ret=0
for i in list:
ret += i
return ret
# The test case:
print listsum([2,3,4]) # Should output 9.
I'm not sure how you're building your "user entered list." Are you using a loop? Is it a pure input? Are you reading from JSON or pickle? That's the big unknown.
Let's say you're trying to get them to enter comma-separated values, just for the sake of having an answer.
# ASSUMING PYTHON3
user_input = input("Enter a list of numbers, comma-separated\n>> ")
user_input_as_list = user_input.split(",")
user_input_as_numbers_in_list = map(float, user_input_as_list) # maybe int?
# This will fail if the user entered any input that ISN'T a number
def sum(lst):
accumulator = 0
for element in lst:
accumulator += element
return accumulator
The top three lines are kind of ugly. You can combine them:
user_input = map(float, input("Enter a list of numbers, comma-separated\n>> ").split(','))
But that's kind of ugly too. How about:
raw_in = input("Enter a list of numbers, comma-separated\n>> ").split(',')
try:
processed_in = map(float, raw_in)
# if you specifically need this as a list, you'll have to do `list(map(...))`
# but map objects are iterable so...
except ValueError:
# not all values were numbers, so handle it
The for loop in Python is exceptionally easy to use. For your application, something like this works:
def listsum(list):
ret=0
for i in list:
ret+=i
return ret
# the test case:
print listsum([2,3,4])
# will then output 9
Edit: Aye, I am slow. The other answer is probably way more helpful. ;)
This will work for python 3.x, It is similar to the Adam Smith solution
list_user = str(input("Please add the list you want to sum of format [1,2,3,4,5]:\t"))
total = 0
list_user = list_user.split() #Get each element of the input
for value in list_user:
try:
value = int(value) #Check if it is number
except:
continue
total += value
print(total)
You can even write a function that can sum elements in nested list within a list. For example it can sum [1, 2, [1, 2, [1, 2]]]
def my_sum(args):
sum = 0
for arg in args:
if isinstance(arg, (list, tuple)):
sum += my_sum(arg)
elif isinstance(arg, int):
sum += arg
else:
raise TypeError("unsupported object of type: {}".format(type(arg)))
return sum
for my_sum([1, 2, [1, 2, [1, 2]]])
the output will be 9.
If you used standard buildin function sum for this task it would raise an TypeError.
This is a somewhat slow version but it works wonders
# option 1
def sumP(x):
total = 0
for i in range(0,len(x)):
total = total + x[i]
return(total)
# option 2
def listsum(numList):
if len(numList) == 1:
return numList[0]
else:
return numList[0] + listsum(numList[1:])
sumP([2,3,4]),listsum([2,3,4])
This should work nicely
user_input = input("Enter a list of numbers separated by a comma")
user_list = user_input.split(",")
print ("The list of numbers entered by user:" user_list)
ds = 0
for i in user_list:
ds += int(i)
print("sum = ", ds)
}
Using accumulator function which initializes accumulator variable(runTotal) with a value of 0:
def sumTo(n):
runTotal=0
for i in range(n+1):
runTotal=runTotal+i
return runTotal
print sumTo(15)
#outputs 120
If you are using Python 3.0.1 or above version then use below code for Summing list of numbers / integer using reduce
from functools import reduce
from operator import add
def sumList(list):
return reduce(add, list)
def oper_all(arr, oper):
sumlist=0
for x in arr:
sumlist+=x
return sumlist
Here the function addelements accept list and return sum of all elements in that list only if the parameter passed to function addelements is list and all the elements in that list are integers. Otherwise function will return message "Not a list or list does not have all the integer elements"
def addelements(l):
if all(isinstance(item,int) for item in l) and isinstance(l,list):
add=0
for j in l:
add+=j
return add
return 'Not a list or list does not have all the integer elements'
if __name__=="__main__":
l=[i for i in range(1,10)]
# l.append("A") This line will print msg "Not a list or list does not have all the integer elements"
print addelements(l)
Output:
45
import math
#get your imput and evalute for non numbers
test = (1,2,3,4)
print sum([test[i-1] for i in range(len(test))])
#prints 1 + 2 +3 + 4 -> 10
#another sum with custom function
print math.fsum([math.pow(test[i-1],i) for i in range(len(test))])
#this it will give result 33 but why?
print [(test[i-1],i) for i in range(len(test))]
#output -> [(4,0), (1, 1) , (2, 2), (3,3)]
# 4 ^ 0 + 1 ^ 1 + 2 ^ 2 + 3 ^ 3 -> 33

Categories