<commit_before>#!/bin/env python
#coding:utf-8

import random
import math
import likelihood_function

"""
PFoEのための関数を提供するモジュール
likelihood_function.pyの中で尤度関数の内容を定義
"""
class Robot:
    def __init__(self,sensor,choice,particle = 1000,maximum = 100,resetting = False,reduction = 0.0):
        self.sensor = [None for i in range(sensor)] #センサ値が入るリスト
        self.particle_num = particle #パーティクルの数
        self.particle_distribution = [0 for i in range(particle)] #パーティクルの分布場所
        self.particle_weight = [1.0 / particle for i in range(particle)] #パーティクルの重み
        self.choice = choice #ロボットが取りうる選択肢の数
        self.action = None #選択された行動
        self.reward = None  #報酬値
        self.episode = [ [self.sensor,self.action,self.reward] ] #エピソード集合
        self.maximum = maximum #エピソード集合に保存されるイベント数の上限
        self.resetting = resetting #resettingを行うか否か
        self.alpha = 0.0 #各パーティクルの重みの平均
        self.reduction_rate = reduction #辻褄のあわないエピソードをどの程度削減するか

    def add_event(self,sensor,action,reward):
        """
        処理:ロボットのエピソード集合に新しいイベントを追加する
             追加した結果、エピソード数の上限に達した場合は最も古いイベントを削除する
        引数:sensor[],action,reward
        戻り値: -
        """
        l = []
        l.append(sensor)
        l.append(action)
        l.append(reward)
        if(self.episode[0][1] is None):
            self.episode[0] = l
        else:
            self.episode.append(l)

        if( len(self.episode) > self.maximum ):
            del self.episode[0]

    def likeli_func(self):
        """
        尤度関数のテスト
        """
        l = likelihood_function.func(self.sensor,self.episode)
        print "尤度:",l

    def sensor_update(self):
        """
        処理:全てのパーティクルについて、尤度に基づいて重みを更新する
             新しい重みの平均でalphaを更新する
        引数: -
        戻り値: -
        """
        likelihood = likelihood_function.func(self.sensor, self.episode)
        s = 0.0
        self.alpha = 0.0

        for i in range(self.particle_num):
            self.particle_weight[i] = self.particle_weight[i]\
                                       * likelihood[ self.particle_distribution[i] ]
            s += self.particle_weight[i]

        for i in range(self.particle_num):
            if s != 0.0:
                self.particle_weight[i] = self.particle_weight[i] / s
            self.alpha += self.particle_weight[i]

        self.alpha /= self.particle_num

    def particle_resampling(self):
        """
        処理:重みに基づきパーティクルをリサンプリングする
             1 % のパーティクルはランダムにリサンプリングする
        引数: -
        戻り値: -
        """
        weight_of_episode = [0.0 for i in range( len(self.episode) ) ]

        for i in range( len(self.episode) ):
            for ii in range(self.particle_num):
                if self.particle_distribution[ii] == i:
                    weight_of_episode[i] += self.particle_weight[ii]

        if sum(weight_of_episode) == 0.0:
            for i in range( len(self.episode) ):
                weight_of_episode[i] = 1.0 / len(self.episode)

        for i in range(self.particle_num):
            seed = random.randint(1,100)
            if seed == 1:
                self.particle_distribution[i] = random.randint(0,len(self.episode) - 1)
            else:
                seed = random.randint(1,10000)
                seed = float(seed) / 10000
                for ii in range( len(self.episode) ):
                    seed -= weight_of_episode[ii]
                    if seed <= 0:
                        self.particle_distribution[i] = ii
                        break

    def equality_resampling(self):
        """
        処理:全てのパーティクルをエピソード中に均等にリサンプリングする
             全てのパーティクルの重みを均等にする
        引数: -
        戻り値: -
        """
        for i in range(self.particle_num):
            self.particle_distribution[i] = i % len(self.episode)
            self.particle_weight[i] = 1.0 / self.particle_num

    def decision_making(self):
        """
        処理:パーティクルの分布から行動を決定して返す
        引数: -
        戻り値: action
        """
        vote = [0.0 for i in range(self.particle_num) ]

        if(self.episode[0][1] == None):
            return random.randint(0,self.choice - 1)

        for i in range(self.particle_num):
            distance = 0
            non_zero_reward = 0.0
            for l in range( len(self.episode) - self.particle_distribution[i] ):
                distance += 1
                if self.episode[ self.particle_distribution[i] + l ][2] != 0:
                    non_zero_reward = self.episode[ self.particle_distribution[i] + l ][2]
                    break
            if non_zero_reward != 0:
                vote[i] = non_zero_reward / distance
            else:
                vote[i] = 0.0

        got = [0.0 for i in range(self.choice) ] #各選択肢が持つ得票数
        for p in range(self.particle_num):
            for g in range( len(got) ):
                if self.episode[self.particle_distribution[p]][1] == g:
                    got[g] += vote[p]
                    break

        #最大の評価を持つ選択肢を返す
        #最大値を持つ選択肢が複数存在する場合は、その中からランダムに返す
        mx = max(got)
        mx_n = 0 #有効な選択肢が幾つあるか
        mx_list = [0 for i in range(self.choice)] #有効な選択肢はどれか
        for i in range(self.choice):
            if got[i] == mx:
                mx_list[mx_n] = i
                mx_n += 1
        seed = random.randint(0,mx_n-1)
        action = mx_list[seed]
        return action

    def particle_sliding(self):
        """
        処理:全てのパーティクルの分布をひとつずらす
        引数:
        戻り値:
        """
        for i in range(self.particle_num):
            if self.particle_distribution[i] != (len(self.episode) - 1):
                self.particle_distribution[i] += 1

    def weight_reduction(self):
        """
        処理:パーティクルが持つ重み(particle_weight[])について、
             そのパーティクルが存在しているエピソードが、
             最新のイベントと比較して矛盾している場合に、
             係数(reduction_rate)を掛けて削減する
             最新のイベントを追加した後、パーティクルをスライドさせる前に実行する
        引数: -
        戻り値: -
        """
        latest = len(self.episode) - 1
        # 行動による削減
        for i in range(self.particle_num):
            if( self.episode[ self.particle_distribution[i] ][1] != self.episode[latest][1] \
                or \
            self.episode[ self.particle_distribution[i] ][2] != self.episode[latest][2] ):
                self.particle_weight[i] *= self.reduction_rate

    def see_distribution(self,star = 50):
        """
        処理:パーティクルの分布の様子を画面に表示する
        引数:star
        戻り値: -
        """
        particle_numbers = [0 for i in range( len(self.episode) ) ]
        for i in range(self.particle_num):
            particle_numbers[ self.particle_distribution[i] ] += 1

        print "A\t|R\t|N\t|Distribution",

        for i in range( len(self.episode) ):
            print "\n",self.episode[i][1],"\t|",self.episode[i][2],"\t|",particle_numbers[i],"\t|",
            for ii in range(int( float(particle_numbers[i]) / float(self.particle_num) * float(star) ) ):
                print "*",
<commit_msg>equality_resampling -> randomly_resamplingに<commit_after>#!/bin/env python
#coding:utf-8

import random
import math
import likelihood_function

