Problem with a Python function - python

Well I have a little problem. I want to get the sum of all numbers below to 1000000, and who has 4 divisors...
I try, but i have a problem because the GetTheSum(n) function always returns the number "6"...
This is my Code :
http://pastebin.com/bhiDb5fe

The problem seems to be that you return as soon as you find the first number (which is 6).
You have this:
def GetTheSum(n):
k = 0
for d in range(1,n):
if NumberOfDivisors(d) == 4:
k += d
return k
But you have probably meant this:
def GetTheSum(n):
k = 0
for d in range(1,n):
if NumberOfDivisors(d) == 4:
k += d
return k

Related

Best way to store the bigger out of 2 numbers

I am trying to make my python program as optimised as possible, and there is this portion I am unsure about. I need to store the largest value obtained so far, and I have 2 candidate codes to do so. Which one is the most time-optimised? Or is there a faster way to do so?
Code 1:
if value > biggest_value:
biggest_value = value
Code 2:
biggest_value = max(biggest_value, value)
Context:
def check_palindrome(num):
num = str(num)
if len(num) < 1:
return True
else:
if num[0] == num[-1]:
return check_palindrome(num[1:-1])
else:
return False
def main():
biggest_product = 0
for a in range(100, 1000):
for b in range(100, 1000):
product = a * b
if check_palindrome(product):
# store the biggest_product here
return biggest_product
main()
Code 2 is the better option because in Code 1 you have to compare the numbers with 2 commands ( < = ) and in Code 2 you only have one command.
Good Luck with your Programm and have fun!
Jonas

Divide and Conquer. Find the majority of element in array

I am working on a python algorithm to find the most frequent element in the list.
def GetFrequency(a, element):
return sum([1 for x in a if x == element])
def GetMajorityElement(a):
n = len(a)
if n == 1:
return a[0]
k = n // 2
elemlsub = GetMajorityElement(a[:k])
elemrsub = GetMajorityElement(a[k:])
if elemlsub == elemrsub:
return elemlsub
lcount = GetFrequency(a, elemlsub)
rcount = GetFrequency(a, elemrsub)
if lcount > k:
return elemlsub
elif rcount > k:
return elemrsub
else:
return None
I tried some test cases. Some of them are passed, but some of them fails.
For example, [1,2,1,3,4] this should return 1, buit I get None.
The implementation follows the pseudocode here:
http://users.eecs.northwestern.edu/~dda902/336/hw4-sol.pdf
The pseudocode finds the majority item and needs to be at least half. I only want to find the majority item.
Can I get some help?
Thanks!
I wrote an iterative version instead of the recursive one you're using in case you wanted something similar.
def GetFrequency(array):
majority = int(len(array)/2)
result_dict = {}
while array:
array_item = array.pop()
if result_dict.get(array_item):
result_dict[array_item] += 1
else:
result_dict[array_item] = 1
if result_dict[array_item] > majority:
return array_item
return max(result_dict, key=result_dict.get)
This will iterate through the array and return the value as soon as one hits more than 50% of the total (being a majority). Otherwise it goes through the entire array and returns the value with the greatest frequency.
def majority_element(a):
return max([(a.count(elem), elem) for elem in set(a)])[1]
EDIT
If there is a tie, the biggest value is returned. E.g: a = [1,1,2,2] returns 2. Might not be what you want but that could be changed.
EDIT 2
The pseudocode you gave divided into arrays 1 to k included, k + 1 to n. Your code does 1 to k - 1, k to end, not sure if it changes much though ? If you want to respect the algorithm you gave, you should do:
elemlsub = GetMajorityElement(a[:k+1]) # this slice is indices 0 to k
elemrsub = GetMajorityElement(a[k+1:]) # this one is k + 1 to n.
Also still according to your provided pseudocode, lcount and rcount should be compared to k + 1, not k:
if lcount > k + 1:
return elemlsub
elif rcount > k + 1:
return elemrsub
else:
return None
EDIT 3
Some people in the comments highligted that provided pseudocode solves not for the most frequent, but for the item which is present more that 50% of occurences. So indeed your output for your example is correct. There is a good chance that your code already works as is.
EDIT 4
If you want to return None when there is a tie, I suggest this:
def majority_element(a):
n = len(a)
if n == 1:
return a[0]
if n == 0:
return None
sorted_counts = sorted([(a.count(elem), elem) for elem in set(a)], key=lambda x: x[0])
if len(sorted_counts) > 1 and sorted_counts[-1][0] == sorted_counts[-2][0]:
return None
return sorted_counts[-1][1]

Brute Force Sudoku Recursion in Python

