Python multiprocessing adventures

Trying to figure out some multiprocessing code from last night.
 
As one would expect, the single thread code maxes out a single core and the other three(it’s a dual core HT chip) are very lightly loaded with random background crap.
 
For multiprocessing, the average load per core is in between the peak vs low cores for the single, and it close to the same for all four. Basically what you’d expect to see with smaller tasks spread around.
 
RAM usage remains flat, or too close to flat for Ubuntus System Monitor to notice a difference.
 
But, the runtime is about .8s longer. Less stress on CPU cores and same stress on RAM and it takes longer.
 
Hmm. Some work to do on optimizing the algorithm.
Advertisements

Daily Programmer 239 Easy – Game of Threes

So, the latest Daily Programmer project I’m working on(I’ll get to finishing the last one, eventually) is this weeks Easy level project, Game of Threes.

This one wasn’t complicated, here’s the code.


def get_diff_from_multiple(n):
    """ Returns -1, 0, or 1, whichever will add to n to           
    make the sum divisible by 3
    """
    if n % 3 == 2:
        return 1
    elif n % 3 == 1:
        return -1
    elif n % 3 == 0:
        return 0

The core of the program is to either divide by three, or tweak the number to make it divisible by three.  The easiest way I saw was to just check how far it was from a multiple of three, and add the appropriate value.  It was pretty clear that modulus 3 would be the easy way- a remainder of 2, means adding 1 will make the number divisible by 3.  A remainder of 1, just subtract 1.  Remainder of 0, no change needed.

The function to play the game runs a loop until n reaches 1, outputting the appropriate status on each iteration of the loop.


def game_of_threes(n):
    """ Plays the game of threes with starting number n """

    while n > 1:
        diff = get_diff_from_multiple(n)
        print("{} {}".format(n, diff))
        n = (n + diff) // 3

    print(n)

There you go. Simple design for a simple project, though I’m sure there are some cleverer ways to do it.

Daily Programmer 238 Intermediate: Fallout Hacking Game(Wordlist data structure design)

One of my current projects is the Daily Programmer challenge here.  It’s a project to write a program to play a version of a hacking minigame from the Fallout series.  Here, I’ll work through my design process for a Python 3.4 implementation.

I started by just throwing out a little bit of code.  I didn’t expect this to get me anywhere, at least nowhere good.  But sometimes, just typing a few things out can help you realize what a project requires that purely thinking through it doesn’t.

I quickly realized I needed a data structure of some sort to hold the list of potential words.  A simple list of words would work, but depending on my source wordlist, I might end up with many words longer and shorter than the 4-15 letters the game design specifies.  I’d also have to look through the entire list to retrieve the small handful of words that are part of a run of the game.  Simply using a list would mean I’d have to account for these issues in many places in the game code, and that’s a problem.

I could use a list, and then have functions I call to work with the list.  But then I’d have to worry about global variables and/or passing a list all over the place.  That can be quite a mess.  Not as bad as repeating my data access code, but still a mess.  So I decided to implement it as a class, to package the data and its access code together.

I decided first it needed a way to give the user a list of words of appropriate length.  From here, I tried to think of an appropriate internal representation, and the easiest seemed to be a list of lists, indexed by word length. With that, I can use random.sample() to easily get an appropriate length list.

I can also use a function to fill the internal data structure that rejects words with lengths outside the specified limits.  There’s no sense having words with length of 16 in the data structure when I never need words that long.

The complete class is as follows:

class HackingGameWordList: 
    def __init__(self, wordlist):
    """ Wordlist is a list of strings, constants determine
    what length words I want to pull from the list
    """
 
        self._MIN_LENGTH = 4
        self._MAX_LENGTH = 15
        self.words = [[] for _ in range(self._MAX_LENGTH)]
        self.fill_list(wordlist)
 
    def fill_list(self, wordlist):
        """ Breaks up the full wordlist into the internal list of lists
        indexed by word length
        """
        for word in wordlist:
            l = len(word)
            if l >= self._MIN_LENGTH and l <= self._MAX_LENGTH:
                self.words[l].append(word)
 
     def get_n_words(self, n, l):
         """ Return a list of n randomly selected words of length l """
         return random.sample(self.words[l], n)

Python For Loops

So, working on learning Python, I’ll be blogging short bits of code and tutorials to help hone my own understanding- and hopefully someone out there will find it helpful.

So, a for loop is used in Python for iterating over a container, and for other loops where you can easily know ahead of time how many times you need to loop.

In the first case, for iterating over a container, here’s how you do it.

for x in container:
    print(x)</pre>

This loop will print each item in container, one after another, each on their own lines.  Whereas simply using print(x) will print the entire container in one line(wrapped in the REPL).

Now, let’s say you need to do something x number of times.  You could create a container with the necessary values, but Python provides the range() function to handle this.

The simple case is start from zero, go up by 1, last iteration is 1 less than your limit.

for x in range(10):
    print(x)</pre>

This will print the digits 0-9.

Range can do more, of course, giving you a great deal of flexibility with your loop.

#Basic format.  start defaults to zero,
#step size to +1.  end is not included
#in the range, start is.
range(start, end, step_size)

#5-9
for x in range(5,10):
    print(x)

#Step size
for x in range(5,10,3):
    print(x)  # Will print 5 and 8

#You can go backwards!
for x in range(10, 5, -1):
    print(x) #10,9,8,7,6

So, that’s it for Python for loops. Of course, using them effectively can be much more complicated than the basic syntax would make it look, but you can work that out on your own.

Perfect numbers in Python