"""
PFoEのための関数を提供するモジュール
likelihood_function.pyの中で尤度関数の内容を定義
"""
class Robot:
    def __init__(self,sensor,choice,particle = 1000,maximum = 100,resetting = False,reduction = 0.0):
        self.sensor = [None for i in range(sensor)] #センサ値が入るリスト
        self.particle_num = particle #パーティクルの数
        self.particle_distribution = [0 for i in range(particle)] #パーティクルの分布場所
        self.particle_weight = [1.0 / particle for i in range(particle)] #パーティクルの重み
        self.choice = choice #ロボットが取りうる選択肢の数
        self.action = None  #選択された行動
        self.reward = None  #報酬値
        self.episode = [ [self.sensor,self.action,self.reward] ] #エピソード集合
        self.maximum = maximum #エピソード集合に保存されるイベント数の上限
        self.resetting = resetting #resettingを行うか否か
        self.alpha = 0.0 #各パーティクルの重みの平均
        self.reduction_rate = reduction #辻褄のあわないエピソードをどの程度削減するか

    def add_event(self,sensor,action,reward):
        """
        処理:ロボットのエピソード集合に新しいイベントを追加する
             追加した結果、エピソード数の上限に達した場合は最も古いイベントを削除する
        引数:sensor[],action,reward
        戻り値: -
        """
        l = []
        l.append(sensor)
        l.append(action)
        l.append(reward)
        if(self.episode[0][1] is None):
            self.episode[0] = l
        else:
            self.episode.append(l)

        if( len(self.episode) > self.maximum ):
            del self.episode[0]

    def likeli_func(self):
        """
        尤度関数のテスト
        """
        l = likelihood_function.func(self.sensor,self.episode)
        print "尤度:",l

    def sensor_update(self):
        """
        処理:全てのパーティクルについて、尤度に基づいて重みを更新する
             新しい重みの平均でalphaを更新する
        引数: -
        戻り値: -
        """
        likelihood = likelihood_function.func(self.sensor, self.episode)
        s = 0.0
        self.alpha = 0.0

        for i in range(self.particle_num):
            self.particle_weight[i] = self.particle_weight[i]\
                                       * likelihood[ self.particle_distribution[i] ]
            s += self.particle_weight[i]

        for i in range(self.particle_num):
            if s != 0.0:
                self.particle_weight[i] = self.particle_weight[i] / s
            self.alpha += self.particle_weight[i]

        self.alpha /= self.particle_num

    def particle_resampling(self):
        """
        処理:重みに基づきパーティクルをリサンプリングする
             1 % のパーティクルはランダムにリサンプリングする
        引数: -
        戻り値: -
        """
        weight_of_episode = [0.0 for i in range( len(self.episode) ) ]

        for i in range( len(self.episode) ):
            for ii in range(self.particle_num):
                if self.particle_distribution[ii] == i:
                    weight_of_episode[i] += self.particle_weight[ii]

        if sum(weight_of_episode) == 0.0:
            for i in range( len(self.episode) ):
                weight_of_episode[i] = 1.0 / len(self.episode)

        for i in range(self.particle_num):
            seed = random.randint(1,100)
            if seed == 1:
                self.particle_distribution[i] = random.randint(0,len(self.episode) - 1)
            else:
                seed = random.randint(1,10000)
                seed = float(seed) / 10000
                for ii in range( len(self.episode) ):
                    seed -= weight_of_episode[ii]
                    if seed <= 0:
                        self.particle_distribution[i] = ii
                        break

    def randomly_resampling(self):
        """
        処理:全てのパーティクルをエピソード中に均等にリサンプリングする
             全てのパーティクルの重みを均等にする
        引数: -
        戻り値: -
        """
        for i in range(self.particle_num):
            self.particle_distribution[i] = random.randint(0,len(self.episode) - 1)
            self.particle_weight[i] = 1.0 / self.particle_num

    def decision_making(self):
        """
        処理:パーティクルの分布から行動を決定して返す
        引数: -
        戻り値: action
        """
        vote = [0.0 for i in range(self.particle_num) ]

        if(self.episode[0][1] == None):
            return random.randint(0,self.choice - 1)

        for i in range(self.particle_num):
            distance = 0
            non_zero_reward = 0.0
            for l in range( len(self.episode) - self.particle_distribution[i] ):
                distance += 1
                if self.episode[ self.particle_distribution[i] + l ][2] != 0:
                    non_zero_reward = self.episode[ self.particle_distribution[i] + l ][2]
                    break
            if non_zero_reward != 0:
                vote[i] = non_zero_reward / distance
            else:
                vote[i] = 0.0

        got = [0.0 for i in range(self.choice) ] #各選択肢が持つ得票数
        for p in range(self.particle_num):
            for g in range( len(got) ):
                if self.episode[self.particle_distribution[p]][1] == g:
                    got[g] += vote[p]
                    break

        #最大の評価を持つ選択肢を返す
        #最大値を持つ選択肢が複数存在する場合は、その中からランダムに返す
        mx = max(got)
        mx_n = 0 #有効な選択肢が幾つあるか
        mx_list = [0 for i in range(self.choice)] #有効な選択肢はどれか
        for i in range(self.choice):
            if got[i] == mx:
                mx_list[mx_n] = i
                mx_n += 1
        seed = random.randint(0,mx_n-1)
        action = mx_list[seed]
        return action

    def particle_sliding(self):
        """
        処理:全てのパーティクルの分布をひとつずらす
        引数:
        戻り値:
        """
        for i in range(self.particle_num):
            if self.particle_distribution[i] != (len(self.episode) - 1):
                self.particle_distribution[i] += 1

    def weight_reduction(self):
        """
        処理:パーティクルが持つ重み(particle_weight[])について、
             そのパーティクルが存在しているエピソードが、
             最新のイベントと比較して矛盾している場合に、
             係数(reduction_rate)を掛けて削減する
             最新のイベントを追加した後、パーティクルをスライドさせる前に実行する
        引数: -
        戻り値: -
        """
        latest = len(self.episode) - 1
        # 行動による削減
        for i in range(self.particle_num):
            if( self.episode[ self.particle_distribution[i] ][1] != self.episode[latest][1] \
                or \
            self.episode[ self.particle_distribution[i] ][2] != self.episode[latest][2] ):
                self.particle_weight[i] *= self.reduction_rate

    def see_distribution(self,star = 50):
        """
        処理:パーティクルの分布の様子を画面に表示する
        引数:star
        戻り値: -
        """
        particle_numbers = [0 for i in range( len(self.episode) ) ]
        for i in range(self.particle_num):
            particle_numbers[ self.particle_distribution[i] ] += 1

        print "A\t|R\t|N\t|Distribution",

        for i in range( len(self.episode) ):
            print "\n",self.episode[i][1],"\t|",self.episode[i][2],"\t|",particle_numbers[i],"\t|",
            for ii in range(int( float(particle_numbers[i]) / float(self.particle_num) * float(star) ) ):
                print "*",
<|endoftext|>


<commit_before>from rest_framework import serializers
from goals.models import Goal
from datetime import datetime
from rest_framework.exceptions import ValidationError

class GoalSerailizer(serializers.ModelSerializer):
    class Meta:
        model = Goal
        fields = ('id', 'slug', 'title', 'description', 'end_date')
        read_only_fields = ('id', 'slug')

    def to_representation(self, instance):
        goal = super(GoalSerailizer, self).to_representation(instance)
        goal['slug'] = instance.slug
        goal['is_completed'] = instance.completed
        return goal

    def validate_end_date(self, value):
        if value < datetime.now().date():
            raise ValidationError("End date should not be in past")
<commit_msg>serializer validation was added for end_date<commit_after>from rest_framework import serializers
from goals.models import Goal
from datetime import datetime
from rest_framework.exceptions import ValidationError

class GoalSerailizer(serializers.ModelSerializer):
    class Meta:
        model = Goal
        fields = ('id', 'slug', 'title', 'description', 'end_date')
        read_only_fields = ('id', 'slug')

    def to_representation(self, instance):
        goal = super(GoalSerailizer, self).to_representation(instance)
        goal['slug'] = instance.slug
        goal['is_completed'] = instance.completed
        return goal

    def validate_end_date(self, value):
        if value < datetime.now().date():
            raise ValidationError("End date should not be in past")
        return value
<|endoftext|>


<commit_before>
from ggame import App, RectangleAsset, ImageAsset, Sprite, LineStyle, Color, Frame
import random
import time

SCREEN_WIDTH = 1280
SCREEN_HEIGHT = 940
#BINGOWASTHEPLAYER
class Bingo(Sprite):
    black = Color(0,1)
    skin = Color(0x003300, 1)
    line = LineStyle(0, black)
    asset = RectangleAsset(20,20, line, skin)

    def __init__(self,position):
        super().__init__(Bingo.asset, position)
        self.vy = 0
        self.vx = 0
        self.vr = 0
        self.fxcenter = self.fycenter = 0
        Zoxy.listenKeyEvent("keydown", "up arrow", self.movenorth)
        Zoxy.listenKeyEvent("keyup", "up arrow", self.moveoff)
        Zoxy.listenKeyEvent("keydown", "down arrow", self.movesouth)
        Zoxy.listenKeyEvent("keyup", "down arrow", self.moveoff)
        Zoxy.listenKeyEvent("keydown", "right arrow", self.moveeast)
        Zoxy.listenKeyEvent("keyup", "right arrow", self.moveoff)
        Zoxy.listenKeyEvent("keydown", "left arrow", self.movewest)
        Zoxy.listenKeyEvent("keyup", "left arrow", self.moveoff)

    def step(self):
        self.x += self.vx
        self.y += self.vy

    def movesouth(self,event):
        if self.vy >= 0 and self.vy <= 10:
            self.vy = self.vy + 0.2
        else:
            self.vy = 10
    def movenorth(self,event):
        if self.vy >= -10 and self.vy <= 0:
            self.vy = self.vy - 0.2
        else:
            self.vy = -10
    def moveeast(self,event):
        if self.vx >= 0 and self.vx <= 10:
            self.vx = self.vx + 0.2
        else:
            self.vx = 10

    def movewest(self,event):
        if self.vx >= -10 and self.vx <= 0:
            self.vx = self.vx - 0.2
        else:
            self.vx = -10

    def moveoff(self,event):
        self.vx = self.vy = 0
#PEOPLEBEPEOPLE
class People(Sprite):
    time.time()
    black = Color(0,1)
    skin = Color(0x003300, 1)
    line = LineStyle(0, black)
    asset = RectangleAsset(20,20, line, skin)

    def __init__(self,position):
        super().__init__(Bingo.asset, position)
        self.vy = 0
        self.vx = 0
        self.vr = 0
        self.fxcenter = self.fycenter = 0
        self.waituntil = time.time() + 1

    def step(self):
        thetime = time.time()
        self.x += self.vx
        self.y += self.vy
        if thetime > self.waituntil:
            self.waituntil = thetime + 1
            Singularity = random.randrange(10000)
            if Singularity > 0 and Singularity <= 2500:
                self.vy = -2
            elif Singularity > 2500 and Singularity <= 5000:
                self.vy = 2
            elif Singularity > 5000 and Singularity <= 7500:
                self.vx = -2
            elif Singularity > 7500 and Singularity <= 10000:
                self.vx = 2
            else:
                pass
#ZOXYGAMEISBESTZOXYGAME
class Zoxy(App):
    def __init__(self, width, height):
        super().__init__(width, height)
        black = Color(1, 1)
        line = LineStyle(2, black)
        grass = Color(0x229954, 1)
        hedge = Color(0x145A32, 1)
        stone = Color(0xB2BABB, 1)
        road = Color(0x515A5A, 1)
        roof = Color(0xA04000, 1)
        Grass = RectangleAsset(1279,939,line,grass)
        Hedge = RectangleAsset(25,700,line,hedge)
        Hedge2 = RectangleAsset(25,340,line,hedge)
        Hedge3 = RectangleAsset(25,290,line,hedge)
        Hedge4 = RectangleAsset(485,25,line,hedge)
        Stone = RectangleAsset(20,50,line,stone)
        Road = RectangleAsset(60,940,line,road)
        Roof = RectangleAsset(300,400,line,roof)
        Sprite(Grass, (0,0))
        Sprite(Roof, (440,270))
        Sprite(Stone, (420,520))
        Sprite(Stone, (380,520))
        Sprite(Road, (310,0))
        Sprite(Hedge, (840,170))
        Sprite(Hedge2, (380, 170))
        Sprite(Hedge3, (380, 580))
        Sprite(Hedge4, (380, 845))
        Sprite(Hedge4, (380, 145))
        People((500, 500))
        People((600, 600))
        People((500, 600))
        People((600, 500))
        People((500, 500))
        People((600, 600))
        People((500, 600))
        People((600, 500))
        People((500, 500))
        People((600, 600))
        People((500, 600))
        People((600, 500))
        People((500, 500))
        People((600, 600))
        People((500, 600))
        People((600, 500))
        Bingo((0,0))

    def step(self):
        for ship in self.getSpritesbyClass(Bingo):
            ship.step()
        for hip in self.getSpritesbyClass(People):
            hip.step()
            if hip.x >= 1280 or hip.x <= 0:
                hip.vx = hip.vx * -1
            if hip.y >= 940 or hip.y <= 0 :
                hip.vy = hip.vy * -1

