I want to take user input and add each number up to 0. For example user inputs 9 I want to add 9+8+7+6.... +1 and output the total. My code
def main(*args):
sum = 0
for i in args:
sum = i + (i - 1)
return sum
result = main(9)
print(result)
comes close, but I can't get it to iterate through until 0. I've tried adding ranges in a few ways but no luck there. I'm stuck.
Let's say the user input is assigned to x, then the most simplistic answer is:
sum(range(int(x)+1))
Note that range() will generate a list (actually, an immutable sequence type in Python 3) of numbers up to, but not including, x, hence the +1.
In terms of your original code, there are a few issues. First, you should avoid naming variables the same as Python built-ins, such as sum. Second, you are attempting to iterate through a tuple of input arguments (e.g. args = (9,) in your case), which will perform 9 + (9-1), or otherwise 17 and then return that sum as an output.
Instead, you could do something like:
def main(*args):
mysum = 0
for i in range(args[0]+1):
mysum = mysum + i
return mysum
result = main(9)
print(result)
Both solutions here will return 45.
Nth triangle number. No iteration needed.
def calculate_nth_triangle_number(value):
return value * (value + 1) / 2
Your code misuses a relatively advanced feature of Python, that is argument packing, where all the arguments supplied to a function are packed in a tuple.
What happens when you call main(9)? the loop is entered once (because calling the function with a single argument is equivalent to args = (9, ) in the body of the function) i takes only one value, i = 9 and you have sum = 9+8 = 17.
For your case I don't like a for loop, can you use a while loop? with a while your function follows exactly the definition of your task!
def my_sum(n):
result = 0
while n>0:
result = result + n
n = n - 1
return result
Note that the order of summation and decrease is paramount to a correct result... note also that sum is the name of a built-in function and it is considered bad taste to overload a built-in name with an expression of yours.
Related
I'm given the task to define a function to find the largest pyramidal number. For context, this is what pyramidal numbers are:
1 = 1^2
5 = 1^2 + 2^2
14 = 1^2 + 2^2 + 3^2
And so on.
The first part of the question requires me to find iteratively the largest pyramidal number within the range of argument n. To which, I successfully did:
def largest_square_pyramidal_num(n):
total = 0
i = 0
while total <= n:
total += i**2
i += 1
if total > n:
return total - (i-1)**2
else:
return total
So far, I can catch on.
The next part of the question then requires me to define the same function, but this time recursively. That's where I was instantly stunned. For the usual recursive functions that I have worked on before, I had always operated ON the argument, but had never come across a function where the argument was the condition instead. I struggled for quite a while and ended up with a function I knew clearly would not work. But I simply could not wrap my head around how to "recurse" such function. Here's my obviously-wrong code:
def largest_square_pyramidal_num_rec(n):
m = 0
pyr_number = 0
pyr_number += m**2
def pyr_num(m):
if pyr_number >= n:
return pyr_number
else:
return pyr_num(m+1)
return pyr_number
I know this is erroneous, and I can say why, but I don't know how to correct it. Does anyone have any advice?
Edit: At the kind request of a fellow programmer, here is my logic and what I know is wrong:
Here's my logic: The process that repeats itself is the addition of square numbers to give the pyr num. Hence this is the recursive process. But this isn't what the argument is about, hence I need to redefine the recursive argument. In this case, m, and build up to a pyr num of pyr_number, to which I will compare with the condition of n. I'm used to recursion in decrements, but it doesn't make sense to me (I mean, where to start?) so I attempted to recall the function upwards.
BUT this clearly isn't right. First of all, I'm sceptical of defining the element m and pyr_num outside of the pyr_num subfunction. Next, m isn't pre-defined. Which is wrong. Lastly and most importantly, the calling of pyr_num will always call back pyr_num = 0. But I cannot figure out another way to write this logic out
Here's a recursive function to calculate the pyramid number, based on how many terms you give it.
def pyramid(terms: int) -> int:
if terms <=1:
return 1
return terms * terms + pyramid(terms - 1)
pyramid(3) # 14
If you can understand what the function does and how it works, you should be able to figure out another function that gives you the greatest pyramid less than n.
def base(n):
return rec(n, 0, 0)
def rec(n, i, tot):
if tot > n:
return tot - (i-1)**2
else:
return rec(n, i+1, tot+i**2)
print(base(NUMBER))
this output the same thing of your not-recursive function.
I'm currently taking a course in Computer Science, I got an assignment to use either Python or pseudocode to ask the user to enter a digit, then divide it by 2, and then count how many divisions it takes to reach 1 (and add 1 more as it reaches 1). I've never coded before but I came up with this; but it only returns a 1 no matter what I input.
def divTime (t):
if d <= 1:
return t + 1
else:
return t + 1, divTime(d / 2)
d = input("Enter a number:")
t = 0
print (divTime)(t)
You can add 1 to the recursive call with the input number floor-divided by 2, until the input number becomes 1, at which point return 1:
def divTime(d):
if d == 1:
return 1
return 1 + divTime(d // 2)
so that:
print(divTime(1))
print(divTime(3))
print(divTime(9))
outputs:
1
2
4
This works:
def div_time(d, t=0):
if d < 1:
return t
else:
return div_time(d/2, t+1)
d = input("Enter a number:")
print(f"t = {div_time(int(d))}")
It always returns 1 because you're always passing it 0.
It looks like you're "thinking in loops" – you don't need a separate counter variable.
How many times does it take to divide:
k smaller than 2? None.
k greater than or equal to 2? One more than it takes to divide k // 2.
That is,
def divTime(x):
if x < 2:
return 0
return 1 + divTime(x // 2)
or
def divTime(x):
return 0 if x < 2 else 1 + divTime(x //2)
Instead of providing a straight forward answer, I'll break the problem out into a few steps for students:
Ignore the input and edge cases for now, let's focus on writing a function that solves the problem at hand, then we may come back to providing an input to this function.
Problem statement confusion - You will often divide an odd number with a remainder, skipping the exact number 1 due to remainders. There is ambiguity with your problem from dealing with remainders - we will reword the problem statement:
Write a function that returns the number of times it takes to divide an input integer to become less than or equal to 1.
The next part is identifying the type of algorithm that can solve this type of problem. Since we want to run the function an unknown amount of times using the same function, this seems to be a perfect use case of recursion.
Say I provide 10 as an input. We then want to say 10/2=5 (count 1), 5/2=2.5 (count 2), 2.5/2=1.25 (count 3), 1.25/2=0.625 (count 4), return [4] counts.
Now we know we need a counter (x = x+1), recursion, and a return/print statement.
class solution:
''' this class will print the number of times it takes to divide an integer by 2 to become less than or equal to 1 '''
def __init__(self):
#this global counter will help us keep track of how many times we divide by two. we can use it in functions inside of this class.
self.counter=0
def counter_2(self, input_integer):
#if the input number is less than or equal to 1 (our goal), then we finish by printing the counter.
if input_integer<=1:
print(self.counter, input_integer)
#if the input is greater than 1, we need to keep dividing by 2.
else:
input_integer=input_integer/2
#we divided by two, so make our counter increase by +1.
self.counter=self.counter+1
#use recursion to call our function again, using our current inputer_integer that we just divided by 2 and reassigned the value.
self.counter_2(input_integer)
s=solution()
s.counter_2(10)
My code is as follows.
I tried coding out for each case first, so given n = 4, my code looks like this:
a = overlay_frac(0,blank_bb,scale(1/4,rune))
b = overlay_frac(1/4,blank_bb,scale(1/2,rune))
c = overlay_frac(1/2,blank_bb,scale(3/4,rune))
d = overlay_frac(3/4,blank_bb,scale(1,rune))
show (overlay(a,(overlay(b,(overlay(c,d))))))
My understanding is that the recursion pattern is:
a = overlay_frac((1/n)-(1/n),blank_bb,scale(1/n,rune))
b = overlay_frac((2/n)-(1/n),blank_bb,scale(2/n,rune))
c = overlay_frac((3/n)-(1/n),blank_bb,scale(3/n,rune))
d = overlay_frac((4/n)-(1/n),blank_bb,sale(4/n,rune))
Hence, the recursion pattern that I came up with is:
def tree(n,rune):
if n==1:
return rune
else:
for i in range(n+1):
return overlay(overlay_frac(1-(1/n),blank_bb,scale(i/n,rune)),tree(n-1,rune))
When I hardcode this, everything turns out just fine, but I suspect I'm not doing the recursion properly. Where have I gone wrong?
You are in fact trying to do an iteration within a recursive call. In stead of using loop, you can use an inner function to memorize your status. The coefficient you defined is actually changed with both n and i, but for a given n it changed with i only. The status you need to memorize with inner function is then i, which is the same as you looping through i.
You can still achieve your goal by doing so
def f(i, n):
return overlay_frac((i/n)-(1/n),blank_bb,scale(i/n,rune))
# for each iteration, you check if i is equal to n
# if yes, return the result (base case)
# otherwise, you apply next coefficient to the previous result
# you start with i = 0 and increase by one every iteration until i reach to n (base case)
# notice how similar this recursive call looks like a loop
# the only difference is the status are updated within the function call itself
# therefore you will not have the problem of earlier return
def recursion(n):
def iteration(i, out):
if i == n:
return out
else:
return iteration(i+1, overlay(f(n-1, n), out))
return iteration(0, f(n, n))
Here, n is assumed to be the times of overlay you want to apply. When n = 0, no function applied on the last coefficient f(n, n). When n = 1, the output would be overlay applied once on coefficient with i = n - 1 and coefficient with i = n.
This way avoids the earlier return inside your loop.
In fact you can omit the inner function by adding additional argument to your outer function. Then you need to assign the default initial i. The inner function is not really necessary here. The key is to use the function argument to memorize the status (variable i in this case).
def f(i, n):
return overlay_frac((i/n)-(1/n),blank_bb,scale(i/n,rune))
def recursion(n, i=0):
if i == n:
return f(n, n)
else:
return overlay(f(n-1, n), recursion(n, i+1))
Your first two code blocks don't correspond to the same operations. This would be equivalent to your first block (in Python 3).
def overlayer(n, rune):
def layer(k):
# Scale decreases linearly with k
return overlay_frac((1 - (k+1)/n), blank_bb, scale(1-k/n, rune))
result = layer(0)
for i in range(1, n):
# Overlay on top of previous layers
result = overlay(layer(i), result)
return result
show(overlayer(4, rune))
Let's look at your equations again:
a = overlay_frac(0,blank_bb,scale(1/4,rune))
b = overlay_frac(1/4,blank_bb,scale(1/2,rune))
c = overlay_frac(1/2,blank_bb,scale(3/4,rune))
d = overlay_frac(3/4,blank_bb,scale(1,rune))
show (overlay(a,(overlay(b,(overlay(c,d))))))
What you wrote as "recursion" is not a recursion formula. If you compare your formulas for the recursion with the ones you gave us, you can infer n=4 which makes no sense. For a recursion pattern you need to describe your inner variables as a manifestation of the same expression with only a different parameter. That is, you should replace:
f_n = overlay_frac((1/4)*(n-1),blank_bb,sale(n/4,rune))
such that f_1=a, f_2=b etc...
Then your recursion fomula that you want to calculate translates to:
show (overlay(f_1,(overlay(f_2,(overlay(f_3,f_4))))))
You can write the function f_n as f(n) (and maybe other paramters) in your code and then do
def recurse(n):
if n == 4:
return f(4)
else:
return overlay(f(n),recurse(n+1))
then call:
show( recurse (1))
You need to assert that n<5and integer, otherwise you'll end up in an infinity loop.
There may still be some mistake, but it should be along those lines. Once you've actually written it like this however, it (maybe) doesn't really make sense to do a recursion anyways. If you only want to do it for n_max=4, that is. Just call the function in one line by replacing a,b,c,d with f_1,f_2,f_3,f_4
I am following the below blog and understood how to get the median in a very subtle way. The blog is here
Now, I added the below function to the streamMedian class to get the mean of the number inserted and not getting the desired output
import heapq
class streamMedian:
def __init__(self):
self.minHeap, self.maxHeap = [], []
self.N=0
def insert(self, num):
if self.N%2==0:
heapq.heappush(self.maxHeap, -1*num)
self.N+=1
if len(self.minHeap)==0:
return
if -1*self.maxHeap[0]>self.minHeap[0]:
toMin=-1*heapq.heappop(self.maxHeap)
toMax=heapq.heappop(self.minHeap)
heapq.heappush(self.maxHeap, -1*toMax)
heapq.heappush(self.minHeap, toMin)
else:
toMin=-1*heapq.heappushpop(self.maxHeap, -1*num)
heapq.heappush(self.minHeap, toMin)
self.N+=1
def getMedian(self):
if self.N%2==0:
return (-1*self.maxHeap[0]+self.minHeap[0])/2.0
else:
return -1*self.maxHeap[0]
def getMean(self):
sum = 0
for num in self.maxHeap:
sum += num
for num in self.minHeap:
sum += num
return sum/self.N
This is the function call to the streamMedian class.
test = streamMedian()
test.insert(1)
test.insert(2)
test.insert(3)
print test.getMedian()
print test.getMean()
The median here should be 2 and mean should be 2 (Instead 0 is the output). Thanks in advance.
You are pushing negative numbers to your maxHeap (-1*num).
You need to reverse that in your getMean(), e.g.:
def getMean(self):
total = 0
for num in self.maxHeap:
total -= num
for num in self.minHeap:
total += num
return total/self.N
Or alternatively:
def getMean(self):
return (abs(sum(self.maxHeap)) + sum(self.minHeap))/self.N
Note: don't use sum as a variable it hides the python builtin sum() function.
AChampion's answer correctly identifies the issue with your current code and offers a reasonable fix while still using your current algorithm. However, that algorithm is not very efficient (it takes O(N) time) and you can do better.
Specifically, you should add the value you're inserting to a cumulative sum in addition to pushing it onto one of your heaps. That way, when you need to get a mean, you can compute it in constant time (with just a single division):
class streamMedian:
def __init__(self):
self.minHeap, self.maxHeap = [], []
self.cumulative_sum = 0.0 # new instance variable
self.N=0
def insert(self, num):
self.cumulative_sum += num # add each value to it
# rest of insert code...
# median code...
def getMean(self):
return self.cumulative_sum / self.N # compute the mean in constant time
Note that if you're using Python 2 (which it appears you are) it's important that cumulative_sum is initialized with the float value 0.0 instead of the integer 0 (which would otherwise be natural). When you divide two integers in Python 2, you'll get another integer, rounding down. That may not be desirable if you're computing, say, the mean of 1 and 2 (you'd expect 1.5, but you'd get 1 if you just do (1 + 2) / 2). Python 3 does this better (you always get a float from regular division and can use the // operator to explicitly request "floor" division). If you want to get the same semantics in Python 2, you can put from __future__ import division at the top of your module.
I'd really love your help with understanding this using of Memoization in Python. I'm new to Python and I'm not quiet sure how to understand this syntax.
def fib_mem(n):
return fib_mem_helper(n,[0,1]+[-1]*(n-1))
def fib_mem_helper(i,mem):
if mem[i] == -1:
mem[i]=fib_mem_helper(i-1,mem) + fib_mem_helper(i-2,mem)
return mem[i]
This is a code I saw for avaluating fibonacci number using memoization, what does [0,1]+[-1]*(n-1) mean? Can you please explain me what does this type of writing represent?
[0, 1] + [-1] * (n - 1) means "concatenate two lists, one is [0, 1], the other one is a -1 repeated n-1 times".
[-1]*5 will create a new list with five elements being -1,i.e [-1 -1 -1 -1 -1]
[0 1]+[-1]*5 will append the two lists becoming [0 1 -1 -1 -1 -1 -1]
Strange coding, though. Looks like syntax errors. But according to your question:
[0,1] is a list with two elements, the first is an integer 0 and the second one is an integer 1.
A sensible implementation of such a function with memoization in Python would be:
def fib(i):
try:
return fib._memory[i]
except KeyError:
pass
if i == 1 or i == 2:
return 1
else:
f = fib(i-1) + fib(i-2)
fib._memory[i] = f
return f
fib._memory = {}
Memoization is a technique to avoid re-computing the same problem. I will come back to your question but here is an easier to understand solution.
mem = {0:0, 1:1}
def fib(n):
global mem
if mem.get(n,-1) == -1:
mem[n] = fib(n-1) + fib(n-2)
return mem[n]
By making mem a global variable, you can take advantage of memoization across calls to fib(). The line mem.get(n,-1) == -1 checks if mem already contains the computation for n. If so, it returns the result mem[n]. Otherwise, it makes recursive calls to fib() to compute fib(n) and stores this in mem[n].
Let's walk through your code. The second argument here fib_mem_helper(n,[0,1]+[-1]*(n-1)) passes a list of the form [0,1,-1,-1,...] with a length of (n+1). Within the fib_mem_helper function, this list is referenced by variable mem. If mem[i] turns out be -1, you compute m[i]; otherwise use the already computed result for mem[i]. Since you are not persisting mem across the calls to fib_mem(), it would run an order of magnitude slower.
First, I have to say that even after editing, your code still has a wrong indentation: return mem[i] should be unindented.
Among list operations, "+" means concatenation, "*" means repetition, so [0,1]+[-1]*(n-1) means a list: [0, 1, -1, ..., -1](totally (n-1) negative 1's).
More explanation:
List [0, 1, -1, ..., -1] stores calculated fibonacci sequences(memoization). Initially it only contains two valid values: 0 and 1, all "-1" elements mean the sequence at that index has not been computed yet. This memo is passed as the 2nd parameter to function fib_mem_helper. If the specified index(i.e. i)'s fibonacci number hasn't been computed(test if mem[i] == -1), fib_mem_helper will recursively compute it and store it to mem[i]. If it's been computed, just return from the memo without recomputing.
That's the whole story.
Final word:
This code is not efficient enough, although it takes use of memoization. In fact, it creates a new list each time when fib_mem is called. For example, if you call fib_mem(8) twice, the second call still has to recreate a list and recompute everything afresh. The reason is that you store the memo inside the scope of fib_mem. To fix it, you could save memo as a dictionary that's outside fib_mem.
The speed-up in python can be a million fold or more, when using memoization on certain functions. Here is an example with the fibonacci series. The conventional recursive way is like this and takes forever.
def recursive_fibonacci(number):
if number==0 or number==1:
return 1
return recursive_fibonacci(number-1) + recursive_fibonacci(number-2)
print recursive_fibonacci(50),
The same algorithm with memoization takes a few milli seconds. Try it yourself!
def memoize(f):
memo={}
def helper(x):
if x not in memo:
memo[x]=f(x)
return memo[x]
return helper
#memoize
def recursive_fibonacci(number):
if number==0 or number==1:
return 1
return recursive_fibonacci(number-1) + recursive_fibonacci(number-2)
print recursive_fibonacci(50),