'Perl to Python hash table Translation

Hi I'm working on converting perl to python for something to do.

I've been looking at some code on hash tables in perl and I've come across a line of code that I really don't know how it does what it does in python. I know that it shifts the bit strings of page by 1

%page_table = ();           #page table is a hash of hashes
%page_table_entry = (       #page table entry structure
"dirty", 0,                 #0/1 boolean
"referenced", 0,            #0/1 boolean
"valid", 0,                 #0/1 boolean
"frame_no", -1,             #-1 indicates an "x", i.e. the page isn't in ram
"page", 0                   #used for aging algorithm.  8 bit string.);
@ram = ((-1) x $num_frames);

Could someone please give me an idea on how this would be represented in python? I've got the definitions of the hash tables done, they're just there as references as to what I'm doing. Thanks for any help that you can give me.

for($i=0; $i<@ram; $i++){
    $page_table{$ram[$i]}->{page} = $page_table{$ram[$i]}->{page} >> 1;}


Solution 1:[1]

The only thing confusing is that page table is a hash of hashes. $page_table{$v} contains a hashref to a hash that contains a key 'page' whose value is an integer. The loop bitshifts that integer but is not very clear perl code. Simpler would be:

foreach my $v (@ram) {
    $page_table{$v}->{page} >>= 1;
}

Now the translation to python should be obvious:

for v in ram:
    page_table[v][page] >>= 1

Solution 2:[2]

Here is what my Pythonizer generates for that code:

#!/usr/bin/env python3
# Generated by "pythonizer -mV q8114826.pl" v0.974 run by snoopyjc on Thu Apr 21 23:35:38 2022
import perllib, builtins

_str = lambda s: "" if s is None else str(s)
perllib.init_package("main")
num_frames = 0
builtins.__PACKAGE__ = "main"
page_table = {}  # page table is a hash of hashes
page_table_entry = {"dirty": 0, "referenced": 0, "valid": 0, "frame_no": -1, "page": 0}
# page table entry structure
# 0/1 boolean
# 0/1 boolean
# 0/1 boolean
# -1 indicates an "x", i.e. the page isn't in ram
# used for aging algorithm.  8 bit string.
ram = [(-1) for _ in range(num_frames)]

for i in range(0, len(ram)):
    page_table[_str(ram[i])]["page"] = perllib.num(page_table.get(_str(ram[i])).get("page")) >> 1

Solution 3:[3]

Woof! No wonder you want to try Python!

Yes, Python can do this because Python dictionaries (what you'd call hashes in Perl) can contain other arrays or dictionaries without doing references to them.

However, I highly suggest that you look into moving into object oriented programming. After looking at that assignment statement of yours, I had to lie down for a bit. I can't imagine trying to maintain and write an entire program like that.

Whenever you have to do a hash that contains an array, or an array of arrays, or a hash of hashes, you should be looking into using object oriented code. Object oriented code can prevent you from making all the sorts of errors that happen when you do that type of stuff. And, it can make your code much more readable -- even Perl code.

Take a look at the Python Tutorial and take a look at the Perl Object Oriented Tutorial and learn a bit about object oriented programming.

This is especially true in Python which was written from the ground up to be object oriented.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Steve C
Solution 2 snoopyjc
Solution 3 David W.