myapp = Zoxy(SCREEN_WIDTH, SCREEN_HEIGHT)
myapp.run()
<commit_msg>Updated from Brython Server: 12/20/2016 2:01:35 PM<commit_after>
from ggame import App, RectangleAsset, ImageAsset, Sprite, LineStyle, Color, Frame
import random
import time

SCREEN_WIDTH = 1280
SCREEN_HEIGHT = 940
#BINGOWASTHEPLAYER
class Bingo(Sprite):
    black = Color(0,1)
    skin = Color(0x003300, 1)
    line = LineStyle(0, black)
    asset = RectangleAsset(20,20, line, skin)

    def __init__(self,position):
        super().__init__(Bingo.asset, position)
        self.vy = 0
        self.vx = 0
        self.vr = 0
        self.fxcenter = self.fycenter = 0
        Zoxy.listenKeyEvent("keydown", "up arrow", self.movenorth)
        Zoxy.listenKeyEvent("keyup", "up arrow", self.moveoff)
        Zoxy.listenKeyEvent("keydown", "down arrow", self.movesouth)
        Zoxy.listenKeyEvent("keyup", "down arrow", self.moveoff)
        Zoxy.listenKeyEvent("keydown", "right arrow", self.moveeast)
        Zoxy.listenKeyEvent("keyup", "right arrow", self.moveoff)
        Zoxy.listenKeyEvent("keydown", "left arrow", self.movewest)
        Zoxy.listenKeyEvent("keyup", "left arrow", self.moveoff)

    def step(self):
        self.x += self.vx
        self.y += self.vy

    def movesouth(self,event):
        self.vy = 10

    def movenorth(self,event):
        self.vy = -10

    def moveeast(self,event):
        self.vx = 10

    def movewest(self,event):
        self.vx = -10

    def moveoff(self,event):
        self.vx = self.vy = 0
#PEOPLEBEPEOPLE
class People(Sprite):
    time.time()
    Human = True
    black = Color(0,1)
    skin = Color(0xfbc02d, 1)
    line = LineStyle(1, black)
    asset = RectangleAsset(20,20, line, skin)

    def __init__(self,position):
        super().__init__(People.asset, position)
        self.vy = 0
        self.vx = 0
        self.vr = 0
        self.fxcenter = self.fycenter = 0
        self.waituntil = time.time() + 1

    def step(self):
        thetime = time.time()
        self.x += self.vx
        self.y += self.vy
        Infection = self.collidingWithSprites(Bingo)
        if len(Infection) != 0:
            self.visible = False
        if thetime > self.waituntil:
            self.waituntil = thetime + .5
            Singularity = random.randrange(10000)
            if Singularity > 0 and Singularity <= 2500:
                self.vy = -2
            elif Singularity > 2500 and Singularity <= 5000:
                self.vy = 2
            elif Singularity > 5000 and Singularity <= 7500:
                self.vx = -2
            elif Singularity > 7500 and Singularity <= 10000:
                self.vx = 2
            else:
                pass
#ZAMBIESBEZAMBIES
class ZPeople(Sprite):
    black = Color(0,1)
    skin = Color(0x003300, 1)
    line = LineStyle(1, black)
    asset = RectangleAsset(20,20, line, skin)

    def __init__(self,position):
        super().__init__(ZPeople.asset, position)
        self.vy = 0
        self.vx = 0
        self.vr = 0
        self.fxcenter = self.fycenter = 0
        self.visible = False

    def step(self):
        self.x = People.x
        self.y = People.y
        Infection = self.collidingWithSprites(Bingo)
        if len(Infection) != 0:
            self.visible = True
#ZOXYGAMEISBESTZOXYGAME
class Zoxy(App):
    def __init__(self, width, height):
        super().__init__(width, height)
        black = Color(1, 1)
        line = LineStyle(2, black)
        grass = Color(0x229954, 1)
        hedge = Color(0x145A32, 1)
        stone = Color(0xB2BABB, 1)
        road = Color(0x515A5A, 1)
        roof = Color(0xA04000, 1)
        Grass = RectangleAsset(1279,939,line,grass)
        Hedge = RectangleAsset(25,700,line,hedge)
        Hedge2 = RectangleAsset(25,340,line,hedge)
        Hedge3 = RectangleAsset(25,290,line,hedge)
        Hedge4 = RectangleAsset(485,25,line,hedge)
        Stone = RectangleAsset(20,50,line,stone)
        Road = RectangleAsset(60,940,line,road)
        Roof = RectangleAsset(300,400,line,roof)
        Sprite(Grass, (0,0))
        Sprite(Roof, (440,270))
        Sprite(Stone, (420,520))
        Sprite(Stone, (380,520))
        Sprite(Road, (310,0))
        Sprite(Hedge, (840,170))
        Sprite(Hedge2, (380, 170))
        Sprite(Hedge3, (380, 580))
        Sprite(Hedge4, (380, 845))
        Sprite(Hedge4, (380, 145))
        People((500, 500))
        People((600, 600))
        People((500, 600))
        People((600, 500))
        People((500, 500))
        People((600, 600))
        People((500, 600))
        People((600, 500))
        People((500, 500))
        People((600, 600))
        People((500, 600))
        People((600, 500))
        People((500, 500))
        People((600, 600))
        People((500, 600))
        People((600, 500))

        ZPeople((500, 500))
        ZPeople((600, 600))
        ZPeople((500, 600))
        ZPeople((600, 500))
        ZPeople((500, 500))
        ZPeople((600, 600))
        ZPeople((500, 600))
        ZPeople((600, 500))
        ZPeople((500, 500))
        ZPeople((600, 600))
        ZPeople((500, 600))
        ZPeople((600, 500))
        ZPeople((500, 500))
        ZPeople((600, 600))
        ZPeople((500, 600))
        ZPeople((600, 500))
        Bingo((0,0))

    def step(self):
        for ship in self.getSpritesbyClass(Bingo):
            ship.step()
        for hip in self.getSpritesbyClass(People):
            hip.step()
            if hip.x >= 1280:
                hip.x = 20
                hip.y = random.randrange(940)
            if hip.x <= 0:
                hip.x = 1260
                hip.y = random.randrange(940)
            if hip.y >= 940:
                hip.x = random.randrange(1280)
                hip.y = 20
            if hip.y <= 0:
                hip.x = random.randrange(1280)
                hip.y = 920

myapp = Zoxy(SCREEN_WIDTH, SCREEN_HEIGHT)
myapp.run()
<|endoftext|>


<commit_before>from typing import List

from ..twitter import get_api
from bot.lib.statusdb import Addstatus
from timeline.models import add_status_tl, Status
import tweepy
import logging
import sys

logger = logging.getLogger(__name__)

def get_timeline_with_rts():
    API = get_api()
    return API.user_timeline(include_rts=True)

def get_timeline_id_lst(n=None) -> List:
    """
    Return n last tweet from timeline as a list of statusid, excluding replies
    """
    return [status.statusid
            for status
            in Status.objects.all().filter(json__contains={'in_reply_to_status_id': None})][:n]

def record_timeline():
    for status in get_timeline_with_rts():
        add_status_tl(status)

def record_user_timeline(user_id, count=200, force=False):
    """
    Send requests to record user timeline as long as not all tweets during one
    request already exist in database.
    """
    max_statusid = None
    api=get_api()
    new_tweets = True
    while new_tweets:
        if not force:
            new_tweets = False
        try:
            status_lst = api.user_timeline(user_id=user_id, count=count, max_id=max_statusid)
            if not status_lst:
                logger.warn("request is empty")
                break
            for status in status_lst:
                dbstatus = Addstatus(status._json)
                created = dbstatus.addtweetdj()
                statusid = status._json["id"]
                if max_statusid is None:
                    max_statusid = statusid
                elif statusid < max_statusid:
                    max_statusid = statusid
                if created:
                    if not force:
                        new_tweets = True
        except tweepy.TweepError as e:
            logger.debug(e.response.text)
            break
        except tweepy.RateLimitError as e:
            logger.debug(e.response.text)
        max_statusid -= 1

        <commit_msg>extended mode for user_timeline<commit_after>from typing import List

from ..twitter import get_api
from bot.lib.statusdb import Addstatus
from timeline.models import add_status_tl, Status
import tweepy
import logging
import sys

logger = logging.getLogger(__name__)

def get_timeline_with_rts():
    API = get_api()
    return API.user_timeline(include_rts=True)

def get_timeline_id_lst(n=None) -> List:
    """
    Return n last tweet from timeline as a list of statusid, excluding replies
    """
    return [status.statusid
            for status
            in Status.objects.all().filter(json__contains={'in_reply_to_status_id': None})][:n]

def record_timeline():
    for status in get_timeline_with_rts():
        add_status_tl(status)

def record_user_timeline(user_id, count=200, force=False):
    """
    Send requests to record user timeline as long as not all tweets during one
    request already exist in database.
    """
    max_statusid = None
    api=get_api()
    new_tweets = True
    while new_tweets:
        if not force:
            new_tweets = False
        try:
            status_lst = api.user_timeline(user_id=user_id, count=count, max_id=max_statusid, tweet_mode="extended")
            if not status_lst:
                logger.warn("request is empty")
                break
            for status in status_lst:
                dbstatus = Addstatus(status._json)
                created = dbstatus.addtweetdj()
                statusid = status._json["id"]
                if max_statusid is None:
                    max_statusid = statusid
                elif statusid < max_statusid:
                    max_statusid = statusid
                if created:
                    if not force:
                        new_tweets = True
        except tweepy.TweepError as e:
            logger.debug(e.response.text)
            break
        except tweepy.RateLimitError as e:
            logger.debug(e.response.text)
        max_statusid -= 1

        <|endoftext|>


<commit_before>import numpy as np
import itertools
import nltk

UNKNOWN_TOKEN = 'UNKNOWN_TOKEN'

data = {}
"""
data can contain the following keys:
sentences: list of sentence strings
tokens: word-tokenized list of sentences
unique_tokens: list of unique tokens sorted by frequency
indices: integer representation of tokens
one_hot: one-hot representation of indices
vocab_size: number of unique tokens
token_to_index: map from token to index space
index_to_token: map from index to token space
max_sentence_length: number of tokens in the longest sentence
raw_data: full text
data_size: number of tokens in data
filename: name of file to read raw data from
tokens_flat: flattened sequence of word tokens
token_to_one_hot: map from tokens to one-hot space
index_to_one_hot: map from indices to one-hot space
"""
current_epoch = 0
position_in_batch = 0

