Can't print binary heap in python - python

I try to make a binary heap in python but I get trouble printing it. I make sure that the logic in the program is right but when I want to try printing it I get the wrong result. This is what I want for program output:
Input:
6
1 2
1 3
1 7
2
3
2
Output:
7
3
command 1 to insert number
command 2 to display the highest number
command 3 to delete the highest number
This is my program:
class BinaryHeap:
def __init__(self):
self.items = []
def size(self):
return len(self.items)
def parent(self, i):
return (i - 1)//2
def left(self, i):
return 2*i + 1
def right(self, i):
return 2*i + 2
def get(self, i):
return self.items[i]
def get_max(self):
if self.size() == 0:
return None
return self.items[0]
def extract_max(self):
if self.size() == 0:
return None
largest = self.get_max()
self.items[0] = self.items[-1]
del self.items[-1]
self.max_heapify(0)
return largest
def max_heapify(self, i):
l = self.left(i)
r = self.right(i)
if (l <= self.size() - 1 and self.get(l) > self.get(i)):
largest = l
else:
largest = i
if (r <= self.size() - 1 and self.get(r) > self.get(largest)):
largest = r
if (largest != i):
self.swap(largest, i)
self.max_heapify(largest)
def swap(self, i, j):
self.items[i], self.items[j] = self.items[j], self.items[i]
def insert(self, key):
index = self.size()
self.items.append(key)
while (index != 0):
p = self.parent(index)
if self.get(p) < self.get(index):
self.swap(p, index)
index = p
bheap = BinaryHeap()
n = int(input())
for i in range (n):
operation= input('What would you like to do? ').split()
if operation == 1:
data = int(operation[1])
bheap.insert(data)
elif operation == 2:
print('Maximum value: {}'.format(bheap.get_max()))
elif operation == 3:
print('Maximum value removed: {}'.format(bheap.extract_max()))
elif operation == 4:
break
I need your opinion to fixed it.

operation is a list (you called split), but you compare it as an int in your if statements. Also, you should compare it against "1", "2", ... not 1, 2, ...
So:
operation = input('What would you like to do? ').split()
if operation[0] == "1":
data = int(operation[1])
bheap.insert(data)
elif operation[0] == "2":
print('Maximum value: {}'.format(bheap.get_max()))
elif operation[0] == "3":
print('Maximum value removed: {}'.format(bheap.extract_max()))
elif operation[0] == "4":
break
If you just want 7 and 3 in the output, and only after the input has been completely processed, then you should remove those verbose print statement (where you output phrases), and instead collect the output -- for instance in a list:
output = []
n = int(input())
for i in range(n):
operation = input('What would you like to do? ').split()
if operation[0] == "1":
data = int(operation[1])
bheap.insert(data)
elif operation[0] == "2":
output.append(bheap.get_max())
elif operation[0] == "3":
bheap.extract_max()
elif operation[0] == "4":
break
print("\n".join(map(str, output)))

Related

making recursion faster using array

I was trying to get this recursion faster but when I use numbers 50 and 44.4 it takes too long my desired outcome for those numbers is -800555.6302016332
z = int(input())
x = float(input())
def rec(n):
global x
l = {}
if n == 0:
return -1
elif n == 1:
return x
elif n == 2:
return -(x+1)/3
else:
if n in l:
return l[n]
value = float((n/x)*rec(n-1) + ((-1)**n)*((n+1)/(n-1)) * rec(n-2) + ((n-1)/(2*x))*rec(n-3))
l[n] = value
return value
print(rec(z))
You are reinitializing your dictionary l = {} each time you recurse. Making l a global var should fix your problem:
l = {}
def rec(n):
global x
global l
if n == 0:
return -1
elif n == 1:
return x
elif n == 2:
return -(x+1)/3
else:
if n in l:
return l[n]
value = float((n/x)*rec(n-1) + ((-1)**n)*((n+1)/(n-1)) * rec(n-2) + ((n-1)/(2*x))*rec(n-3))
l[n] = value
return value
You could also use functools.lru_cache which does memoization for you:
import functools
#functools.lru_cache
def rec(n):
global x
if n == 0:
return -1
elif n == 1:
return x
elif n == 2:
return -(x+1)/3
else:
return float((n/x)*rec(n-1) + ((-1)**n)*((n+1)/(n-1)) * rec(n-2) + ((n-1)/(2*x))*rec(n-3))
I would also suggest avoiding the use of global variables:
import functools
def rec(n, x):
#functools.lru_cache
def recurse(n):
if n == 0:
return -1
elif n == 1:
return x
elif n == 2:
return -(x+1)/3
else:
return float((n/x)*recurse(n-1) + ((-1)**n)*((n+1)/(n-1)) * recurse(n-2) + ((n-1)/(2*x))*recurse(n-3))
return recurse(n)
def main():
n = int(input())
x = float(input())
print(rec(n, x))
if __name__ == "__main__":
main()

