it works fine but i donot understand ("salt" + str(ni) + str(x) + "salt).
This part is trivial.
First, the str functions takes any object and converts it to its string representation. For example, ni is going to be a number 0 or 1, which str will convert to the string "0" or "1".
Next, we're just concatenating four strings together: "a" + "bc" + "d" + "ef" gives you "abcdef".
I'm guessing that you're really asking is why you would do this.
When you're writing a hash function for some combination of values in terms of a simpler hash function, you want to be careful to make sure you include some kind of "salting", so your special combination of values doesn't accidentally hash to the same thing as a simple combination of the same values.
For an even simpler example, consider this class:
class Point(object): def __init__(self, x, y): self.x, self.y = x, y def __hash__(self): return hash((self.x, self.y))
But this means that hash((1.0, 2.0)) == hash(Point(1.0, 2.0)). Usually, you don't want that; a Point isn't the same thing as a tuple, it's a type with its own (very thin, but not nonexistent) semantics. So, you stick some extra value, called a "salt", into the hash. For example:
class Point(object): def __init__(self, x, y): self.x, self.y = x, y def __hash__(self): return hash((type(self), self.x, self.y))
And now, hash((1.0, 2.0)) != hash(Point(1.0, 2.0)).
Notice that this is distinct from, but not unrelated to, other important reasons for salting hashes (e.g., in cryptographic hashes, you can negotiate some shared random nonce to use as a salt, to make sure that nobody can reproduce the same hash results unless they have the negotiated salt, and you can use key exchange protocols to make sure they don't have it).
However, it's worth mentioning that this is a very silly hash function.
First, it's simpler, more robust, and more efficient to hash a tuple of values than to has a concatenated string. Most likely this code was written for some other language that didn't have a generic hash function, only a hash_string function.
Second, the only reason you'd want to both prepend and append a salt, instead of just one or the other, is if you didn't trust the hash function you're relying on to treat the parts of its values uniformly. And really, if you can't trust that, putting the salt on both ends doesn't help that much—and may actually hurt. (For example, if your hash_string undervalues everything after the first few characters, then prepending the salt does nicely avoid collision with unsalted values while appending it wouldn't—but it also means you're pushing 4 more actual characters out of the over-valued parts of the input, so your salted hashes are going to be even more badly distributed than normal hashes. If you really can't trust a hash function, you can't build a more complex hash function on top of it; you have to build your own.
strcalls) that you don't understand? Or do you not understand why they're doing that, or how thelambdais used to wrap it up as a function, or something else other than what you asked?