Moving average program (Python) - python-3.x

I'm trying to solve a math problem but I would like to make some informatic tests before to understand what happend (and maybe find the solution with my program), my problem is :
Consider the list consisting of the first n natural numbers without zero, ie from 1 to n.
We define the transformation "moving average" on the list of n elements by adding the average of all the terms at the end of the list and eliminating the first term at the beginning of the list.
For example, if n = 4, we have: (1,2,3,4) -> (2,3,4,2.5)
By iterating this process many times, one can observe a phenomenon of standardization and that all elements of the list tend to a common value when the number of iterations tends to + infinity.
It asks for the value of n for this limit is 254859658745.
Well, i'm trying to program the function "moving average" like this :
def moving_average(liste,t):
k=0
S=0
m=0
c=0
n=len(liste)
while c<t:
while k<n:
S+=int(liste[k])
k+=1
m=S/n
liste.pop(0)
liste.append(m)
c+=1
return m
My program works but don't answer what I want, if I take liste=[1,2,3] (for example) for all t>1 the answer is always the same... but I don't understand why.
Can you help me please ?

In the interests of helping you move forwards, here is the first part of an answer. The way to debug this is like this:
def moving_average(liste,t):
k=0
S=0
m=0
c=0
n=len(liste)
while c<t:
print("At c: ", c)
k=0
while k<n:
print(" At k: ", k)
S+=int(liste[k])
k+=1
m=S/n
print(" .. new S", S)
print(" .. new k", k)
print(" .. new m", m)
liste.pop(0)
liste.append(m)
print(" liste: ", liste)
c+=1
return m
test_list = [1,2,3]
test_t = 4
print("Result:", moving_average(test_list, test_t))
Then look at each result until you find one that isn't what you expect
Since you know better than I do what you expect at each step, you might find the underlying issue quicker than I can by doing this :)
Update:
One "obvious" reason why it's not working is because you're not resetting k each time around the c loop.
If you look at the output before fixing, you will see that the "at K" messages only come out once, the first time through.
I've updated the code above to fix this, and I think it does something like you are expecting. I'm not sure why you are taking taking the int() of liste[k], but that is a separate issue.

Related

Execution timed out (12000ms) kata Generate Numbers from Digits #2 on Code Wars (Python)

Could you give me a hint where the time consuming part of this code is?
It's my temporary solutions for the kata Generate Numbers from Digits #2 from codewars.com.
Thanks!
from collections import Counter
from itertools import permutations
def proc_arrII(arr):
length = Counter(arr).most_common()[-1][1]
b = [''.join(x) for x in list(set(permutations(arr,length)))]
max_count = [max(Counter(x).values()) for x in b]
total = 0
total_rep = 0
maximum_pandigit = 0
for i in range(len(b)):
total+=1
if max_count[i] > 1:
total_rep+=1
elif int(b[i]) > maximum_pandigit:
maximum_pandigit = int(b[i])
if maximum_pandigit == 0:
return([total])
else:
return([total,total_rep,maximum_pandigit])
When posting this,
it would have been helpful to offer example input,
or link to the original question,
or include some python -m cProfile output.
Here is a minor item, it inflates the running time very very slightly.
In the expression [''.join(x) for x in list(set(permutations(arr, length)))]
there's no need to call list( ... ).
The join just needs an iterable, and a set works fine for that.
Here is a bigger item.
permutations already makes the promise that
"if the input elements are unique, there will be no repeat values in each permutation."
Seems like you want to dedup (with set( ... )) on the way in,
rather than on the way out,
for an algorithmic win -- reduced complexity.
The rest looks nice enough.
You might try benching without the elif clause,
using the expression max(map(int, b)) instead.
If there's any gain it would only be minor,
turning O(n) into O(n) with slightly smaller coefficient.
Similarly, you should just assign total = len(b) and be done with it,
no need to increment it that many times.

Why does the "AddOre" Function doesn't work?