def read(filename, vocab_fraction=0, sentence_tokenized=False, is_string=False):
    """
    Read raw data and add data properties to self.data

    Args:
        filename: String. Name of file to read raw data from
        tokenize: Use NLTK to tokenize (word or sentence), or split into chars
        tokenize_type: if tokenizing, whether to use word or sentence tokenization

    Returns:
        dict: python dictionary containing data properties
    """
    # TODO: change name of variable 'filename' to reflect that it can also be a string of the raw data
    # TODO: add paramter 'is_string' to docstring
    global data

    # load raw data
    if is_string:
        raw_data = filename
    else:
        raw_data = open(filename, 'r').read()

    # sentence tokenize data
    if not sentence_tokenized:
        sentences = nltk.sent_tokenize(raw_data)

    # word-tokenize each sentence
    tokenized_sentences = [nltk.word_tokenize(sentence) for sentence in sentences]
    # flatten list of tokens
    tokens = list(itertools.chain(*tokenized_sentences))
    # get data and full vocab size
    data_size, vocab_size = len(tokens), len(set(tokens))

    if vocab_fraction == 1:  # include all words in vocabulary
        unique_tokens = sorted(list(set(tokens)))
    else:  # remove least common words
        # get word frequencies
        word_freq = nltk.FreqDist(tokens)
        # filter rare words, ignore number of occurences
        unique_tokens = [x[0] for x in word_freq.most_common(int(vocab_fraction * vocab_size))]

    # add UNKNOWN_TOKEN to vocabulary
    unique_tokens.insert(0, UNKNOWN_TOKEN)
    # get final vocab size
    vocab_size = len(unique_tokens)
    indices = tokens_to_indices(tokenized_sentences, unique_tokens)
    data_update = {'filename': filename,
                   'raw_data': raw_data,
                   'sentences': sentences,
                   'tokens': tokens,
                   'tokens_flat': tokens,
                   'unique_tokens': unique_tokens,
                   'data_size': data_size,
                   'vocab_size': vocab_size}
    update_data(data_update)
    return data_update

def update_data(properties):
    """
    :param kwargs: Dict containing properties to add to data
    :return: None
    """
    global data
    data.update(properties)
    return properties

def tokens_to_indices(tokenized_sentences, unique_tokens):
    # mapping from tokens to indices
    word_to_index = {w: i for i, w in enumerate(unique_tokens)}
    # replace all invalid tokens with UNKOWN_TOKEN
    for i, sent in enumerate(tokenized_sentences):
        tokenized_sentences[i] = [w if w in unique_tokens[:-1] else UNKNOWN_TOKEN for w in sent]
    indices = [[word_to_index[word] for word in sent] for sent in tokenized_sentences]
    update_data({'indices': indices})
    return indices

def one_hot_encode(indices, vocab_size):
    """
    Encode given data (or default data) as one-hot numpyvectors
    :param tokens: String. If None, uses raw_data from self.data
    :return: one-hot encoded numpy array
    """
    global data

    if data['sentence_tokenized']:
        # TODO: make usable with sentence-tokenized inputs
        pass
    else:
        char_to_ix = {ch: i for i, ch in enumerate(unique_tokens)}
        indices = np.array([char_to_ix[char] for char in tokens]).astype(int)
        one_hot = np.eye(vocab_size)[indices].astype(bool)

    data_update = {'indices': indices,
                   'one_hot': one_hot}
    update_data(data_update)
    return one_hot

def one_hot_decode(one_hot_data=None):
    """
    Convert one-hot encoded vectors to vector containing integer indices
    :param one_hot_data:
    :return:
    """
    if one_hot_data is None:
        one_hot_data = self.data['one_hot']
    return np.argmax(one_hot_data, axis=int(len(one_hot_data.shape) != 1))
def save_data(obj_name):
    """
    pirkcle and save object data at <working_dir>\<data_filename>\objname
    Args:
        obj_name (object): object to be saved
    Returns (str):
        full path to saved file
    """
    global data
    # get working directory
    dir = sys.path[0]
    subfolder = os.path.join(data['filename'].split('.')[0] + '_data', 'pickled_data')
    save_folder = os.path.join(dir, subfolder)
    save_file = os.path.join(save_folder, obj_name)

    try:
        os.makedirs(save_folder)
    except:
        pass

    with open(save_file, 'wb') as f:
        pickle.dump(data[obj_name], f)

    return save_file

def load_data(filename):
    """
    Args:
        filename (str): name of key to store loaded data in
    Returns (object):
        object from loaded data
    """
    global data
    dir = sys.path[0]
    subfolder = os.path.join(data['filename'].split('.')[0] + '_data', 'pickled_data')
    save_folder = os.path.join(dir, subfolder)
    save_file = os.path.join(save_folder, filename)

    try:
        with open(save_file, 'rb') as f:
            _update_data({filename: pickle.load(f)})
    except Exception as e:
        logging.error("Unable to open file at {}".format(save_file))
        logging.info(traceback.format_exc())
    return data[filename]

def batch(batch_size):
    global current_epoch
    global position_in_batch
    if current_epoch == position_in_batch == 0:
        pass
        # TODO: create list of 'sections'
    for ndx in range(0, data['vocab_size'], batch_size):
        pass

def main(filename=None, vocab_fraction=1):
    """
    Args:
        filename (str): If not provided, read() method must be called explicitly to add data
    """
    global data
    if filename is not None:
        read(filename=filename, vocab_fraction=vocab_fraction)  # read raw data from file
        one_hot_encode_tokens(data['tokens'], data['vocab_size'])
        return filename

    # TODO: condition: filename == None -- what then?

if __name__ == '__main__':
    data_to_save = ['index_to_token',
                    'token_to_index',
                    'index_to_one_hot',
                    'sentences',
                    'indices',
                    'unique_tokens']

    main('1984.txt', vocab_fraction=0.95)
    for obj_name in data_to_save:
        save_data(obj_name)

    print('All done')<commit_msg>separated one_hot_encode into index-based and token-based<commit_after>import numpy as np
import itertools
import nltk

UNKNOWN_TOKEN = 'UNKNOWN_TOKEN'

data = {}
"""
data can contain the following keys:
sentences: list of sentence strings
tokens: word-tokenized list of sentences
unique_tokens: list of unique tokens sorted by frequency
indices: integer representation of tokens
one_hot: one-hot representation of indices
vocab_size: number of unique tokens
token_to_index: map from token to index space
index_to_token: map from index to token space
max_sentence_length: number of tokens in the longest sentence
raw_data: full text
data_size: number of tokens in data
filename: name of file to read raw data from
tokens_flat: flattened sequence of word tokens
token_to_one_hot: map from tokens to one-hot space
index_to_one_hot: map from indices to one-hot space
"""
current_epoch = 0
position_in_batch = 0

def read(filename, vocab_fraction=0, sentence_tokenized=False, is_string=False):
    """
    Read raw data and add data properties to self.data

    Args:
        filename: String. Name of file to read raw data from
        tokenize: Use NLTK to tokenize (word or sentence), or split into chars
        tokenize_type: if tokenizing, whether to use word or sentence tokenization

    Returns:
        dict: python dictionary containing data properties
    """
    # TODO: change name of variable 'filename' to reflect that it can also be a string of the raw data
    # TODO: add paramter 'is_string' to docstring
    global data

    # load raw data
    if is_string:
        raw_data = filename
    else:
        raw_data = open(filename, 'r').read()

    # sentence tokenize data
    if not sentence_tokenized:
        sentences = nltk.sent_tokenize(raw_data)

    # word-tokenize each sentence
    tokenized_sentences = [nltk.word_tokenize(sentence) for sentence in sentences]
    # flatten list of tokens
    tokens = list(itertools.chain(*tokenized_sentences))
    # get data and full vocab size
    data_size, vocab_size = len(tokens), len(set(tokens))

    if vocab_fraction == 1:  # include all words in vocabulary
        unique_tokens = sorted(list(set(tokens)))
    else:  # remove least common words
        # get word frequencies
        word_freq = nltk.FreqDist(tokens)
        # filter rare words, ignore number of occurences
        unique_tokens = [x[0] for x in word_freq.most_common(int(vocab_fraction * vocab_size))]

    # add UNKNOWN_TOKEN to vocabulary
    unique_tokens.insert(0, UNKNOWN_TOKEN)
    # get final vocab size
    vocab_size = len(unique_tokens)
    indices = tokens_to_indices(tokenized_sentences, unique_tokens)
    data_update = {'filename': filename,
                   'raw_data': raw_data,
                   'sentences': sentences,
                   'tokens': tokens,
                   'tokens_flat': tokens,
                   'unique_tokens': unique_tokens,
                   'data_size': data_size,
                   'vocab_size': vocab_size}
    update_data(data_update)
    return data_update

def update_data(properties):
    """
    :param kwargs: Dict containing properties to add to data
    :return: None
    """
    global data
    data.update(properties)
    return properties

def tokens_to_indices(tokens, unique_tokens):
    # mapping from tokens to indices
    token_to_index = {w: i for i, w in enumerate(unique_tokens)}
    index_to_token = {i: w for i, w in enumerate(unique_tokens)}
    # replace all invalid tokens with UNKOWN_TOKEN
    for i, sent in enumerate(tokens):
        tokens[i] = [w if w in unique_tokens[:-1] else UNKNOWN_TOKEN for w in sent]
    indices = [[token_to_index[word] for word in sent] for sent in tokens]
    data_update = {'indices': indices,
                   'token_to_index': token_to_index,
                   'index_to_token': index_to_token}
    _update_data(data_update)
    return indices

def one_hot_encode_indices(indices, vocab_size):
    """
    Encode given data (or default data) as one-hot numpyvectors
    :param indices: String. If None, uses raw_data from self.data
    :return: one-hot encoded numpy array
    """
    global data
    index_to_one_hot = dict((index, enc) for index, enc in zip(range(vocab_size), np.eye(vocab_size, dtype=bool)))
    one_hot = [[index_to_one_hot[index] for index in sentence] for sentence in indices]
    max_sentece_length = max([len(sentence) for sentence in indices])
    data_update = {'index_to_one_hot': index_to_one_hot,
                   'one_hot': one_hot,
                   'max_sentence_length': max_sentece_length}
    _update_data(data_update)
    return one_hot

