Print harmonic series for the given series in Python 3 - python

I want to print harmonic series in python as follow but I don't understand how to do it, pls help and it would be nice if you could maybe explain how you did it. I have not tried any code and was not able to find it on the web

The problem
We want to iterate n (1, 2, 3, 4, 5, ...) and pass it in the formula nx/n!, for example user ill define x by this line of code x = int(input("What's the value of x? ")), so image user types number 5, so we need to get: 1*5/1!, 2*5/2!, 3*5/3!, 4*5/4!.
Here is another problem: Python's ! symbol means boolean invert, so !true is equal to false, not factorial.
factorial function in Python
So we need to define function factorial:
def factorial(number):
fact = 1
for n in range(1, number+1):
fact *= n # The same as fact = fact * n
return fact
# TEST OF THE FACTORIAL FUNCTION
# print(f'factorial(3) == 1*2*3 => { factorial(3) == 1*2*3 }')
Limit of the sequence
We actually need to get the nlim number from the user that tells the loop when to stop.
nlim = int(input("What's the limit of the sequence? "))
The sequence
So, we need to get Python evaluate this (if x is equal to 5 and n is increasing from 1 by step 1 to limit nlim): 1*5/factorial(1), 2*5/factorial(2), 3*5/factorial(3) and so on.
results = [] # in this list all the results will be stored
for n in range(1, nlim+1):
results.append((n*x) / factorial(n)) # here comes the formula!
Read sequence
for i, result in enumerate(results):
# enumerate([7, 8, 9]) will give us 2D list with indexes [[0, 7], [1, 8], [2, 9]]
# Then we will iterate this, so on each loop cycle we get [0, 7], then [1, 8] and so on
# if we do following: a, b = [1, 2] then variable a will be 1 and variable b will be 2
print(f'result[{ i }]: { result }')
All the code
def factorial(number):
fact = 1
for n in range(1, number+1):
fact *= n
return fact
x = int(input("What's the value of x? "))
nlim = int(input("What's the limit of the sequence? "))
results = []
for n in range(1, nlim+1):
results.append((n*x) / factorial(n))
for i, result in enumerate(results):
print(f'result[{ i }]: { result }')

Related

What is wrong with this cumulative sum function, and is there a better way to write the function?

