Here's my current code:
def even(x):
if x % 2 == 0:
even = True
else:
even = False
if even is True:
print("Even")
if even is False:
print("Odd")
N=[1,3,2,4]
for x in N:
even(x)
As it is the function takes each input and prints whether it's Even or Odd, very basic.
I gave myself the objective of writing a function/script that will take a list of numbers and spit out something like: "There are 15 even numbers and 8 odd numbers." However, I'm having trouble understanding how to count up a running total of how many times my variable "even" is True or False. Furthermore I don't understand how to then use that variable outside the function. So far my best attempts result in an output like:
There were 1 Odd numbers
There were 1 Odd numbers
There were 1 Even numbers
There were 1 Even numbers
etc... for whatever is in list N.
Whereas what I want is:
There were 2 Odd numbers
There were 2 Even numbers
Can anyone help me learn how to do something like this?
You could use a Counter:
from collections import Counter
c = Counter(x % 2 == 0 for x in lst)
print "There are %d even numbers and %d odd numbers" % (c[True], c[False])
You can use sum() and map():
def even(x):
return (x % 2 == 0)
N = [1,3,2,4,6,8]
n_even = sum(map(even, N))
print(n_even)
# 4
Now even returns True (1) if the number is even and False (0) otherwise. Now simply sum it up and you have the times an even number occurred.
Additionally, you might want to define n_odd as
n_odd = len(N) - n_even
Related
during the Kata on Codewars called 'Find The Parity Outlier' I faced a problem, and have been trying to solve it using dictionary. I pass almost all tests except 4.
Instruction for the Kata is:
You are given an array (which will have a length of at least 3, but could be very large) containing integers. The array is either entirely comprised of odd integers or entirely comprised of even integers except for a single integer N. Write a method that takes the array as an argument and returns this "outlier" N.
The function is:
def find_outlier(integers):
d = dict()
count = 0
count1 = 0
for i in range(len(integers)):
if integers[i] % 2 != 0 :
d['odd'] = integers[i]
else:
d['even'] = integers[i]
for j in range(len(integers)):
if integers[j] % 2 == 0:
count += 1
else:
count1 += 1
if count > count1:
return d['odd']
return d['even']
Test Results:
2 should equal 1
36 should equal 17
36 should equal -123456789
0 should equal 1
So the question is? Why is it so? Can you help me to sort the problem out? Thanks a lot!
I'm not sure what exactly you're referring to with that list of test results. In general though, your method with the dictionary seems like it might be overcomplicating things a bit as well. You shouldn't need to use a dict, and you shouldn't need two for loops either. Here's an alternative solution to this problem using only list comprehension.
def find_outlier(arr):
# input should be an array-like of integers (and length >= 3) with either only one odd element OR only one even element
odd_mask = [n%2 != 0 for n in arr] # boolean array with True in the location(s) where the elements are odd
even_mask = [n%2 == 0 for n in arr] # boolean array with True in the location(s) where the elements are even
N_odd = sum(odd_mask) # number of odd elements in the input
N_even = sum(even_mask) # number of even elements in the input
if N_even == 1: # if even is the 'outlier'...
return arr[even_mask.index(True)] # return the element of the input array at the index we determined we had an even
elif N_odd == 1: # if odd is the 'outlier'...
return arr[odd_mask.index(True)] # return the element of the input array at the index we determined we had an odd
else: # something has gone wrong or the input did not adhere to the standards set by the problem
return None
And even this is technically not as efficient as it could be. Let me know if you try this and whether it solves whatever issue you were experiencing with expected results.
In your code the final part should not be in the else block, nor even in the for loop:
if count > count1:
return d['odd']
return d['even']
Like this is may give a wrong result. For instance, if the first number in the input is odd, and is the only odd one, then this code will return d['even'] which is obviously wrong.
Place these lines after the loop (with correct indentation) and it should work.
However, this problem can be solved without dictionary or extra lists. Have a go at it.
def find_outlier(integers):
parity = integers[-2] % 2
if integers[-1] % 2 != parity:
if integers[0] % 2 != parity:
return integers[-2]
else:
return integers[-1]
for i in integers:
if i % 2 != parity:
return i
I have the following problem statement:
Write a function odd_finder(a,b,c,d,e,f,g,h,i,j) which takes 10 integers as inputs and returns the count of positive odd integers. For instance, if the 10 integers inputted by the user are 1,2,3,4,5,-1,-2,-3,-4,0 then output by the function will be 3 (3 positive odd integers: 1,3 and 5).
I wrote this code:
def odd_finder(a,b,c,d,e,f,g,h,i,j):
count = 0
for number in range(10):
if(number % 2 != 0 & number >= 0):
count = count + 1
print(count)
For the example input, my code prints 5 instead of the correct answer of 3. What is wrong with the code? I'm not sure if the issue is with my range or with the operator for evaluating positive integers as number > 0 prints overall count of 0.
There are some issues with the function you have written:
You are taking values a through j as parameter, but not using them, you are just using the values coming from range(10) which will always be 0 through 9 no matter what are the values passed to the function for a through j.
You are combining the conditions using bitwise and operator &, which has higher precedence than !=, and >=, take a look at precedence table
You are comparing against zero number >= 0 which will be true for number=0, but 0 is not an odd integer.
A modified version of the function would look something like this:
def odd_finder(a,b,c,d,e,f,g,h,i,j):
numbers = (a,b,c,d,e,f,g,h,i,j) #Create a sequence to iterate
count = 0
for number in numbers: #range(10):
if(number % 2 != 0 and number > 0):
count = count + 1
print(count)
OUTPUT:
>>> odd_finder(1,2,3,4,5,-1,-2,-3,-4,0)
3
The first issue is fixed by creating a sequence from the values a through j in order to iterate these values. You can then replace range(10) by iterating numbers
The second issue is fixed by replacing bitwise and operator & by logical and operator
The third issue is fixed by using greater than operator > in place of greater than or equal to >=
I'm trying to write a python function that will sum up all of the elements in a list up to but not including the first even number. The function needs to pass the following tests:
from test import testEqual
testEqual(sum_of_initial_odds([1,3,1,4,3,8]), 5)
testEqual(sum_of_initial_odds([6,1,3,5,7]), 0)
testEqual(sum_of_initial_odds([1, -7, 10, 23]), -6)
testEqual(sum_of_initial_odds(range(1,555,2)), 76729)
I tried the following:
import random
lst = []
def sum_of_initial_odds(nums):
sum = 0
#test if element is odd number - if it's odd, add it to the previous integer
for i in lst:
if i % 2 != 0:
sum = sum + i
return sum
#test if element is even number - if it's even, don't include it and break code
else:
if i % 2 == 0:
break:
I'm currently getting a parse error:
ParseError: bad input on line 11
which is the line:
else:
How else can I write this code so that it adds the elements in a list, but doesn't include the first even number, without getting Parse errors?
You can do this very easily using itertools.takewhile:
>>> import itertools
>>> sum(itertools.takewhile(lambda x: x % 2 == 1, [1,3,1,4,3,8]))
5
takewhile will yield elements from the given sequence while the predicate x % 2 == 1 is True, i.e. it will get you all numbers up to the first even one. And sum, well, sums those values.
You have a few problems:
Indentations, which others have already mentioned
You return sum the first time you hit an odd number; this is so not what you want.
You ignore the input parameter nums and work with the empty global lst.
Your lowest if is redundant: you already know you have an even number when you get here.
In general, stuff partial results into local variables; have a single return at the bottom of your routine.
import random
def sum_of_initial_odds(lst):
sum = 0
#test if element is odd number - if it's odd, add it to the previous integer
for i in lst:
if i % 2 != 0:
sum = sum + i
#test if element is even number - if it's even, don't include it and break code
else:
break
return sum
print sum_of_initial_odds([1,3,1,4,3,8]) == 5
print sum_of_initial_odds([6,1,3,5,7]) == 0
print sum_of_initial_odds([1, -7, 10, 23]) == -6
print sum_of_initial_odds(range(1,555,2)) == 76729
THe output from this is four True values.
You could also use
def sum(numbers):
sum = 0
for number in numbers:
if number % 2 == 0:
break
else:
sum += number
return sum
And test using the asset statement which is a specialized form of raise statement
The advantage is that it throws AssertionError only when __debug__ is true thus avoiding throwing exception in production.
assert sum([1,3,1,4,3,8]) == 5 , "Your message if assertion fails"
You can turn off __debug__ by
Start interactive mode with python -O
Setting variable PYTHONOPTIMIZE to True
I have written this short function to calculate the number of factors a number has as a part of my program, however I have noticed that it does not work in certain cases.
Here is my code:
def divisors(n):
number_of_factors = 0
max_test_num = int(math.ceil(math.sqrt(n))+1)
for i in xrange(1,max_test_num):
if n%i ==0:
number_of_factors += 2
if i*i == n:
number_of_factors -= 1
return number_of_factors
Now if the number has a pair of divisors which are coprime, then the result returned is 2 too big.
For example, with input as 20, it returns 8, when the correct answer is 6.
Any suggestions on how to fix this or simply a better way to do this?
Thanks in advance
max_test_num = int(math.ceil(math.sqrt(n))+1)
This makes you count elements twice, for example, with 20: ceil(sqrt(20))+1 = 5, so the condition if n%i ==0 applies for both 4 and 5, and for each you increase by 2.
The +1 in the mentioned line is redundant, remove it.
I was told to solve a problem in which I would have to find out the number of 4-digit numbers which are all composed of odd digits. I tried the following python code:
new_list =[] # A list which holds the numbers
for a in range(1111,10000):
for b in str(a):
if int(b) % 2 == 1:
new_list.append(a)
print len(new_list)
However, it has a flaw in the second loop's if statement which only checks if the current digit is odd and it also caused the digits to be added multiple times, not to mention they didn't meet the criteria. So how do I solve this problem using python? And if you could write a function that checks if all the numbers of a list(argument) are composed of numbers which consist of only odd/even digits, it would be great too.
Edit: I also need a list of the numbers, that's why multiplication can't do all of the work.
A 4 digit number that is composed only of odd digits can only use the digits 1, 3, 5, 7 and 9. That gives you 5 to the power 4 is 625 different numbers. That didn't require trying them all out.
You can still do that of course, using itertools.product() for example:
from itertools import product
print sum(1 for combo in product('13579', repeat=4))
because product('13579', repeat=4) will produce all possible combinations of 4 characters from the string of odd digits.
Your code needs to test if all digits are odd; break out early if any digit is not odd:
new_list =[] # A list which holds the numbers
for a in range(1111,10000):
for b in str(a):
if int(b) % 2 == 0:
break
else:
# only executed if the loop wasn't broken out of
new_list.append(a)
You could use the all() function with a generator expression for that test too:
new_list = []
for a in range(1111,10000):
if all(int(b) % 2 == 1 for b in str(a)):
new_list.append(a)
which then can be collapsed into a list comprehension:
new_list = [a for a in range(1111,10000) if all(int(b) % 2 == 1 for b in str(a))]
I believe something like this would work if you're looking to model what you already have, but I echo the comment by yotommy that some intuitive multiplication would do the trick.
for a in range(1111,10000):
allOdd = True
for b in str(a):
if int(b) % 2 == 0:
allOdd = False
if(allOdd):
new_list.append(a)
You could try something like this
def isAllOdd(num):
if num < 10: return num % 2 == 1;
return isAllOdd(num % 10) and isAllOdd(int(num / 10))
for i in range(1000,3001):
s=str(i)
if (int(s[0])%2==0 and int(s[1])%2==0 and int(s[2])%2==0 and int(s[3])%2==0):
print(i,end=",")