def one_hot_encode_tokens(tokens, vocab_size):
    """
    Encode given data (or default data) as one-hot nested list
    :param tokens (list): nested list of word-tokenized sentences
    :return (list): one-hot encoded list
    """
    global data
    indices = tokens_to_indices(data['tokens'], data['unique_tokens'])
    one_hot = one_hot_encode_indices(indices, vocab_size)
    data_update = {'indices': indices,
                   'one_hot': one_hot}
    _update_data(data_update)
    return one_hot

def one_hot_decode(one_hot_data=None):
    """
    Convert one-hot encoded vectors to vector containing integer indices
    :param one_hot_data:
    :return:
    """
    if one_hot_data is None:
        one_hot_data = self.data['one_hot']
    return np.argmax(one_hot_data, axis=int(len(one_hot_data.shape) != 1))
def save_data(obj_name):
    """
    pirkcle and save object data at <working_dir>\<data_filename>\objname
    Args:
        obj_name (object): object to be saved
    Returns (str):
        full path to saved file
    """
    global data
    # get working directory
    dir = sys.path[0]
    subfolder = os.path.join(data['filename'].split('.')[0] + '_data', 'pickled_data')
    save_folder = os.path.join(dir, subfolder)
    save_file = os.path.join(save_folder, obj_name)

    try:
        os.makedirs(save_folder)
    except:
        pass

    with open(save_file, 'wb') as f:
        pickle.dump(data[obj_name], f)

    return save_file

def load_data(filename):
    """
    Args:
        filename (str): name of key to store loaded data in
    Returns (object):
        object from loaded data
    """
    global data
    dir = sys.path[0]
    subfolder = os.path.join(data['filename'].split('.')[0] + '_data', 'pickled_data')
    save_folder = os.path.join(dir, subfolder)
    save_file = os.path.join(save_folder, filename)

    try:
        with open(save_file, 'rb') as f:
            _update_data({filename: pickle.load(f)})
    except Exception as e:
        logging.error("Unable to open file at {}".format(save_file))
        logging.info(traceback.format_exc())
    return data[filename]

def batch(batch_size):
    global current_epoch
    global position_in_batch
    if current_epoch == position_in_batch == 0:
        pass
        # TODO: create list of 'sections'
    for ndx in range(0, data['vocab_size'], batch_size):
        pass

def main(filename=None, vocab_fraction=1):
    """
    Args:
        filename (str): If not provided, read() method must be called explicitly to add data
    """
    global data
    if filename is not None:
        read(filename=filename, vocab_fraction=vocab_fraction)  # read raw data from file
        one_hot_encode_tokens(data['tokens'], data['vocab_size'])
        return filename

    # TODO: condition: filename == None -- what then?

if __name__ == '__main__':
    data_to_save = ['index_to_token',
                    'token_to_index',
                    'index_to_one_hot',
                    'sentences',
                    'indices',
                    'unique_tokens']

    main('1984.txt', vocab_fraction=0.95)
    for obj_name in data_to_save:
        save_data(obj_name)

    print('All done')<|endoftext|>


<commit_before>import re
import sys

RE_TOK = re.compile('\W')

MAP_RE = (('\|\|','(//|\.)'),
          ('\^', r'[/\\:+!@#\$^\^&\*\(\)\|]'),
          ('\*', r'.*'))

class RuleSyntaxError(Exception):
    pass

TYPE_OPTS = (('script', 'external scripts loaded via HTML script tag'),
             ('image', 'regular images, typically loaded via HTML img tag'),
             ('stylesheet', 'external CSS stylesheet files'),
             ('object', 'content handled by browser plugins, e.g. Flash or Java'),
             ('xmlhttprequest', 'requests started by the XMLHttpRequest object'),
             ('object-subrequest', 'requests started plugins like Flash'),
             ('subdocument', 'embedded pages, usually included via HTML frames'),
             ('document', 'the page itself (only exception rules can be applied to the page)'),
             ('elemhide', 'for exception rules only, similar to document but only disables element hiding rules on the page rather than all filter rules (Adblock Plus 1.2 and higher required)'),
             ('other', 'types of requests not covered in the list above'))
TYPE_OPT_IDS = [x[0] for x in TYPE_OPTS]

class Rule(object):
    def __init__(self, rule_str):
        self.rule_str = rule_str.strip()
        if '$' in rule_str:
            try:
                self.pattern, self.optstring = rule_str.split('$')
            except ValueError:
                raise RuleSyntaxError()
        else:
            self.pattern = self.rule_str
            self.optstring = ''
        self.regex = self._to_regex()
        opts = self.optstring.split(',')
        self.excluded_elements = []
        self.matched_elements = []
        for o in opts:
            if o.startswith('~') and o[1:] in TYPE_OPT_IDS:
                self.excluded_elements.append(o)
            elif o in TYPE_OPT_IDS:
                self.matched_elements.append(o)
        if self.matched_elements == []:
            self.matched_elements = TYPE_OPT_IDS

    def get_tokens(self):
        return RE_TOK.split(self.pattern)

    def match(self, url, elementtype=None):
        if elementtype:
            if elementtype in self.excluded_elements or\
                    (elementtype not in self.matched_elements and\
                         'other' not in self.matched_elements):
                return False
        return self.regex.search(url)

    def _to_regex(self):
        re_str = re.escape(self.pattern)
        for m in MAP_RE:
            re_str = re_str.replace(*m)
        return re.compile(re_str)

    def __unicode__(self):
        return self.rule_str

class Filter(object):
    def __init__(self, f):
        self.index = {}
        for rul in f.xreadlines():
            if rul.startswith('!'): # Comment
                continue
            if '##' in rul: # HTML rule
                continue
            try:
                rule = Rule(rul)
            except RuleSyntaxError:
                print 'syntax error in ', rul
            for tok in rule.get_tokens():
                if len(tok) > 2:
                    if tok not in self.index:
                        self.index[tok] = []
                    self.index[tok].append(rule)

    def match(self, url, elementtype=None):
        tokens = RE_TOK.split(url)
        for tok in tokens:
            if len(tok) > 2:
                if tok in self.index:
                    for rule in self.index[tok]:
                        if rule.match(url, elementtype=elementtype):
                            print unicode(rule)

if __name__ == '__main__':
    f = Filter(file('easylist.txt'))
    print 'start matching'
    f.match(sys.argv[1])
<commit_msg>fixed typo<commit_after>import re
import sys

RE_TOK = re.compile('\W')

MAP_RE = (('\|\|','(//|\.)'),
          ('\^', r'[/\\:+!@#\$^\^&\*\(\)\|]'),
          ('\*', r'.*'))

class RuleSyntaxError(Exception):
    pass

TYPE_OPTS = (('script', 'external scripts loaded via HTML script tag'),
             ('image', 'regular images, typically loaded via HTML img tag'),
             ('stylesheet', 'external CSS stylesheet files'),
             ('object', 'content handled by browser plugins, e.g. Flash or Java'),
             ('xmlhttprequest', 'requests started by the XMLHttpRequest object'),
             ('object-subrequest', 'requests started plugins like Flash'),
             ('subdocument', 'embedded pages, usually included via HTML frames'),
             ('document', 'the page itself (only exception rules can be applied to the page)'),
             ('elemhide', 'for exception rules only, similar to document but only disables element hiding rules on the page rather than all filter rules (Adblock Plus 1.2 and higher required)'),
             ('other', 'types of requests not covered in the list above'))
TYPE_OPT_IDS = [x[0] for x in TYPE_OPTS]

class Rule(object):
    def __init__(self, rule_str):
        self.rule_str = rule_str.strip()
        if '$' in rule_str:
            try:
                self.pattern, self.optstring = rule_str.split('$')
            except ValueError:
                raise RuleSyntaxError()
        else:
            self.pattern = self.rule_str
            self.optstring = ''
        self.regex = self._to_regex()
        opts = self.optstring.split(',')
        self.excluded_elements = []
        self.matched_elements = []
        for o in opts:
            if o.startswith('~') and o[1:] in TYPE_OPT_IDS:
                self.excluded_elements.append(o)
            elif o in TYPE_OPT_IDS:
                self.matched_elements.append(o)
        if self.matched_elements == []:
            self.matched_elements = TYPE_OPT_IDS

    def get_tokens(self):
        return RE_TOK.split(self.pattern)

    def match(self, url, elementtype=None):
        if elementtype:
            if elementtype in self.excluded_elements or\
                    (elementtype not in self.matched_elements and\
                         'other' not in self.matched_elements):
                return False
        return self.regex.search(url)

    def _to_regex(self):
        re_str = re.escape(self.pattern)
        for m in MAP_RE:
            re_str = re_str.replace(*m)
        return re.compile(re_str)

    def __unicode__(self):
        return self.rule_str

class Filter(object):
    def __init__(self, f):
        self.index = {}
        for rul in f.xreadlines():
            if rul.startswith('!'): # Comment
                continue
            if '##' in rul: # HTML rule
                continue
            try:
                rule = Rule(rul)
            except RuleSyntaxError:
                print ('syntax error in rule')
            for tok in rule.get_tokens():
                if len(tok) > 2:
                    if tok not in self.index:
                        self.index[tok] = []
                    self.index[tok].append(rule)

    def match(self, url, elementtype=None):
        tokens = RE_TOK.split(url)
        for tok in tokens:
            if len(tok) > 2:
                if tok in self.index:
                    for rule in self.index[tok]:
                        if rule.match(url, elementtype=elementtype):
                            print unicode(rule)

if __name__ == '__main__':
    f = Filter(file('easylist.txt'))
    print 'start matching'
    f.match(sys.argv[1])
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
import numbers
import numpy as np
from ..constants import BOLTZMANN_IN_MEV_K
from ..energy import Energy

