difficulty with a math assignment in python - python

I am provided with a value N. I am to calculate the sum of all squares up to and including N. In math this is commonly called ∑Ni=0i2. It must be calculated in a loop. I have tried everything I can think of, even break statements, but I haven't been able to get it to work.
This is the closest I've come
Ans = 1
for i in range(N):
if i == N:
Ans = Ans*N
print (Ans)
I've made sure everything is indented and that my print statement is outside the loop, I think I am using the wrong formula, but I can't think of a better one. Can someone point me in the right direction?

Try this. You can set the upper value with num, and it prints the answer. sum acts on an iterable here rather than a list.
num=5
print(sum(e**2 for e in range(num+1)))

Related

I don't understand how this recursive function works

So these are the examples I got:
def bottom_up(n):
if n == 0:
pass
else:
bottom_up(n-1)
print(n)
and this one, which is fine:
def top_down(n):
if n == 0:
pass
else:
print(n)
top_down(n-1)
I have an understanding of recursion, so that isn't the problem. My problem is the result for bottom_down():
bottom_up(5)
1
2
3
4
5
I've asked other students and my teacher(math teacher, because my school won't hire a computer science teacher since I'm the only one doing computer science), and I don't know what to search on google.
I highly encourage you to walk through the functions yourself to see how it works, but the difference is in the order of the print statement and the recursive call.
The first function has the recursive call before the print statement, so that means it has to go down to the base case in order to start printing the numbers. This means it will start at the smallest number and go up and back to the starting number.
The second function has the print statement before the recursive call, which means that it will print the number then take a step closer to the base case. Once the base case is reached, the recursive calls go back up, and exit as there is nothing after them.
Hope this helped.
Pass is a placeholder for code.
Need more context in what you are trying to do.
bottom_up(5) is looping
So before bottom_up(5) prints 5 it will run the function bottom_up(4), bottom_up(3), bottom_up(2), bottom_up(1), bottom_up(0) and so on....
bottom_up(0) and and negative n will pass and not print anything.
So the first thing to print will be bottom_up(1) then bottom_up(2) and so on until 5.

sum of cubes using formula

Given
\sum_{k=0}^{n}k^3 = \frac{n^2(n+1)^2}{4}
I need to compute the left hand side. I should make a list of the first 1000 integer cubes and sum them.
Then I should compute the right hand side and to the same.
Also, I am supposed to compare the computational time for the above methods.
What I've done so far is:
import time
start = time.clock()
list = []
for n in range(0,1001):
list.append(n**3)
print(list)
print("List of the first 1000 integer cubes is:",list, "and their sum is:", sum(list))
stop = time.clock()
print("Computation time: ",stop-start, "seconds.")
a=0
for n in range (0,1001):
a=(int)(n*(n+1)/2)
print ("Sum of the first 1000 integer cubes is:",a*a)
First part for the left hand side works fine, but the problem is the right hand side.
When I type n=4, I will get the same result for the both sides, but problem occurs when n is big, because I get that one side is bigger than the other, i.e. they are not same.
Also, can you help me create a list for the right hand side, I've tried doing something like this:
a=[]
for n in range (0,10):
a.append(int)(n**2(n+1)**2/4)
But it doesn't work.
For the computational time, I think I am supposed to set one more timer for the right hand side, but then again I am not sure how to compare them.
Any advice is welcome,
Ok, I think what you tried in a for loop is completely wrong. If you want to prove the formula "the hard way" (non-inductive way it is) - you need to simply sum cubes of n first integers and compare it against your formula - calculated one time (not summed n times).
So evaluate:
n=100
s=0
for i in range(1,n+1):
s+=i**3
###range evaluates from 1 till n if you specify it till n+1
s_ind=(n**2)*((n+1)**2)/4
print(s==s_ind)
Otherwise if you are supposed to use induction - it's all on paper i.e. base condition a_1=1^3=((1)*(2)^2)/4=1 and step condition i.e. a_n-a_(n-1)=sum(i^3)[i=1,...,n]-sum(j^3)[i=1,...,n-1]=n^3 (and that it also holds assuming a_n=your formula here (which spoiler alert - it does ;) )
Hope this helps.

How can I get my function to add together its output?

