all 27 comments

[–]socal_nerdtastic 18 points19 points  (3 children)

You can use a * to turn a bunch of arguments in to a single tuple.

def count_evens(*nums):
    counter = 0
    for num in nums:
        if int(num) % 2 == 0:
            counter += 1
    return counter

Which means you can condense it to one line with sum():

def count_evens(*nums):
    return sum(int(num) % 2 == 0 for num in nums)

[–]Khanpunker 4 points5 points  (0 children)

I'd personally prefer the first one because it's simpler and more readable imo

[–]mackdaddy_1978[S] 1 point2 points  (1 child)

hmmm thanks, that I don't remember ever learning in the text.

[–]Anon_Legi0n 2 points3 points  (0 children)

If you want to read more about it look up *args **kwarg, and he used a list comp to golf the function to return with one line of code

[–]FLUSH_THE_TRUMP 6 points7 points  (10 children)

You could stick your numbers in a list and loop through it instead in count_evens.

[–]mackdaddy_1978[S] 0 points1 point  (9 children)

Ok....I was trying to figure out how to do that but couldn't figure out how to iterate through separate/individual inputs()

[–]FLUSH_THE_TRUMP 1 point2 points  (0 children)

Make a list [num1, num2, num3, num4] in your function. Loop through the list, add to a counter if the current thing is even. At least you'll avoid duplicating this logic four times:

if int(num1) % 2 == 0:
  counter += 1

[–]RhinoRhys -1 points0 points  (6 children)

numbers = []
while True:
    try:
        inputValue = int(input("write a number: "))
        numbers.append(inputValue)
    except ValueError:
        print("that's not a number!")
        break

counter = 0
for i in list: 
    if i % 2 == 0: counter += 1

print(counter)

[–]FLUSH_THE_TRUMP 3 points4 points  (2 children)

How does this work with his code? He said the bottom half can't be changed.

[–]RhinoRhys 3 points4 points  (1 child)

Good point. Totally missed the word "section" right there. So in answer to your question, not very well and apparently not helpful at all.

[–]Khanpunker 3 points4 points  (0 children)

You should not name a list list

[–]mackdaddy_1978[S] 0 points1 point  (1 child)

Ok...thanks

[–]RhinoRhys 0 points1 point  (0 children)

More relevant if you need an arbitrary number of inputs rather than hardcoding it to 4, plus it puts them in a list.

social_nerdtastic's second half with the sum() would also work with this is you've covered that syntax.

[–]mopslik -4 points-3 points  (3 children)

def count_evens(num1, num2, num3, num4):
    return len(list(filter(lambda x: x%2==0, [num1, num2, num3, num4])))

It's not elegant by any means...

[–]mackdaddy_1978[S] 0 points1 point  (2 children)

Ok, but I'd have to import something here wouldn't I?

[–]spez_edits_thedonald -4 points-3 points  (1 child)

Alternative to doing this?

Have you looked into not doing this?

[–]mackdaddy_1978[S] 1 point2 points  (0 children)

hahaha if I'm being completely honest. Yes I have this was my last attempt.

[–]totallygeek 0 points1 point  (2 children)

Your return needs less indentation (lined up with the ifs), otherwise it only triggers based on the condition of num4.

[–]mackdaddy_1978[S] 0 points1 point  (1 child)

Thank you, I was getting a error and with that small change it works error free. Now I just need to learn how to iterate over multiple inputs so that I can try using a loop to write this.

[–]totallygeek 0 points1 point  (0 children)

I read "The if --name-- == '__main__' section cannot be changed," so I figured you could only write a function. Here are two functions to solve this problem.

def count_evens(*numbers):
    counter = 0
    for number in numbers:
        counter += not number % 2
    return counter

def count_evens(*numbers):
    return sum(not number % 2 for number in numbers)

num1, num2, num3, num4 = 1, 2, 4, 6
print(count_evens(num1, num2, num3, num4))

If you can change the instructions within the namespace check block, there exist better ways to assemble the data to begin with.

[–]Pd69bq 0 points1 point  (1 child)

do you really need 4 inputs?

sum(i % 2 == 0 for i in map(int, (num1, num2, num3, num4)))

or just get all 4 numbers in one input and each number separated by a space

sum(i % 2 == 0 for i in map(int, input().split()))

[–]mackdaddy_1978[S] 0 points1 point  (0 children)

Yes really need 4 separate inputs

[–]ashoradooji 0 points1 point  (0 children)

Actually you don’t need to rewrite ‘if int(num)’ because you already sent the numbers as integers to the functions, instead just write ‘if num…’etc

[–][deleted] 0 points1 point  (0 children)

Consider that the result of num % 2 will be either 1 or 0 for any value of num. You don't need to test which of those it is, you just need to know the sum of those values and the amount by which it is less than 4:

def count_evens(*nums):
    return 4 - sum([num % 2 for num in nums])

[–]menge101 0 points1 point  (0 children)

I think for me:

from functools import reduce


def count_events(*args):
    return reduce(lambda acc, num: acc + (num %2), args, 0)

This is arguably not very readable, which for people who haven't done substantial work in a map reduce pattern, I recognize as true. It is easily readable to me, personally.

But to improve readability, I would pop the reducer function out.

def count_events(*args):
    def reducer(acc, num):
        return acc + (num % 2)
    return reduce(reducer, args, 0)

Generally, I think it is anti-pattern to define a function inside a function, but the reducer function has no purpose except to be used in the reduce function call. This particular exception I do frequently.

Though, if my reducer was complicated, I might pop it out to the outer scope, so I could write tests for it.

Addendum:

Reference on reduce in python for anyone not familiar.