관리 메뉴

Jun Hyuk Kim's Blog

About testing and printing 본문

Coding Explanation

About testing and printing

junhyuk1229 2022. 12. 20. 12:56

I learned the importance of testing and printing from the previous 2 days.

class MaxMinHeap:
    def __init__(self, max_len):
        self.heap_arr = [0 for _ in range(max_len + 1)]
        self.arr_len = 0

    def empty(self):
        if self.arr_len == 0:
            return True
        return False

    def is_min_level(self):
        if math.floor(math.log2(self.arr_len)) % 2 == 1:
            return False
        return True

    def insert_num(self, input_num):
        self.arr_len += 1
        self.heap_arr[self.arr_len] = input_num
        if self.arr_len == 1:
            return
        elif self.is_min_level():
            self.min_insert()
        else:
            self.max_insert()

    def max_insert(self):
        if self.heap_arr[self.arr_len // 2] > self.heap_arr[self.arr_len]:
            self.heap_arr[self.arr_len], self.heap_arr[self.arr_len // 2] = self.heap_arr[self.arr_len // 2], self.heap_arr[self.arr_len]
            self.minify_up(self.arr_len // 2)
        else:
            self.maxity_up(self.arr_len)

    def min_insert(self):
        if self.heap_arr[self.arr_len // 2] < self.heap_arr[self.arr_len]:
            self.heap_arr[self.arr_len], self.heap_arr[self.arr_len // 2] = self.heap_arr[self.arr_len // 2], self.heap_arr[self.arr_len]
            self.maxity_up(self.arr_len // 2)
        else:
            self.minify_up(self.arr_len)

    def max_output(self):
        if self.empty():
            return None
        if self.arr_len == 1:
            self.arr_len -= 1
            return self.heap_arr[1]
        temp_index = 2
        if temp_index + 1 <= self.arr_len and self.heap_arr[temp_index] < self.heap_arr[temp_index + 1]:
            temp_index += 1
        self.heap_arr[self.arr_len], self.heap_arr[temp_index] = self.heap_arr[temp_index], self.heap_arr[self.arr_len]
        self.arr_len -= 1
        self.maxify_down(temp_index)
        return self.heap_arr[self.arr_len + 1]

    def min_output(self):
        if self.empty():
            return None
        self.heap_arr[self.arr_len], self.heap_arr[1] = self.heap_arr[1], self.heap_arr[self.arr_len]
        self.arr_len -= 1
        self.minify_down(1)
        return self.heap_arr[self.arr_len + 1]

    def maxify_down(self, input_index):
        while input_index * 2 <= self.arr_len:
            if input_index * 4 > self.arr_len:
                comp_index = input_index * 2
                if comp_index + 1 <= self.arr_len and self.heap_arr[comp_index] < self.heap_arr[comp_index + 1]:
                    comp_index += 1
                if self.heap_arr[input_index] < self.heap_arr[comp_index]:
                    self.heap_arr[input_index], self.heap_arr[comp_index] = self.heap_arr[comp_index], self.heap_arr[input_index]
                return
            comp_index = input_index * 2 + 1
            for temp_index in range(input_index * 4, input_index * 4 + 4):
                if temp_index <= self.arr_len and self.heap_arr[comp_index] < self.heap_arr[temp_index]:
                    comp_index = temp_index
            if self.heap_arr[input_index] < self.heap_arr[comp_index]:
                self.heap_arr[input_index], self.heap_arr[comp_index] = self.heap_arr[comp_index], self.heap_arr[input_index]
            if comp_index == input_index * 2 + 1:
                return
            if self.heap_arr[comp_index] < self.heap_arr[comp_index // 2]:
                self.heap_arr[comp_index // 2], self.heap_arr[comp_index] = self.heap_arr[comp_index], self.heap_arr[comp_index // 2]
            input_index = comp_index

    def minify_down(self, input_index):
        while input_index * 2 <= self.arr_len:
            if input_index * 4 > self.arr_len:
                comp_index = input_index * 2
                if comp_index + 1 <= self.arr_len and self.heap_arr[comp_index] > self.heap_arr[comp_index + 1]:
                    comp_index += 1
                if self.heap_arr[input_index] > self.heap_arr[comp_index]:
                    self.heap_arr[input_index], self.heap_arr[comp_index] = self.heap_arr[comp_index], self.heap_arr[input_index]
                return
            comp_index = input_index * 2 + 1
            for temp_index in range(input_index * 4, input_index * 4 + 4):
                if temp_index <= self.arr_len and self.heap_arr[comp_index] > self.heap_arr[temp_index]:
                    comp_index = temp_index
            if self.heap_arr[input_index] > self.heap_arr[comp_index]:
                self.heap_arr[input_index], self.heap_arr[comp_index] = self.heap_arr[comp_index], self.heap_arr[input_index]
            if comp_index == input_index * 2 + 1:
                return
            if self.heap_arr[comp_index] > self.heap_arr[comp_index // 2]:
                self.heap_arr[comp_index // 2], self.heap_arr[comp_index] = self.heap_arr[comp_index], self.heap_arr[comp_index // 2]
            input_index = comp_index

    def maxity_up(self, input_index):
        while input_index // 4 > 0:
            comp_index = input_index // 4
            if self.heap_arr[comp_index] >= self.heap_arr[input_index]:
                break
            self.heap_arr[comp_index], self.heap_arr[input_index] = self.heap_arr[input_index], self.heap_arr[comp_index]
            input_index = comp_index

    def minify_up(self, input_index):
        while input_index // 4 > 0:
            comp_index = input_index // 4
            if self.heap_arr[comp_index] <= self.heap_arr[input_index]:
                break
            self.heap_arr[comp_index], self.heap_arr[input_index] = self.heap_arr[input_index], self.heap_arr[comp_index]
            input_index = comp_index

I made the following code and got lots of errors(It is fixed now).

This made the debugging process so hard to follow.

So I uploaded the problem to stackoverflow: https://stackoverflow.com/questions/74849006/having-problems-making-a-max-min-priority-queuepython/74852593#74852593

 

Having problems making a max-min priority queue(python)

I made a min-max priority queue in python. I tested it using my example and had no problems, but the coding website(a site like leetcode) said that the output was wrong(Not an error)... Is there any

stackoverflow.com

 

The answer I got helped alot, and if you never tested your code I recommend reading the response(Thank you so much!).

From this I learned the importance of testing. All the code below are from the response.

 

First is to print the class to get the output we want.

def print(self, i=1, tab=""):
    if i > self.arr_len:
        return
    self.print(i * 2 + 1, tab + "     ")
    print(tab, self.heap_arr[i])
    self.print(i * 2, tab + "     ")

Adding this single simple function to the class made all the debugging processes easier to view.

 

Next is a verify function to check if the heap is correct.

def verify(self, i=1, is_min=True, low=-math.inf, high=math.inf):
    if i > self.arr_len:
        return
    val = self.heap_arr[i]
    if not (low <= val <= high):
        self.print()
        raise ValueError(f"inconsistent heap at {val}")
    if is_min:
        low = val
    else:
        high = val
    self.verify(i*2, not is_min, low, high)
    self.verify(i*2+1, not is_min, low, high)

This will print an error if the input is wrong with the exact point it cases an error.

 

Lastly 'random' import is used to input a random input and get the corresponding output.

import random

orig = list(range(20))
for i in range(100):  # repeat a few times with different shuffles of input
    values = orig[:]
    random.shuffle(values)
    heap  = MaxMinHeap(len(values)+3)  # Allocate enough space for the heap
    for value in values:  # Insert the values in their shuffled order
        heap.insert_num(value)
        heap.verify()  # ... and each time verify all is well

    res = []  # output of values as they are removed from the heap
    while not heap.empty():
        res.append(heap.min_output())
        heap.verify()

    if res != orig:
        print(values)
        print("Removal was not in order", res)
        break

This will check if the heap is correct for every random input and output.

 

These steps will be used by me for future code where the code is too long to debug.

'Coding Explanation' 카테고리의 다른 글

[SSH] Transfering files between servers  (0) 2023.08.07
[Backend] CORS  (0) 2023.08.06
About printing string formats in python  (0) 2023.03.08