So this is my line of code so far,
def Adder (i,j,k):
if i<=j:
for x in range (i, j+1):
print(x**k)
else:
print (0)
What it's supposed to do is get inputs (i,j,k) so that each number between [i,j] is multiplied the power of k. For example, Adder(3,6,2) would be 3^2 + 4^2 + 5^2 + 6^2 and eventually output 86. I know how to get the function to output the list of numbers between i and j to the power of K but I don't know how to make it so that the function sums that output. So in the case of my given example, my output would be 9, 16, 25, 36.
Is it possible to make it so that under my if conditional I can generate an output that adds up the numbers in the range after they've been taken to the power of K?
If anyone can give me some advice I would really appreciate it! First week of any coding ever and I don't quite know how to ask this question so sorry for vagueness!
Question now Answered, thanks to everyone who responded so quickly!
You could use built-in function sum()
def adder(i,j,k):
if i <= j:
print(sum(x**k for x in range(i,j+1)))
else:
print(0)
The documentation is here
I'm not sure if this is what you want but
if i<=j:
sum = 0
for x in range (i, j+1):
sum = sum + x**k #sum += x**k for simplicity
this will give you the sum of the powers
Looking at a few of the answers posted, they do a good job of giving you pythonic code for your solution, I thought I could answer your specific questions:
How can I get my function to add together its output?
A perhaps reasonable way is to iteratively and incrementally perform your calculations and store your interim solutions in a variable. See if you can visualize this:
Let's say (i,j,k) = (3,7,2)
We want the output to be: 135 (i.e., the result of the calculation 3^2 + 4^2 + 5^2 + 6^2 + 7^2)
Use a variable, call it result and initialize it to be zero.
As your for loop kicks off with x = 3, perform x^2 and add it to result. So result now stores the interim result 9. Now the loop moves on to x = 4. Same as the first iteration, perform x^2 and add it to result. Now result is 25. You can now imagine that result, by the time x = 7, contains the answer to the calculation 3^2+4^2+5^2+6^2. Let the loop finish, and you will find that 7^2 is also added to result.
Once loop is finished, print result to get the summed up answer.
A thing to note:
Consider where in your code you need to set and initialize the _result_ variable.
If anyone can give me some advice I would really appreciate it! First week of any coding ever and I don't quite know how to ask this question so sorry for vagueness!
Perhaps a bit advanced for you, but helpful to be made aware I think:
Alright, let's get some nuance added to this discussion. Since this is your first week, I wanted to jot down some things I had to learn which have helped greatly.
Iterative and Recursive Algorithms
First off, identify that the solution is an iterative type of algorithm. Where the actual calculation is the same, but is executed over different cumulative data.
In this example, if we were to represent the calculation as an operation called ADDER(i,j,k), then:
ADDER(3,7,2) = ADDER(3,6,2)+ 7^2
ADDER(3,6,2) = ADDER(3,5,2) + 6^2
ADDER(3,5,2) = ADDER(3,4,2) + 5^2
ADDER(3,4,2) = ADDER(3,3,2) + 4^2
ADDER(3,3,2) = 0 + 3^2
Problems like these can be solved iteratively (like using a loop, be it while or for) or recursively (where a function calls itself using a subset of the data). In your example, you can envision a function calling itself and each time it is called it does the following:
calculates the square of j and
adds it to the value returned from calling itself with j decremented
by 1 until
j < i, at which point it returns 0
Once the limiting condition (Point 3) is reached, a bunch of additions that were queued up along the way are triggered.
Learn to Speak The Language before using Idioms
I may get down-voted for this, but you will encounter a lot of advice displaying pythonic idioms for standard solutions. The idiomatic solution for your example would be as follows:
def adder(i,j,k):
return sum(x**k for x in range(i,j+1)) if i<=j else 0
But for a beginner this obscures a lot of the "science". It is far more rewarding to tread the simpler path as a beginner. Once you develop your own basic understanding of devising and implementing algorithms in python, then the idioms will make sense.
Just so you can lean into the above idiom, here's an explanation of what it does:
It calls the standard library function called sum which can operate over a list as well as an iterator. We feed it as argument a generator expression which does the job of the iterator by "drip feeding" the sum function with x^k values as it iterates over the range (1, j+1). In cases when N (which is j-i) is arbitrarily large, using a standard list can result in huge memory overhead and performance disadvantages. Using a generator expression allows us to avoid these issues, as iterators (which is what generator expressions create) will overwrite the same piece of memory with the new value and only generate the next value when needed.
Of course it only does all this if i <= j else it will return 0.
Lastly, make mistakes and ask questions. The community is great and very helpful
Well, do not use print. It is easy to modify your function like this,
if i<=j:
s = 0
for x in range (i, j+1):
s += x**k
return s # print(s) if you really want to
else:
return 0
Usually functions do not print anything. Instead they return values for their caller to either print or further process. For example, someone may want to find the value of Adder(3, 6, 2)+1, but if you return nothing, they have no way to do this, since the result is not passed to the program. A side note, do not capitalize functions. Those are for classes.