I have been reading the book "Automate the Boring Stuff with Python" and trying to learn Python on my own, I decided to practice what I've learned in chapter one and got a little bit confused by this code and why it doesn't work.
Been sitting and trying to figure it out but still didn't make it.
I've tried to switch the given values of the function and other stuff as well but if I am being honest I don't really know what I am doing I will be very glad if someone explains causes the problem and how to fix it, here's the code :
Mine = {'Bronze': 10,'Iron': 40,'Gold': 2,'Diamonds':2}
def ShowMine(cave):
for k, v in cave.items():
Total_Res = 0
print("There is : " + str(k))
print("And there is : " + str(v) + " of it")
Total_Res += int(v)
print("total ores in the cave : " + str(Total_Res))
def AddOre(cave, ore):
for k,v in cave.items():
cave += ore.values()
Mine1 = {'Bronzze': 10,'Iron': 0,'Gold': 2,'Diamonds':4}
ShowMine(Mine)
AddOre(Mine,Mine1)
ShowMine(Mine)
I expect the code to output the added values from Mine1 to the original Mine created at the start of the program.
The two arguments cave and ore of the function AddOre are both dictionaries. The function then iterates over the items of the first arguments and in each iteration tries to add the return value of ore.values(), which is a list, to the dictionary cave. This doesn't work and I'm not sure what the result of that operation is even supposed to be.
What you want to do, I'm guessing, is to add the values of the second argument to the values of the first argument identifying them by their keys. This can be done by this code:
def AddOre(cave, ore):
for k, _ in cave.items():
if k in ore:
cave[k] += ore[k]
for k, v in ore.items():
if k not in cave:
cave[k] = v
The first loop adds the values of the ores that already exist in the cave and the second loop adds all the new ores. There might be a simpler way to do the same thing with native addition operations of list and dictionary types, but I can't think of any right now.

Locating prime numbers using for loop(s) in Python

