Exemple #1
0
    def __init__(self, array):
        super(TripletMaker, self).__init__()
        if array is None or len(array) < 0:
            raise Exception("WTF man an empty array is not valid")

        self.tree = {}
        for item in range(-100, 101):
            self.tree[item] = 0

        for item in array:
            try:
                if type(item) is str:
                    item = int(item)
                self.tree[item] += 1
            except ValueError as e:
                warning("Not a valid item {0}".format(item))
                continue

        # Don't do this shit if we aren't in debug mode
        if messages.debug_mode:
            self.size = 0
            for key in range(-100, 101):
                value = self.tree[key]
                self.size += value
                verbose("Key: {0};      Value: {1}".format(key, value))
            verbose("size {0}".format(self.size))

        self.size = len(array) - 1
        self.time = None
        self.done = False
        self.triplets = []
        self.domain = list(range(-100, 101))
Exemple #2
0
def hashBase64(string, tsize=4):
    """Create a hash of a given string

    :string: TODO
    :returns: TODO

    """
    global __values

    if len(__values) == 0:
        base64Values()

    start = time()

    bstring = ""

    for i in str(string):
        bits = bin(ord(i))[2:]
        bsize = len(bits)
        if bsize < 8:
            bits = "0" * (8 - bsize) + bits
        bstring = bstring + bits

    encode = ""
    while len(bstring) > 0:
        encode += __values[int(bstring[0:6], 2)]
        bstring = bstring[6:]

    hashvalue = sum(ord(x) for x in encode)
    end = time()
    verbose("Hash: {0}".format(hashvalue))
    verbose("Hashing time: {0}".format(end - start))
    return hashvalue % 4
Exemple #3
0
    def __init__(self, size=4, json_db=None, hashfunction=None):
        super(HashDataBase, self).__init__()
        self.size = size
        self.container = []
        self.collisions = []
        self.numbers = {}
        self.last_names = {}

        for item in range(0, size):
            # self.container.append(BTree())
            self.container.append({})
            self.collisions.append(0)

        self.hashfunction = hashBase64 if hashfunction is None else hashfunction

        if json_db is not None and path.isfile(json_db):
            with open(json_db, "r") as database:
                data = json.load(database)
                for rid, register in data.items():
                    verbose("Register: {0}".format(register))
                    element = self.Register(
                        name=register["name"],
                        last_name=register["last_name"],
                        address=register["address"],
                        cellphone=register["cellphone"],
                        email=register["email"],
                        social_network=register["social_network"])
                    self.insert(register=element)
        elif json_db is not None and not path.isfile(json_db):
            error("{0} must be a valid json file to load the registers")
Exemple #4
0
def hashAscii(string, tsize=4):
    start = time()
    if type(string) != str:
        raise Exception(
            "Only strings are allow to be used in this hash function")
    hashvalue = sum(ord(x) for x in string)
    end = time()
    verbose("Hash: {0}".format(hashvalue))
    verbose("Hashing time: {0}".format(end - start))
    return hashvalue % tsize
Exemple #5
0
    def insert(self, register=None):
        """TODO: Docstring for insert.

        :register: TODO
        :returns: TODO

        """
        if register is None:
            valid = False
            while not valid:
                name = input("Enter name: ")
                last_name = input("Enter last name: ")
                address = input("Enter address: ")
                cellphone = input("Enter cellphone: ")
                if cellphone in self.numbers:
                    error("This cellphone is already in use")
                    continue
                valid = True
                email = input("Enter email address: ")
                social_network = input("Enter social network: ")
            register = self.Register(name, last_name, address, cellphone,
                                     email, social_network)
        rc = False
        start = time()

        hashvalue = self.hashfunction(register.name)

        isEmpty = False

        # TODO: This must be changed for the tree
        if len(self.container[hashvalue]) == 0:
            isEmpty = True

        # TODO: This must be changed for the tree
        self.container[hashvalue][register.name] = register

        self.numbers[register.cellphone] = hashvalue
        if register.last_name not in self.last_names:
            self.last_names[register.last_name] = [hashvalue]
        else:
            self.last_names[register.last_name].append(hashvalue)

        if not isEmpty:
            self.collisions[hashvalue] += 1

        verbose("Collisions in container {0}: {1}".format(
            hashvalue, self.collisions[hashvalue]))

        rc = True
        status("Register inserted")

        end = time()
        verbose("Insertion time {0}".format(end - start))

        return rc