'Sum of Triangles': Codechef How can the code be optimised for speed and large test cases?

I am a Python newbie.
The following was a beginner level problem at codechef.com Link to problem
Problem Text:
Let's consider a triangle of numbers in which a number appears in the first line, two numbers appear in the second line, three in the third line, etc. Develop a program which will compute the largest of the sums of numbers that appear on the paths starting from the top towards the base, so that:
on each path the next number is located on the row below, more
precisely either directly below or below and one place to the right;
the number of rows is strictly positive, but less than 100
all numbers are positive integers between O and 99.
Input
In the first line integer n - the number of test cases (equal to about 1000). Then n test cases follow. Each test case starts with the number of lines which is followed by their content.
Output
For each test case write the determined value in a separate line.
The following is my code:
tempij=[]
s=0
def solve(i,j,ll):
global s
s=0
tempij=[]
if i==len(ll):
return 0
elif (i,j) in tempij:
return s
else:
tempij.append((i,j))
t1=solve(i+1,j,ll)
t2=solve(i+1,j+1,ll)
t=max(t1,t2)+ll[i][j]
s=t
return t
t=int(input())
ll=[]
for k in range(t):
ll=[]
n=int(input())
for i in range(n):
lst=[]
text=input().split()
for j in range(len(text)):
lst.append(int(text[j]))
ll.append(lst)
print(solve(0,0,ll))
Problem with this code:
I have tried to implement Recursion with Memoization in accordance with their editorial on this problem. Link to editorial
Code explained (Relevant part of editorial):
(I am using tempij for caching in the code above. Something similar to SO question: SO question about memoization)
While it works for the test cases given as example, it seems to be exceeding the time limit for other test cases.
My question: How do I improve this code? Or is there a better way?
I'm not convinced your memoization is working. Every time you call solve, you blow away your cache and you have a local tempij that shadows the global copy. Moreover, you're only storing one calculated value at a time in s, so even if it was working, you probably wouldn't retrieve the correct cached value in most cases. Leaving aside the use of the global variable (shudder), I think you should use something more like
cache = {}
def solve(i,j,ll):
global cache
if i==len(ll):
return 0
elif (i,j) not in cache:
t1=solve(i+1,j,ll)
t2=solve(i+1,j+1,ll)
t=max(t1,t2)+ll[i][j]
cache[(i, j)] = t
return cache[(i, j)]
I realized my mistake. Thanks to JCVanHamme.
The above code was not caching correctly because of reasons mentioned by JCVanHamme. I had been resetting the cache after every call. So I did away with all the global variables which were creating problems (since they would have to be re-set for every test case and that was creating a problem). Modified code looks like:
def solve(i,j,ll,cache):
if i==len(ll):
return 0
elif (i,j) not in cache:
t1=solve(i+1,j,ll,cache)
t2=solve(i+1,j+1,ll,cache)
t=max(t1,t2)+ll[i][j]
cache[(i, j)] = t
return cache[(i, j)]
t=int(input())
ll=[]
cache={}
for k in range(t):
ll=[]
cache={}
n=int(input())
for i in range(n):
lst=[]
text=input().split()
for j in range(len(text)):
lst.append(int(text[j]))
ll.append(lst)
print(solve(0,0,ll,cache))
The original question still holds. Can it be made faster and better using python itself? I checked out run-times of people who used other languages like C/C++ and it is as low as 0:08 while for python 3.x it is 0.57!

Basic program generating random numbers Python

