Project Euler – Exercise 1 - python

I am trying to find the sum of all numbers less than 1000 divisible by 3 and 5. I have this so far:
for i in range(0, 1000):
if i % 3 == 0:
print i
elif i % 5 == 0:
print i
b = sum(i)
print b
I get a TypeError: 'int' object is not iterable (referring to b = sum(i))

You could try something like this:
# initially we declare a variable that will hold the current sum
# and at the end of the for it will hold
# the sum of the numbers you have mentioned.
b = 0
for i in range(1000):
# Then whether i is evenly divided by 3 or 5
# we add this number to the current sum
if i % 3 == 0 or i % 5 == 0:
b += i
# last we print the sum
print b

use the following line
sum takes an iterable object as input. List, sets, etc. are iterable.
So try the following
b = sum(i for i in range(1000) if i%3 == 0 or i%5 == 0)

From your code I suppose you need the sum of the numbers which are divisible by 3 or 5. Among all the solutions, another possible one-liner solution is:
print(sum(filter(lambda x: x%3==0 or x%5==0, range(1000))))
Here you get this TypeError because sum function takes a sequence of numbers and returns sum of the sequence. In your code you are passing i as the parameter of sum which is, in you case, an int type object. So you are getting this error.

Related

Happy Number from Python list

i am an absolute Beginner in Python and im trying to, find happy numbers from a given List. but it doesn't give anything back, i searched for a solution but i couldnt find one. My code is this :
a = [1,4,7,82]
def is_happy(a):
for i in range (len(a)):
sum = a[i]
for digit in str(a[i]):
sum = 0
while sum != 1 and sum !=4:
sum = sum + int(digit) ** 2
if sum ==1:
b.append(a[i])
return b
print(is_happy(a))
May you can help me. Thank you!
Converting the integers to strings in order to calculate the sum of squares is not a great idea - better to combine division and modulus. Write a discrete function to do that.
Then write a function that handles one value at a time. Call that multiple times - once for each item in your list.
Here's an approach you could use:
def ss(n):
r = 0
while n > 0:
d = n % 10
r += d * d
n //= 10
return r
def is_happy(n):
if n > 0:
while True:
if (n := ss(n)) == 1:
return True
if n == 4:
break
return False
a = [1, 4, 7, 82]
for n in a:
print(n, is_happy(n))
Output:
1 True
4 False
7 True
82 True
the indents of Python made me suffer..
my solution now looks like:
a = [8,2,7,82]
b = []
def is_happy(a):
for i in range (len(a)):
sum = a[i]
while sum!=1 and sum !=4:
tempsum = 0
for digit in str(sum):
tempsum += int(digit) ** 2
sum = tempsum
if sum == 1:
b.append(a[i])
return b
print(is_happy(a))
and works fine. Thanks for your help and suggestions
Eminos,
I will help with some suggestions.
In Python, white space is very important, and it takes some time for any newbie to get used to.
In for i in range (len(a)):, there is an extra space between "range" and "(". It could still run, but is not the preferred style, since it is defined as a range() function.
Code blocks need consistent spacing (left indent). Each level should be 2 or 4 spaces, with 4 spaces recommended by PEP8 (not tabs). The below examples have too many spaces in left indent.
sum = 0
sum = sum + int(digit) ** 2
b.append(a[i])
To calculate the squre of a number, it is not necessary to change data type from integer to string.
squared = a[i]**2
To keep track of your squared numbers list, try:
tally = 0
for i in range(len(a)):
squared = a[i]**2 # squares each number in list
tally += squared # keeps a running sum of squared numbers
Generally, I think a function like is_happy should return a true/false statement(s). So a sample returned list can be ["True", "False", "True", "True"] for your input example [1, 4, 7, 82].
More work to do, but hope that will get you started. :-)

How to sum even and odd values with one for-loop and no if-condition?

