_____

psplague

../images/psplague1.png

Inspired by Julian Oliver's psworld, psplague further explores the links between environment (simulation) and code. Rather than mapping a computer's internal processes onto visual features in the world (as in the case of psworld), in this instance (psplague) UNIX-like processes are attached to medieval villagers within a simple SIR (susceptible, infected, recovered) model of plague infection.

When a villager becomes infected and dies after a period of time, the attached process running on the computer is terminated or killed.

Warning: psplague can result in a more or less instantaneous hard crash.

Code:

import sys, random, os, time, signal

countd=0
infected=10 # of which 10 infected
recovery = 10 # days to recover
Iprob = 0.4 # probability of transmission
Dprob = 0.1 # probability of death

# SuscIinfectedRecoveredDead

S = 0
I = 1 # (days)
R = -1
D = 1024 # dead
pop = dict()

def checkos(pop):
    newpop=dict()
    for pid in os.listdir('/proc'):
        if pid.isdigit(): newpop[pid]=S
    for key in newpop.keys():
        if key in pop:
           newpop[key]=pop[key]
    return newpop

def init_pop(pop, inf):
    for pid in os.listdir('/proc'):
        if pid.isdigit(): pop[pid]=S
    for z in range(inf):
        x=random.choice(pop.keys())
        pop[x]=I


def isinfected(pop,procid):
    x=1
    count=0
    popp=pop.items()
    for key in pop.keys():
        if key == procid:
            ind = popp[x-1]
            if ind>=1 and ind!=D: count=count+1
            ind = popp[(x+1)%len(pop)]
            if ind>=1 and ind!=D: count=count+1
            return count
        x=x+1
    return 0

def do_plague(pop):
    global countd

    pop_temp = dict()

    for procid, ind in pop.items():

        if ind>0 and ind!=D: 
            ind=ind+1
            if random.random()<=Dprob:
                ind=D 
                countd=countd+1
                print "killed process ID:", procid,  open(os.path.join('/proc', procid, 'cmdline'), 'rb').read()

                del pop[procid]
                # kill the process (for testing just print process ID)                
                try:
                    os.kill(int(procid), signal.SIGKILL)
                except OSError:
                    continue

        if ind>=recovery and ind!=D: ind=R
        if ind==0:
            if isinfected(pop,procid)>0 and random.random()<=Iprob:
                ind=I
        pop_temp[procid]=ind
    return pop_temp


def draw_pop(pop):

    counts=0
    counti=0
    countr=0
    for procid, state in pop.items():
        if state==0: counts=counts+1
        if state>0: counti=counti+1
        if state==-1: countr=countr+1

    print '\nDay: %d Susceptible: %d Infected: %d Recovered: %d Dead: %d\n' % (days, counts,counti,countr, countd) 
        
days=0
random.seed()
init_pop(pop, infected)

while 1:
    days=days+1
    draw_pop(pop)
    pop=dict.copy(do_plague(pop))
    time.sleep(1)
    pop=dict.copy(checkos(pop))

Author: root <m@1010.co.uk>

Date: 2011-11-12 00:48:39 GMT

HTML generated by org-mode 6.31trans in emacs 23