class Analysis(object):
    r"""Class containing methods for the Data class

    Attributes
    ----------
    detailed_balance_factor

    Methods
    -------
    integrate
    position
    width
    scattering_function
    dynamic_susceptibility
    estimate_background

    """

    @property
    def detailed_balance_factor(self):
        r"""Returns the detailed balance factor (sometimes called the Bose
        factor)

        Parameters
        ----------
            None

        Returns
        -------
        dbf : ndarray
            The detailed balance factor (temperature correction)

        """

        return 1. - np.exp(-self.Q[:, 3] / BOLTZMANN_IN_MEV_K / self.temp)

    def integrate(self, background=None, **kwargs):
        r"""Returns the integrated intensity within given bounds

        Parameters
        ----------
        bounds : bool, optional
            A boolean expression representing the bounds inside which the
            calculation will be performed

        background : float or dict, optional
            Default: None

        Returns
        -------
        result : float
            The integrated intensity either over all data, or within
            specified boundaries

        """
        result = 0
        for i in range(4):
            result += np.trapz(self.intensity[self.get_bounds(kwargs)] - self.estimate_background(background),
                               np.squeeze(self.Q[self.get_bounds(kwargs), i]))

        return result

    def position(self, background=None, **kwargs):
        r"""Returns the position of a peak within the given bounds

        Parameters
        ----------
        bounds : bool, optional
            A boolean expression representing the bounds inside which the
            calculation will be performed

        background : float or dict, optional
            Default: None

        Returns
        -------
        result : tup
            The result is a tuple with position in each dimension of Q,
            (h, k, l, e)

        """
        result = ()
        for j in range(4):
            _result = 0
            for i in range(4):
                _result += np.trapz(self.Q[self.get_bounds(kwargs), j] *
                                    (self.intensity[self.get_bounds(kwargs)] - self.estimate_background(background)),
                                    np.squeeze(self.Q[self.get_bounds(kwargs), i])) / self.integrate(**kwargs)

            result += (np.squeeze(_result),)

        return result

    def width(self, background=None, fwhm=False, **kwargs):
        r"""Returns the mean-squared width of a peak within the given bounds

        Parameters
        ----------
        bounds : bool, optional
            A boolean expression representing the bounds inside which the
            calculation will be performed

        background : float or dict, optional
            Default: None

        fwhm : bool, optional
            If True, returns width in fwhm, otherwise in mean-squared width.
            Default: False

        Returns
        -------
        result : tup
            The result is a tuple with the width in each dimension of Q,
            (h, k, l, e)

        """
        result = ()
        for j in range(4):
            _result = 0
            for i in range(4):
                _result += np.trapz((self.Q[self.get_bounds(kwargs), j] - self.position(**kwargs)[j]) ** 2 *
                                    (self.intensity[self.get_bounds(kwargs)] - self.estimate_background(background)),
                                    self.Q[self.get_bounds(kwargs), i]) / self.integrate(**kwargs)

            if fwhm:
                result += (np.sqrt(np.squeeze(_result)) * 2. * np.sqrt(2. * np.log(2.)),)
            else:
                result += (np.squeeze(_result),)

        return result

    def scattering_function(self, material, ei):
        r"""Returns the neutron scattering function, i.e. the detector counts
        scaled by :math:`4 \pi / \sigma_{\mathrm{tot}} * k_i/k_f`.

        Parameters
        ----------
        material : object
            Definition of the material given by the :py:class:`.Material`
            class

        ei : float
            Incident energy in meV

        Returns
        -------
        counts : ndarray
            The detector counts scaled by the total scattering cross section
            and ki/kf
        """
        ki = Energy(energy=ei).wavevector
        kf = Energy(energy=ei - self.e).wavevector

        return 4 * np.pi / material.total_scattering_cross_section * ki / kf * self.detector

    def dynamic_susceptibility(self, material, ei):
        r"""Returns the dynamic susceptibility
        :math:`\chi^{\prime\prime}(\mathbf{Q},\hbar\omega)`

        Parameters
        ----------
        material : object
            Definition of the material given by the :py:class:`.Material`
            class

        ei : float
            Incident energy in meV

        Returns
        -------
        counts : ndarray
            The detector counts turned into the scattering function multiplied
            by the detailed balance factor
        """
        return self.scattering_function(material, ei) * self.detailed_balance_factor

    def estimate_background(self, bg_params):
        r"""Estimate the background according to ``type`` specified.

        Parameters
        ----------
        bg_params : dict
            Input dictionary has keys 'type' and 'value'. Types are
                * 'constant' : background is the constant given by 'value'
                * 'percent' : background is estimated by the bottom x%, where x
                  is value
                * 'minimum' : background is estimated as the detector counts

        Returns
        -------
        background : float or ndarray
            Value determined to be the background. Will return ndarray only if
            `'type'` is `'constant'` and `'value'` is an ndarray
        """
        if isinstance(bg_params, type(None)):
            return 0

        elif isinstance(bg_params, numbers.Number):
            return bg_params

        elif bg_params['type'] == 'constant':
            return bg_params['value']

        elif bg_params['type'] == 'percent':
            inten = self.intensity[self.intensity >= 0.]
            Npts = int(inten.size * (bg_params['value'] / 100.))
            min_vals = inten[np.argsort(inten)[:Npts]]
            background = np.average(min_vals)
            return background

        elif bg_params['type'] == 'minimum':
            return min(self.intensity)

        else:
            return 0

    def get_bounds(self, kwargs):
        r"""Generates a to_fit tuple if bounds is present in kwargs

        Parameters
        ----------
        kwargs : dict

        Returns
        -------
        to_fit : tuple
            Tuple of indices
        """
        if 'bounds' in kwargs:
            to_fit = np.where(kwargs['bounds'])
        else:
            to_fit = np.where(self.Q[:, 0])

        return to_fit
<commit_msg>REF: Explicit kwargs for Analysis methods<commit_after># -*- coding: utf-8 -*-
import numbers
import numpy as np
from ..constants import BOLTZMANN_IN_MEV_K
from ..energy import Energy

class Analysis(object):
    r"""Class containing methods for the Data class

    Attributes
    ----------
    detailed_balance_factor

    Methods
    -------
    integrate
    position
    width
    scattering_function
    dynamic_susceptibility
    estimate_background

    """

    @property
    def detailed_balance_factor(self):
        r"""Returns the detailed balance factor (sometimes called the Bose
        factor)

        Parameters
        ----------
            None

        Returns
        -------
        dbf : ndarray
            The detailed balance factor (temperature correction)

        """

        return 1. - np.exp(-self.Q[:, 3] / BOLTZMANN_IN_MEV_K / self.temp)

    def integrate(self, bounds=None, background=None):
        r"""Returns the integrated intensity within given bounds

        Parameters
        ----------
        bounds : bool, optional
            A boolean expression representing the bounds inside which the
            calculation will be performed

        background : float or dict, optional
            Default: None

        Returns
        -------
        result : float
            The integrated intensity either over all data, or within
            specified boundaries

        """
        result = 0
        for i in range(4):
            result += np.trapz(self.intensity[self.get_bounds(bounds)] - self.estimate_background(background),
                               np.squeeze(self.Q[self.get_bounds(bounds), i]))

        return result

    def position(self, bounds=None, background=None):
        r"""Returns the position of a peak within the given bounds

        Parameters
        ----------
        bounds : bool, optional
            A boolean expression representing the bounds inside which the
            calculation will be performed

        background : float or dict, optional
            Default: None

        Returns
        -------
        result : tup
            The result is a tuple with position in each dimension of Q,
            (h, k, l, e)

        """
        result = ()
        for j in range(4):
            _result = 0
            for i in range(4):
                _result += np.trapz(self.Q[self.get_bounds(bounds), j] *
                                    (self.intensity[self.get_bounds(bounds)] - self.estimate_background(background)),
                                    np.squeeze(self.Q[self.get_bounds(bounds), i])) / self.integrate(bounds, background)

            result += (np.squeeze(_result),)

        return result

    def width(self, bounds=None, background=None, fwhm=False):
        r"""Returns the mean-squared width of a peak within the given bounds

        Parameters
        ----------
        bounds : bool, optional
            A boolean expression representing the bounds inside which the
            calculation will be performed

        background : float or dict, optional
            Default: None

        fwhm : bool, optional
            If True, returns width in fwhm, otherwise in mean-squared width.
            Default: False

        Returns
        -------
        result : tup
            The result is a tuple with the width in each dimension of Q,
            (h, k, l, e)

        """
        result = ()
        for j in range(4):
            _result = 0
            for i in range(4):
                _result += np.trapz((self.Q[self.get_bounds(bounds), j] - self.position(bounds, background)[j]) ** 2 *
                                    (self.intensity[self.get_bounds(bounds)] - self.estimate_background(background)),
                                    self.Q[self.get_bounds(bounds), i]) / self.integrate(bounds, background)

            if fwhm:
                result += (np.sqrt(np.squeeze(_result)) * 2. * np.sqrt(2. * np.log(2.)),)
            else:
                result += (np.squeeze(_result),)

        return result

    def scattering_function(self, material, ei):
        r"""Returns the neutron scattering function, i.e. the detector counts
        scaled by :math:`4 \pi / \sigma_{\mathrm{tot}} * k_i/k_f`.

        Parameters
        ----------
        material : object
            Definition of the material given by the :py:class:`.Material`
            class

        ei : float
            Incident energy in meV

        Returns
        -------
        counts : ndarray
            The detector counts scaled by the total scattering cross section
            and ki/kf
        """
        ki = Energy(energy=ei).wavevector
        kf = Energy(energy=ei - self.e).wavevector

        return 4 * np.pi / material.total_scattering_cross_section * ki / kf * self.detector

    def dynamic_susceptibility(self, material, ei):
        r"""Returns the dynamic susceptibility
        :math:`\chi^{\prime\prime}(\mathbf{Q},\hbar\omega)`

        Parameters
        ----------
        material : object
            Definition of the material given by the :py:class:`.Material`
            class

        ei : float
            Incident energy in meV

        Returns
        -------
        counts : ndarray
            The detector counts turned into the scattering function multiplied
            by the detailed balance factor
        """
        return self.scattering_function(material, ei) * self.detailed_balance_factor

    def estimate_background(self, bg_params):
        r"""Estimate the background according to ``type`` specified.

        Parameters
        ----------
        bg_params : dict
            Input dictionary has keys 'type' and 'value'. Types are
                * 'constant' : background is the constant given by 'value'
                * 'percent' : background is estimated by the bottom x%, where x
                  is value
                * 'minimum' : background is estimated as the detector counts

        Returns
        -------
        background : float or ndarray
            Value determined to be the background. Will return ndarray only if
            `'type'` is `'constant'` and `'value'` is an ndarray
        """
        if isinstance(bg_params, type(None)):
            return 0

        elif isinstance(bg_params, numbers.Number):
            return bg_params

        elif bg_params['type'] == 'constant':
            return bg_params['value']

        elif bg_params['type'] == 'percent':
            inten = self.intensity[self.intensity >= 0.]
            Npts = int(inten.size * (bg_params['value'] / 100.))
            min_vals = inten[np.argsort(inten)[:Npts]]
            background = np.average(min_vals)
            return background

        elif bg_params['type'] == 'minimum':
            return min(self.intensity)

        else:
            return 0

    def get_bounds(self, bounds):
        r"""Generates a to_fit tuple if bounds is present in kwargs

        Parameters
        ----------
        bounds : dict

        Returns
        -------
        to_fit : tuple
            Tuple of indices
        """
        if bounds is not None:
            to_fit = np.where(bounds)
        else:
            to_fit = np.where(self.Q[:, 0])

        return to_fit
