Diablo III API

So I was doing a bit of research on a Diablo III API, and stumbled across this article:

http://us.battle.net/d3/en/forum/topic/4877377752

It seems they are still in the early stages, but there is a Character Calculator API, and it is in JSON.

First off we need to load in our Python libraries:

>>> from urllib2 import urlopen
>>> from json import loads

We can make our request using common URL methods:

>>> res = urlopen('http://us.battle.net/d3/en/data/calculator/monk').read()
>>> monk = loads(res)

Now we are given a simple Python dictionary:

>>> monk.keys()
[u'skills', u'traits']

And like most APIs these keys contain a list of objects:

>>> type(monk['skills'])
<type 'list'>
>>> type(monk['skills'][0])
<type 'dict'>

>>> monk['skills'][0].keys()
[u'tooltipParams', u'name', u'runes', u'simpleDescription', u'description', u'primary', u'slug',
u'requiredLevel', u'categoryName', u'categorySlug', u'icon']

So far so good, lets go ahead and itter over all our skills and get their names:

>>> for skill in sorted(monk['skills']):
...   print skill['name']
...
Blinding Flash
Serenity
Breath of Heaven
Inner Sanctuary
Mystic Ally
Cyclone Strike
Seven-Sided Strike
Mantra of Conviction
Mantra of Healing
Mantra of Retribution
Mantra of Evasion
Deadly Reach
Way of the Hundred Fists
Fists of Thunder
Crippling Wave
Tempest Rush
Lashing Tail Kick
Wave of Light
Dashing Strike
Exploding Palm
Sweeping Wind

So there you have it, using one of the new Diablo III APIs to get class information.

Bytes, Nibbles, and Bits in Python

Binary

Binary is nothing more than a base 2 numbering system using the numbers 0 and 1.

Bit

A Bit is merely a single number of either 1 and 0 within the binary.

Byte

A Byte consists of 8 bits. A byte containing all 0s will be the integer 0, while a byte containing all 1s will be the integer of 255.

Nibble

A Nibble consits of 4 bits. A nibble containing all 0s will be the iteger 0, while a nibble containing all 1s will be the integer 15 (very useful for hex numbers).

Python code

What I want to do is write a Python class for taking a valid byte (number from 0 – 255), and get its binary representation. I would also like to get the high nibble and low nibble from that binary.

Constructor

Lets start by making a constructor and verifying we have a valid byte.

class Byte(object):
    """Do cool things with a 8 bit number"""

    def __init__(self, number):
        if not self.__isbyte(number):
            raise Exception('"%s" is not a 8 bit integer' % number)
        self.number = number

    def __isint(self, number):
        """Check if a input is of type int"""
        if type(number) == int:
            return True

    def __isbyte(self, number):
        """Check if a input is a byte, 0 - 255"""
        if self.__isint(number):
            if len(bin(number)[2:]) <= 8:
                return True

Alright, this code will let us define a object and verify it is a 8 bit integer.

Binary Representation

Next lets create the pretty binary representation with leading 0s as padding.

def __format(self, num, size=8):
    """Format a number as binary with leading zeros"""
    return str(bin(num)[2:]).zfill(size)

@property
def binary(self):
    """Return Byte in binary"""
    return self.__format(self.number)

Here I wrote a small helper function for extracting the binary representation from the bin function and stripped the leading 0b. The binary property will return the binary.

High Nibble

Being all bytes are 8 bits, we can be sure a byte will have a high nibble (first 4 bits), and a low nibble (last 4 bits).

In order to get our high nibble all we need to do is use the bitwise right shift operator.

def __high_nibble(self):
    """Use Bitwise shift to get high nibble from byte"""
    return self.number >> 4

@property
def high_nibble(self):
    """Return High Nibble in binary"""
    return self.__format(self.__high_nibble(), 4)

Low Nibble

In order to get our low nibble we can use the bitwise AND operator with a mask of 15 (remember 15 is a nibble of all 1s).

def __low_nibble(self):
    """Use Bitwise AND to get low nibble"""
    return self.number & 0x0F  # 0x0F == 15

@property
def low_nibble(self):
    """Return Low Nibble in binary"""
    return self.__format(self.__low_nibble(), 4)

Code in action

There you have it, lets go ahead and give it a try.

In [1]: myByte = Byte(15)

In [2]: myByte.binary
Out[2]: '00001111'

In [3]: myByte.high_nibble
Out[3]: '0000'

In [4]: myByte.low_nibble
Out[4]: '1111'