I have tried to implement the brute force approach to solving a Sudoku puzzle using Python, as explained in the following link: http://en.wikipedia.org/wiki/Sudoku_solving_algorithms#Brute-force_algorithm
I am aware there are other threads with the same question. I have read through all of them and still keep having problems.
Here is my code for recursion:
def recurse(x, k, grid):
if x > 8:
for line in grid:
print line
raw_input()
if grid[x][k] == '0':
for number in '123456789':
if clear(number, x, k, grid):
grid[x] = grid[x][0:k] + number + grid[x][k+1:]
k += 1
if k > 8:
x += 1
k = 0
recurse(x, k, grid)
k -= 1
if k < 0:
x -= 1
k = 8
else:
k += 1
if k > 8:
x += 1
k = 0
recurse(x, k, grid)
Basically I keep the Sudoku in an array of 9x9 slots, where grid[x] accesses the xth line of the entire Sudoku and grid[x][k] accesses the kth number at the xth line.
There is a function up there called 'clear' which finds out whether a certain number can fit in that slot or not. I have tested it many times and it works properly. Problem here is that the value 'x' never goes above 8, which means the Sudoku never reaches the end. The recursion stops before all the slots are filled in correctly. I am quite inexperienced in writing recursive methods so please bear with me.
I figured, if a number fits in a slot, then that number is placed within that slot and then k is incremented. If k is above 8, then it means it is end of the line so we skip to the next line. Then the recurse function is called again. If a recurse function ends without being able to call itself again, then this means no number fits in that slot so we have to go back. In that case, k is decremented.
So what is the problem here exactly?
You forgot to reset the cells before backtracking. You're leaving wrong numbers all over the place, and at some point there is no valid number to fill in any more, and execution stops.
Add grid[x] = grid[x][0:k] + '0' + grid[x][k+1:] after
k -= 1
if k < 0:
x -= 1
k = 8
to fix this.
To stop recursing when a solution has been found:
def recurse(x, k, grid):
if x>8:
return grid
if grid[x][k] == '0':
for number in '123456789':
if clear(number, x, k, grid):
grid[x] = grid[x][0:k] + number + grid[x][k+1:]
k += 1
if k > 8:
x += 1
k = 0
solution= recurse(x, k, grid)
if solution:
return solution
k -= 1
if k < 0:
x -= 1
k = 8
grid[x] = grid[x][0:k] + '0' + grid[x][k+1:]
else:
k += 1
if k > 8:
x += 1
k = 0
return recurse(x, k, grid)

While loop code keeps running

For some reason this code doesn't print anything and doesn't stop running, can anybody tell me what is going wrong here?
l = [1,2]
i = 0
k = l[i]+l[i+1]
while k <= 10:
l.append(k)
i += 1
print l
The value of k (and therefore the loop condition) is set before the loop using the current value of i (0), and never changes during the loop execution. You would have to reassign k based on the new value for i inside the loop for it to change.
Python evaluates the value of k so that k isn't the expression, but the result of that expression:
k = l[i]+l[i+1] # In your case it's l[0] + l[1] = 3
You probably want to evaluate k every loop:
l = [1,2]
i = 0
for i in range(0, 10 + 1):
l.append(l[i] + l[i + 1])
print l
And just for fun, a more Pythonic Fibonacci sequence generator (literally):
def Fibonacci():
a, b = 0, 1
while True:
yield a
a += b
a, b = b, a
for n in Fibonacci():
raw_input(n)
Just move the line with k in it:
l = [1,2]
i = 0
k = l[i]+l[i+1]
while k <= 10:
l.append(k)
i += 1
k = l[i]+l[i+1]
print l
You're not doing any changes to the k variable. Once you calculate the value of K, the code gets stock in the while loop because the value of k never changes, you simply keep appending the value of k to the list.
not sure about python,
but looks like you update the value of K ever also, not sure what is the scope of the while loop in python syntax.

Trouble with Recursion in Python

Working with python 2.7.
The following code allows me to input the winning percentage of two teams (WP_1 and WP_2) a number of wins (k) and determine given the two team's winning percentages, the probability that team one will have more wins at the end of the season (Playoff_Probability):
def PlayoffProb(WP_1, k, WP_2):
TProb_2 = 0
p = float(WP_1)/1000
q = float(WP_2)/1000
n = 162.0
G = math.factorial(n)/(math.factorial(k)*math.factorial(n-k))
Prob = G*(p**k)*((1-p)**(n-k))
for c in range(0, k):
G_2 = math.factorial(n)/(math.factorial(c)*math.factorial(n-c))
Prob_2 = G_2*(q**c)*(1-q)**(n-c)
TProb_2 += Prob_2
Playoff_Probability = Prob*TProb_2
print Playoff_Probability
print TProb_2
But what would be a lot easier is if the function could be written recursively so that it would perform the same operation over every possible value of k and return the total probability of ending the season with more wins (which I believe should be given by the Playoff_Probability for each value run through the function of k, which I've tried to set equal to Total_Playoff_Probability).
I've tried the following code, but I get a TypeError telling me that 'float' object is not callable at the return Total_Playoff_Probability step. I'm also not at all sure that I've set up the recursion appropriately.
def PlayoffProb2(WP_1, k, WP_2):
TProb_2 = 0
Total_Playoff_Probability = 0
p = float(WP_1)/1000
q = float(WP_2)/1000
n = 162.0
G = math.factorial(n)/(math.factorial(k)*math.factorial(n-k))
Prob = G*(p**k)*((1-p)**(n-k))
for c in range(0, k):
G_2 = math.factorial(n)/(math.factorial(c)*math.factorial(n-c))
Prob_2 = G_2*(q**c)*(1-q)**(n-c)
TProb_2 += Prob_2
Playoff_Probability = Prob*TProb_2
Total_Playoff_Probability += Playoff_Probability
if k == 162:
return Total_Playoff_Probability
else:
return PlayoffProb2(WP_1, k+1, WP_2)
Any help would be greatly appreciated!
return Total_Playoff_Probability(WP_1, k+1, WP_2)
I think you meant
return PlayoffProb2(WP_1, k+1, WP_2)
You've got that error because you are trying to treat a floating point number as a function. Obviously, that doesn't compute.
EDIT
Actually, it should be:
return Total_Playoff_Probability + PlayoffProb2(WP_1, k+1, WP_2)
As it is, you aren't doing anything with Total_Playoff_Probability after you calculate it. If k != 167, you just return the value for k+1.
You've called your function PlayoffProb2. You must use that name when you recurse.

Categories