FAQ: Hash Maps: Python - Defining the Setter

This community-built FAQ covers the “Defining the Setter” exercise from the lesson “Hash Maps: Python”.

Paths and Courses
This exercise can be found in the following Codecademy content:

Computer Science

Complex Data Structures

FAQs on the exercise Defining the Setter

There are currently no frequently asked questions associated with this exercise – that’s where you come in! You can contribute to this section by offering your own questions, answers, or clarifications on this exercise. Ask or answer a question by clicking reply (reply) below.

If you’ve had an “aha” moment about the concepts, formatting, syntax, or anything else with this exercise, consider sharing those insights! Teaching others and answering their questions is one of the best ways to learn and stay sharp.

Join the Discussion. Help a fellow learner on their journey.

Ask or answer a question about this exercise by clicking reply (reply) below!

Agree with a comment or answer? Like (like) to up-vote the contribution!

Need broader help or resources? Head here.

Looking for motivation to keep learning? Join our wider discussions.

Learn more about how to use this guide.

Found a bug? Report it!

Have a question about your account or billing? Reach out to our customer support team!

None of the above? Find out where to ask other questions here!

In order for my “assign” method to run properly, I have to to write “self.array” and “self.compressor”. Without any of those, I get an error.

But I don’t have to write “self.hash”. I can just write “hash” without the “self” and the code runs fine.

Why?
Why am I allowed to not use “self” in “hash”, while being forced to use “self” in the others?
I understand what “self” does, so I’d expect to have to use it in all three (array, compressor and hash). But for some reason I don’t.

(Also, in my “hash” function, the function name is in white, instead of blue. Not sure why either.)

1 Like

That’s the key!! hash() is a Python built-in function. In this Class, you are overriding the built-in function hash() with your own version. With self, you are calling the Class method; without self, you are calling the Python function
When you get to step 6, where you are actually running the functions, put in some print statements to see what the hash value is either way. You’ll see that, without self, the Class method hash() is not even called.

5 Likes

image

Turns out you are absolutely right!
Thanks!

2 Likes

Can someone explain in simple terms what encode() is doing?

The global idea behind the encode() function is to translate the input into a number:

key = "hello"
encode = [ord(key[i]) for i in range(len(key))]
hash_code = sum(encode)

I’m curious, here. Is that really a hash? Couldn’t it be duplicated for all 60 permutations?

Absolutely not, I didn’t pretend to give a hash! It is just an example to explain the main idea to @eric-heim behind the encode() function we use to produce the hash code. It would probally not work for many scenarios. It was just my 2 cents :slightly_smiling_face:

1 Like

Just using the term, ‘hash’ in the variable name led to inferences. No big deal. Just asking.

from itertools import permutations
def get_hash(x):
  ords = [ord(y) for y in x]
  h = ords[0]
  for x in ords[1:]:
    h <<= 1
    h += x
  return h

keys = permutations("hello")
for key in keys:
  print (get_hash(key))
output
3231
3234
3231
3234
3240
3240
3259
3262
3273
3283
3282
3289
3259
3262
3273
3283
3282
3289
3280
3280
3294
3301
3294
3301
3207
3210
3207
3210
3216
3216
3223
3226
3231
3238
3240
3244
3223
3226
3231
3238
3240
3244
3244
3244
3252
3256
3252
3256
3291
3294
3305
3315
3314
3321
3279
3282
3287
3294
3296
3300
3321
3331
3315
3322
3345
3342
3342
3349
3336
3340
3357
3354
3291
3294
3305
3315
3314
3321
3279
3282
3287
3294
3296
3300
3321
3331
3315
3322
3345
3342
3342
3349
3336
3340
3357
3354
3336
3336
3350
3357
3350
3357
3324
3324
3332
3336
3332
3336
3366
3373
3360
3364
3381
3378
3366
3373
3360
3364
3381
3378
>>> 

FTR, there are 120 permutations but I factored out 2 for the l’s, though perhaps mistakenly. It turns out there are only 48 unique hashes in that list. Any insight into that?


Turns out 60 is the number…

keys = set([''.join(key) for key in permutations("hello")])
h = [get_hash(key) for key in keys]
print (sorted(h), len(h))
data
[3207, 3210, 3216, 3223, 3226, 3231, 3231, 3234, 3238, 3240, 3240, 3244, 3244, 3252, 3256, 3259, 3262, 3273, 3279, 3280, 3282, 3282, 3283, 3287, 3289, 3291, 3294, 3294, 3294, 3296, 3300, 3301, 3305, 3314, 3315, 3315, 3321, 3321, 3322, 3324, 3331, 3332, 3336, 3336, 3336, 3340, 3342, 3342, 3345, 3349, 3350, 3354, 3357, 3357, 3360, 3364, 3366, 3373, 3378, 3381]
60

Until the various methods agree, we need some way to reason out their differences.

We’re actually only getting hashes from helo. At 5 unique characters there would be 120 hashes.

>>> from math import factorial as f
>>> f(7)
5040
>>> f(49) / f(6) / f(49 - 6)
13983816.0
>>> 

Darn, that’s a combination not a permutation.

>>> f(5)
120
>>> 

Gotta love Newton. In all the labyrinth of mathematics he discovered mirroring. And he came up with a general term to describe it at any value for x. Sheer beauty.

Isaac Newton is generally credited with the generalized binomial theorem, valid for any rational exponent.
Binomial theorem - Wikipedia

2 Likes