Write a function div_3_5(start, end) that computes the number of integers from start up to, but not including end that are divisible by 3 or 5 using a while loop.
NOTE: I must use a while loop inside a function for this exercise (i understand that a for loop is best).
Examples:
div_3_5(7, 27) evaluates to 9 ( numbers divisible by 3 or 5 in that range: 9,10,12,15,18,20,21,24,25)
I really don't understand why or what I'm doing and can someone to explain where i went wrong.
This is my code so far:
count = 0
def div_3_5(start, end):
while start < end:
if start%3 == 0 or start%5 == 0:
count + 1
start = start + 1
start + 1
return count
This obviously isn't complete or correct and the current error I'm getting is:
Expected Output:
div_3_5(7, 27) -> 9
Test Result: 0 != 9
There a few tips that would help here.
The mod operation % will return the remainder of an object so it a number is divisible by another the mod will be 0, for example 6 % 3 == 0 returns true.
A while loop isn't the best for this opertation, better would be a for loop
for i in range(start, end+1):
This wil fix the infinite loop.
This is how I would write it:
def div_3_5(start, end):
count = 0
for i in range(start, end + 1):
if i % 3 == 0 or i % 5 == 0:
count += 1
return count
start = 1
end = 10
count = div_3_5(start, end)
print(count)
Python has a modulus operator (%) which returns the remainder of A/B (10%4 == 2).
In your case, you would be looking for numbers which have a remainder of 0 when divided by 3 or 5
(i.e x%3 == 0 OR x%5 == 0).
Finally, the last elif where you ask elif start >= end is unnecessary because you stated that as the condition when you created the loop. Instead, try replacing those 2 lines with start = start + 1
The answer i found was:
def div_3_5(start, end):
count = 0
while start < end:
if start % 3 == int() or start % 5 == int():
count += 1
start = start + 1
return count
You need no loops to accomplish this task, here is simple -and fun- mathematical method that Python allows us to implement easily:
- One, create a set from 0 to the end with steps of 3s, i.e. {0,3,6,...end} this will get you all the elements that are divisible 3 within the boundary of your end (while keeping the end not included), in Python, this is done this way: set_of_3=set(range(0,b,3)) simple eh?
- Two, do the same but for the 5s, set_of_5=set(range(0,b,5))
- Three, add these sets together: set_of_all=set_of_3.union(set_of_5)
Now you got all the elements divisible by 3 and 5 from 0 to end, but you don't want that, you want from beginning to end, simply, just remove all numbers from 0 to your beginning from the set_of_all, by: result = set_of_all - set(range(0,a)) and just return the len() of that result. Your complete code:
def div_3_5(start,end):
set_of_3 = set(range(0,end,3))
set_of_5 = set(range(0,end,5))
set_of_all = set_of_3.union(set_of_5)
result = set_of_all - set(range(0,start))
return len(result)
A bit convoluted I know, but fun! At least for me. Hope this helps.
EDITED
Yeah I didn't notice you said you must use while loop, you can do this version of your code:
def div_3_5(start,end):
list = []
while start<end:
if start%3==0 or start%5==0:
list.append(start)
start+=1
return len(list)
Use the power of Python and forget these C-ish methods, and regarding what is wrong with your code, the line:
count + 1 doesn't work in Python, you have to do this: count+=1
Related
So I am new to recursion and I am trying to make a program where you can enter a list and python tests each integer (lets say 9 for example) and sees if the integer following it is doubled. So if I entered a list of 2 4 8 16 32, would return 4, and -5 -10 0 6 12 9 36, would return 2 because -5 followed by -10 is one and 6 followed by 12 is the second. This is the code I have so far. I feel like I am very close. but just a few thing stand in my way. Any help would be great!
L = []
def countDouble(L):
x = input(f'Enter a list of numbers separated by a space: ')
y = (x.split(' '))
print(y[1])
print(y[0])
count = 0
y[0] += y[0]
# unsure of how to multiple y[0] by 2
if y[0]*2 == y[1]:
count += 1
else:
count += 0
#how would I traverse through the rest of the entered list using recursion?
print(count)
countDouble(L)
If you want/need to solve it using recursion, the following will do the trick:
def count_sequential_doubles(li, count=0):
return count_sequential_doubles(li[1:], count + int(li[0] * 2 == li[1])) if len(li) > 1 else count
I would suggest this recursive way:
def countDouble(L):
count = 0
if len(L) == 1:
return count
else:
if int(L[0])*2 == int(L[1]):
count += 1
return count + countDouble(L[1:])
x = input(f'Enter a list of numbers separated by a space: ')
y = (x.split(' '))
count = countDouble(y)
print(count)
I urge you to read the entire answer, but in case you are not interested in tips, notes and the process of finding the solution, here are two solutions:
solution using recursion (not recommended):
x = input()
y = x.split(' ')
count = 0
def countDouble(i):
if(i+1 == len(y)):
return 'recursion ends here when'
if(int(y[i])*2==int(y[i+1])):
count += 1
countDouble(i+1)
countDouble(0)
print(count)
this solution just imitates a while loop:
solution using a while loop (recommended):
x = input()
y = x.split(' ')
count = 0
i = 0
while(i < len(y) - 1):
if(int(y[i]) * 2 == int(y[i+1])):
count += 1
i += 1
print(count)
Before I continue, here are a few tips and notes: (some of them will only make sense after)
I assume the 14 in your example is a typo
I didn't put the code in a function because it's not needed, but you can change it easily.
In your code, you are passing L as a parameter to the countDouble() function, but you don't use it. if you don't need a parameter don't pass it.
when splitting the input, the values of the list are still strings. so you have to invert them to integers (for instance, you can do that with the int() 'function') before comparing their values - otherwise multiplying by 2 will just repeat the string. for example: '13'*2 is the string '1313'
I don't know why you why you added y[0] to itself in line 9, but based on the code that comes after this would yield incorrect results, you don't need to change the elements in order to get their value multiplied by 2.
notice that in the else block, nothing has changed. adding 0 to the count doesn't change it. so you can remove the else block entirely
While it's possible to solve the problem in recursion, there's something else designed for these kind of problems: loops.
The problem is essentially repeating a simple check for every element of a list.
This is how I would arrive to a solution
so we want to run the following 'code':
if(y[0]*2 == y[1]):
count += 1
if(y[1]*2 == y[2]):
count += 1
if(y[2]*2 == y[3]):
count += 1
...
of course the computer doesn't understand what "..." means, but it gives us an idea to the pattern in the code. now we can do the following:
divide the extended 'code' into similar sections.
identify the variables in the pattern - the values that change between sections
find the starting values of all variables
find a pattern in the changes of each variable
find a breaking point, a condition on one of the variables that tells us we have reached the last repeating section.
here are the steps in this specific problem:
the sections are the if statements
the variables are the indexes of the elements in y we compare
the first index starts at 0 and the second at 1
both indexes increase by one after each if-statement
when the second index is bigger then the last index of y then we already checked all the elements and we can stop
so all is left is to set the needed variables, have a while loop with the breaking condition we found, and in the while loop have the general case of the repeating sections and then the changing of the variables.
so:
x = input(f'Enter a list of numbers separated by a space: ')
y = (x.split(' '))
count = 0
# setting the starting values of the variables
index1 = 0
index2 = 1
# creating a loop with the breaking condition
while(index2 < len(y)):
# the general case of the repeated code:
if(int(y[index1]) * 2 == int(y[index2])):
count += 1
# changing the variables for the next loop
index1 += 1
index2 += 1
print(count)
We see that the index2 is just index1 + 1 at all time. so we can replace it like that:
x = input(f'Enter a list of numbers separated by a space: ')
y = (x.split(' '))
count = 0
index1 = 0
while(index1 + 1 < len(y)):
if(int(y[index1]) * 2 == int(y[index1 + 1])):
count += 1
index1 += 1
print(count)
Note: You can use a for loop similarly to the while loop
So in summary, you can use recursion to solve the problem, but the recursion would just be imitating the process of a loop:
in each call, the breaking condition will be checked, the repeated code would run and the variables/parameters would change.
Hope you find this answer useful :)
Final edit: OP edited his example so my other code didnt apply
Some good questions people are asking, but in the spirit of helping, here's a recursive function that returns the count of all doubles.
def get_doubles_count_with_recursion(a_list, count, previous=None):
while a_list:
try:
first = previous if previous else a_list.pop(0)
next_item = a_list.pop(0)
except IndexError:
return count
if next_item / 2 == first:
count += 1
return get_doubles_count_with_recursion(a_list, count, next_item)
return count
a_list = [1, 3, 5, 10, 11, 14, 28, 56, 88, 116, 232, 464, 500]
doubles = get_doubles_count_with_recursion(a_list, 0)
print(doubles == 5)
Probably could clean it up a bit, but it's a lot easier to read than the other guy's ;)
If I'm reading your question right, you want a count of all pairs where the 2nd item is double the first. (and the 14 in the first list is a typo). In which case a simple function like this should do the job:
#a = [2,4,8,16,32]
a = [-5, -10, 0, 16, 32]
count = 0
for i, x in enumerate(a):
# Stop before the list overflows
if i < len(a) - 1:
# If the next element is double the current one, increment the counter
if a[i+1] == x * 2:
count = count + 1
else:
break
print(count)
I am attempting to create a function that sums all even numbers from "Start" to "End".
I have written the following code, and need to use a while loop. When I run the program, it is not returning anything. Thanks for the help.
def sum_of_even_num(start,end):
sum = 0
while start <= end:
if(start % 2 == 0):
sum = sum + start
start = start + 1
return sum
print("sum_of_even_num(1,10) =",sum_of_even_num(1,10))
You can simplify your code by ensuring start is even to begin with, and then just incrementing it by 2:
def sum_of_even_num(start,end):
sum = 0
start += start % 2
while start <= end:
sum += start
start += 2
return sum
And the mandatory list comprehension:
def sum_of_even_num(start,end):
return sum(i for i in range(start + (start % 2), end + 1, 2))
In the while loop, you only add 1 to start when its a even number, but not when its a odd number, so it starts at 1, which is odd and never reaches 2. So move the start = start + 1 outside the if statement
def sum_of_even_num(start,end):
sum = 0
while start <= end:
if(start % 2 == 0):
sum += start
start += 1
return sum
print("sum_of_even_num(1,10) =",sum_of_even_num(1,10))
Write a function that takes an array/list of numbers and returns a number.
See the examples and try to guess the pattern:
even_odd([1,2,6,1,6,3,1,9,6]) => 393
even_odd([1,2,3]) => 5
even_odd([0,2,3]) => 3
even_odd([1,0,3]) => 3
even_odd([3,2]) => 6
def even_odd(arr):
count = 0
index = 0
length = len(arr)
while index < length:
for num in range(len(arr)):
if arr[index] % 2 != 0:
count += arr[index]
index += 1
else:
count *= arr[index]
index += 1
return count
So basically the pattern is multiply the first 2 numbers and add the third and I set it to where for each index value if it it was the first number I would add it to the count to keep track and then multiply it with the second number and then add the third. I passed 3/4 sample cases except for one which was the first one ---> even_odd([1,2,6,1,6,3,1,9,6]) => 393. I am just wondering what is the flaw with my logic and does anyone have a better way to solve this that is efficient and clean.
Your question is a challenge on Codewars (https://www.codewars.com/kata/559e708e72d342b0c900007b), so maybe you should use this platform to discuss solutions with other competitiors, instead of Stackoverflow.
The main point of this challange is to investigate the calculated pattern and not the code itself.
If you know the required pattern, the code is easy (Spoiler!):
def even_odd(arr):
num = 0
for i, e in enumerate(arr):
if (i % 2) == 0:
num += e
else:
num *= e
return num
This produces the desired results:
from operator import add, mul
def even_odd(nums):
acc = nums[0] # accumulator
ops = [mul, add]
i = 0
for num in nums[1:]:
acc = ops[i](acc, num)
i = 1 - i # alternates between the two operators
return acc
New to coding and am trying to solve this coding problem to learn.
Prompt:
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. Find the sum of all the multiples of 3 or 5 below 1000.
three = []
five = []
def threeList():
n = 1
while (n*3<1000):
result = n*3
three.append(result)
n += 1
return three
def fiveList():
n = 1
while (n*5<1000):
result = n*5
five.append(result)
n += 1
return five
threeList()
fiveList()
print(three,five)
This results in printing [3] [5] to the console.
Your return is part of the loop which means that at the end of iteration, instead of doing another iteration you just return from the function. Move it out of a loop, i.e.:
def threeList():
n = 1
while (n*3<1000):
result = n*3
three.append(result)
n += 1
return three
Also this return makes little sense, because you are returning global variables. No point to return something that is already available (I suggest you read about variable scope), so it's safe to get rid of these returns completely:
def threeList():
n = 1
while (n*3<1000):
result = n*3
three.append(result)
n += 1
In fact, as both your functions differ very little, you should refactor your code and have just one function accepting the multiplier (as this is the only difference) and return populated list. This time we go with local variable to create the result list, so this time you need to return it otherwise result list will not be available outside the function:
def my_func(multiplier):
result = []
n = 1
while (n*multiplier < 1000):
result.append(n*multiplier)
n += 1
return result
and then replace
threeList()
fiveList()
with
three = my_func(3)
five = my_func(5)
In fact, you could merge this with print() as there's no other use for three and five, so your final code would then look like this:
def my_func(multiplier):
result = []
n = 1
while (n*multiplier < 1000):
result.append(n*multiplier)
n += 1
return result
print(my_func(3), my_func(5))
In addition to Marcin's fantastic answer, note that you can also do the math for which elements to use ahead of time and avoid the while loop entirely. range is your friend here.
multiples_of_five = range(5, 1001, step=5)
multiples_of_three = range(3, 1001, 3)
Since range's stop is exclusive, but we want all the multiples of three and five up to 1000 inclusive, we have to stop at 1001 instead. This simplifies the my_func that Marcin lays out above.
def list_multiples(n):
result = []
for i in range(n, 1001, n):
result.append(i)
return result
Though if we examine this more closely, you'll see we're basically just casting to list and returning. Let's do that directly.
def list_multiples(n):
return list(range(n, 1001, n))
From there we can find the multiples of five and multiples of three
fives = list_multiples(5)
threes = list_multiples(3)
Cast to set to remove duplicates (15 is a multiple of both 5 and 3, but shouldn't be summed twice)
all_nums = set(fives + threes)
And sum the result
result = sum(all_nums)
To solve your problem in Pythonic way, use sum() with a generator expression like:
Code:
sum(i for i in range(1000) if i % 5 == 0 or i % 3 == 0)
Test Code:
max_num = 1000
print(sum(i for i in range(max_num) if i % 5 == 0 or i % 3 == 0))
Results:
233168
I've been trying to find how do I do check the length of integer using recursion. For example: 100, it will say that there's 3 number. 12, it will say that there's 2 number.
What I've saw online is all about the summation of the last digit. I couldn't source for help on the length of an integer.
can someone help me out on this?
I've tried to use lens to count, but my output is always 0.
def num(x):
if x == 0:
return 0
else:
return num(x / 10)
print len(str(num(100)))
I've also tried this
def num(x):
if x == 0:
return 0
else:
return num(x / 10) + len(str(x % 10))
print num(100)
You need to add 1 with num(N/10) if N is not 0 :
>>> def num(N):
... if N==0:
... return 0
... return 1+num(N/10)
...
>>> num(100)
3
This code will add ones in each calling the function with N/10 until it get to 0, so at the end based on what time your number can bi divide by 10 you'll have 1's which have been sum together, and at last for 0 they eill be add with 0.
For example for 100 your function will do the following :
1+(100/10)
^
1+1+(10/10)
^
1+1+1(1/10)
^
1+1+1+0
Are you looking for this -
def numlen(i):
if i:
return numlen(i//10) + 1
return 0