Exemple #6
0
    def _save_triplet(self, first, second, third):
        """TODO: Docstring for _save_triplet.

        :triplet: TODO
        :returns: TODO

        """
        triplet = self._remove_numbers(first, second, third)
        verbose("Found triplet {0}".format(triplet))
        self.done = False
        self.triplets.append(triplet)
Exemple #7
0
def main():
    """Main CLI function
    :returns: TODO

    """
    global debug_mode
    global start_time

    cli_args = __parse_arguments()

    if cli_args.version:
        status("Current version {0}".format(__version__))
        return 0

    messages.debug_mode = cli_args.verbose
    messages.quiet = cli_args.quiet
    messages.logger = cli_args.logger

    if cli_args.hash == 1:
        hashfunction = hashAscii
    else:
        hashfunction = hashBase64

    verbose("Hash function {0}".format(repr(hashfunction.__name__)))

    action = ""

    table = HashDataBase(hashfunction=hashfunction, json_db=cli_args.json)

    # While True is always a bad idea
    while action.upper() != "E":
        action = input(MAIN_MENU)
        if action == "1":
            table.insert()
        elif action == "2":
            result = table.search()
            if result is not None and len(result) == 0:
                status("Register: {0}".format(result))
            elif result is not None and len(result) > 0:
                for item in result:
                    status("Register: {0}".format(item))
            else:
                error("Element was not found")
        elif action == "3":
            table.update()
        elif action == "4":
            table.delete()
        elif action == "5":
            for item in table.container:
                for name, register in item.items():
                    status("Register: {0}".format(register))
        elif action.upper() != "E":
            status("Sin acción en {action}".format(action=action))
Exemple #8
0
def check_files(size=1000, filename="", override=False):
    """TODO: Docstring for check_files.

    :size: TODO
    :returns: TODO

    """

    if filename == "":
        filename = get_filename(size) + ".txt"

    if not os.path.isfile(filename) or override is True:
        if os.path.isfile(filename) and override is True:
            verbose("Removing {0}".format(filename))
        gen_files(size, filename)
Exemple #9
0
    def delete(self, register=None, name=None, last_name=None, cellphone=None):
        """TODO: Docstring for insert.

        :register: TODO
        :returns: TODO

        """
        selected_type = -1
        if register is None and name is None and last_name is None and cellphone is None:
            parameter, selected_type = self._select_search_type()
        elif register is not None:
            parameter = register.name
            selected_type = 0
        elif name is not None:
            parameter = name
            selected_type = 0
        elif last_name is not None:
            parameter = last_name
            selected_type = 1
        elif cellphone is not None:
            parameter = cellphone
            selected_type = 2

        rc = False
        start = time()

        if selected_type == 0:
            register = self.search(name=parameter)
        elif selected_type == 1:
            register = self.search(last_name=parameter)
        elif selected_type == 2:
            register = self.search(cellphone=parameter)

        if register is not None:
            # Register is not None so if its len is 0 then is just one register
            hashvalue = self.hashfunction(register.name)
            if len(register) == 0:
                self._delete_register(register, hashvalue)
            else:
                for item in register:
                    self._delete_register(item, hashvalue)
        else:
            error("{0} could not be deleted".format(parameter))

        end = time()
        verbose("Deletion time {0}".format(end - start))

        return rc