I am taking a programming class in college and one of the exercises in the problem sheet was to write this code:
number = int(input())
x = 0
y = 0
for n in range(number):
if n % 2 == 0:
x += n
else:
y += n
print(x)
print(y)
using only one "for" loop, and no "while" or "if".
The purpose of the code is to find the sum of the even and the sum of
the odd numbers from zero to the number inputted and print it to the
screen.
Be reminded that at this time we aren't supposed to know about
functions.
I've been trying for a long time now and can't seem to find a way of doing it without using "if" statements to know if the loop variable is even or odd.
Purely for educational purposes (and a bit of fun), here is a solution that does not use any for loops at all. (Granted, in the underlying logic of the functions, there are at least five loops.)
num = list(range(int(input('Enter number: '))))
even = num[::2]
odd = num[1::2]
print('Even list:', even)
print('Odd list:', odd)
print('Even:', sum(even))
print('Odd:', sum(odd))
Output:
Enter number: 10
Even list: [0, 2, 4, 6, 8]
Odd list: [1, 3, 5, 7, 9]
Even: 20
Odd: 25
How does it work?
The input() function returns a str object, which is converted into an integer using the int() function.
The integer is wrapped in the range() and list() functions to convert the given number into a list of values within that range.
This is a convention you will use/see a lot through your Python career.
List slicing is used to get every second element in the list. Given the list is based at zero, these will be even numbers.
Slice the same list again, starting with the second element, and get every second element ... odd numbers.
Link to a nice SO answer regarding slicing in Python.
The simply use the sum() function to get the sums.
for n in range(number):
x += (1 - n % 2) * n
y += (n % 2) * n
You asked for a solution with one loop, but how about a solution with no loop?
It is well known that the sum of the numbers from 1 to n is (n+1)*n/2. Thus, the sum of even numbers is 2 * (m+1)*m/2 with m = n//2 (i.e. floor(n/2)). The sum of odd can then be calculated by the sum of all numbers minus the sum of even numbers.
n = 12345
m = n // 2
e = (m+1)*m
o = (n+1)*n//2 - e
Verification:
>>> e, e==sum(i for i in range(n+1) if i % 2 == 0)
38112102 True
>>> o, o==sum(i for i in range(n+1) if i % 2 == 1)
38105929 True
Note: This calculates the sums for number up to and including n.
for n in range(1,number,2):
x += n
y += n-1
print(y)
print(x)
This code has the same output with the example.
Ternary operator:
for n in range(number):
x += (n,0)[n%2]
y += (0,n)[n%2]
I think you are a beginner. I wouldn't like to confuse you with slicing operators complex implementation.
As you mentioned
The purpose of the code is to find the sum of the even and the sum of
the odd numbers from zero to the number inputted and print it to the
screen.
There is no need to find the initial number is odd/even
And your program is wrong if you want to include the input number in calculating the even/odd sum.
Example
Input
5
Expected Output
6
9
Explanation
Even Sum : 2+4 = 6
Odd Sum : 1+3+5 = 9
Your Output
6 4 (wrong output)
The range() function will exclude the number. It will only iterate from 0 to 4 while the input is 5. so if you want to include 5, you should add 1 to the number while passing it in the range() function.
number = int(input())
x = 0
y = 0
for n in range(number+1):
x += (1 - n % 2) * n #this will add 0 if not even
y += (n % 2) * n #this will add 0 if not odd
print(x)
print(y)
There is also mathematical way:
num = int(input("Enter number:"))
odd = ((num+1)/2)**2
even = num*(num+1)/2 - odd
The sum of the first n odd numbers is n^2. To get count of odd numbers we use (num+1)/2. To get sum of even numbers, we could use similar approach, but I preferred, subtracting odd from the sum of the first n numbers, which is n*(n+1)/2.
Here is my 2cents if we are allowed to use numpy.
import numpy as np
number = int(input())
l = np.array(range(number))
print('odd:',sum(l % 2 * l))
print('even:', sum((1- l % 2) * l))
If you're allowed to use a list
number = int( input() )
counts = [ 0, 0 ]
for n in range( number ):
counts[ n % 2 ] += n
print( counts[ 0 ] )
print( counts[ 1 ] )
There's another way which sums the odd and even indices together in the for loop based on the remainder modulo 2:
number = int(input())
odd = 0
even = 0
for i in range(len(number)):
odd += i * (i % 2)
even += i * ((i + 1) % 2)
print (odd, even)
number = 1000000
x = 0
y = 0
[(x:=x+n, y:=y+(n+1)) for n in range(0,number,2)]
print(f'{x}, {y}')
This uses a list comprehension and the new Python assignment operator.
Sum of first n numbers is n(n+1)/2 (Mathematically derived). So if we know the value of n then we can find the sum of all numbers from 1 to n.
If we find the sum of all odd numbers before n and subratract it from the sum of first n we get he sum of all even numbers before n.
Here's the code:
n = int(input("Enter a number: "))
odd = 0
for i in range(1,n+1,2):
odd += i
even = int(n*(n+1)/2) - odd
print("even:",even,"odd:",odd)

Invalid syntax Sum += 1

It says I have invalid syntax at Sum += 1. If my code is incorrect what is a better way to go about counting how many even numbers are in a list?
def countEvens(listOfInts):
'''
- Returns an integer value representing the number of even numbers that
exist in listOfInts.
- Return 0 if listOfInts is not a list type or if no even number exists
in listOfInts.
- Note: elements in listOfInts can contain any data type.
'''
Sum = 0
for x in listOfInts:
if x % 2 == 0:
return Sum += 1
if type(listOfInts) != list:
return 0
In Python you cannot return assignments. And Sum += 1 is an assignment, it assigns Sum + 1 to Sum.
In fact the return isn't just a SyntaxError it's also wrong (in a logical sense), so just remove it:
Sum = 0
for x in listOfInts:
if x % 2 == 0:
Sum += 1
return Sum
Alternatively you can use sum with a generator:
return sum(1 for value in listOfInts if value % 2 == 0)
The syntax error comes from this line, as you say
return Sum += 1
That's because (Sum += 1) is not a valid value to return from a function. It's a separate statement
Keeping your code as close as possible, try this
Sum += 1
return Sum
or, more simply
return Sum+1
As for a more pythonic approach
def countEvens(listOfInts):
return sum( x % 2 == 0 for x in listOfInts )
does the entire thing