Recursive Hexadecimal Conversion Python 3

I've made a hexadecimal converter to practice recursion/recursive thinking. I, however, The recurssion doesn't appear to be happening as the functions seems to just output the result of 9 as of current.The code is as follows:
import math
curr=0
def convert(x):
L=len(x)
L-=1
sol=0
if L == 0:
return 0
else:
if x[curr]==["A","a"]:
v=10
elif x[curr]==["B","b"]:
v=11
elif x[curr]==["C","c"]:
v=12
elif x[curr]==["D","d"]:
v=13
elif x[curr]==["E","e"]:
v=14
elif x[curr]==["F","f"]:
v=15
else:
v=int(x[curr])
sol+=((v)*(16**(L-1)))
return sol + convert(x[curr+1])
def main():
print(convert('98A'))
main()
You were setting L = len(x) everytime you call the function. Here is one solution:
import math
def convert(x, L):
c = len(x) - 1
sol=0
if L > c:
return 0
else:
if (x[L]=="A" or x[L]=="a"):
v=10
elif (x[L]=="B" or x[L]=="b"):
v=11
elif (x[L]=="C" or x[L]=="c"):
v=12
elif (x[L]=="D" or x[L]=="d"):
v=13
elif (x[L]=="E" or x[L]=="e"):
v=14
elif (x[L]=="F" or x[L]=="f"):
v=15
else:
v=int(x[L])
sol+=((v)*(16**(c - L)))
print(sol)
return sol + convert(x, L + 1)
def main():
print(convert('98A', 0))
main()
You can use something like this:
class HexMap:
# mapping char to int
d = { hex(n)[2:]:n for n in range(16)}
def convert(x):
s = 0
# use reverse string and sum up - no need for recursion
for i,c in enumerate(x.lower()[::-1]):
s += HexMap.d[c]*16**i
return s
def main():
print(convert('98A'))
main()
Output:
2442
Recursive version:
# class HexMap: see above
def convert(x):
def convert(x,fak):
if not x:
return 0
else:
return HexMap.d[x[-1]]*16**fak + convert(x[:-1],fak+1)
return convert(x.lower(),0)
def main():
print(convert('98A'))
main()
Same output.

Python Class Setters Not Changing Variables