Function:
def comulative_sum(arr):
arr1 = []
for number in range(1, len(arr)):
sum1 = 0
for number1 in range(0, arr[number]):
sum1 += number1
arr1.append(sum1)
return arr1
arr = [1, 2, 3, 4]
print(comulative_sum(arr))
Output:
[3, 6, 10]
Expected output:
[1, 3, 6, 10]
I have tried slicing ([1:], [0:number) instead of the range function. Still no results.
The better way to write this function is simply using itertools.accumulate() which does exactly that:
>>> import itertools
>>> print(list(itertools.accumulate([1,2,3,4]))
[1, 3, 6, 10]
you dont need to loop it twice
def cum_sum(x):
result = []
current_sum = 0
for value in x:
current_sum += value
result.append(current_sum)
return result
Multiple issues:
On the first loop you need to range until len() + 1 as the last number is len() and then the last number in second loop will be len() - 1 which is also the index.
On the second loop, instead of ranging until number, you range until the original number in the array.
Fixed code:
def comulative_sum(arr):
arr1 = []
for number in range(1, len(arr)+1):
sum1 = 0
for number1 in range(0, number):
sum1 += arr[number1]
arr1.append(sum1)
return arr1
arr = [1, 2, 3, 4]
print(comulative_sum(arr))
If you wish to improve upon this code and not use a built-in accumulate, you can do so:
def comulative_sum(input_list):
output = []
sum_ = 0 # The underscore is to avoid renaming the built-in sum()
for i in input_list:
sum_ += i
output.append(sum_)
return output
input_list = [1, 2, 3, 4]
print(comulative_sum(input_list))
Advantages:
Better variable naming.
Less code nesting.
Easier overall code readability.
Faster code (no need to recalculate everything on each iteration)
I built in your solution. This version relies on Python's loop through indexes and also addresses a possible number '0'.
def cumulative_sum(arr):
arr1 = []
# Python does the hard work for you, it loops through each value on the list
for value in arr:
sum1 = 0
# Range is going to have a list as follows [0, ... , value-1]
for number1 in range(0, value):
sum1 += number1
# Adding 'value' to sum1 because the loop did not add the last value
arr1.append(sum1+value)
return arr1
arr = [1, 3, 6, 10]
# Calling the function with 'print' to make sure the results are displayed
print(cumulative_sum(arr))
The for loop will only deal with numbers from index 1 to the end of the array. Thus index 0 will be ignored.
Working function:
def comulative_sum(arr):
arr1 = []
for number in arr[:len(arr)]:
sum1 = 0
for number1 in arr[0:number]:
sum1 += number1
arr1.append(sum1)
return arr1
arr = [1, 2, 3, 4]
print(comulative_sum(arr))
All that was changed was the indexing in the first and second for loop.

Could you help me with this Dynamic Programming Problem?

I tried to solve the problem below using dynamic programming, but there is something wrong with my code and I could not figure it out. Could you help me with it? Thank you!
Problem:
Given two arrays of length m and n with digits 0-9 representing two numbers. Create the maximum number of length k <= m + n from digits of the two. The relative order of the digits from the same array must be preserved. Return an array of the k digits.
Note: You should try to optimize your time and space complexity.
Example 1:
Input:
nums1 = [3, 4, 6, 5]
nums2 = [9, 1, 2, 5, 8, 3]
k = 5
Output:
[9, 8, 6, 5, 3]
Example 2:
Input:
nums1 = [6, 7]
nums2 = [6, 0, 4]
k = 5
Output:
[6, 7, 6, 0, 4]
Example 3:
Input:
nums1 = [3, 9]
nums2 = [8, 9]
k = 3
Output:
[9, 8, 9]
My idea is as following:
dp[i][j][t] is the the maximum number of length i which is picked out of first j digits of array 1 and first t digits of array 2, where i goes from 0 to k, j goes from 0 to len(nums1), t goes from 0 to len(nums2). the state transition equation goes like this:
when nums1[j-1] > nums2[t-1]:
if we already have k-2 digits, then we have to take both nums1[j-1] and nums2[t-1], and we must take nums1[j-1] first in order to maximize the result
if we already have k-1 digits, then we only have to take one more digit, and it must be nums1[j-1], because it is bigger
if we already have k digits, then we do not need to take more digits, so we keep the last result dp[i][j-1][t-1]
Given that we are looking for maximum, our current result should be the biggest among these 3 situations, so we have:
dp[i][j][t] = max(
(dp[i-2][j-1][t-1]*10+nums1[j-1])*10+nums2[t-1],
dp[i-1][j-1][t-1]*10+nums1[j-1],
dp[i][j-1][t-1]
)
when nums1[j-1] < nums2[t-1]:
if we already have k-2 digits, then we have to take both nums1[j-1] and nums2[t-1], and this time we must take nums2[t-1] first because it is bigger
if we already have k-1 digits, then we only have to take one more digit, and it must be nums2[t-1], because it is bigger
if we already have k digits, then we do not need to take more digits, so we keep the last result dp[i][j-1][t-1]
Likewise, we take the biggest result from these possible ones:
dp[i][j][t] = max(
(dp[i-2][j-1][t-1]*10+nums2[t-1])*10+nums1[j-1],
dp[i-1][j-1][t-1]*10+nums2[t-1],
dp[i][j-1][t-1]
)
Here is my code:
import numpy as np
def maxNumber(nums1, nums2, k):
m = len(nums1)
n = len(nums2)
dp = [[[0 for _ in range(n + 1)] for _ in range(m + 1)] for _ in range(k + 1)]
for i in range(2, k + 1):
for j in range(i + 1):
if j > m or (i - j) > n:
continue
tmp = 0
tmp_nums1 = nums1[:j]
tmp_nums2 = nums2[:(i-j)]
while tmp_nums1 or tmp_nums2:
if tmp_nums1 > tmp_nums2:
tmp = tmp * 10 + tmp_nums1.pop(0)
else:
tmp = tmp * 10 + tmp_nums2.pop(0)
dp[i][j][i - j] = tmp
for i in range(m + 1):
for j in range(n + 1):
if not i and not j:
continue
dp[1][i][j] = max(nums1[:i] + nums2[:j])
for i in range(2, k+1):
for j in range(m+1):
for t in range(i+1-j, n + 1):
if nums1[j - 1] > nums2[t - 1]:
dp[i][j][t] = max((dp[i-2][j-1][t-1]*10+nums1[j-1])*10+nums2[t-1], dp[i][j-1][t-1], dp[i-1][j-1][t-1]*10+nums1[j-1])
else:
dp[i][j][t] = max((dp[i-2][j-1][t-1]*10+nums2[t-1])*10+nums1[j-1], dp[i][j-1][t-1], dp[i-1][j-1][t-1]*10+nums2[t-1])
# print(np.array(dp))
res = []
tmp_res = dp[-1][-1][-1]
while tmp_res:
res.append(tmp_res % 10)
tmp_res //= 10
return res[::-1]
But it outputs [8, 9, 9] on Example 3, and I cannot figure out the reason. Could you help me with it?
Thank you in advance!
Dynamic programming usually implies short-circuiting some of the computation based on results from computations made to date. Often this takes the form of a recursive function. You seem to be taking more of a brute force approach (which usually corresponds to the worse case scenario for dp)
Here is an example of a recursive approach that will lend itself better to optimization:
def largestFrom(M,N,K):
if K == 1: return [max(M+N)] # simple case
if not M and len(N)==K : return N # simple case
if not N and len(M)==K : return M # simple case
result = []
for A,B in [(N,M),(M,N)]:
for i,a in enumerate(A): # trial on numbers from A
if len(A)-i+len(B)<K: break # can't take more from A
if result and a < result[0]: continue # short-circuit
R = [a] + largestFrom(A[i+1:],B,K-1) # recurse with remaining numbers
if R > result: result = R # track best so far
return result
After eliminating the obvious solutions that require no special processing, it goes into a recursive trial/error process that short-circuits the traversal for candidate numbers that won't improve the best result found so far.
The traversal goes through the two lists and attempts to use the number at each position as the first one in the result. It then recurses with the remaining numbers and a size of K-1. So, upon returning from the recursion, a list R is formed of the selected number followed by the largest K-1 sized suffix that can be made with the remaining numbers.
One part of the short circuiting is stopping the loop when the index of the selected number would not leave enough remaining numbers to reach a size of K-1 (i.e. combining the remainder of the current list plus all numbers of the other one).
Another part of short circuiting is comparing the number we are about to try with the first one in the best result. If the candidate number is smaller than the first one in the result, then it would be pointless to go deeper as there is no possibility to form an R list greater than the result we already have.
For example:
combining [3,9] [8,9] with K=3
result starts empty
Going through first list [3,9]
select 3 at position 0
recurse with M=[9] N=[8,9] K=2
will produce R = [3] + [9,8]
R > result, result is now [3,9,8]
select 9 at position 1
recurse with M=[] N=[8,9] K=2
will produce R = [9] + [8,9]
R > result, result is now [9,8,9]
Going through second list [8,9]
select 8 at position 0
8 is smaller than R[0] (9)
short-circuit
select 9 at position 1
recurse with M=[3,9] N=[] K=2
will produce R = [9] + [3,9]
result unchanged (R is < result)
return result [9,8,9]
The for A,B in [(N,M),(M,N)]: loop is merely a shorthand way to avoid duplicating the code for the trial loops on numbers in M and numbers N.
testSet = [ ([3,4,6,5],[9,1,2,5,8,3],5),
([6, 7], [6, 0, 4],5),
([3, 9], [8, 9],3)
]
for M,N,K in testSet:
print(M,N,K,":",largestFrom(M,N,K))
[3, 4, 6, 5] [9, 1, 2, 5, 8, 3] 5 : [9, 8, 6, 5, 3]
[6, 7] [6, 0, 4] 5 : [6, 7, 6, 0, 4]
[3, 9] [8, 9] 3 : [9, 8, 9]
There is alternative way than DP to solve it. Here I've just crafted another solution:
def maxNumber(nums1, nums2, k):
def pick(nums, k):
stack = []
drop = len(nums) - k
for num in nums:
while drop and stack and stack[-1] < num:
stack.pop()
drop -= 1
stack.append(num)
return stack[:k]
def merge(A, B):
ans = []
while A or B:
bigger = A if A > B else B
ans.append(bigger.pop(0))
return ans
return max(merge(pick(nums1, i), pick(nums2, k-i))
for i in range(k+1) if i <= len(nums1) and k-i <= len(nums2))
if __name__ == '__main__':
nums1 = [3, 4, 6, 5]
nums2 = [9, 1, 2, 5, 8, 3]
print(maxNumber(nums1, nums2, 5))
print(maxNumber([3,9],[8,9], 3))
Are those answers to your examples provided by the professor? Because they don't make sense to me. Surely the largest number is one that uses all of the digits available? i.e. the largest value will always mean k=m+n. You can't possibly have a larger answer with k=m+(n-1) for instance. What am I missing?
Example 3:
Input: nums1 = [3, 9]
nums2 = [8, 9]
k = 3
Output: [9, 8, 9]
or - in my world k = 4 / Output: [8, 9, 3, 9]
(Hmm... I guess they were provided. Seems a weird question to me. Sorry - I'm unable to help, but I'll post this anyway in case someone else wonders the same thing I did. To me the hard part would be to actually work out what the largest number would be, using all digits. But even then that's not that hard: Compare positions 1 - use the value from the larger array. Compare position 1 of the non-chosen array with position 2... and so on.)

Calculate the product from a list of multiples

I have a Python assignment where it asks me to create a function that returns a list of numbers that are multiples. Then, write another function that takes the list of numbers and calculates the product of all the items in the list. For loop must be used in your function.
The output should be like:
Enter multiple of: 2
Enter an upper limit: 10
[2, 4, 6, 8, 10]
product is 3840
but I cannot get the second function to work, it prints 0.
#from functools import reduce # Valid in Python 2.6+, required in Python 3
#import operator
a = []
def func_list(multi,upper,a):
for i in range (upper):
if i % multi == 0:
a.append(i) #DOESNT INCLUDE THE UPPER LIMIT
multi = int(input("Enter multiple of: "))
upper = int(input("Enter an upper limit: "))
func_list(multi,upper,a)
print(a)
#b
#input = list of number (param)
#output = calculates the product of all the list (sum)
def prod(a):
prod1 = 1
for i in a:
prod1 *= i
return prod1
#return reduce(operator.mul, a, 1)
#func_list(multi,upper)
prod(a)
print (prod(a))
The output I get is:
Enter multiple of: 2
Enter an upper limit: 10
[0, 2, 4, 6, 8] I don't know how to inc. the limiter, but it's not my concern yet.
0 not right
I tried using reduce as suggested on here, but I don't know if I did something incorrect, because it didn't work.
Python's range() already has this functionality built in: range(start, stop, increment)
Simply:
def func_list(multi,upper,a):
a = list(range(multi, upper+1, a))
If you need to use a for loop:
def func_list(multi,upper,inc):
for i in range(multi, upper+1, inc):
a.append(i)
Your second product function does actually work. The reason why it is printing 0 is because of this line: for i in range (upper):. This results in 0 getting appended to your list, making the product 0.
import numpy as np
def multiples_list(numbers, upper):
'''
Create a function that returns a list of multiples
with a upper limit of 10.
'''
numbers_list = []
for number in numbers:
if number <= upper and number % 2 == 0:
numbers_list.append(number)
return numbers_list
def product_of_multiples(numbers):
new_numbers = []
for num in numbers:
new_numbers.append(num)
numbers_array = np.array(new_numbers)
product = np.product(numbers_array)
return product
#numbers_list = list(int(input('Please enter a series of numbers: ')))
numbers_list = [2, 4, 6, 8, 10]
print(multiples_list(numbers_list, 10))
print(product_of_multiples(numbers_list))
Here is the output:
[2, 4, 6, 8, 10]
3840
What I did here in your product function is create a new list from the list that you pass as the argument. We use a for loop to append to the new list. We can pass the new list to np.array() to create an array from the list after the for loop. We can use the np.product() function and pass the array of the list and return a fully formatted version of the product.

Dynamic Programming - Primitive Calculator

I am trying to solve the following problem using dynamic programming.
You are given a primitive calculator that can perform the following three operations with the current number x: multiply x by 2, multiply x by 3, or add 1 to x. Your goal is given a positive integer n, find the minimum number of operations needed to obtain the number n starting from the number 1.
The output should contain two parts - the number of minimum operations, and the sequence to get to n from 1.
I found the following solution from this post: Dynamic Programming - Primitive Calculator Python.
I am having problem understanding the back tracing part, starting from
"numbers = [ ]
k = n"
Could anyone explain the logic behind it? It works like magic...
The code is as follows:
def dp_min_ops(n):
all_parents = [None] * (n + 1)
all_min_ops = [0] + [None] * n
for k in range(1, n + 1):
curr_parent = k - 1
curr_min_ops = all_min_ops[curr_parent] + 1
if k % 3 == 0:
parent = k // 3
num_ops = all_min_ops[parent] + 1
if num_ops < curr_min_ops:
curr_parent, curr_min_ops = parent, num_ops
if k % 2 == 0:
parent = k // 2
num_ops = all_min_ops[parent] + 1
if num_ops < curr_min_ops:
curr_parent, curr_min_ops = parent, num_ops
all_parents[k], all_min_ops[k] = curr_parent, curr_min_ops
numbers = []
k = n
while k > 0:
numbers.append(k)
k = all_parents[k]
numbers.reverse()
return all_min_ops, numbers
print(dp_min_ops(5)) # ([0, 1, 2, 2, 3, 4], [1, 3, 4, 5])
print(dp_min_ops(10)) # ([0, 1, 2, 2, 3, 4, 3, 4, 4, 3, 4], [1, 3, 9, 10])
Hint : To find the Minimum operations to reach a number n. You will need the following answers :
1) min_operations[n-1]
2) if ( n is divisible by 2)
min_operations[n/2]
3) if ( n is divisible by 3)
min_operations[n/3]
Now if we find the minimum of these above three operations we will have minimum number of operations to reach n by adding one to the minimum of these three(if valid).
Now you know that minimum number of operations to reach 1 is zero. So now start calculating minimum number of operations from 1 to n. Since whenever you will calculate any number say k you will always have answer for all numbers less than k ie. k-1, k/2(if divisible), k/3(if divisible). Hence you could calculate for n if you would traverse from 1 to n finding answers for all numbers in between.