Exemple #10
0
    def update(self, register=None, name=None, last_name=None, cellphone=None):
        """TODO: Docstring for insert.

        :register: TODO
        :returns: TODO

        """
        selected_type = -1
        if register is None and name is None and last_name is None and cellphone is None:
            parameter, selected_type = self._select_search_type()
        elif register is not None:
            parameter = register.name
            selected_type = 0
        elif name is not None:
            parameter = name
            selected_type = 0
        elif last_name is not None:
            parameter = last_name
            selected_type = 1
        elif cellphone is not None:
            parameter = cellphone
            selected_type = 2

        rc = False
        start = time()

        hashvalue = self.hashfunction(parameter, selected_type)
        # register = self.container[hashvalue].search(parameter, selected_type)
        if parameter in self.container[hashvalue]:
            register = self.container[hashvalue][parameter]
            register = self._update_field(register)
            self.container[hashvalue][parameter] = register
            status("Register updated")
        else:
            # if register is None:
            error("{0} doesn't exists".format(parameter, selected_type))
        # else:
        #     pass

        end = time()
        verbose("Update time {0}".format(end - start))

        return rc
Exemple #11
0
def gen_files(size=1000, filename="", seed=None):
    """TODO: Docstring for gen_files.

    :size: TODO
    :returns: TODO

    """
    # start_time = time.time()

    if filename == "":
        filename = get_filename(size) + ".txt"

    if seed is not None:
        verbose("Using seed {0}".format(seed))

    with open(filename, "w") as data:
        verbose("Creating {0}".format(filename))
        for x in range(size):
            number = str(randint(-100, 100))
            data.write(number + ',')
Exemple #12
0
    def _delete_register(self, register, hashvalue):
        """TODO: Docstring for _delete_register.

        :register: TODO
        :returns: TODO

        """
        # TODO: This must be changed for the tree
        self.container[hashvalue].pop(register.name, None)
        if self.collisions[hashvalue] > 0:
            self.collisions[hashvalue] -= 1

        self.numbers.pop(register.cellphone, None)
        for container in self.last_names[register.last_name]:
            if container == hashvalue:
                self.last_names[register.last_name].remove(hashvalue)
                break

        verbose("Collisions in container {0}: {1}".format(
            hashvalue, self.collisions[hashvalue]))
        status("Register deleted: {0}".format(register))
Exemple #13
0
    def _find_triplet(self, number, domain):
        """Select the best next number of the triplet
        :returns: int, the number which is also the key of the self.tree dict

        """
        usable = False
        # By default the domain is negative, we can reverse it to use the positive domain
        limits = self.domain if domain < 0 else list(reversed(self.domain))
        verbose("Domain: {0}".format(limits))
        for pair in limits:
            if self.tree[pair] > 0:
                if self._reduce_to_zero(number + pair) is True:
                    repeated = repeated_numbers(number, pair,
                                                (number + pair) * -1)
                    if len(repeated) != 0 and self.tree[repeated[0]] < len(
                            repeated):
                        continue
                    self._save_triplet(number, pair, (number + pair) * -1)
                    usable = True
                    break

        return usable