The closest thread I could find to my problem was this: Python setter does not change variable
It didn't really help, the volume and the channels are not changing at all. The first fucntion which is to "watch TV" works perfectly fine.
class TV(object):
def __init__(self, channel, volume):
self.__channel = channel
self.__volume = volume
def __str__(self):
out = ""
out += "You're on channel #" + str(self.__channel) + ", " + self.channelNetwork()
out += "\nVolume is currently at: " + str(self.__volume) + "/20"
return out
# a method that determines the name for each channel from 1-10
def channelNetwork(self):
c = self.__channel
if c == 1:
return "CBS"
elif c==2:
return "NBC"
elif c==3:
return "ABC"
elif c==4:
return "Fox"
elif c==5:
return "ESPN"
elif c==6:
return "PBS"
elif c==7:
return "CNN"
elif c==8:
return "Comedy Central"
elif c==9:
return "Cartoon Network"
elif c==10:
return "Nicklodeon"
# a volume slider that has a range from 0-20
def volumeSlider(self, newVolume):
v = self.__volume
if newVolume == "+":
v += 1
else:
v -= 1
if v < 0:
v = 0
if v > 20:
v = 20
def channelChanger(self, newChannel):
c = self.__channel
if newChannel == "+":
c += 1
else:
c -= 1
if c < 0:
c = 0
if c > 10:
c = 10
def main():
import random
randomChannel = random.randint(1,10)
randomVolume = random.randrange(21)
televsion = TV(randomChannel, randomVolume)
choice = None
while choice != "0":
print \
("""
TV Simulator
0 - Turn off TV
1 - Watch TV
2 - Change channel
3 - Change volume
""")
choice = input("Choice: ")
print()
# exit
if choice == "0":
print("Have a good day! :)")
elif choice == "1":
print("You relax on your couch and watch some TV")
print(televsion)
elif choice == "2":
newChannel = None
while newChannel not in ('+', '-'):
newChannel = input("\nPress '+' to go up a channel and press '-' to go down a channel: ")
televsion.channelChanger(newChannel)
elif choice == "3":
newVolume = None
while newVolume not in ('+', '-'):
newVolume = input("\nPress '+' to increase volume and press '-' to decrease volume: ")
televsion.volumeSlider(newVolume)
else:
print("\nSorry, but", choice, "isn't a valid choice.")
main()
input("\n\nPress enter to exit.")
The problem is, that when you do:
v = self.__volume
In:
def volumeSlider(self, newVolume):
v = self.__volume
if newVolume == "+":
v += 1
else:
v -= 1
if v < 0:
v = 0
if v > 20:
v = 20
Assigning to v won't affect self.__volume. You need to use self.__volume = 20 or whatever.
As an aside, don't use double-underscore name-mangling unless you actually need it. E.g. self.volume is fine.

Trying to find the next prime number

MyFunctions file file -
def factList(p,n1):
counter = 1
while counter <= n1:
if n1 % counter == 0:
p.append(counter)
counter = counter + 1
def isPrime(lst1,nbr):
factList(lst1, nbr)
if len(lst1) == 2:
return True
else:
return False
def nextPrime(nbr1):
cnt1 = 1
while cnt1 == 1:
nbr1 == nbr1 + 1
if isPrime(lst2,nbr1):
cnt1 = 0
Filetester file -
nbr1 = 13
nextPrime(nbr1)
print nbr1
My isPrime function already works I'm tring to use my isPrime function for my nextPrime function, when I run this I get
">>>
13
" (when using 13)
">>> " (When using 14)
I am supposed to get 17 not 13. And if I change it to a composite number in function tester it gets back in a infinite loop. Please only use simple functions (the ones I have used in my code).
This is NOT the right way to do this, but this is the closest adaptation of your code that I could do:
def list_factors_pythonic(number):
"""For a given number, return a list of factors."""
factors = []
for x in range(1, number + 1):
if number % x == 0:
factors.append(x)
return factors
def list_factors(number):
"""Alternate list_factors implementation."""
factors = []
counter = 1
while counter <= number:
if number % counter == 0:
factors.append(counter)
return factors
def is_prime(number):
"""Return true if the number is a prime, else false."""
return len(list_factors(number)) == 2
def next_prime(number):
"""Return the next prime."""
next_number = number + 1
while not is_prime(next_number):
next_number += 1
return next_number
This would be helpful:
def nextPrime(number):
for i in range(2,number):
if number%i == 0:
return False
sqr=i*i
if sqr>number:
break
return True
number = int(input("Enter the num: ")) + 1
while(True):
res=nextPrime(number)
if res:
print("The next number number is: ",number)
break
number += 1
I don't know python but if it's anything like C then you are not assigning anything to your variables, merely testing for equality.
while cnt1 == 1:
nbr1 == nbr1 + 1
if isPrime(lst2,nbr1):
cnt1 == cnt1 + 1
Should become
while cnt1 == 1:
nbr1 = nbr1 + 1 << changed here
if isPrime(lst2,nbr1):
cnt1 = cnt1 + 1 << and here
Well this code help you
n=int(input())
p=n+1
while(p>n):
c=0
for i in range(2,p):
if(p%i==0):
break
else:c+=1
if(c>=p-2):
print(p)
break
p+=1
this code optimized for finding sudden next prime number of a given number.it takes about 6.750761032104492 seconds
def k(x):
return pow(2,x-1,x)==1
n=int(input())+1
while(1):
if k(n)==True:
print(n)
break
n=n+1

Evaluating infix expression with two stacks in python