How to return a list of numbers of the power of 2?

def problem(n):
myList = []
for j in range(0, n):
number = 2 ** j
myList.append(number)
return myList
I want this code to return the powers of 2 based upon the first n powers of 2. So for example, if I enter in 4, I want it to return [2,4,6,8,16]. Right now, the code returns [1,2,4,8] if I enter in 4. I think it's my range that's messing up the code.
just use range(1,n+1) and it should all work out. range is a little confusing for some because it does not include the endpoint. So, range(3) returns the list [0,1,2] and range(1,3) returns [1,2].
As a side note, simple loops of the form:
out = []
for x in ...:
out.append(...)
should typically be replaced by list comprehensions:
out = [ 2**j for j in range(1,n+1) ]
Yet another simple and efficient solution (every step in O(1)) without the power operator:
def problem(n):
return [1 << i for i in range(n)]
The 1 << i operations is a bitwise operation which translates to 2 ^ i for i integer positive.
https://en.wikipedia.org/wiki/Arithmetic_shift
If you want to do every step in O(1):
def gen(x):
i = 2
for n in range(x + 1):
yield i
i <<= 1
>>> list(gen(4))
[2, 4, 8, 16, 32]
PS: There's a typo in the question and if you want 4 numbers for gen(4), use range(x) instead
As #JBernardo pointed out, I assume there is a typo in your question.
def squares(n):
power = n
square_list = []
for i in range(1,n+1):
square_list.append(2 ** i)
return square_list
print squares(4)
will return
[2,4,8,16]
import math
n = input()
a = [i for i in xrange(2, n+1) if (math.log(i)/math.log(2)).is_integer()]
print a
>>> [2, 4, 8, 16 ...]
Returns list of powers of 2 less than or equal to n
Explanation:
A number can only be a power of 2 if its log divided by the log of 2 is an integer.
eg. log(32) = log(2^5) = 5 * log(2)
5 * log(2) when divided by log(2) gives 5 which is an integer.
Also there will be floor(math.log(n, 2)) elements in the list, as that is the formula for the number of powers of 2 below n if n itself is not a power of 2
You can use map:
x = [1, 2, 3, 4]
def power(n):
return n * n
list(map(power, x))
#output
[1, 4, 9, 16]

Categories

Resources