So first of all, I realise there are much easier ways to get a list of prime numbers, but I'm just doing this to learn. I have a very poor understanding of a lot of this (as you'll see) so sorry if this is a dumb question. I'm trying to learn.
#make an empty list to store primes in
primes = list()
#make a variable to easily change the amount of numbers I test for primality
high_val = 15
#Allocate a range that I will test all numbers in for primality
for n in range(2, high_val):
#Within the previous for loop, start another for loop to test every integer against every
#value inside the primes list
for p in primes:
if n % p == 0:
print(%s is not prime" % n)
else:
#If n is prime, I add it to the list and print that it is prime
primes.append(n)
print("%s is a prime" % n)
I don't know if those comments make it harder to read, but that's my logic. There is no print output for the function. So I figured, there's just no value in primes, I need to give it something to compare to. So I added a primes.append(2) at the start immediately after the first line, and changed the range to (3, high_val)...
If I do that, it ends up printing about 5 times for every number that it is prime and 5 more messages saying it is not prime. Clearly I'm doing something massively wrong, if anyone knows where I went wrong and/or how to fix this that would be greatly appreciated. Thanks!
The thing is that you are missing some flags: you are printing if the number is prime every time you check it against another number. You should print it only after iterating over all primes.
About this, consider using all:
primes = [2]
high_val = 15
for n in range(3, high_val, 2):
if all(n % p == 0 for p in primes):
print(f"{n} is prime")
primes.append(n)
else:
print(f"{n} is not prime")
ps: I didn't test it.

Can someone help me with my Goldbach code ? When i call the function and then put 1,000,000 it seems not to spit out any output i dont know why?

I need to reach 1,000,000 and for some reason it doesn't give me the output for 1,000,000, I don't know what i am doing wrong. Every time i put a small number like 500 it would give me the correct output but as soon as i put 999,999 or 1,000,000 it just doesn't give out any output and when i do a keyboard interruption it says it stopped at break but I need that break in order for the values to only repeat once.
bachslst=[]
primeslst=[]
q=[]
newlst=[]
z=[]
def goldbach(limit):
primes = dict()
for i in range(2, limit+1):
primes[i] = True
for i in primes:
factors = range(i, limit+1, i)
for f in factors[1:]:
primes[f] = False
for i in primes:
if primes[i]==True:
z.append(i)
for num in range(4,limit+1,2):
for k in range(len(z)):
for j in z:
if (k + j ) == num :
x=(str(k),str(j))
q.append(x)
newlst.append([x,[num]])
break
bachslst.append(num)
print(bachslst,'\n')
return newlst
The break that is referred to is not the break in the code, it is the break caused by the keyboard interrupt.
If you want to get your result in less than 1.5 hours, try to reduce the amount of computing that you are doing. There are many implementations for testing the Goldbach Conjecture if you do a search. Some are in other languages, but you can still use them to influence your algorithm.
I have not looked at it, but here is another implementation in Python: https://codereview.stackexchange.com/questions/99161/function-to-find-two-prime-numbers-that-sum-up-to-a-given-even-number

make a function that take an integer and reduces it down to an odd number

I'm working on my final for a class I'm taking(Python 3) im stuck at this part.
he gave us a file with numbers inside of it. we opened it and add those numbers to a list.
"Create a function called makeOdd() that returns an integer value. This function should take in any integer and reduce it down to an odd number by dividing it in half until it becomes an odd number.
o For example 10 would be cut in half to 5.
o 9 is already odd, so it would stay 9.
o But 12 would be cut in half to 6, and then cut in half again to 3.
o While 16 would be cut to 8 which gets cut to 4 which gets cut to 2 which gets cut to 1.
 Apply this function to every number in the array. "
I have tried to search the internet but i have not clue where to even begin with this one. any help would be nice.
Here my whole final so far:
#imports needed to run this code.
from Final_Functions import *
#Defines empty list
myList = []
sumthing = 0
sortList = []
oddList = []
count = 0
#Starts the Final Project with my name,class, and quarter
intro()
print("***************************************************************",'\n')
#Opens the data file and reads it then places the intrager into a list we can use later.
with open('FinalData.Data', 'r') as f:
myList = [line.strip() for line in f]
print("File Read Complete",'\n')
#Finds the Sum and Adverage of this list from FinalData.Data
print("*******************sum and avg*********************************")
for oneLine in myList:
tempNum = int(oneLine)
sumthing = sumthing + tempNum
avg = sumthing /1111
print("The Sum of the List is:",sumthing)
print("The Adverage of the List is:",avg,'\n')
print("***************************************************************",'\n')
#finds and prints off the first Ten and the last ten numbers in the list
firstTen(myList)
lastTen(myList)
print("***************************************************************",'\n')
#Lest sort the list then find the first and last ten numbers in this list
sortList = myList
sortList.sort()
firstTen(sortList)
lastTen(sortList)
print("****************************************************************",'\n')
Language:Python 3
I don't want to give you the answer outright, so I'm going to talk you through the process and let you generate your own code.
You can't solve this problem in a single step. You need to divide repeatedly and check the value every time to see if it's odd.
Broadly speaking, when you need to repeat a process there are two ways to proceed; looping and recursion. (Ok, there are lots, but those are the most common)
When looping, you'd check if the current number x is odd. If not, halve it and check again. Once the loop has completed, x will be your result.
If using recursion, have a function that takes x. If it's odd, simply return x, otherwise call the function again, passing in x/2.
Either of those methods will solve your problem and both are fundamental concepts.
adding to what #Basic said, never do import * is a bad practice and is a potential source of problem later on...
looks like you are still confuse in this simple matter, you want to given a number X reduce it to a odd number by dividing it by 2, right? then ask yourself how I do this by hand? the answer is what #Basic said you first ask "X is a even number?" if the answer is No then I and done reducing this number, but if the answer is Yes then the next step dividing it by 2 and save the result in X, then repeat this process until you get to the desire result. Hint: use a while
to answer your question about
for num in myList:
if num != 0:
num = float(num)
num / 2
the problem here is that you don't save the result of the division, to do that is as simple as this
for num in myList:
if num != 0:
num = float(num)
num = num / 2

Resources