This is my first time asking a question on here, and I am only doing this because I have spent the past week trying to figure this out and haven't been able to. I found similar questions, but the results did not help me. I have to take an infix expression and calculate the results using two stacks, one for the operator and one for the numbers. An example would be 6 - ( 5 - 3 ) * ( 4 + 2 ) = -6 or 3 * 11 / 8 + 5 – 4 * 7 = -18.875. I just cannot figure out how to get this to work. Currently my code is this:
class NumStack:
def __init__(self):
"""Create an empty stack."""
self._data = [] #nonpublic list instance
def __len__(self):
"""Return the number of elements in the stack."""
return len(self._data)
def is_empty(self):
"""Return True if the stack is empty."""
return len(self._data) == 0
def push(self,e):
"""Add element e to the top of the stack."""
self._data.append(e) #new item stored at end of list
print(self._data)
def top(self):
"""Return (but do not remove) the element at the top of the stack.
Raise Empty exception if the stack is empty"""
if self.is_empty():
return
return self._data[-1] #the last item in the list
def pop(self):
"""Remove and return the element from the top of the stack (i.e, LIFO)
Raise Empty exception if the stack is empty."""
if self.is_empty():
return "empty"
return self._data.pop() #remove last item from list
def str(self):
return self._data
class OperatorStack:
def __init__(self):
"""Create an empty stack."""
self._data = [] #nonpublic list instance
def __len__(self):
"""Return the number of elements in the stack."""
return len(self._data)
def is_empty(self):
"""Return True if the stack is empty."""
length = len(self._data)
if length == 0:
return True
else:
return False
def push(self,e):
"""Add element e to the top of the stack."""
self._data.append(e) #new item stored at end of list
print(self._data)
def top(self):
"""Return (but do not remove) the element at the top of the stack.
Raise Empty exception if the stack is empty"""
if self.is_empty():
return
return self._data[-1] #the last item in the list
def pop(self):
"""Remove and return the element from the top of the stack (i.e, LIFO)
Raise Empty exception if the stack is empty."""
length = len(self)
if length == 0:
print("list is empty")
else:
if self.is_empty():
return
return self._data.pop()
def str(self):
return self._data
def main():
expression = str(input("Enter an expression: "))
expression = expression.split()
print(expression)
N = NumStack()
O = OperatorStack()
new = []
NewOP = []
NewNum = [0,0]
for e in expression:
if e == '(' or e == ')' or e == '+' or e == '-' or e == '*' or e == '/':
O.push(e)
else:
N.push(e)
while O.is_empty() == False or N.is_empty() == False:
TmpOp = O.top()
if TmpOp == ')':
O.pop()
elif TmpOp == '(':
O.pop()
if TmpOp != '(' and TmpOp != ')':
new.append(N.pop())
new.append(O.pop())
print(TmpOp)
while TmpOp == ')':
if N.top() != "empty":
NewNum[1] = N.pop()
if N.top() != "empty":
NewNum[0] = N.top()
print(NewNum[0],NewNum[1])
if O.pop() == '+':
num = float(NewNum[1]) + float(NewNum[0])
new.append(num)
print(num)
O.pop()
break
elif O.pop() == '-':
num = float(NewNum[0]) - float(NewNum[1])
new.append(num)
print(num)
O.pop()
break
elif O.pop() == '*':
num = NewNum[1]*NewNum[0]
new.append(num)
print(num)
# O.pop()
break
elif O.pop() == '/':
num = NewNum[1]/NewNum[0]
new.append(num)
print(num)
# O.pop()
break
if O.top() == ')':
O.pop()
break
if O.__len__() == 0 and N.__len__() == 0:
break
continue
while TmpOp != ')' and TmpOp != '(':
new.append(N.pop())
new.append(O.pop())
print(new)
if O.__len__() == 0 and N.__len__() == 0:
break
print(new)
main()
I believe my classes to be correct, I just cannot find a way of extracting the needed information correctly. I am trying to pop the items into a list and when I get to a parenthesis I go ahead and perform the calculation. If I could just get the correct numbers into my list then I know I can get it to work. I just need to get the "new" to contain the correct numbers. With the problem: "6 - ( 5 - 3 ) * ( 4 + 2 )" I should get [6.0, '*', 2.0, '-', 6]. It is not coming out to that. I really appreciate any help that can be given.

Categories