I want to create a program that will take a positive integer n, then create a list consisting of n random numbers between 0 and 9. Once I find that, I want to return the average of those numbers. Am I on the right track?
import random
def randomNumbers(n):
n > 0
myList = random.randrange(0,9)
I know I haven't gotten to the second part yet.. but is this how I start out?
This is my final code:
import random
def randomNumbers(n):
myList = []
for i in range(n):
myList.append(random.randrange(0, 9))
return sum(myList)/len(myList)
Could someone direct me to a page where it talks about a for and while loops and when to use them?
The equals sign (=) is only used to set the value of the "entire variable" (like myList). You want a list, which will then have values added to it, so start with this:
myList = []
to make it an empty list.
Now you had the right idea about repeating something while n > 0- but the ideal way is to use a for loop:
for i in range(n): # repeats the following line(s) of code n times
myList.append(random.randrange(0,9))
To find the average, take the sum and divide by the number of items (n).
If you are using Python 2.x, then note that an integer divided by another integer will round to an integer, so you should convert into a float (decimal) before division:
average = sum(myList)*1.0/n
For Python 3.x, int/int gives a float like you might expect:
average = sum(myList)/n
To return a value, use the return statement:
return average
It helps to break down what you're trying to do, if it's too complicated in a single explanation.
Take a positive integer, n
create a list of n length
each element should be a number 0-9
return the average of that list.
Let's tackle this one at a time:
take a positive integer, n
def randomNumbers(n):
if type(n)==int and n>0:
when you say def randomNumbers(n): you're saying
Hey, computer, this is a function called "randomNumbers",
and it's going to be called with a single thing in parentheses
and we're going to call that `n` from now on.
Here's what that function does:
But you haven't ensured that n is an integer greater than 0. It's just a thing. So we need to ensure that it is. if type(n)==int and n>0: does that by checking that the type of n is int and that n's value is positive (greater than 0).
That's the first bullet point done. Next is creating a list of n length with each element being an integer numbered 0-9. These should be random[1].
result=list()
for i in range(n):
result.append(random.randint(0,9))
This is less complicated than it seems. You start by creating a list that you'll call result (or whatever you want, I don't care). The for loop is just saying:
Hey, computer, you're gonna do the same thing a number of times,
and that number is "until you've counted from 0 to n times".
And when you do that, "i" is going to represent where you are
in that "0 to n" range. Here's what you're gonna do all those times:
So what are you going to do n times? You're going to append a random integer between 0 and 9 to that list we just called result. That's what result.append(random.randint(0,9)) does.
So next you want to return the average of that list. Well, the average of a list is the sum of the numbers in the list divided by the length.
return sum(result)/float(len(result))
sum and len can take any iterable, like a list, or a set, or whatever you please, and give you the sum, length, or whatever else you ask for. These are great tools to learn about. So do it. Elsewhere, preferably, frankly.
Now, if you've been really attentive, you'll see that so far we have this:
import random # I added this secretly, sorry!
def randomNumbers(n):
if type(n)==int and n>0:
result=list()
for i in range(n):
result.append(random.randint(0,9))
return sum(result)/float(len(result))
Which is great! That's what you need; try print(randomNumbers(5)) and you'll get exactly what you're looking for: the average of a bunch of random numbers.
But what if you try print(randomNumbers('foo'))? You probably get None, right? That's because it didn't fit in with the if statement we wrote, and so it never went down that path! You need to write an else statement so things that aren't positive integers still get some love.
else:
return "That's no good. Try a positive integer instead"
Stupid, but it works. Someday you'll learn about raising exceptions and all that smooth Jazz, but until then, it's fine just to say
Hey, computer, if n wasn't up to my stratospheric expectations,
then just spit back this message. I'll understand.
So at the end of the day you've got
import random
def randomNumbers(n):
if type(n)==int and n>0:
result=list()
for i in range(n):
result.append(random.randint(0,9))
return sum(result)/float(len(result))
else:
return "That's no good. Try a positive integer instead"
There's some stuff you can do with this code to make it more efficient. To make you curious, I'll give an example:
from random import randint
def randy(n:int):
return sum({randint(0,9) for i in range(n)})/n if n>0 else "Try again."
That gets into list comprehensions, sets, function annotations, and other stuff that you don't need to worry about. And frankly, that line of code might be too convoluted for good "Pythonic" code, but it's possible, which is cool.
Keep at it, and don't get discouraged. Python makes an effort to explain what you did wrong, and the community is generally pretty good if you've done your due diligence. Just don't abuse them(/us) by asking for help without seeking answers on your own first.
[1]technically they're pseudorandom but true randomness is hard to produce.
You are not on the right track. See this variate for the track.
import random
def randomNumbers(n):
l = random.sample(xrange(10), n)
return sum(l)/len(l)
Could be done more concisely with a list comprehension:
myList = [randrange(0, 9) for x in xrange(n)]
average = sum(myList) / len(myList)
You should think about making use of Numpy. This would make your task easy.
import numpy as np
def myfunc(n):
x = np.random.randint(low=0, high=10, size=n)
return np.mean(x)

Categories