<|endoftext|>


<commit_before>##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
#    Thinkopen Brasil
#    Copyright (C) Thinkopen Solutions Brasil (<http://www.tkobr.com>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

import openerp
from openerp import tools, api
from openerp.osv import osv, fields

class nfeio_servicomunicipio(osv.Model):
    _name = 'nfeio.servicomunicipio'
    _description = ''
    _order = 'name'

    _columns = {
        'name': fields.char('Code', size=64, required=True),
        'description': fields.char('Description', size=256),
        'country_id': fields.many2one('res.country', 'Country'),
        'state_id': fields.many2one('res.country.state', 'UF',
            domain="[('country_id','=',country_id)]"),
        'l10n_br_city_id': fields.many2one(
            'l10n_br_base.city', 'Municipio',
            domain="[('state_id','=',state_id)]"),
        'cnae_id': fields.many2one('l10n_br_account.cnae', u'CNAE'),
        'code_federal': fields.char('Federal Code', size=128),
        'code_municipal': fields.char('Municipal Code', size=128),
        'iss': fields.float('ISS'),
        'rt_ir': fields.float('IR Withholding'),
        'rt_pis': fields.float('PIS Withholding'),
        'rt_cofins': fields.float('COFINS Withholding'),
        'rt_csl': fields.float('CSL Withholding'),
        'rt_inss': fields.float('INSS Withholding'),
        'rt_iss': fields.float('ISS Withholding'),
        }

    _defaults = {
        'country_id': lambda self, cr, uid, c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.country_id.id,
        }

    _sql_constraints = [
        ('description_unique', 'unique(name)', u'The code must be unique.'),
        ]<commit_msg>siggest new fields to API<commit_after>##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
#    Thinkopen Brasil
#    Copyright (C) Thinkopen Solutions Brasil (<http://www.tkobr.com>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

import openerp
from openerp import tools, api
from openerp.osv import osv, fields

class nfeio_servicomunicipio(osv.Model):
    _name = 'nfeio.servicomunicipio'
    _description = ''
    _order = 'name'

    _columns = {
        'name': fields.char('Code', size=64, required=True),
        'description': fields.char('Description', size=256),
        'country_id': fields.many2one('res.country', 'Country'),
        'state_id': fields.many2one('res.country.state', 'UF',
            domain="[('country_id','=',country_id)]"),
        'l10n_br_city_id': fields.many2one(
            'l10n_br_base.city', 'Municipio',
            domain="[('state_id','=',state_id)]"),
        'cnae_id': fields.many2one('l10n_br_account.cnae', u'CNAE'),
        'code_federal': fields.char('Federal Code', size=128),
        'code_municipal': fields.char('Municipal Code', size=128),
        'iss': fields.float('ISS'),
        'rt_ir': fields.float('IR Withholding'),
        'rt_pis': fields.float('PIS Withholding'),
        'rt_cofins': fields.float('COFINS Withholding'),
        'rt_csl': fields.float('CSL Withholding'),
        'rt_inss': fields.float('INSS Withholding'),
        'rt_iss': fields.float('ISS Withholding'),
        #date_start DATETIME
        #date_end  DATETIME
        #state  updated or changed or inactive  SELECTION FIELD
        }

    _defaults = {
        'country_id': lambda self, cr, uid, c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.country_id.id,
        }

    _sql_constraints = [
        ('description_unique', 'unique(name)', u'The code must be unique.'),
        ]<|endoftext|>


<commit_before><commit_msg>Simplify rbac callback names to make it easier to understand the policy for each method.<commit_after><|endoftext|>


<commit_before>
# Setup path for local evaluation.
# When copying to another file, just change the parameter to be accurate.
if __name__ == '__main__':
    def __local_eval_fix(package):
        global __package__
        import sys
        __package__ = package
        sys.path.insert(0, '/'.join(['..'] * (1 + package.count('.'))))
        __import__(__package__)
    __local_eval_fix('nitrogen.route')

import re
import logging
import hashlib
import base64
from pprint import pprint
import collections

from webtest import TestApp

from . import tools
from ..uri import Path
from ..status import HttpNotFound

log = logging.getLogger(__name__)

class Route(object):
    """
    >>> r = Route(r'/{controller}/{action}/{id:\d+}')
    >>> r
    <Route:r'/{controller}/{action}/{id:\d+}'>

    >>> r.match('/gallery/photo/12')[0]
    {'action': 'photo', 'controller': 'gallery', 'id': '12'}

    >>> r.match('/controller/action/12extra')
    >>> r.match('/controller/action/not_digits')

    >>> r.match('/controller/action/12/extra')
    ({'action': 'action', 'controller': 'controller', 'id': '12'}, '/extra')

    >>> r.build(controller='news', action='archive', id='24')
    '/news/archive/24'

    >>> r = Route('/gallery/{action}', controller='gallery')
    >>> m = r.match('/gallery/view')
    >>> m[0]
    {'action': 'view', 'controller': 'gallery'}
    >>> r.build(**m[0])
    '/gallery/view'

    >>> r = Route('/{id}', _requirements={'id': r'\d+'})
    >>> r.match('/12')[0]
    {'id': '12'}
    >>> r.match('/hi')

    >>> r = Route('/{id:\d+}', _parsers={'id':int})
    >>> r.match('/12')[0]
    {'id': 12}

    >>> r = Route('/{method:[A-Z]+}', _formatters={'method': str.upper})
    >>> r.match('/GET')[0]
    {'method': 'GET'}
    >>> r.build(method='post')
    '/POST'

    """

    default_pattern = '[^/]*'
    token_re = re.compile(r'''
        {                           # start of keyword match
        ([a-zA-Z_]\w*)              # group 1: name
        (?::(                       # colon and group 2: pattern
        [^}\\]*(?:\\.[^}\\]*)*      # zero or more chars. } can be escaped.
        ))?                         # the colon and pattern are optional
        }
    ''', re.X)

    def __init__(self, raw, **kwargs):

        self._raw = raw
        self._constants = kwargs

        self._requirements = kwargs.pop('_requirements', {})
        self._requirements = dict((k, re.compile(v + '$'))
            for k, v in self._requirements.items())

        self._parsers = kwargs.pop('_parsers', {})
        self._formatters = kwargs.pop('_formatters', {})

        self._compile()

    def __repr__(self):
        return '<Route:r%s>' % repr(self._raw).replace('\\\\', '\\')

    def _compile(self):

        self._hash_to_key = {}
        self._hash_to_pattern = {}

        format = self.token_re.sub(self._compile_sub, self._raw)

        pattern = re.escape(format)
        for hash, patt in self._hash_to_pattern.items():
            pattern = pattern.replace(hash, patt, 1)

        for hash, key in self._hash_to_key.items():
            format = format.replace(hash, '%%(%s)s' % key, 1)

        self.format = format
        self.compiled = re.compile(pattern + r'(?=/|$)')

        del self._hash_to_key
        del self._hash_to_pattern

    def _compile_sub(self, match):
        name = match.group(1)
        patt = match.group(2) or self.default_pattern
        hash = 'x' + base64.b32encode(hashlib.md5(name).digest()).strip('=')
        self._hash_to_key[hash] = name
        self._hash_to_pattern[hash] = '(?P<%s>%s)' % (name, patt)
        return hash

    def match(self, value):
        m = self.compiled.match(value)
        if not m:
            return None

        result = self._constants.copy()
        result.update(m.groupdict())

        for key, pattern in self._requirements.items():
            if not key in result or not pattern.match(result[key]):
                return None

        for key, callback in self._parsers.items():
            if key in result:
                result[key] = callback(result[key])

        return result, value[m.end():]

    def build(self, **kwargs):
        for key, callback in self._formatters.items():
            if key in kwargs:
                kwargs[key] = callback(kwargs[key])
        return self.format % kwargs

class ReMatch(collections.Mapping):

    def __init__(self, route, data, unmatched):
        self.route = route
        self.data = data
        self.unmatched = unmatched

    def __getitem__(self, key):
        return self.data[key]

    def __getattr__(self, key):
        return self.data[key]

    def __iter__(self):
        return iter(self.data)

    def __len__(self):
        return len(self.data)

    def __items__(self):
        return colle

class ReRouter(object):

    def __init__(self, default=None):
        self._apps = []
        self.default = default

    def register(self, name, pattern=None, app=None, **kwargs):
        """Register directly, or use as a decorator.

        Params:
            pattern -- The pattern to match with.
            app -- The app to register. If not provided this method returns
                a decorator which can be used to register with.
            lock_front -- The pattern should match only to the front.
            snap_back -- Require the pattern to match at the end of the URI
                or at the end of a path segment.

        """

        if pattern is None and app is None:
            pattern = name
            name = None

        # We are being used directly here.
        if app:
            route = Route(pattern, **kwargs)
            self._apps.append((route, app))
            return

        # We are not being used directly, so return a decorator to do the
        # work later.
        def decorator(app):
            self.register(name, pattern, app, **kwargs)
            return app
        return decorator

    def __call__(self, environ, start):
        path = tools.get_unrouted(environ)
        log.debug('matching on %r' % path)
        for route, app in self._apps:
            m = route.match(path)
            if m:
                kwargs, unmatched = m
                match = ReMatch(route, kwargs, unmatched)
                tools.set_unrouted(environ,
                    unrouted=unmatched,
                    router=self,
                    data=match,
                    builder=self._builder,
                    kwargs={'data': match}
                )

                return app(environ, start)

        if self.default:
            return self.default(environ, start)

        raise HttpNotFound()

    def _builder(self, route, kwargs):
        raise NotImplemented