What does this line do? (using num and enumerate)

I'm a python beginner, and have been given this code to write out what each line does. Here is the code:
z = [int(input("Enter your nth term sequence ")) for _ in range(12)]
total = sum([num * 8 if i % 2 == 0 else num * 4 for i, num in enumerate(z)])
So, I assume that z is a list, where a user inputs the numbers of the nth term sequence, there are 12 digits which they can enter. The code then finds a sum of the numbers multiplied by 8 if something divided by 2 gives a remainder of 0. I just don't get what ([num * 8 if i % 2 == 0 else num * 4 for i, num in enumerate(z)]) means. I've tried and have attempted to search things up, but it's just too confusing. Please help if possible
The code:
foo = [num * 8 if i % 2 == 0 else num * 4 for i, num in enumerate(z)]
is functionally equivalent to this:
foo = []
for i, num in enumerate(z): # num is element in z, i is index of num
if i % 2 == 0:
foo.append(num*8)
else:
foo.append(num*4)
Then the user calls sum on the result.
Does this answer your question?
EDIT: explain enumerate
You should get used to reading documentation on functions, for example enumerate. After you've read it, if you still don't understand then you should search stackoverflow. For example: A post asking what enumerate is with a good answer
Calling:
for num in z:
i = z.index(num)
# Do stuff
is functionally the same as saying:
for i, num in enumerate(z):
# Do stuff
Lets break this down step by step.
z = [int(input("Enter your nth term sequence ")) for _ in range(12)]
First, your assumption that z is a list is correct. It is generated from a list comprehension. It gets input from a user with input("Enter your nth term sequence ") a total of 12 times using for _ in range(12). So z will be a list of 12 user-input integers (not digits, as it can be any integer, not just 0-9).
Next we have:
total = sum([num * 8 if i % 2 == 0 else num * 4 for i, num in enumerate(z)])
It's immediately clear that we are generating a total from the sum of a list with total = sum([...]). So next we need to figure out the contents of the list generated by the list comprehension.
To make the list comprehension a little bit easier to understand we can add in some parentheses to break up the comprehension into easier to manage parts which we will then handle individually.
(num * 8) if (i % 2 == 0) else (num * 4) for (i, num) in (enumerate(z))
The first three groups are fairly self-explanatory:
num * 8 eight times a number
i % 2 == 0 check if i is even
num * 4 four times a number
So the first half of the list comprehensions returns a value that is eight times a number if i is even or four times that number if it isn't.
So that leaves us with the last half of the list comprehension for i, num in enumerate(z).
Lets discuss enumerate first. Enumerate takes a sequence and numbers each element in that sequence. For example enumerate(['a', 'b', 'c']) would return a list of 2-element tuples [(0, 'a'), (1, 'b'), (2, 'c')].
The for i, num in takes the tuples from enumerate(z) and unpacks each tuple into i and num. So i is the index generated by enumerate and num is the original user input.
TL;DR
z = [int(input("Enter your nth term sequence ")) for _ in range(12)]
total = sum([num * 8 if i % 2 == 0 else num * 4 for i, num in enumerate(z)])
Line 1 gets 12 integers from user input and stores them in z
Line 2 takes those integers, indexes them (starting at 0), and if the index is even multiplies that number by 8, if the index is odd multiplies that number by 4.
Finally line 2 sums all the multiplied user inputs and stores them in total
Well lets break it down. You are storing something to the variable "total".
Then you are taking the Sum of everything inside your parentheses. You run an if statement, saying if i modulus 2(i.e. if it is divisible by two and has no remainder left over) append num(a variable) times 8 to the list z.
else, num times 4 appended to the list z. Its a compact way that they wrote out the statement instead of multiple lines

Can't assign to operator

i = 0
num = 0
while i <= 1000:
if i % 3 and i % 5 == 0:
num + i = num <--- Adding Up Numbers Divisable by 3 & 5...
i += 1
print num
Error:* can't assign to operator (line 5)
Are you sure you don't want:
num = num + i
or equivalently:
num += i
?
Note that this can be done a little easier using sum, range and a generator expression:
sum( x for x in range(0,1000,5) if x % 3 == 0 )
#^only take every 5th element (0, 5, 10, 15 ...)
#^ Also only take elements divisible by 3
If you're planning on running this code on only python 2.x, you can change range to xrange in the above expression. Also, when reading other people's code, you'll sometimes see if x % 3 == 0 written as if not x % 3 in this type of context, but I prefer the first version (it seems a little more explicit to me).
num + i = num <--- Adding Up Numbers Divisable by 3 & 5...
You cannot assign a value to an expression.
Also, why not just add 5 each time and check that it is divisible by 3? You'll already know it is divisible by 5...

Categories