Exemple #14
0
    def _remove_numbers(self, first, second, third):
        """Remove the triplet from the dictionary

        TODO: Should we use a vector instead ?

        :self.tree: dict, Dictionary with all the numbers
        :first: int, the first number of the triplet
        :second: int, the first number of the triplet
        :third: int, the first number of the triplet
        :returns: dict, the self.tree with decreased index if the found triplet

        """
        repeated = repeated_numbers(first, second, third)

        minimun = 0
        if len(repeated) == 0:
            verbose("All numbers are different")
            # All numbers are different from each other, so normal triplet
            minimun = min([
                self.tree[first],
                self.tree[second],
                self.tree[third],
            ])

            self.tree[first] -= minimun
            self.tree[second] -= minimun
            self.tree[third] -= minimun
        elif len(repeated) == 3:
            verbose("Using {0} three times with {1} elements".format(
                repeated[0], self.tree[repeated[0]]))
            # Same number in each case, just "0" can be here
            minimun = (self.tree[first] // 3) * 3
            self.tree[first] -= minimun
        else:
            verbose("Using {0} two times with {1} elements".format(
                repeated[0], self.tree[repeated[0]]))
            # We have two repeated numbers so need to perform a division
            minimun = min([(self.tree[repeated[0]] // 2), self.tree[first]])

            diff = 0
            if not (first in repeated):
                diff = first
            elif not (second in repeated):
                diff = second
            elif not (third in repeated):
                diff = third

            self.tree[repeated[0]] -= (minimun * 2)
            self.tree[diff] -= minimun

        triplet = Triplet(first, second, third, minimun)

        return triplet
Exemple #15
0
    def search(self, register=None, name=None, last_name=None, cellphone=None):
        """TODO: Docstring for insert.

        :register: TODO
        :returns: TODO
        """
        selected_type = -1
        if register is None and name is None and last_name is None and cellphone is None:
            parameter, selected_type = self._select_search_type()
        elif register is not None and type(register) is self.Register:
            parameter = register.name
            selected_type = 0
        elif name is not None:
            parameter = name
            selected_type = 0
        elif last_name is not None:
            parameter = last_name
            selected_type = 1
        elif cellphone is not None:
            parameter = cellphone
            selected_type = 2
        else:
            # We fall here if register is not None and is not a Register type
            raise Exception("Unknown type {0}".format(repr(register)))

        start = time()

        register = None

        verbose("Searching for: {0}".format(parameter))
        if selected_type == 0:
            hashvalue = self.hashfunction(parameter)

            # TODO: This must be changed for the tree
            verbose("Name {0}".format(parameter))
            if parameter in self.container[hashvalue]:
                register = self.container[hashvalue][parameter]
            else:
                error("The register {0} doesn't exists".format(parameter))
        elif selected_type == 1:
            if parameter in self.last_names:
                verbose("Last name {0}".format(parameter))
                containers = self.last_names[parameter]
                verbose("List of containers {0}".format(containers))
                # Since last names are not unic, the dictionary has a list with all the containers with the last name
                register = []
                for container in containers:
                    # TODO: This must be changed for the tree
                    for key, value in self.container[container].items():
                        if value.last_name == parameter:
                            register.append(
                                self.container[container][parameter])

                # status("Please select a register")
            else:
                error("The register {0} doesn't exists".format(parameter))
        elif selected_type == 2:
            if parameter in self.numbers:
                verbose("Number to find {0}".format(parameter))
                # TODO: This must be changed for the tree
                container = self.numbers[parameter]
                for key, value in self.container[container].items():
                    if value.cellphone == parameter:
                        register = self.container[container][value.name]
                        break
            else:
                error("The register {0} doesn't exists".format(parameter))
        else:
            raise Exception("Not a valid option {0}".format(selected_type))

        # register = self.container[hashvalue].search(parameter, selected_type)
        # if register is not None:
        #     return register
        # error("{0} doesn't exists".format(parameter, selected_type))

        end = time()
        verbose("Search time {0}".format(end - start))

        return register
Exemple #16
0
    def start(self):
        """Look for the next triplet of numbers
        :returns: Tuple, Returns a tuple with a vector of the 3 numbers and the
                        updated dictionary, And empty vector is return if no
                        triplet was found
        """
        start_time = time.time()
        while not self.done:
            self.done = True
            for item in range(-100, 101):
                # Check whether or not we have elements in the next number
                if self.tree[item] > 0:
                    verbose("Looking triplet for {0} with {1} elements".format(
                        item, self.tree[item]))
                    usable = self._find_triplet(item, item * -1)
                    if not usable:
                        verbose("No triplet found for {0}".format(item))
                else:
                    verbose("Skipping {0}: {1}".format(item, self.tree[item]))

        end_time = time.time()

        self.time = end_time - start_time

        status("End time of {0}. {1} different triplets found".format(
            self.time, len(self.triplets)))

        # Save time by not doing this shit if is not debug mode
        if messages.debug_mode:
            total = 0
            verbose("Unpaird numbers")
            for key in range(-100, 101):
                value = self.tree[key]
                if value > 0:
                    total += value
                    verbose("Key: {0};      Value: {1}".format(key, value))
            verbose("Total {0}".format(total))