def test_routing_path_setup():

    router = ReRouter()

    @router.register(r'/{word:one|two|three}')
    def one(environ, start):
        start('200 OK', [('Content-Type', 'text-plain')])
        yield tools.get_route_data(environ).word

    @router.register(r'/x-{num:\d+}', _parsers=dict(num=int))
    def two(environ, start):
        kwargs = tools.get_route_data(environ)
        output = list(router(environ, start))
        yield '%02d\n' % kwargs['num']
        for x in output:
            yield x

    @router.register(r'/{key:pre\}post}')
    def three(environ, start, *args, **kwargs):
        start('200 OK', [('Content-Type', 'text-plain')])
        kwargs = tools.get_route_data(environ)
        yield kwargs['key']

    app = TestApp(router)

    res = app.get('/one/two')
    assert res.body == 'one'
    # pprint(tools.get_history(res.environ))
    tools._assert_next_history_step(res,
            path='/one/two',
            unrouted='/two',
            router=router,
            builder=router._builder
    )

    res = app.get('/x-4/x-3/x-2/one')
    # print res.body
    assert res.body == '04\n03\n02\none'
    # pprint(tools.get_history(res.environ))
    tools._assert_next_history_step(res,
        path='/x-4/x-3/x-2/one', unrouted='/x-3/x-2/one', router=router, builder=router._builder, _data={'num': 4})
    tools._assert_next_history_step(res,
        path='/x-3/x-2/one', unrouted='/x-2/one', router=router, builder=router._builder, _data={'num': 3})
    tools._assert_next_history_step(res,
        path='/x-2/one', unrouted='/one', router=router, builder=router._builder, _data={'num': 2})
    tools._assert_next_history_step(res,
        path='/one', unrouted='', router=router, builder=router._builder, _data={'word': 'one'})

    try:
        app.get('/-does/not/exist')
        assert False
    except HttpNotFound:
        pass

    try:
        app.get('/one_extra/does-not-exist')
        assert False
    except HttpNotFound:
        pass

    res = app.get('/pre}post')
    assert res.body == 'pre}post'

if __name__ == '__main__':
    from .. import test
    test.run()
<commit_msg>ReRouter default pattern is one-or-more characters<commit_after>
# Setup path for local evaluation.
# When copying to another file, just change the parameter to be accurate.
if __name__ == '__main__':
    def __local_eval_fix(package):
        global __package__
        import sys
        __package__ = package
        sys.path.insert(0, '/'.join(['..'] * (1 + package.count('.'))))
        __import__(__package__)
    __local_eval_fix('nitrogen.route')

import re
import logging
import hashlib
import base64
from pprint import pprint
import collections

from webtest import TestApp

from . import tools
from ..uri import Path
from ..status import HttpNotFound

log = logging.getLogger(__name__)

class Route(object):
    """
    >>> r = Route(r'/{controller}/{action}/{id:\d+}')
    >>> r
    <Route:r'/{controller}/{action}/{id:\d+}'>

    >>> r.match('/gallery/photo/12')[0]
    {'action': 'photo', 'controller': 'gallery', 'id': '12'}

    >>> r.match('/controller/action/12extra')
    >>> r.match('/controller/action/not_digits')

    >>> r.match('/controller/action/12/extra')
    ({'action': 'action', 'controller': 'controller', 'id': '12'}, '/extra')

    >>> r.build(controller='news', action='archive', id='24')
    '/news/archive/24'

    >>> r = Route('/gallery/{action}', controller='gallery')
    >>> m = r.match('/gallery/view')
    >>> m[0]
    {'action': 'view', 'controller': 'gallery'}
    >>> r.build(**m[0])
    '/gallery/view'

    >>> r = Route('/{id}', _requirements={'id': r'\d+'})
    >>> r.match('/12')[0]
    {'id': '12'}
    >>> r.match('/hi')

    >>> r = Route('/{id:\d+}', _parsers={'id':int})
    >>> r.match('/12')[0]
    {'id': 12}

    >>> r = Route('/{method:[A-Z]+}', _formatters={'method': str.upper})
    >>> r.match('/GET')[0]
    {'method': 'GET'}
    >>> r.build(method='post')
    '/POST'

    """

    default_pattern = '[^/]+'
    token_re = re.compile(r'''
        {                           # start of keyword match
        ([a-zA-Z_]\w*)              # group 1: name
        (?::(                       # colon and group 2: pattern
        [^}\\]*(?:\\.[^}\\]*)*      # zero or more chars. } can be escaped.
        ))?                         # the colon and pattern are optional
        }
    ''', re.X)

    def __init__(self, raw, **kwargs):

        self._raw = raw
        self._constants = kwargs

        self._requirements = kwargs.pop('_requirements', {})
        self._requirements = dict((k, re.compile(v + '$'))
            for k, v in self._requirements.items())

        self._parsers = kwargs.pop('_parsers', {})
        self._formatters = kwargs.pop('_formatters', {})

        self._compile()

    def __repr__(self):
        return '<Route:r%s>' % repr(self._raw).replace('\\\\', '\\')

    def _compile(self):

        self._hash_to_key = {}
        self._hash_to_pattern = {}

        format = self.token_re.sub(self._compile_sub, self._raw)

        pattern = re.escape(format)
        for hash, patt in self._hash_to_pattern.items():
            pattern = pattern.replace(hash, patt, 1)

        for hash, key in self._hash_to_key.items():
            format = format.replace(hash, '%%(%s)s' % key, 1)

        self.format = format
        self.compiled = re.compile(pattern + r'(?=/|$)')

        del self._hash_to_key
        del self._hash_to_pattern

    def _compile_sub(self, match):
        name = match.group(1)
        patt = match.group(2) or self.default_pattern
        hash = 'x' + base64.b32encode(hashlib.md5(name).digest()).strip('=')
        self._hash_to_key[hash] = name
        self._hash_to_pattern[hash] = '(?P<%s>%s)' % (name, patt)
        return hash

    def match(self, value):
        m = self.compiled.match(value)
        if not m:
            return None

        result = self._constants.copy()
        result.update(m.groupdict())

        for key, pattern in self._requirements.items():
            if not key in result or not pattern.match(result[key]):
                return None

        for key, callback in self._parsers.items():
            if key in result:
                result[key] = callback(result[key])

        return result, value[m.end():]

    def build(self, **kwargs):
        for key, callback in self._formatters.items():
            if key in kwargs:
                kwargs[key] = callback(kwargs[key])
        return self.format % kwargs

class ReMatch(collections.Mapping):

    def __init__(self, route, data, unmatched):
        self.route = route
        self.data = data
        self.unmatched = unmatched

    def __getitem__(self, key):
        return self.data[key]

    def __getattr__(self, key):
        return self.data[key]

    def __iter__(self):
        return iter(self.data)

    def __len__(self):
        return len(self.data)

    def __items__(self):
        return colle

class ReRouter(object):

    def __init__(self, default=None):
        self._apps = []
        self.default = default

    def register(self, name, pattern=None, app=None, **kwargs):
        """Register directly, or use as a decorator.

        Params:
            pattern -- The pattern to match with.
            app -- The app to register. If not provided this method returns
                a decorator which can be used to register with.
            lock_front -- The pattern should match only to the front.
            snap_back -- Require the pattern to match at the end of the URI
                or at the end of a path segment.

        """

        if pattern is None and app is None:
            pattern = name
            name = None

        # We are being used directly here.
        if app:
            route = Route(pattern, **kwargs)
            self._apps.append((route, app))
            return

        # We are not being used directly, so return a decorator to do the
        # work later.
        def decorator(app):
            self.register(name, pattern, app, **kwargs)
            return app
        return decorator

    def __call__(self, environ, start):
        path = tools.get_unrouted(environ)
        log.debug('matching on %r' % path)
        for route, app in self._apps:
            m = route.match(path)
            if m:
                kwargs, unmatched = m
                match = ReMatch(route, kwargs, unmatched)
                tools.set_unrouted(environ,
                    unrouted=unmatched,
                    router=self,
                    data=match,
                    builder=self._builder,
                    kwargs={'data': match}
                )

                return app(environ, start)

        if self.default:
            return self.default(environ, start)

        raise HttpNotFound()

    def _builder(self, route, kwargs):
        raise NotImplemented

def test_routing_path_setup():

    router = ReRouter()

    @router.register(r'/{word:one|two|three}')
    def one(environ, start):
        start('200 OK', [('Content-Type', 'text-plain')])
        yield tools.get_route_data(environ).word

    @router.register(r'/x-{num:\d+}', _parsers=dict(num=int))
    def two(environ, start):
        kwargs = tools.get_route_data(environ)
        output = list(router(environ, start))
        yield '%02d\n' % kwargs['num']
        for x in output:
            yield x

    @router.register(r'/{key:pre\}post}')
    def three(environ, start, *args, **kwargs):
        start('200 OK', [('Content-Type', 'text-plain')])
        kwargs = tools.get_route_data(environ)
        yield kwargs['key']

    app = TestApp(router)

    res = app.get('/one/two')
    assert res.body == 'one'
    # pprint(tools.get_history(res.environ))
    tools._assert_next_history_step(res,
            path='/one/two',
            unrouted='/two',
            router=router,
            builder=router._builder
    )

    res = app.get('/x-4/x-3/x-2/one')
    # print res.body
    assert res.body == '04\n03\n02\none'
    # pprint(tools.get_history(res.environ))
    tools._assert_next_history_step(res,
        path='/x-4/x-3/x-2/one', unrouted='/x-3/x-2/one', router=router, builder=router._builder, _data={'num': 4})
    tools._assert_next_history_step(res,
        path='/x-3/x-2/one', unrouted='/x-2/one', router=router, builder=router._builder, _data={'num': 3})
    tools._assert_next_history_step(res,
        path='/x-2/one', unrouted='/one', router=router, builder=router._builder, _data={'num': 2})
    tools._assert_next_history_step(res,
        path='/one', unrouted='', router=router, builder=router._builder, _data={'word': 'one'})

    try:
        app.get('/-does/not/exist')
        assert False
    except HttpNotFound:
        pass

    try:
        app.get('/one_extra/does-not-exist')
        assert False
    except HttpNotFound:
        pass

    res = app.get('/pre}post')
    assert res.body == 'pre}post'

if __name__ == '__main__':
    from .. import test
    test.run()
<|endoftext|>