Помоги мне, пожалуйста, переписать код с C++ на Python. Этот класс нужен для работы алгоритма consistent hashing. 
Важные замечания: 
1. код на C++ предполагает работу со строками, наш код на Python будет работать только с числами (это важно из-за специфической работы функции хеширования)
2. нужно будет использовать уже готовый способ хеширования. Вот он с примером его использования:
def generate_matrix_and_vector(n, m=32):
    A = np.random.randint(0, 2, size=(n, m), dtype=np.int8)
    b = np.random.randint(0, 2, size=n, dtype=np.int8)
    return A, b

def generate_hash(A, b, x):
    n, m = A.shape
    if m != 32:
        raise ValueError("Matrix A must have 32 columns.")
    if len(b) != n:
        raise ValueError("Vector b must have same number of rows as A.")

    x = int(x)
    x_bits = np.array([(x >> i) & 1 for i in range(32)], dtype=np.int8)
    r = np.zeros(n, dtype=np.int8)
    for i in range(n):
        Ai = A[i]
        parity = np.sum(Ai & x_bits) % 2
        r[i] = parity
    return r ^ b

A, b = generate_matrix_and_vector(8)
x = [1,2,3,4]
hashed_values = [generate_hash(A, b, x_value) for x_value in x]

А вот и сам код на C++:
#include <iostream>
#include <map>
#include <string>
#include <functional>

using namespace std;

// Define a simple hash function using hash
size_t hash_fn(const string &key) {
    hash<string> hasher;
    return hasher(key);
}

class ConsistentHashing {
public:
    // Constructor to initialize the number of virtual nodes
    ConsistentHashing(int virtualNodes) : virtualNodes_(virtualNodes) {}

    // Add a node to the consistent hashing ring
    void addNode(const string &node) {
        for (int i = 0; i < virtualNodes_; ++i) {
            string virtualNodeName = node + "-" + to_string(i);
            size_t hash = hash_fn(virtualNodeName);
            ring_[hash] = node;
        }
    }

    // Remove a node from the consistent hashing ring
    void removeNode(const string &node) {
        for (int i = 0; i < virtualNodes_; ++i) {
            string virtualNodeName = node + "-" + to_string(i);
            size_t hash = hash_fn(virtualNodeName);
            ring_.erase(hash);
        }
    }

    // Get the node responsible for a given key
    string getNode(const string &key) {
        if (ring_.empty()) {
            return "";
        }

        size_t hash = hash_fn(key);
        auto it = ring_.lower_bound(hash);

        if (it == ring_.end()) {
            // Wrap around if the key's hash is greater than the largest hash in the ring
            it = ring_.begin();
        }

        return it->second;
    }
    
    void printInfo()
    {
        std::cout << "virtualNodes_: " << virtualNodes_ << "\n";
        for(const auto& it : ring_)
        {
            std::cout << "ring_[size_t]: " << it.first << "\t";
            std::cout << "ring_[string]: " << it.second << "\n";
        }
    }

private:
    int virtualNodes_;  // Number of virtual nodes per real node
    map<size_t, string> ring_;
};

int main() {
    ConsistentHashing ch(3); // Number of virtual nodes per real node
    
    ch.printInfo();
    
    ch.addNode("Node1"); ch.printInfo();
    ch.addNode("Node2"); ch.printInfo();
    ch.addNode("Node3"); ch.printInfo();

    cout << "Key 'mykey' is assigned to node: " << ch.getNode("mykey") << endl;

    ch.removeNode("Node2");

    cout << "After removing 'Node2', key 'mykey' is assigned to node: " << ch.getNode("mykey") << endl;
    
    ch.printInfo();
    
    return 0;
}