1

I've been set a homework task by a tutor to create a procedure which hashes a string, or in a sense gives the index of the string in a hash table if it was hashed.

It was supposed to return 11, but returned 0, can someone help me figure out why?

def hash_string(keyword, buckets):
    ords = []
    for e in string_to_list(keyword):
        ords.append(ord(e))

    sum_of_ords = ords.pop()

    for e in ords:
        sum_of_ords = sum_of_ords * e

    return sum_of_ords % buckets

print(hash_string('udacity', 12)) # should return 11 but returns 0?

Here is the string_to_list, I know theres probably a better way, but this is the only way I knew how without using google to search a built in method for this type of thing

def string_to_list(str):
    result_list = []
    i = 0

    while i < len(str):
        result_list.append(str[i:i + 1])
        i += 1


    return result_list

Here is how my tutor described the answer, but I don't undersand what he is doing with h? Is this just a simplified version of what I'm trying to do?

def hash_string(keyword, buckets):
    h = 0
    for c in keyword:
        h = (h + ord(c)) % buckets
    return h
2
  • 2
    A conversion to list isn't necessary to iterate a string. Anyway, you can use list(your_string) if you need to. Commented Mar 29, 2019 at 3:41
  • Thanks, I knew this come to think of it but must of forgot. Commented Mar 29, 2019 at 3:43

2 Answers 2

2

It seems like you meant to add but multiplied by accident here:

sum_of_ords = sum_of_ords * e

Change this to:

sum_of_ords = sum_of_ords + e

Or, with compound assignment:

sum_of_ords += e

On a side note, you can greatly simplify your function to simply this:

def hash_string(keyword, buckets):
    return sum(ord(c) for c in keyword) % buckets
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, this as fixed it. I knew there was a reason why I hadn't used compound assignemnt and that was because I was so used to using it when adding.
Also (to OP), I have nothing really to add, but just thinking about the difference between the "simplified" version" vs the original attempt: it's useful to print out your intermediate values in your loop (or step through them with a debugger, eg pycharm) to figure out exactly what's going on. If looping thru w/ multiplication (obviously incorrect), why does it return zero? Is the resulting (huge) number overflowing? Or does mod return zero? (It's the latter, naturally, since you multiply by the same number in the prev step.) Any pro/con for mod in the loop vs after? (Food for thought.)
0

The issue is that you used a few unnecessary functions, like using .pop(), a for loop, and your hash_string function can be replaced by using list(<string>).

Example:

def hash_string(keyword, buckets):
    ords = []
    for e in list(keyword):
        ords.append(ord(e))

    return sum(ords) % buckets

This can be even further simplified to:

def hash_string(keyword, buckets):
    return sum([ord(char) for char in list(keyword)]) % buckets

2 Comments

+1 for the sum(ords) but I have to give the answer to the first reply, although I do appreciate this answer.
No problem! It's always good to see different approaches to the same issue.