<commit_before>from axelrod import Player

class Retaliate(Player):
    """
    A player starts by cooperating but will retaliate once the opponent
    has won more than 10 percent times the number of defections the player has.
    """
    retaliation_threshold = 0.1

    def __init__(self):
        """
        Uses the basic init from the Player class, but also set the name to
        include the retaliation setting.
        """
        Player.__init__(self)
        self.name = (
            'Retaliate (' +
            str(self.retaliation_threshold) + ')')

    def strategy(self, opponent):
        """
        If the opponent has played D to my C more often than x% of the time
        that I've done the same to him, play D. Otherwise, play C.
        """
        history = zip(self.history, opponent.history)
        if history.count(('C', 'D')) > (
           history.count(('D', 'C')) * self.retaliation_threshold):
            return 'D'
        return 'C'

class Retaliate2(Retaliate):
    retaliation_threshold = 0.08

class Retaliate3(Retaliate):
    retaliation_threshold = 0.12

class LimitedRetaliate(Player):
    """
    A player that co-operates unless the opponent defects and wins.
    It will then retaliate by defecting. It stops when either, it has beaten
    the opponent 10 times more often that it has lost or it reaches the
    retaliation limit (20 defections).
    """
    retaliation_limit = 20
    retaliation_threshold = 0.1
    retaliating = False
    retaliation_count = 0

    def __init__(self):
        """
        Uses the basic init from the Player class, but also set the name to
        include the retaliation setting.
        """
        Player.__init__(self)
        self.name = (
            'Limited Retaliate (' +
            str(self.retaliation_threshold) +
            '/' + str(self.retaliation_limit) + ')')

    def strategy(self, opponent):
        """
        If the opponent has played D to my C more often than x% of the time
        that I've done the same to him, retaliate by playing D but stop doing
        so once I've hit the retaliation limit.
        """
        history = zip(self.history, opponent.history)
        if history.count(('C', 'D')) > (
           history.count(('D', 'C')) * self.retaliation_threshold):
            self.retaliating = True
        else:
            self.retaliating = False
            self.retaliation_count = 0

        if self.retaliating:
            if self.retaliation_count < self.retaliation_limit:
                self.retaliation_count += 1
                return 'D'
            else:
                self.retaliation_count = 0
                self.retaliating = False

        return 'C'

    def reset(self):
        Player.reset(self)
        self.retaliating = False
        self.retaliation_count = 0

class LimitedRetaliate2(LimitedRetaliate):
    retaliation_limit = 25
    retaliation_threshold = 0.1

class LimitedRetaliate3(LimitedRetaliate):
    retaliation_limit = 20
    retaliation_threshold = 0.08
<commit_msg>alters settings for retaliate3 and limitedRetaliate3<commit_after>from axelrod import Player

class Retaliate(Player):
    """
    A player starts by cooperating but will retaliate once the opponent
    has won more than 10 percent times the number of defections the player has.
    """
    retaliation_threshold = 0.1

    def __init__(self):
        """
        Uses the basic init from the Player class, but also set the name to
        include the retaliation setting.
        """
        Player.__init__(self)
        self.name = (
            'Retaliate (' +
            str(self.retaliation_threshold) + ')')

    def strategy(self, opponent):
        """
        If the opponent has played D to my C more often than x% of the time
        that I've done the same to him, play D. Otherwise, play C.
        """
        history = zip(self.history, opponent.history)
        if history.count(('C', 'D')) > (
           history.count(('D', 'C')) * self.retaliation_threshold):
            return 'D'
        return 'C'

class Retaliate2(Retaliate):
    retaliation_threshold = 0.08

class Retaliate3(Retaliate):
    retaliation_threshold = 0.05

class LimitedRetaliate(Player):
    """
    A player that co-operates unless the opponent defects and wins.
    It will then retaliate by defecting. It stops when either, it has beaten
    the opponent 10 times more often that it has lost or it reaches the
    retaliation limit (20 defections).
    """
    retaliation_limit = 20
    retaliation_threshold = 0.1
    retaliating = False
    retaliation_count = 0

    def __init__(self):
        """
        Uses the basic init from the Player class, but also set the name to
        include the retaliation setting.
        """
        Player.__init__(self)
        self.name = (
            'Limited Retaliate (' +
            str(self.retaliation_threshold) +
            '/' + str(self.retaliation_limit) + ')')

    def strategy(self, opponent):
        """
        If the opponent has played D to my C more often than x% of the time
        that I've done the same to him, retaliate by playing D but stop doing
        so once I've hit the retaliation limit.
        """
        history = zip(self.history, opponent.history)
        if history.count(('C', 'D')) > (
           history.count(('D', 'C')) * self.retaliation_threshold):
            self.retaliating = True
        else:
            self.retaliating = False
            self.retaliation_count = 0

        if self.retaliating:
            if self.retaliation_count < self.retaliation_limit:
                self.retaliation_count += 1
                return 'D'
            else:
                self.retaliation_count = 0
                self.retaliating = False

        return 'C'

    def reset(self):
        Player.reset(self)
        self.retaliating = False
        self.retaliation_count = 0

class LimitedRetaliate2(LimitedRetaliate):
    retaliation_limit = 15
    retaliation_threshold = 0.08

class LimitedRetaliate3(LimitedRetaliate):
    retaliation_limit = 20
    retaliation_threshold = 0.05
<|endoftext|>


<commit_before>from barrel import Store, Field, FloatField, EmbeddedStoreField
from barrel.rpc import RpcMixin
from barrel_reaktor.document.models import Document

class Stat(Store):
    count = Field(target="count")
    name = Field(target="name")

class DocumentResult(Store):
    """Search result object wrapping search itemsalongside search info
    like pagination information.
    """

    class DocumentItem(Store):
        """Search result item wrapping a document alongside search info like
        item relevance.
        """
        document = EmbeddedStoreField(target="searchResult", store_class=Document)
        relevance = FloatField(target="relevance")

    class Stats(Store):
        """Represents stats about a search result, e.g. how many books for
        this language, how many books available as pdf, ...
        """
        available_as_epub = EmbeddedStoreField(target="available_as_epub", store_class=Stat, is_array=True)
        available_as_pdf = EmbeddedStoreField(target="available_as_pdf", store_class=Stat, is_array=True)
        available_as_pdf_mobile = EmbeddedStoreField(target="available_as_pdf_mobile", store_class=Stat, is_array=True)
        category = EmbeddedStoreField(target="category", store_class=Stat, is_array=True)
        collection_title = EmbeddedStoreField(target="collectionTitle", store_class=Stat, is_array=True)
        language = EmbeddedStoreField(target="language", store_class=Stat, is_array=True)
        source = EmbeddedStoreField(target="source", store_class=Stat, is_array=True)
        tag = EmbeddedStoreField(target="tag", store_class=Stat, is_array=True)
        version_access_type = EmbeddedStoreField(target="currentVersionAccessType", store_class=Stat, is_array=True)
        version_format = EmbeddedStoreField(target="currentVersionFormat", store_class=Stat, is_array=True)

    # Without blocking search, other fields don't make sense anymore so there
    # they are just ignored.
    count = Field(target="numberOfResults")
    has_less = Field(target="hasLess")
    has_more = Field(target="hasMore")
    items = EmbeddedStoreField(target='results', store_class=DocumentItem, is_array=True)
    offset = Field(target="offset")
    stats = EmbeddedStoreField(target='relatedObjects', store_class=Stats)
    total_count = Field(target="totalNumberOfResults")

class Search(RpcMixin):
    """Interface to various API search endpoints. Beware that this one is not
    a `Store`, which means that when calling its class methods,
    expect different types.
    """
    interface = 'WSSearchDocument'

    @classmethod
    def documents(cls, token, search_string, offset, number_of_results, sort=None, direction=None, include_search_fields=None, sources=None, related=None, options=None):
        """Returns documents for a given string."""
        invert = direction == 'desc'
        if not options:
            options = {'resultType': 'Object'}
        return cls.signature(method='searchDocuments', data_converter=DocumentResult,
            args=[token, search_string, sources, offset, number_of_results, sort, invert, related, include_search_fields, options])

    @classmethod
    def suggestions(cls, token, search_string, number_of_results, sources=None, highlight=None):
        """Returns document suggestions for a given string."""
        args = [token, search_string, sources, number_of_results]
        method = 'getSuggestionObjects'
        if highlight:
            method = 'getSuggestionObjectsWithHighlights'
            args.append(highlight)
        return cls.signature(method=method, data_converter=Document, args=args)
<commit_msg>Add id field to stat model<commit_after>from barrel import Store, Field, FloatField, EmbeddedStoreField
from barrel.rpc import RpcMixin
from barrel_reaktor.document.models import Document

class Stat(Store):
    count = Field(target="count")
    id = Field(target="id")
    name = Field(target="name")

class DocumentResult(Store):
    """Search result object wrapping search itemsalongside search info
    like pagination information.
    """

    class DocumentItem(Store):
        """Search result item wrapping a document alongside search info like
        item relevance.
        """
        document = EmbeddedStoreField(target="searchResult", store_class=Document)
        relevance = FloatField(target="relevance")

    class Stats(Store):
        """Represents stats about a search result, e.g. how many books for
        this language, how many books available as pdf, ...
        """
        available_as_epub = EmbeddedStoreField(target="available_as_epub", store_class=Stat, is_array=True)
        available_as_pdf = EmbeddedStoreField(target="available_as_pdf", store_class=Stat, is_array=True)
        available_as_pdf_mobile = EmbeddedStoreField(target="available_as_pdf_mobile", store_class=Stat, is_array=True)
        category = EmbeddedStoreField(target="category", store_class=Stat, is_array=True)
        collection_title = EmbeddedStoreField(target="collectionTitle", store_class=Stat, is_array=True)
        language = EmbeddedStoreField(target="language", store_class=Stat, is_array=True)
        source = EmbeddedStoreField(target="source", store_class=Stat, is_array=True)
        tag = EmbeddedStoreField(target="tag", store_class=Stat, is_array=True)
        version_access_type = EmbeddedStoreField(target="currentVersionAccessType", store_class=Stat, is_array=True)
        version_format = EmbeddedStoreField(target="currentVersionFormat", store_class=Stat, is_array=True)

    # Without blocking search, other fields don't make sense anymore so there
    # they are just ignored.
    count = Field(target="numberOfResults")
    has_less = Field(target="hasLess")
    has_more = Field(target="hasMore")
    items = EmbeddedStoreField(target='results', store_class=DocumentItem, is_array=True)
    offset = Field(target="offset")
    stats = EmbeddedStoreField(target='relatedObjects', store_class=Stats)
    total_count = Field(target="totalNumberOfResults")

class Search(RpcMixin):
    """Interface to various API search endpoints. Beware that this one is not
    a `Store`, which means that when calling its class methods,
    expect different types.
    """
    interface = 'WSSearchDocument'

    @classmethod
    def documents(cls, token, search_string, offset, number_of_results, sort=None, direction=None, include_search_fields=None, sources=None, related=None, options=None):
        """Returns documents for a given string."""
        invert = direction == 'desc'
        if not options:
            options = {'resultType': 'Object'}
        return cls.signature(method='searchDocuments', data_converter=DocumentResult,
            args=[token, search_string, sources, offset, number_of_results, sort, invert, related, include_search_fields, options])

    @classmethod
    def suggestions(cls, token, search_string, number_of_results, sources=None, highlight=None):
        """Returns document suggestions for a given string."""
        args = [token, search_string, sources, number_of_results]
        method = 'getSuggestionObjects'
        if highlight:
            method = 'getSuggestionObjectsWithHighlights'
            args.append(highlight)
        return cls.signature(method=method, data_converter=Document, args=args)
<|endoftext|>


<commit_before>import time

from django.conf import settings
from django.core.urlresolvers import reverse_lazy

from requests_oauthlib import OAuth2Session

config = {
    'authorization_url': getattr(settings, 'OAUTH_AUTHORIZATION_URL', ''),
    'client_id': getattr(settings, 'HELLO_BASE_CLIENT_ID', ''),
    'client_secret': getattr(settings, 'HELLO_BASE_CLIENT_SECRET', ''),
    'token_url': getattr(settings, 'OAUTH_TOKEN_URL', ''),
}

def _clean_token(token):
    return {
        'access_token': token['access_token'],
        'token_type': token['token_type'],
        'refresh_token': token['refresh_token'],
        'expires_at': int(time.time() + token['expires_in'])
    }

def _token_updater(old_token, request):
    def wrapped(new_token):
        token = _clean_token(new_token)

        # Persist the new token... somehow.
        old_token.update(token)
        if request.user:
            user.access_token = token['access_token']
            user.refresh_token = token['refresh_token']
            user.token_expiration = token['expires_in']
            user.save()
    return wrapped

def auth_session(request, token=None, state=None):
    if token and 'expires_at' in token:
        token['expires_in'] = int(token['expires_at'] - time.time())

    return OAuth2Session(
        config['client_id'],
        redirect_uri=request.build_absolute_uri(reverse_lazy('oauth-callback')),
        auto_refresh_url=config['token_url'],
        auto_refresh_kwargs={
            'client_id': config['client_id'],
            'client_secret': config['client_secret']
        },
        token_updater=_token_updater(token, request),
        token=token,
        state=state,
    )

def auth_url(oauth):
    return oauth.authorization_url(config['authorization_url'])

def auth_token(oauth, response_url):
    token = oauth.fetch_token(
        config['token_url'],
        auth=(config['client_id'], config['client_secret']),
        authorization_response=response_url
    )
    return _clean_token(token)
<commit_msg>Hm. Let's not make this lazy.<commit_after>import time

from django.conf import settings
from django.core.urlresolvers import reverse

from requests_oauthlib import OAuth2Session

config = {
    'authorization_url': getattr(settings, 'OAUTH_AUTHORIZATION_URL', ''),
    'client_id': getattr(settings, 'HELLO_BASE_CLIENT_ID', ''),
    'client_secret': getattr(settings, 'HELLO_BASE_CLIENT_SECRET', ''),
    'token_url': getattr(settings, 'OAUTH_TOKEN_URL', ''),
}

def _clean_token(token):
    return {
        'access_token': token['access_token'],
        'token_type': token['token_type'],
        'refresh_token': token['refresh_token'],
        'expires_at': int(time.time() + token['expires_in'])
    }

def _token_updater(old_token, request):
    def wrapped(new_token):
        token = _clean_token(new_token)

        # Persist the new token... somehow.
        old_token.update(token)
        if request.user:
            user.access_token = token['access_token']
            user.refresh_token = token['refresh_token']
            user.token_expiration = token['expires_in']
            user.save()
    return wrapped

def auth_session(request, token=None, state=None):
    if token and 'expires_at' in token:
        token['expires_in'] = int(token['expires_at'] - time.time())

    return OAuth2Session(
        config['client_id'],
        redirect_uri=request.build_absolute_uri(reverse('oauth-callback')),
        auto_refresh_url=config['token_url'],
        auto_refresh_kwargs={
            'client_id': config['client_id'],
            'client_secret': config['client_secret']
        },
        token_updater=_token_updater(token, request),
        token=token,
        state=state,
    )

def auth_url(oauth):
    return oauth.authorization_url(config['authorization_url'])

def auth_token(oauth, response_url):
    token = oauth.fetch_token(
        config['token_url'],
        auth=(config['client_id'], config['client_secret']),
        authorization_response=response_url
    )
    return _clean_token(token)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
##############################################################################
#
#    Author: Nicolas Bessi
#    Copyright 2014 Camptocamp SA
#
#    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 time
import re

import openerp.tests.common as test_common

class TestPaymentSlip(test_common.TransactionCase):
    _compile_get_ref = re.compile(r'[^0-9]')

    def make_bank(self):
        company = self.env.ref('base.main_company')
        self.assertTrue(company)
        partner = self.env.ref('base.main_partner')
        self.assertTrue(partner)
        bank = self.env['res.bank'].create(
            {
                'name': 'BCV',
                'ccp': '01-1234-1',
                'bic': '234234',
                'clearing': '234234',
            }
        )
        bank_account = self.env['res.partner.bank'].create(
            {
                'partner_id': partner.id,
                'owner_name': partner.name,
                'street':  partner.street,
                'city': partner.city,
                'zip':  partner.zip,
                'state': 'bvr',
                'bank': bank.id,
                'bank_name': bank.name,
                'bank_bic': bank.bic,
                'acc_number': 'R 12312123',
                'bvr_adherent_num': '1234567',
                'print_bank': True,
                'print_account': True,
                'print_partner': True,
            }
        )
        return bank_account

    def test_invoice_confirmation(self):
        """Test that confirming an invoice generate slips correctly"""
        bank_account = self.make_bank()
        invoice = self.env['account.invoice'].create(
            {
                'partner_id': self.env.ref('base.res_partner_12').id,
                'reference_type': 'none',
                'name': 'A customer invoice',
                'account_id': self.env.ref('account.a_recv').id,
                'type': 'out_invoice',
                'partner_bank_id': bank_account.id
            }
        )

        self.env['account.invoice.line'].create(
            {
                'product_id': False,
                'quantity': 1,
                'price_unit': 862.50,
                'invoice_id': invoice.id,
                'name': 'product that cost 862.50 all tax included',
            }
        )
        invoice.signal_workflow('invoice_open')
        attempt = 0
        while not invoice.move_id:
            invoice.refresh()
            time.sleep(0.1)
            attempt += 1
            if attempt > 20:
                break
        self.assertTrue(invoice.move_id)
        for line in invoice.move_id.line_id:
            if line.account_id.type in ('payable', 'receivable'):
                self.assertTrue(line.transaction_ref)
            else:
                self.assertFalse(line.transaction_ref)
        for line in invoice.move_id.line_id:
            slip = self.env['l10n_ch.payment_slip'].search(
                [('move_line_id', '=', line.id)]
            )
            if line.account_id.type in ('payable', 'receivable'):
                self.assertTrue(slip)
                self.assertEqual(slip.amount_total, 862.50)
                self.assertEqual(slip.invoice_id.id, invoice.id)
            else:
                self.assertFalse(slip)

    def test_slip_validity(self):
        """Test that confirming slip are valid"""
        bank_account = self.make_bank()

        invoice = self.env['account.invoice'].create(
            {
                'partner_id': self.env.ref('base.res_partner_12').id,
                'reference_type': 'none',
                'name': 'A customer invoice',
                'account_id': self.env.ref('account.a_recv').id,
                'type': 'out_invoice',
                'partner_bank_id': bank_account.id
            }
        )

        self.env['account.invoice.line'].create(
            {
                'product_id': False,
                'quantity': 1,
                'price_unit': 862.50,
                'invoice_id': invoice.id,
                'name': 'product that cost 862.50 all tax included',
            }
        )
        invoice.signal_workflow('invoice_open')
        attempt = 0
        while not invoice.move_id:
            invoice.refresh()
            time.sleep(1)
            attempt += 1
            if attempt > 20:
                break
        self.assertTrue(invoice.move_id)
        for line in invoice.move_id.line_id:
            slip = self.env['l10n_ch.payment_slip'].search(
                [('move_line_id', '=', line.id)]
            )
            if line.account_id.type in ('payable', 'receivable'):
                self.assertTrue(slip.reference)
                self.assertTrue(slip.scan_line)
                self.assertTrue(slip.slip_image)
                self.assertTrue(slip.a4_pdf)
                inv_num = line.invoice.number
                line_ident = self._compile_get_ref.sub(
                    '', "%s%s" % (inv_num, line.id)
                )
                self.assertIn(line_ident, slip.reference.replace(' ', ''))
<commit_msg>Add comment on test workflow trick<commit_after># -*- coding: utf-8 -*-
##############################################################################
#
#    Author: Nicolas Bessi
#    Copyright 2014 Camptocamp SA
#
#    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 time
import re

import openerp.tests.common as test_common

class TestPaymentSlip(test_common.TransactionCase):
    _compile_get_ref = re.compile(r'[^0-9]')

    def make_bank(self):
        company = self.env.ref('base.main_company')
        self.assertTrue(company)
        partner = self.env.ref('base.main_partner')
        self.assertTrue(partner)
        bank = self.env['res.bank'].create(
            {
                'name': 'BCV',
                'ccp': '01-1234-1',
                'bic': '234234',
                'clearing': '234234',
            }
        )
        bank_account = self.env['res.partner.bank'].create(
            {
                'partner_id': partner.id,
                'owner_name': partner.name,
                'street':  partner.street,
                'city': partner.city,
                'zip':  partner.zip,
                'state': 'bvr',
                'bank': bank.id,
                'bank_name': bank.name,
                'bank_bic': bank.bic,
                'acc_number': 'R 12312123',
                'bvr_adherent_num': '1234567',
                'print_bank': True,
                'print_account': True,
                'print_partner': True,
            }
        )
        return bank_account

    def test_invoice_confirmation(self):
        """Test that confirming an invoice generate slips correctly"""
        bank_account = self.make_bank()
        invoice = self.env['account.invoice'].create(
            {
                'partner_id': self.env.ref('base.res_partner_12').id,
                'reference_type': 'none',
                'name': 'A customer invoice',
                'account_id': self.env.ref('account.a_recv').id,
                'type': 'out_invoice',
                'partner_bank_id': bank_account.id
            }
        )

        self.env['account.invoice.line'].create(
            {
                'product_id': False,
                'quantity': 1,
                'price_unit': 862.50,
                'invoice_id': invoice.id,
                'name': 'product that cost 862.50 all tax included',
            }
        )
        invoice.signal_workflow('invoice_open')
        # Workflows are async. We have to wait for them to finish
        attempt = 0
        while not invoice.move_id:
            invoice.refresh()
            time.sleep(0.1)
            attempt += 1
            if attempt > 20:
                break
        self.assertTrue(invoice.move_id)
        for line in invoice.move_id.line_id:
            if line.account_id.type in ('payable', 'receivable'):
                self.assertTrue(line.transaction_ref)
            else:
                self.assertFalse(line.transaction_ref)
        for line in invoice.move_id.line_id:
            slip = self.env['l10n_ch.payment_slip'].search(
                [('move_line_id', '=', line.id)]
            )
            if line.account_id.type in ('payable', 'receivable'):
                self.assertTrue(slip)
                self.assertEqual(slip.amount_total, 862.50)
                self.assertEqual(slip.invoice_id.id, invoice.id)
            else:
                self.assertFalse(slip)

    def test_slip_validity(self):
        """Test that confirming slip are valid"""
        bank_account = self.make_bank()

        invoice = self.env['account.invoice'].create(
            {
                'partner_id': self.env.ref('base.res_partner_12').id,
                'reference_type': 'none',
                'name': 'A customer invoice',
                'account_id': self.env.ref('account.a_recv').id,
                'type': 'out_invoice',
                'partner_bank_id': bank_account.id
            }
        )

        self.env['account.invoice.line'].create(
            {
                'product_id': False,
                'quantity': 1,
                'price_unit': 862.50,
                'invoice_id': invoice.id,
                'name': 'product that cost 862.50 all tax included',
            }
        )
        invoice.signal_workflow('invoice_open')
        # Workflows are async. We have to wait for them to finish
        attempt = 0
        while not invoice.move_id:
            invoice.refresh()
            time.sleep(1)
            attempt += 1
            if attempt > 20:
                break
        self.assertTrue(invoice.move_id)
        for line in invoice.move_id.line_id:
            slip = self.env['l10n_ch.payment_slip'].search(
                [('move_line_id', '=', line.id)]
            )
            if line.account_id.type in ('payable', 'receivable'):
                self.assertTrue(slip.reference)
                self.assertTrue(slip.scan_line)
                self.assertTrue(slip.slip_image)
                self.assertTrue(slip.a4_pdf)
                inv_num = line.invoice.number
                line_ident = self._compile_get_ref.sub(
                    '', "%s%s" % (inv_num, line.id)
                )
                self.assertIn(line_ident, slip.reference.replace(' ', ''))
<|endoftext|>


<commit_before>#!/usr/bin/python

import urllib2, sys, os
import re
from BeautifulSoup import BeautifulSoup, BeautifulStoneSoup, NavigableString, Tag

# todo: erratum question / reponse
#start_url = 'http://recherche2.assemblee-nationale.fr/questions/resultats-questions.jsp?NumLegislature=13Questions&C1=QE&C2=QG&C3=QOSD&C4=RET&C5=AR&C6=SR&C7=NR'
# SortField=NAT&SortOrder=ASC&ResultCount=25

def convertdate(s):
    d, m, y = s.split('/')
    return '-'.join((y, m, d))

fn = sys.argv[1]

fieldorder = (
    'source',
    'legislature',
    'type',
    'numero',
    'date_question',
    'date_retrait',
    'date_reponse',
    'date_signalement',
    'date_cht_attr',
    'page_question',
    'page_reponse',
    'ministere_attribue',
    'ministere_interroge',
    'tete_analyse',
    'analyse',
    'rubrique',
    'question',
    'reponse',
    'motif_retrait',
    'auteur',
)

d = dict.fromkeys(fieldorder, '')
leg_reg = re.compile(r'^.*nationale.fr_q(\d+)_.*$')
d['legislature'] = leg_reg.sub(r'\1', fn)
d['type'] = 'QE'

_clean_html_re = re.compile("<.*?>")
def clean_html(s):
    return _clean_html_re.sub('', s)

lastbr_re = re.compile('\s*
$', re.U|re.M)
linebreaks_re = re.compile(r'[\s\r\n]+')
def extracttext(t):
    div = t.parent.findNextSibling('div', attrs={'class': 'contenutexte'})
    text = div.decodeContents().strip()
    return linebreaks_re.sub(' ', lastbr_re.sub('', text))

def extractspan(t):
    span = t.findNextSibling('span', attrs={'class': 'contenu'})
    return span.decodeContents()

re_clean_html = [(re.compile(r'<//[^>]*>'), ''),
		 (re.compile(r"(<[^>]*='[^>'\"]*')['\"]([^>]*>)"), r'\1\2'),
		 (re.compile(r"(<[^>]*=\"[^>'\"]*\")['\"]([^>]*>)"), r'\1\2'),
		 (re.compile(r"(<[^>]*=)=(['\"][^>]*>)"), r'\1\2')]
html = open(fn).read()
for reg, rep in re_clean_html:
    html = reg.sub(rep, html)
s = BeautifulSoup(html, convertEntities=BeautifulStoneSoup.ALL_ENTITIES)

spandict = {
    'ministere_interroge': u'Minist\xe8re interrog\xe9',
    'ministere_attribue': u'Minist\xe8re attributaire',
    'rubrique': u'Rubrique',
    'tete_analyse': u"T\xeate d'analyse",
    'analyse': u'Analyse',
}

for k, v in spandict.iteritems():
    d[k] = extractspan(s.find(text=re.compile(u'^%s >' % v)))

# extrait les dates / pages
pubdict = {
    u'Question publi\xe9e au JO le': (('date', 'date_question'), ('page', 'page_question')),
    u'Question retir\xe9e le': (('date', 'date_retrait'), ('motif', 'motif_retrait')),
    u'R\xe9ponse publi\xe9e au JO le': (('date', 'date_reponse'), ('page', 'page_reponse')),
    u"Date de changement d'attribution": (('date', 'date_cht_attr'),),
    u'Date de signalement': (('date', 'date_signalement'),),
    u'Date de renouvellement': (('date', 'date_signalement'),),
    u'Erratum de la r\xe9ponse publi\xe9 au JO le': (('date', 'date_erratum_reponse'), ('page', 'page_erratum_reponse')),
    u'Erratum de la question publi\xe9 au JO le': (('date', 'date_erratum_question'), ('page', 'page_erratum_question')),
}

# split par lignes
dates = s.find(text=re.compile(u'^Question publi\xe9e au JO le')).parent
dates = dates.decodeContents().split('
')

# integre le deuxieme emplacement de retrait
retrait = s.find(text=re.compile(u'^Question retir\xe9e le'))
if retrait:
    try:
        span = extractspan(retrait)
    except:
        pass
    else:
        dates.append(u'%s\xa0page\xa0:\xa0%s' % (retrait, span))

xre = re.compile(u'(?P<type>[A-Z].*?)\s*:\s*(?P<date>\d+/\d+/\d+)((\s*page\s*:\s*(?P<page>\d*))?(\s*\(\s*(?P<motif>.*?)\s*\)\s*)?)?\s*', re.U|re.M)
for l in dates:
    if not l:
        continue
    for m in xre.finditer(clean_html(l)):
        for k, v in pubdict[m.group('type')]:
            value = m.group(k)
            if value is None:
                value = ''
            if k == 'date':
                value = convertdate(value)
            d[v] = value

# pour les questions au gvt, avec dates identiques
if 'date_reponse' in d and not 'date_question' in d:
    d['date_question'] = d['date_reponse']

num = s.find(text=re.compile(u'^Question N\xb0 : '))
d['numero'] = num.findNextSibling('b').decodeContents()
auteur = num.parent.findNextSibling('td').findNext('b').decodeContents()

preauteur = (u'M.\xa0', u'Mme\xa0', u'Mlle\xa0')
for p in preauteur:
    if auteur.startswith(p):
        auteur = auteur[len(p):]
        break
d['auteur'] = auteur.replace(u'\xa0', u' ')

q = s.find(text=re.compile(u'^\s*Texte de la question\s*$'))
d['question'] = extracttext(q)

if d.get('date_reponse'):
    r = s.find(text=re.compile(u'^\s*Texte de la r\xe9ponse\s*$'))
    d['reponse'] = extracttext(r)

file_reg = re.compile(r'^.*/([^/]+)$')
d['source'] = file_reg.sub(r'\1', fn).replace('_', '/')
d['motif_retrait'] = d['motif_retrait'].lower()

for k, v in d.iteritems():
    d[k] = v.encode('utf8').replace('\\', '\\\\').replace('"', '\\"')
print "{%s}" % ", ".join('"%s": "%s"' % (k, d[k]) for k in fieldorder)
<commit_msg>avoid pointless stacks<commit_after>#!/usr/bin/python

import urllib2, sys, os
import re
from BeautifulSoup import BeautifulSoup, BeautifulStoneSoup, NavigableString, Tag

# todo: erratum question / reponse
#start_url = 'http://recherche2.assemblee-nationale.fr/questions/resultats-questions.jsp?NumLegislature=13Questions&C1=QE&C2=QG&C3=QOSD&C4=RET&C5=AR&C6=SR&C7=NR'
# SortField=NAT&SortOrder=ASC&ResultCount=25

def convertdate(s):
    d, m, y = s.split('/')
    return '-'.join((y, m, d))

fn = sys.argv[1]

fieldorder = (
    'source',
    'legislature',
    'type',
    'numero',
    'date_question',
    'date_retrait',
    'date_reponse',
    'date_signalement',
    'date_cht_attr',
    'page_question',
    'page_reponse',
    'ministere_attribue',
    'ministere_interroge',
    'tete_analyse',
    'analyse',
    'rubrique',
    'question',
    'reponse',
    'motif_retrait',
    'auteur',
)

d = dict.fromkeys(fieldorder, '')
leg_reg = re.compile(r'^.*nationale.fr_q(\d+)_.*$')
d['legislature'] = leg_reg.sub(r'\1', fn)
d['type'] = 'QE'

_clean_html_re = re.compile("<.*?>")
def clean_html(s):
    return _clean_html_re.sub('', s)

lastbr_re = re.compile('\s*
$', re.U|re.M)
linebreaks_re = re.compile(r'[\s\r\n]+')
def extracttext(t):
    div = t.parent.findNextSibling('div', attrs={'class': 'contenutexte'})
    text = div.decodeContents().strip()
    return linebreaks_re.sub(' ', lastbr_re.sub('', text))

def extractspan(t):
    try:
        span = t.findNextSibling('span', attrs={'class': 'contenu'})
        return span.decodeContents()
    except:
        exit(1)

re_clean_html = [(re.compile(r'<//[^>]*>'), ''),
		 (re.compile(r"(<[^>]*='[^>'\"]*')['\"]([^>]*>)"), r'\1\2'),
		 (re.compile(r"(<[^>]*=\"[^>'\"]*\")['\"]([^>]*>)"), r'\1\2'),
		 (re.compile(r"(<[^>]*=)=(['\"][^>]*>)"), r'\1\2')]
html = open(fn).read()
for reg, rep in re_clean_html:
    html = reg.sub(rep, html)
s = BeautifulSoup(html, convertEntities=BeautifulStoneSoup.ALL_ENTITIES)

spandict = {
    'ministere_interroge': u'Minist\xe8re interrog\xe9',
    'ministere_attribue': u'Minist\xe8re attributaire',
    'rubrique': u'Rubrique',
    'tete_analyse': u"T\xeate d'analyse",
    'analyse': u'Analyse',
}

for k, v in spandict.iteritems():
    d[k] = extractspan(s.find(text=re.compile(u'^%s >' % v)))

# extrait les dates / pages
pubdict = {
    u'Question publi\xe9e au JO le': (('date', 'date_question'), ('page', 'page_question')),
    u'Question retir\xe9e le': (('date', 'date_retrait'), ('motif', 'motif_retrait')),
    u'R\xe9ponse publi\xe9e au JO le': (('date', 'date_reponse'), ('page', 'page_reponse')),
    u"Date de changement d'attribution": (('date', 'date_cht_attr'),),
    u'Date de signalement': (('date', 'date_signalement'),),
    u'Date de renouvellement': (('date', 'date_signalement'),),
    u'Erratum de la r\xe9ponse publi\xe9 au JO le': (('date', 'date_erratum_reponse'), ('page', 'page_erratum_reponse')),
    u'Erratum de la question publi\xe9 au JO le': (('date', 'date_erratum_question'), ('page', 'page_erratum_question')),
}

# split par lignes
dates = s.find(text=re.compile(u'^Question publi\xe9e au JO le')).parent
dates = dates.decodeContents().split('
')

# integre le deuxieme emplacement de retrait
retrait = s.find(text=re.compile(u'^Question retir\xe9e le'))
if retrait:
    try:
        span = extractspan(retrait)
    except:
        pass
    else:
        dates.append(u'%s\xa0page\xa0:\xa0%s' % (retrait, span))

xre = re.compile(u'(?P<type>[A-Z].*?)\s*:\s*(?P<date>\d+/\d+/\d+)((\s*page\s*:\s*(?P<page>\d*))?(\s*\(\s*(?P<motif>.*?)\s*\)\s*)?)?\s*', re.U|re.M)
for l in dates:
    if not l:
        continue
    for m in xre.finditer(clean_html(l)):
        for k, v in pubdict[m.group('type')]:
            value = m.group(k)
            if value is None:
                value = ''
            if k == 'date':
                value = convertdate(value)
            d[v] = value

# pour les questions au gvt, avec dates identiques
if 'date_reponse' in d and not 'date_question' in d:
    d['date_question'] = d['date_reponse']

num = s.find(text=re.compile(u'^Question N\xb0 : '))
d['numero'] = num.findNextSibling('b').decodeContents()
auteur = num.parent.findNextSibling('td').findNext('b').decodeContents()

preauteur = (u'M.\xa0', u'Mme\xa0', u'Mlle\xa0')
for p in preauteur:
    if auteur.startswith(p):
        auteur = auteur[len(p):]
        break
d['auteur'] = auteur.replace(u'\xa0', u' ')

q = s.find(text=re.compile(u'^\s*Texte de la question\s*$'))
d['question'] = extracttext(q)

if d.get('date_reponse'):
    r = s.find(text=re.compile(u'^\s*Texte de la r\xe9ponse\s*$'))
    d['reponse'] = extracttext(r)

file_reg = re.compile(r'^.*/([^/]+)$')
d['source'] = file_reg.sub(r'\1', fn).replace('_', '/')
d['motif_retrait'] = d['motif_retrait'].lower()

for k, v in d.iteritems():
    d[k] = v.encode('utf8').replace('\\', '\\\\').replace('"', '\\"')
print "{%s}" % ", ".join('"%s": "%s"' % (k, d[k]) for k in fieldorder)
<|endoftext|>


<commit_before># Copyright 2017-2018 Onestein (<http://www.onestein.eu>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo.tests import common
from odoo.tools.translate import _

class TestL10NNLPostcode(common.TransactionCase):
    def setUp(self):
        super(TestL10NNLPostcode, self).setUp()
        self.Partner = self.env['res.partner']

        self.partner_1 = self.env.ref('base.res_partner_2')
        self.partner_2 = self.env.ref('base.res_partner_3')

    def test_01_onchange(self):
        values = {
            'zip': '80021',
        }

        field_onchange = self.partner_1._onchange_spec()
        self.assertEqual(field_onchange.get('zip'), '1')

        # self.partner_1.onchange(values, 'zip', field_onchange)
        # self.partner_1.with_context(skip_postcode_check=True).onchange(
        #     values, 'zip', field_onchange)

        self.partner_2.write({
            'country_id': self.env.ref('base.nl').id,
            'zip': values['zip'],
        })

        warning = self.partner_2.onchange_zip_l10n_nl_postcode()
        msg = _('The Postcode you entered (%s) is not valid.')
        tst_warning = {'warning': {
            'title': _('Warning!'),
            'message': msg % values['zip'],
        }}
        self.assertEqual(warning, tst_warning)

        self.partner_2.write({
            'zip': '4813LE',
        })
        self.partner_2.onchange_zip_l10n_nl_postcode()
<commit_msg>Fix test of l10n_nl_postcode<commit_after># Copyright 2017-2018 Onestein (<http://www.onestein.eu>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo.tests import common
from odoo.tools.translate import _

class TestL10NNLPostcode(common.TransactionCase):
    def setUp(self):
        super(TestL10NNLPostcode, self).setUp()
        self.Partner = self.env['res.partner']

        self.partner_1 = self.env.ref('base.res_partner_2')
        self.partner_2 = self.env.ref('base.res_partner_3')

    def test_01_onchange(self):
        values = {
            'zip': '80021',
        }

        self.partner_2.write({
            'country_id': self.env.ref('base.nl').id,
            'zip': values['zip'],
        })

        warning = self.partner_2.onchange_zip_l10n_nl_postcode()
        msg = _('The Postcode you entered (%s) is not valid.')
        tst_warning = {'warning': {
            'title': _('Warning!'),
            'message': msg % values['zip'],
        }}
        self.assertEqual(warning, tst_warning)

        self.partner_2.write({
            'zip': '4813LE',
        })
        self.partner_2.onchange_zip_l10n_nl_postcode()

    def test_02_onchange(self):
        values = {
            'zip': '80021',
        }

        field_onchange = self.Partner._onchange_spec()
        self.assertEqual(field_onchange.get('zip'), '1')

        # workaround to avoid _compute_sale_order_count() being called
        # since self.read(['child_ids']) will raise an access right error
        to_remove_fields = [
            'sale_order_count',
            'purchase_order_count',
            'supplier_invoice_count'
        ]
        for to_remove in to_remove_fields:
            if to_remove in field_onchange.keys():
                del field_onchange[to_remove]

        self.Partner.onchange(values, 'zip', field_onchange)
        self.Partner.with_context(skip_postcode_check=True).onchange(
            values, 'zip', field_onchange)
<|endoftext|>


<commit_before>#!/usr/bin/env python
"""
This file introduces an extension to the basic Study-class that allows to compute the distribution of hyper-parameters.
"""

from .study import *
from .preprocessing import *
from mpl_toolkits.mplot3d import Axes3D

class RasterStudy(Study):
    """
    This class serves as an extention to the basic Study class and allows to compute the distribution of hyper-
    parameters of a given transition model. For further information, see the documentation of the fit-method of this
    class.
    """
    def __init__(self):
        super(RasterStudy, self).__init__()

        self.raster = []
        self.rasterValues = []
        self.rasterConstant = []
        self.hyperParameterPrior = None
        self.hyperParameterDistribution = None
        self.averagePosteriorSequence = None

        print '  --> Raster study'

    def fit(self, raster=[], forwardOnly=False, evidenceOnly=False, customRaster=False, silent=False):
        """
        This method over-rides the according method of the Study-class. It runs the algorithm for equally spaced hyper-
        parameter values as defined by the variable 'raster'. The posterior sequence represents the average
        model of all analyses. Posterior mean values are computed from this average model.

        Parameters:
            raster - List of lists with each containing the name of a hyper-parameter together with a lower and upper
                     boundary as well as a number of steps in between.
                     Example: raster = [['sigma', 0, 1, 20],['log10pMin', -10, -5, 10]]

            forwardOnly - If set to True, the fitting process is terminated after the forward pass. The resulting
                posterior distributions are so-called "filtering distributions" which - at each time step -
                only incorporate the information of past data points. This option thus emulates an online
                analysis.

            evidenceOnly - If set to True, only forward pass is run and evidence is calculated. In contrast to the
                forwardOnly option, no posterior mean values are computed and no posterior distributions are stored.

            customRaster - If set to True, the keyword argument 'raster' will not be used. Instead, all relevant
                attributes have to be set manually by the user. May be used for irregular grids of hyper-parameter
                values.

            silent - If set to True, no output is generated by the fitting method.

        Returns:
            None
        """
        print '+ Started new fit.'

        if not customRaster:
            self.raster = raster

            # in case no raster is provided, call standard fit method.
            if not self.raster:
                print '! No raster defined for hyper-parameter values. Using standard fit-method.'
                Study.fit(self, forwardOnly=forwardOnly, evidenceOnly=evidenceOnly, silent=silent)
                return

            # create array with raster-values
            temp = np.meshgrid(*[np.linspace(lower, upper, steps) for name, lower, upper, steps in self.raster],
                               indexing='ij')
            self.rasterValues = np.array([t.ravel() for t in temp]).T
            self.rasterConstant = [np.abs(upper-lower)/(float(steps)-1) for name, lower, upper, steps in self.raster]
        else:
            if self.raster == []:
                print "! A dummy 'raster' attribute has to be set when using customRaster=True."
                print "  (Only hyper-parameter names are extracted from this attribute.)"
                return
            if self.rasterValues == []:
                print "! The attribute 'rasterValues' has to be set manually when using customRaster=True."
                return
            if self.rasterConstant == []:
                print "! The attribute 'rasterConstant' has to be set manually when using customRaster=True."
                return

        # prepare arrays for change-point distribution and average posterior sequence
        self.formattedData = movingWindow(self.rawData, self.observationModel.segmentLength)
        if self.hyperParameterPrior is None:
            self.hyperParameterPrior = np.ones(len(self.rasterValues))/len(self.rasterValues)
        else:
            # check if given prior is correctly formatted to fit length of raster array
            if len(self.hyperParameterPrior) != len(self.rasterValues):
                print '! Given raster expects {0} values for hyper-parameter prior.'.format(len(self.rasterValues))
                return

        if not evidenceOnly:
            self.averagePosteriorSequence = np.zeros([len(self.formattedData)]+self.gridSize)

        logEvidenceList = []
        localEvidenceList = []

        # we use the setSelectedHyperParameters-method from the Study class
        self.selectedHyperParameters = [name for name, lower, upper, steps in self.raster]

        if not self.checkConsistency():
            return

        print '    + {} analyses to run.'.format(len(self.rasterValues))
        for i, hyperParamValues in enumerate(self.rasterValues):
            self.setSelectedHyperParameters(hyperParamValues)

            # call fit method from parent class
            Study.fit(self, forwardOnly=forwardOnly, evidenceOnly=evidenceOnly, silent=True)

            logEvidenceList.append(self.logEvidence)
            localEvidenceList.append(self.localEvidence)
            if not evidenceOnly:
                self.averagePosteriorSequence += self.posteriorSequence*np.exp(self.logEvidence)*\
                                                 self.hyperParameterPrior[i]

            if not silent:
                print '    + Analysis #{} of {} -- Hyper-parameter values {} -- log10-evidence = {:.5f}'\
                    .format(i+1, len(self.rasterValues), hyperParamValues, self.logEvidence / np.log(10))

        # reset list of parameters to optimize, so that unpacking and setting hyper-parameters works as expected
        self.selectedHyperParameters = []

        if not evidenceOnly:
            # compute average posterior distribution
            normalization = np.array([np.sum(posterior) for posterior in self.averagePosteriorSequence])
            for i in range(len(self.grid)):
                normalization = normalization[:, None]  # add axis; needs to match averagePosteriorSequence
            self.averagePosteriorSequence /= normalization

            # set self.posteriorSequence to average posterior sequence for plotting reasons
            self.posteriorSequence = self.averagePosteriorSequence

            if not silent:
                print '    + Computed average posterior sequence'

        # compute log-evidence of average model
        self.logEvidence = np.log(np.sum(np.exp(np.array(logEvidenceList))*self.hyperParameterPrior))

        print '    + Log10-evidence of average model: {:.5f}'.format(self.logEvidence / np.log(10))

        # compute hyper-parameter distribution
        self.hyperParameterDistribution = np.exp(np.array(logEvidenceList))*self.hyperParameterPrior
        self.hyperParameterDistribution /= np.sum(self.hyperParameterDistribution)
        self.hyperParameterDistribution /= np.prod(self.rasterConstant)  # probability density

        if not silent:
            print '    + Computed hyper-parameter distribution'

        # compute local evidence of average model
        self.localEvidence = np.sum((np.array(localEvidenceList).T*self.hyperParameterDistribution).T, axis=0)

        if not silent:
            print '    + Computed local evidence of average model'

        # compute posterior mean values
        if not evidenceOnly:
            self.posteriorMeanValues = np.empty([len(self.grid), len(self.posteriorSequence)])
            for i in range(len(self.grid)):
                self.posteriorMeanValues[i] = np.array([np.sum(p*self.grid[i]) for p in self.posteriorSequence])

            if not silent:
                print '    + Computed mean parameter values.'

        # clear self.hyperParameterPrior (in case fit is called after changing self.raster)
        self.hyperParameterPrior = None

        print '+ Finished fit.'

    # optimization methods are inherited from Study class, but cannot be used in this case
    def optimize(self, *args, **kwargs):
        print "! 'RasterStudy' object has no attribute 'optimize'"
        return

    def optimizationStep(self, *args, **kwargs):
        print "! 'RasterStudy' object has no attribute 'optimizationStep'"
        return

    def plotHyperParameterDistribution(self, param=0, **kwargs):
        """
        Creates a bar chart of a hyper-parameter distribution done with the RasterStudy class. The distribution is
        marginalized with respect to the hyper-parameter passed by name or index.

        Parameters:
            param - Parameter name or index of hyper-parameter to display; default: 0 (first model hyper-parameter)
            **kwargs - All further keyword-arguments are passed to the bar-plot (see matplotlib documentation)

        Returns:
            Two numpy arrays. The first array contains the hyper-parameter values, the second one the
            corresponding probability (density) values
        """
        hyperParameterNames = [name for name, lower, upper, steps in self.raster]

        if isinstance(param, (int, long)):
            paramIndex = param
        elif isinstance(param, basestring):
            paramIndex = -1
            for i, name in enumerate(hyperParameterNames):
                if name == param:
                    paramIndex = i

            # check if match was found
            if paramIndex == -1:
                print '! Wrong hyper-parameter name. Available options: {0}'.format(hyperParameterNames)
                return
        else:
            print '! Wrong parameter format. Specify parameter via name or index.'
            return

        axesToMarginalize = range(len(hyperParameterNames))
        axesToMarginalize.remove(paramIndex)

        # reshape hyper-parameter distribution for easy marginalizing
        rasterSteps = [steps for name, lower, upper, steps in self.raster]
        distribution = self.hyperParameterDistribution.reshape(rasterSteps)
        marginalDistribution = np.squeeze(np.apply_over_axes(np.sum, distribution, axesToMarginalize))

        # marginal distribution is not created by sum, but by the integral
        integrationFactor = np.prod([self.rasterConstant[axis] for axis in axesToMarginalize])
        marginalDistribution *= integrationFactor

        x = np.linspace(*self.raster[paramIndex][1:])
        plt.bar(x, marginalDistribution, align='center', width=self.rasterConstant[paramIndex], **kwargs)

        plt.xlabel(hyperParameterNames[paramIndex])

        # in case an integer step size for hyper-parameter values is chosen, probability is displayed
        # (probability density otherwise)
        if self.rasterConstant[paramIndex] == 1.:
            plt.ylabel('probability')
        else:
            plt.ylabel('probability density')

        return x, marginalDistribution

    def plotJointHyperParameterDistribution(self, params=[0, 1], figure=None, subplot=111,
                                            **kwargs):
        """
        Creates a 3D bar chart of a joint hyper-parameter distribution (of two hyper-parameters) done with the
        RasterStudy class. The distribution is marginalized with respect to the hyper-parameters passed by names or
        indices. Note that the 3D plot can only be included in an existing plot by passing a figure object and subplot
        specification.

        Parameters:
            params - List of two parameter names or indices of hyper-parameters to display; default: [0, 1]
                (first and second model parameter)

            figure - In case the plot is supposed to be part of an existing figure, it can be passed to the method. By
                default, a new figure is created.

            subplot - Characterization of subplot alignment, as in matplotlib. Default: 111

            **kwargs - all further keyword-arguments are passed to the bar3d-plot (see matplotlib documentation)

        Returns:
            Three numpy arrays. The first and second array contains the hyper-parameter values, the
            third one the corresponding probability (density) values
        """
        hyperParameterNames = [name for name, lower, upper, steps in self.raster]

        # check if list with two elements is provided
        if not isinstance(params, (list, tuple)):
            print '! A list of exactly two hyper-parameters has to be provided.'
            return
        elif not len(params) == 2:
            print '! A list of exactly two hyper-parameters has to be provided.'
            return

        # check for type of parameters (indices or names)
        if all(isinstance(p, (int, long)) for p in params):
            paramIndices = params
        elif all(isinstance(p, basestring) for p in params):
            paramIndices = []
            for i, name in enumerate(hyperParameterNames):
                for p in params:
                    if name == p:
                        paramIndices.append(i)

            # check if match was found
            if paramIndices == []:
                print '! Wrong hyper-parameter name. Available options: {0}'.format(hyperParameterNames)
                return
        else:
            print '! Wrong parameter format. Specify parameters either via name or index.'
            return

        # check if one of the parameter names provided is wrong
        if not len(paramIndices) == 2:
            print '! Probably one wrong hyper-parameter name. Available options: {0}'.format(hyperParameterNames)

        # check if parameter indices are in ascending order (so axes are labeled correctly)
        if not paramIndices[0] < paramIndices[1]:
            print '! Switching hyper-parameter order for plotting.'
            paramIndices = paramIndices[::-1]

        axesToMarginalize = range(len(hyperParameterNames))
        for p in paramIndices:
            axesToMarginalize.remove(p)

        # reshape hyper-parameter distribution for easy marginalizing
        rasterSteps = [steps for name, lower, upper, steps in self.raster]
        distribution = self.hyperParameterDistribution.reshape(rasterSteps)
        marginalDistribution = np.squeeze(np.apply_over_axes(np.sum, distribution, axesToMarginalize))

        # marginal distribution is not created by sum, but by the integral
        integrationFactor = np.prod([self.rasterConstant[axis] for axis in axesToMarginalize])
        marginalDistribution *= integrationFactor

        x, y = np.meshgrid(np.linspace(*self.raster[paramIndices[1]][1:]),
                           np.linspace(*self.raster[paramIndices[0]][1:]))
        z = marginalDistribution

        # allow to add plot to predefined figure
        if figure is None:
            fig = plt.figure()
        else:
            fig = figure
        ax = fig.add_subplot(subplot, projection='3d')

        ax.bar3d(x.flatten() - self.rasterConstant[paramIndices[1]]/2.,
                 y.flatten() - self.rasterConstant[paramIndices[0]]/2.,
                 z.flatten()*0.,
                 self.rasterConstant[paramIndices[1]],
                 self.rasterConstant[paramIndices[0]],
                 z.flatten(),
                 zsort='max',
                 **kwargs
                 )

        ax.set_xlabel(hyperParameterNames[paramIndices[1]])
        ax.set_ylabel(hyperParameterNames[paramIndices[0]])

        # in case an integer step size for hyper-parameter values is chosen, probability is displayed
        # (probability density otherwise)
        if self.rasterConstant[paramIndices[0]]*self.rasterConstant[paramIndices[1]] == 1.:
            ax.set_zlabel('probability')
        else:
            ax.set_zlabel('probability density')

        return x, y, marginalDistribution<commit_msg>Added support for multiprocessing<commit_after>#!/usr/bin/env python
"""
This file introduces an extension to the basic Study-class that allows to compute the distribution of hyper-parameters.
"""

from .study import *
from .preprocessing import *
from mpl_toolkits.mplot3d import Axes3D
from copy import copy

class RasterStudy(Study):
    """
    This class serves as an extention to the basic Study class and allows to compute the distribution of hyper-
    parameters of a given transition model. For further information, see the documentation of the fit-method of this
    class.
    """
    def __init__(self):
        super(RasterStudy, self).__init__()

        self.raster = []
        self.rasterValues = []
        self.rasterConstant = []
        self.hyperParameterPrior = None
        self.hyperParameterDistribution = None
        self.averagePosteriorSequence = None
        self.logEvidenceList = []
        self.localEvidenceList = []

        print '  --> Raster study'

    def fit(self, raster=[], forwardOnly=False, evidenceOnly=False, customRaster=False, silent=False, nJobs=1):
        """
        This method over-rides the according method of the Study-class. It runs the algorithm for equally spaced hyper-
        parameter values as defined by the variable 'raster'. The posterior sequence represents the average
        model of all analyses. Posterior mean values are computed from this average model.

        Parameters:
            raster - List of lists with each containing the name of a hyper-parameter together with a lower and upper
                boundary as well as a number of steps in between.
                Example: raster = [['sigma', 0, 1, 20],['log10pMin', -10, -5, 10]]

            forwardOnly - If set to True, the fitting process is terminated after the forward pass. The resulting
                posterior distributions are so-called "filtering distributions" which - at each time step -
                only incorporate the information of past data points. This option thus emulates an online
                analysis.

            evidenceOnly - If set to True, only forward pass is run and evidence is calculated. In contrast to the
                forwardOnly option, no posterior mean values are computed and no posterior distributions are stored.

            customRaster - If set to True, the keyword argument 'raster' will not be used. Instead, all relevant
                attributes have to be set manually by the user. May be used for irregular grids of hyper-parameter
                values.

            silent - If set to True, no output is generated by the fitting method.

            nJobs - Number of processes to employ. Multiprocessing is based on the 'pathos' module.

        Returns:
            None
        """
        print '+ Started new fit.'

        if not customRaster:
            self.raster = raster

            # in case no raster is provided, call standard fit method.
            if not self.raster:
                print '! No raster defined for hyper-parameter values. Using standard fit-method.'
                Study.fit(self, forwardOnly=forwardOnly, evidenceOnly=evidenceOnly, silent=silent)
                return

            # create array with raster-values
            temp = np.meshgrid(*[np.linspace(lower, upper, steps) for name, lower, upper, steps in self.raster],
                               indexing='ij')
            self.rasterValues = np.array([t.ravel() for t in temp]).T
            self.rasterConstant = [np.abs(upper-lower)/(float(steps)-1) for name, lower, upper, steps in self.raster]
        else:
            if self.raster == []:
                print "! A dummy 'raster' attribute has to be set when using customRaster=True."
                print "  (Only hyper-parameter names are extracted from this attribute.)"
                return
            if self.rasterValues == []:
                print "! The attribute 'rasterValues' has to be set manually when using customRaster=True."
                return
            if self.rasterConstant == []:
                print "! The attribute 'rasterConstant' has to be set manually when using customRaster=True."
                return

        # prepare arrays for change-point distribution and average posterior sequence
        self.formattedData = movingWindow(self.rawData, self.observationModel.segmentLength)
        if self.hyperParameterPrior is None:
            self.hyperParameterPrior = np.ones(len(self.rasterValues))/len(self.rasterValues)
        else:
            # check if given prior is correctly formatted to fit length of raster array
            if len(self.hyperParameterPrior) != len(self.rasterValues):
                print '! Given raster expects {0} values for hyper-parameter prior.'.format(len(self.rasterValues))
                return

        if not evidenceOnly:
            self.averagePosteriorSequence = np.zeros([len(self.formattedData)]+self.gridSize)

        self.logEvidenceList = []
        self.localEvidenceList = []

        # we use the setSelectedHyperParameters-method from the Study class
        self.selectedHyperParameters = [name for name, lower, upper, steps in self.raster]

        if not self.checkConsistency():
            return

        print '    + {} analyses to run.'.format(len(self.rasterValues))

        # check if multiprocessing is available
        if nJobs > 1:
            try:
                from pathos.multiprocessing import ProcessPool
            except:
                print "! Install 'pathos.multiprocessing' to enable multiprocessing."
                print "! Switching back to single process."
                nJobs=1

        # prepare parallel execution if necessary
        if nJobs > 1:
            print '    + Creating {} processes.'.format(nJobs)
            pool = ProcessPool(nodes=nJobs)

            # use parallelFit method to create copies of this RasterStudy instance with only partial raster values
            subStudies = pool.map(self.parallelFit,
                                  range(nJobs),
                                  [nJobs]*nJobs,
                                  [forwardOnly]*nJobs,
                                  [evidenceOnly]*nJobs,
                                  [silent]*nJobs)

            # merge all sub-studies
            for S in subStudies:
                self.logEvidenceList += S.logEvidenceList
                self.localEvidenceList += S.localEvidenceList
                self.averagePosteriorSequence += S.averagePosteriorSequence
        # single process fit
        else:
            for i, hyperParamValues in enumerate(self.rasterValues):
                self.setSelectedHyperParameters(hyperParamValues)

                # call fit method from parent class
                Study.fit(self, forwardOnly=forwardOnly, evidenceOnly=evidenceOnly, silent=True)

                self.logEvidenceList.append(self.logEvidence)
                self.localEvidenceList.append(self.localEvidence)
                if not evidenceOnly:
                    self.averagePosteriorSequence += self.posteriorSequence*np.exp(self.logEvidence) *\
                                                     self.hyperParameterPrior[i]

                if not silent:
                    print '    + Analysis #{} of {} -- Hyper-parameter values {} -- log10-evidence = {:.5f}'\
                        .format(i+1, len(self.rasterValues), hyperParamValues, self.logEvidence / np.log(10))

        # reset list of parameters to optimize, so that unpacking and setting hyper-parameters works as expected
        self.selectedHyperParameters = []

        if not evidenceOnly:
            # compute average posterior distribution
            normalization = np.array([np.sum(posterior) for posterior in self.averagePosteriorSequence])
            for i in range(len(self.grid)):
                normalization = normalization[:, None]  # add axis; needs to match averagePosteriorSequence
            self.averagePosteriorSequence /= normalization

            # set self.posteriorSequence to average posterior sequence for plotting reasons
            self.posteriorSequence = self.averagePosteriorSequence

            if not silent:
                print '    + Computed average posterior sequence'

        # compute log-evidence of average model
        self.logEvidence = np.log(np.sum(np.exp(np.array(self.logEvidenceList))*self.hyperParameterPrior))

        print '    + Log10-evidence of average model: {:.5f}'.format(self.logEvidence / np.log(10))

        # compute hyper-parameter distribution
        self.hyperParameterDistribution = np.exp(np.array(self.logEvidenceList))*self.hyperParameterPrior
        self.hyperParameterDistribution /= np.sum(self.hyperParameterDistribution)
        self.hyperParameterDistribution /= np.prod(self.rasterConstant)  # probability density

        if not silent:
            print '    + Computed hyper-parameter distribution'

        # compute local evidence of average model
        self.localEvidence = np.sum((np.array(self.localEvidenceList).T*self.hyperParameterDistribution).T, axis=0)

        if not silent:
            print '    + Computed local evidence of average model'

        # compute posterior mean values
        if not evidenceOnly:
            self.posteriorMeanValues = np.empty([len(self.grid), len(self.posteriorSequence)])
            for i in range(len(self.grid)):
                self.posteriorMeanValues[i] = np.array([np.sum(p*self.grid[i]) for p in self.posteriorSequence])

            if not silent:
                print '    + Computed mean parameter values.'

        # clear self.hyperParameterPrior (in case fit is called after changing self.raster)
        self.hyperParameterPrior = None

        # discard evidence values of individual fits
        self.logEvidenceList = []
        self.localEvidenceList = []

        print '+ Finished fit.'

    def parallelFit(self, idx, nJobs, forwardOnly, evidenceOnly, silent):
        """
        This method is called by the fit method of the RasterStudy class. It creates a copy of the current class
        instance and performs a fit based on a subset of the specified hyper-parameter raster. The method thus allows
        to distribute a RasterStudy fit among multiple processes for multiprocessing.

        Parameters:
            idx - Index from 0 to (nJobs-1), indicating which part of the raster values are to be analyzed.

            nJobs - Number of processes to employ. Multiprocessing is based on the 'pathos' module.

            forwardOnly - If set to True, the fitting process is terminated after the forward pass. The resulting
                posterior distributions are so-called "filtering distributions" which - at each time step -
                only incorporate the information of past data points. This option thus emulates an online
                analysis.

            evidenceOnly - If set to True, only forward pass is run and evidence is calculated. In contrast to the
                forwardOnly option, no posterior mean values are computed and no posterior distributions are stored.

            customRaster - If set to True, the keyword argument 'raster' will not be used. Instead, all relevant
                attributes have to be set manually by the user. May be used for irregular grids of hyper-parameter
                values.

            silent - If set to True, no output is generated by the fitting method.

        Returns:
            RasterStudy instance
        """
        S = copy(self)
        S.rasterValues = np.array_split(S.rasterValues, nJobs)[idx]
        S.hyperParameterPrior = np.array_split(S.hyperParameterPrior, nJobs)[idx]

        for i, hyperParamValues in enumerate(S.rasterValues):
            S.setSelectedHyperParameters(hyperParamValues)

            # call fit method from parent class
            Study.fit(S, forwardOnly=forwardOnly, evidenceOnly=evidenceOnly, silent=True)

            S.logEvidenceList.append(S.logEvidence)
            S.localEvidenceList.append(S.localEvidence)
            if not evidenceOnly:
                S.averagePosteriorSequence += S.posteriorSequence*np.exp(S.logEvidence) *\
                                              S.hyperParameterPrior[i]

            if not silent:
                print '    + Process {} -- Analysis #{} of {}'.format(idx, i+1, len(S.rasterValues))

        print '    + Process {} finished.'.format(idx)
        return S

    # optimization methods are inherited from Study class, but cannot be used in this case
    def optimize(self, *args, **kwargs):
        print "! 'RasterStudy' object has no attribute 'optimize'"
        return

    def optimizationStep(self, *args, **kwargs):
        print "! 'RasterStudy' object has no attribute 'optimizationStep'"
        return

    def plotHyperParameterDistribution(self, param=0, **kwargs):
        """
        Creates a bar chart of a hyper-parameter distribution done with the RasterStudy class. The distribution is
        marginalized with respect to the hyper-parameter passed by name or index.

        Parameters:
            param - Parameter name or index of hyper-parameter to display; default: 0 (first model hyper-parameter)
            **kwargs - All further keyword-arguments are passed to the bar-plot (see matplotlib documentation)

        Returns:
            Two numpy arrays. The first array contains the hyper-parameter values, the second one the
            corresponding probability (density) values
        """
        hyperParameterNames = [name for name, lower, upper, steps in self.raster]

        if isinstance(param, (int, long)):
            paramIndex = param
        elif isinstance(param, basestring):
            paramIndex = -1
            for i, name in enumerate(hyperParameterNames):
                if name == param:
                    paramIndex = i

            # check if match was found
            if paramIndex == -1:
                print '! Wrong hyper-parameter name. Available options: {0}'.format(hyperParameterNames)
                return
        else:
            print '! Wrong parameter format. Specify parameter via name or index.'
            return

        axesToMarginalize = range(len(hyperParameterNames))
        axesToMarginalize.remove(paramIndex)

        # reshape hyper-parameter distribution for easy marginalizing
        rasterSteps = [steps for name, lower, upper, steps in self.raster]
        distribution = self.hyperParameterDistribution.reshape(rasterSteps)
        marginalDistribution = np.squeeze(np.apply_over_axes(np.sum, distribution, axesToMarginalize))

        # marginal distribution is not created by sum, but by the integral
        integrationFactor = np.prod([self.rasterConstant[axis] for axis in axesToMarginalize])
        marginalDistribution *= integrationFactor

        x = np.linspace(*self.raster[paramIndex][1:])
        plt.bar(x, marginalDistribution, align='center', width=self.rasterConstant[paramIndex], **kwargs)

        plt.xlabel(hyperParameterNames[paramIndex])

        # in case an integer step size for hyper-parameter values is chosen, probability is displayed
        # (probability density otherwise)
        if self.rasterConstant[paramIndex] == 1.:
            plt.ylabel('probability')
        else:
            plt.ylabel('probability density')

        return x, marginalDistribution

    def plotJointHyperParameterDistribution(self, params=[0, 1], figure=None, subplot=111,
                                            **kwargs):
        """
        Creates a 3D bar chart of a joint hyper-parameter distribution (of two hyper-parameters) done with the
        RasterStudy class. The distribution is marginalized with respect to the hyper-parameters passed by names or
        indices. Note that the 3D plot can only be included in an existing plot by passing a figure object and subplot
        specification.

        Parameters:
            params - List of two parameter names or indices of hyper-parameters to display; default: [0, 1]
                (first and second model parameter)

            figure - In case the plot is supposed to be part of an existing figure, it can be passed to the method. By
                default, a new figure is created.

            subplot - Characterization of subplot alignment, as in matplotlib. Default: 111

            **kwargs - all further keyword-arguments are passed to the bar3d-plot (see matplotlib documentation)

        Returns:
            Three numpy arrays. The first and second array contains the hyper-parameter values, the
            third one the corresponding probability (density) values
        """
        hyperParameterNames = [name for name, lower, upper, steps in self.raster]

        # check if list with two elements is provided
        if not isinstance(params, (list, tuple)):
            print '! A list of exactly two hyper-parameters has to be provided.'
            return
        elif not len(params) == 2:
            print '! A list of exactly two hyper-parameters has to be provided.'
            return

        # check for type of parameters (indices or names)
        if all(isinstance(p, (int, long)) for p in params):
            paramIndices = params
        elif all(isinstance(p, basestring) for p in params):
            paramIndices = []
            for i, name in enumerate(hyperParameterNames):
                for p in params:
                    if name == p:
                        paramIndices.append(i)

            # check if match was found
            if paramIndices == []:
                print '! Wrong hyper-parameter name. Available options: {0}'.format(hyperParameterNames)
                return
        else:
            print '! Wrong parameter format. Specify parameters either via name or index.'
            return

        # check if one of the parameter names provided is wrong
        if not len(paramIndices) == 2:
            print '! Probably one wrong hyper-parameter name. Available options: {0}'.format(hyperParameterNames)

        # check if parameter indices are in ascending order (so axes are labeled correctly)
        if not paramIndices[0] < paramIndices[1]:
            print '! Switching hyper-parameter order for plotting.'
            paramIndices = paramIndices[::-1]

        axesToMarginalize = range(len(hyperParameterNames))
        for p in paramIndices:
            axesToMarginalize.remove(p)

        # reshape hyper-parameter distribution for easy marginalizing
        rasterSteps = [steps for name, lower, upper, steps in self.raster]
        distribution = self.hyperParameterDistribution.reshape(rasterSteps)
        marginalDistribution = np.squeeze(np.apply_over_axes(np.sum, distribution, axesToMarginalize))

        # marginal distribution is not created by sum, but by the integral
        integrationFactor = np.prod([self.rasterConstant[axis] for axis in axesToMarginalize])
        marginalDistribution *= integrationFactor

        x, y = np.meshgrid(np.linspace(*self.raster[paramIndices[1]][1:]),
                           np.linspace(*self.raster[paramIndices[0]][1:]))
        z = marginalDistribution

        # allow to add plot to predefined figure
        if figure is None:
            fig = plt.figure()
        else:
            fig = figure
        ax = fig.add_subplot(subplot, projection='3d')

        ax.bar3d(x.flatten() - self.rasterConstant[paramIndices[1]]/2.,
                 y.flatten() - self.rasterConstant[paramIndices[0]]/2.,
                 z.flatten()*0.,
                 self.rasterConstant[paramIndices[1]],
                 self.rasterConstant[paramIndices[0]],
                 z.flatten(),
                 zsort='max',
                 **kwargs
                 )

        ax.set_xlabel(hyperParameterNames[paramIndices[1]])
        ax.set_ylabel(hyperParameterNames[paramIndices[0]])

        # in case an integer step size for hyper-parameter values is chosen, probability is displayed
        # (probability density otherwise)
        if self.rasterConstant[paramIndices[0]]*self.rasterConstant[paramIndices[1]] == 1.:
            ax.set_zlabel('probability')
        else:
            ax.set_zlabel('probability density')

        return x, y, marginalDistribution
<|endoftext|>


<commit_before>#!/usr/bin/python

import time
import math
import Adafruit_BBIO.GPIO as GPIO
import Adafruit_BBIO.PWM as PWM
import ProBotConstantsFile

Pconst = ProBotConstantsFile.Constants()

#PWM.start(channel, duty, freq, polarity)
PWM.start(Pconst.PWM_R_DIR, 50, Pconst.PWM_Freq)
PWM.start(Pconst.PWM_R_PWM, 0, Pconst.PWM_Freq) #pwm
PWM.start(Pconst.PWM_L_DIR, 50, Pconst.PWM_Freq)
PWM.start(Pconst.PWM_L_PWM, 0, Pconst.PWM_Freq) #pwm

class PWMClass ():

	def PWMStart(self):
    	    # Starting the communication with the PWM controller
            GPIO.output(Pconst.RedLED, GPIO.HIGH)

            time.sleep(3)									# Wait to stabilize the communication

	    GPIO.output(Pconst.RedLED, GPIO.LOW)
	    GPIO.output(Pconst.BlueLED, GPIO.HIGH)

	def PWM_Signals(self, rightMotor, leftMotor):

	    # Sending the values to the PWM controller that is connected to the motors
	    percentageR=int(math.fabs(rightMotor))
	    percentageL=int(math.fabs(leftMotor))
	    #print int(percentageR), int(percentageL)
	    #print int(rightMotor), int(leftMotor)

	    if rightMotor>0:
		PWM.set_duty_cycle(Pconst.PWM_R_DIR, 100)
		PWM.set_duty_cycle(Pconst.PWM_R_PWM, percentageR)
	    elif rightMotor<0:
		PWM.set_duty_cycle(Pconst.PWM_R_DIR,  0)
		PWM.set_duty_cycle(Pconst.PWM_R_PWM,  percentageR)
	    elif rightMotor==0:
		PWM.set_duty_cycle(Pconst.PWM_R_PWM, 0)

    	    if leftMotor>0:
	        PWM.set_duty_cycle(Pconst.PWM_L_DIR, 0)
	        PWM.set_duty_cycle(Pconst.PWM_L_PWM, percentageL)
	    elif leftMotor<0:
	    	PWM.set_duty_cycle(Pconst.PWM_L_DIR, 100)
      	    	PWM.set_duty_cycle(Pconst.PWM_L_PWM, percentageL)
    	    elif leftMotor==0:
	   	PWM.set_duty_cycle(Pconst.PWM_L_PWM, 0)

	def PWMStop(self):
	    	PWM.stop(Pconst.PWM_R_PWM)
		PWM.stop(Pconst.PWM_R_DIR)
		PWM.stop(Pconst.PWM_L_PWM)
		PWM.stop(Pconst.PWM_L_DIR)
		PWM.cleanup()

<commit_msg>Update PWMFile.py<commit_after>#!/usr/bin/python

import time
import math
import Adafruit_BBIO.GPIO as GPIO
import Adafruit_BBIO.PWM as PWM
import ProBotConstantsFile

Pconst = ProBotConstantsFile.Constants()

#PWM.start(channel, duty, freq, polarity)
PWM.start(Pconst.PWM_R_DIR, 50, Pconst.PWM_Freq)
PWM.start(Pconst.PWM_R_PWM, 0, Pconst.PWM_Freq) #pwm
PWM.start(Pconst.PWM_L_DIR, 50, Pconst.PWM_Freq)
PWM.start(Pconst.PWM_L_PWM, 0, Pconst.PWM_Freq) #pwm

class PWMClass ():

	def PWMStart(self):
    	    # Starting the communication with the PWM controller
            GPIO.output(Pconst.RedLED, GPIO.HIGH)

            time.sleep(3)						# Wait to stabilize the communication

	    GPIO.output(Pconst.RedLED, GPIO.LOW)
	    GPIO.output(Pconst.BlueLED, GPIO.HIGH)

	def PWM_Signals(self, rightMotor, leftMotor):

	    # Sending the values to the PWM controller that is connected to the motors
	    percentageR=math.fabs(rightMotor)
	    percentageL=math.fabs(leftMotor)

	    if rightMotor>0:
		PWM.set_duty_cycle(Pconst.PWM_R_DIR, 100)
		PWM.set_duty_cycle(Pconst.PWM_R_PWM, percentageR)
	    elif rightMotor<0:
		PWM.set_duty_cycle(Pconst.PWM_R_DIR,  0)
		PWM.set_duty_cycle(Pconst.PWM_R_PWM,  percentageR)
	    elif rightMotor==0:
		PWM.set_duty_cycle(Pconst.PWM_R_PWM, 0)

    	    if leftMotor>0:
	        PWM.set_duty_cycle(Pconst.PWM_L_DIR, 0)
	        PWM.set_duty_cycle(Pconst.PWM_L_PWM, percentageL)
	    elif leftMotor<0:
	    	PWM.set_duty_cycle(Pconst.PWM_L_DIR, 100)
      	    	PWM.set_duty_cycle(Pconst.PWM_L_PWM, percentageL)
    	    elif leftMotor==0:
	   	PWM.set_duty_cycle(Pconst.PWM_L_PWM, 0)

	def PWMStop(self):
	    	PWM.stop(Pconst.PWM_R_PWM)
		PWM.stop(Pconst.PWM_R_DIR)
		PWM.stop(Pconst.PWM_L_PWM)
		PWM.stop(Pconst.PWM_L_DIR)
		PWM.cleanup()

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
TextItem Class
"""
from __future__ import (division, print_function, absolute_import,
                        unicode_literals)

from  Qt import QtGui, QtWidgets, QtCore # see https://github.com/mottosso/Qt.py
from collections import OrderedDict

#from supsisim.const import iconFont
from supsisim.const import colors, stdfont

class textItem(QtWidgets.QGraphicsTextItem):
    '''convenience class, extension of QGraphicsSimpleTextItem, that realises aligned text
    textItem.setFlipped() will mirror the text  (in place)
    textItem.setNormal() will put txt in normal (non-mirrored) state

    anchor is (look at numpad):
    1: bottom-left
    2: bottom-center
    3: bottom-right
    4: center-left
    5: center-center
    6: center-right
    7: top-left
    8: top-center
    9: top-right'''
    def __init__(self, text, anchor=1, parent=None):
        super(textItem, self).__init__(text, parent)
        self.anchor = anchor
        self.scale = 1
#        self.setFont(iconFont)

        # compute dx, dy absed on anchor
        self.setAnchor()
        self.setNormal()
        self.setMutable()
#        self.setFlag(self.ItemIsSelectable)
##        self.setFlag(self.ItemIgnoresTransformations)
#        self.setTextInteractionFlags(QtCore.Qt.TextEditorInteraction) # allow edits
        self.setAcceptDrops(False)
        font = self.font()
        font.fromString(stdfont)
        self.setFont(font)

    def setText(self, text):
        self.setPlainText(text)

    def setMutable(self, mutable=True):
        self.setFlag(self.ItemIsMovable, mutable)
        self.setFlag(self.ItemIsSelectable, mutable)
        if mutable:
            self.setTextInteractionFlags(QtCore.Qt.TextEditorInteraction) # allow edits
        else:
            self.setTextInteractionFlags(QtCore.Qt.NoTextInteraction) # disallow edits

    def text(self):
        return self.toPlainText()

    def setBrush(self, color):
        self.setDefaultTextColor(color)

    def setPos(self, x, y=None):
        if isinstance(x, (QtCore.QPoint, QtCore.QPointF)): # called with point
            x, y = x.x(), x.y()
        x, y = round(x*10)/10, round(y*10)/10
        super(textItem, self).setPos(x, y)

    def toData(self):
        text = self.text()
        if text.startswith('.'):
            return text
        else:
            data = OrderedDict(type='label')
            data['text']   = text
            x, y = self.pos().x(), self.pos().y()
            data['x'] = round(x*10)/10
            data['y'] = round(y*10)/10
            data['anchor'] = self.anchor
            data['font'] = self.font().toString()
            return data

    def fromData(self, data):
        if isinstance(data, basestring):
            self.setText(data)
        else:
            self.setText(data['text'])
            if 'font' in data:
                font = QtGui.QFont()
                font.fromString(data['font'])
                self.setFont(font)
            self.setAnchor(data['anchor'])
            self.setPos(data['x'], data['y'])
            self.setNormal()

    def remove(self):
        scene = self.scene()
        scene.removeItem(self)

    def setFlipped(self):
        '''mirror in place (use when parent is flipped'''
        self.setTransform(QtGui.QTransform().translate(self.dx, self.dy).scale(-self.scale,self.scale).translate(-self.boundingRect().width(),0))
        self.setTransform(QtGui.QTransform().translate(self.dx, self.dy).scale(-self.scale,self.scale).translate(-self.boundingRect().width(),0))

    def setNormal(self):
        '''normal orientation'''
        self.setTransform(QtGui.QTransform.fromScale(self.scale,self.scale).translate(self.dx, self.dy))
        self.setTransform(QtGui.QTransform.fromScale(self.scale,self.scale).translate(self.dx, self.dy))

    def setAnchor(self, anchor=None):
        if anchor:
            self.anchor = anchor
        if self.anchor in (4,5,6):
            self.dy = -0.5*self.boundingRect().height()
        elif self.anchor in (1,2,3):
            self.dy = -self.boundingRect().height()
        else:
            self.dy = 0

        if self.anchor in (2,5,8):
            self.dx = -0.5*self.boundingRect().width()
        elif self.anchor in (3,6,9):
            self.dx = -self.boundingRect().width()
        else:
            self.dx = 0

class Comment(textItem):
    def __init__(self, text, anchor=1, parent=None):
        super(Comment, self).__init__(text, anchor, parent)
        self.setBrush(colors['comment'])

    def toData(self):
        data = super(Comment, self).toData()
        data['type'] = 'comment'
        return data

    def fromData(self, data):
        super(Comment, self).fromData(data)
        # comments do not have an anchor
        self.dx = 0
        self.dy = 0
        self.setNormal()

def isTextItem(item):
    return isinstance(item, textItem)

def isComment(item):
    return isinstance(item, Comment)
    <commit_msg>allow for numbers as label<commit_after># -*- coding: utf-8 -*-
"""
TextItem Class
"""
from __future__ import (division, print_function, absolute_import,
                        unicode_literals)

from  Qt import QtGui, QtWidgets, QtCore # see https://github.com/mottosso/Qt.py
from collections import OrderedDict

#from supsisim.const import iconFont
from supsisim.const import colors, stdfont

class textItem(QtWidgets.QGraphicsTextItem):
    '''convenience class, extension of QGraphicsSimpleTextItem, that realises aligned text
    textItem.setFlipped() will mirror the text  (in place)
    textItem.setNormal() will put txt in normal (non-mirrored) state

    anchor is (look at numpad):
    1: bottom-left
    2: bottom-center
    3: bottom-right
    4: center-left
    5: center-center
    6: center-right
    7: top-left
    8: top-center
    9: top-right'''
    def __init__(self, text, anchor=1, parent=None):
        super(textItem, self).__init__(str(text), parent)
        self.anchor = anchor
        self.scale = 1
#        self.setFont(iconFont)

        # compute dx, dy absed on anchor
        self.setAnchor()
        self.setNormal()
        self.setMutable()
#        self.setFlag(self.ItemIsSelectable)
##        self.setFlag(self.ItemIgnoresTransformations)
#        self.setTextInteractionFlags(QtCore.Qt.TextEditorInteraction) # allow edits
        self.setAcceptDrops(False)
        font = self.font()
        font.fromString(stdfont)
        self.setFont(font)

    def setText(self, text):
        self.setPlainText(text)

    def setMutable(self, mutable=True):
        self.setFlag(self.ItemIsMovable, mutable)
        self.setFlag(self.ItemIsSelectable, mutable)
        if mutable:
            self.setTextInteractionFlags(QtCore.Qt.TextEditorInteraction) # allow edits
        else:
            self.setTextInteractionFlags(QtCore.Qt.NoTextInteraction) # disallow edits

    def text(self):
        return self.toPlainText()

    def setBrush(self, color):
        self.setDefaultTextColor(color)

    def setPos(self, x, y=None):
        if isinstance(x, (QtCore.QPoint, QtCore.QPointF)): # called with point
            x, y = x.x(), x.y()
        x, y = round(x*10)/10, round(y*10)/10
        super(textItem, self).setPos(x, y)

    def toData(self):
        text = self.text()
        if text.startswith('.'):
            return text
        else:
            data = OrderedDict(type='label')
            data['text']   = text
            x, y = self.pos().x(), self.pos().y()
            data['x'] = round(x*10)/10
            data['y'] = round(y*10)/10
            data['anchor'] = self.anchor
            data['font'] = self.font().toString()
            return data

    def fromData(self, data):
        if isinstance(data, basestring):
            self.setText(data)
        else:
            self.setText(data['text'])
            if 'font' in data:
                font = QtGui.QFont()
                font.fromString(data['font'])
                self.setFont(font)
            self.setAnchor(data['anchor'])
            self.setPos(data['x'], data['y'])
            self.setNormal()

    def remove(self):
        scene = self.scene()
        scene.removeItem(self)

    def setFlipped(self):
        '''mirror in place (use when parent is flipped'''
        self.setTransform(QtGui.QTransform().translate(self.dx, self.dy).scale(-self.scale,self.scale).translate(-self.boundingRect().width(),0))
        self.setTransform(QtGui.QTransform().translate(self.dx, self.dy).scale(-self.scale,self.scale).translate(-self.boundingRect().width(),0))

    def setNormal(self):
        '''normal orientation'''
        self.setTransform(QtGui.QTransform.fromScale(self.scale,self.scale).translate(self.dx, self.dy))
        self.setTransform(QtGui.QTransform.fromScale(self.scale,self.scale).translate(self.dx, self.dy))

    def setAnchor(self, anchor=None):
        if anchor:
            self.anchor = anchor
        if self.anchor in (4,5,6):
            self.dy = -0.5*self.boundingRect().height()
        elif self.anchor in (1,2,3):
            self.dy = -self.boundingRect().height()
        else:
            self.dy = 0

        if self.anchor in (2,5,8):
            self.dx = -0.5*self.boundingRect().width()
        elif self.anchor in (3,6,9):
            self.dx = -self.boundingRect().width()
        else:
            self.dx = 0

class Comment(textItem):
    def __init__(self, text, anchor=1, parent=None):
        super(Comment, self).__init__(text, anchor, parent)
        self.setBrush(colors['comment'])

    def toData(self):
        data = super(Comment, self).toData()
        data['type'] = 'comment'
        return data

    def fromData(self, data):
        super(Comment, self).fromData(data)
        # comments do not have an anchor
        self.dx = 0
        self.dy = 0
        self.setNormal()

def isTextItem(item):
    return isinstance(item, textItem)

def isComment(item):
    return isinstance(item, Comment)
    <|endoftext|>


<commit_before>from __future__ import unicode_literals
from django.contrib import admin

from .models import Listing, ListingSet, Publishing, Store

class ListingSetInline(admin.TabularInline):
    model = ListingSet
    extra = 1
    raw_id_fields = ('product',)

class ListingAdmin(admin.ModelAdmin):
    inlines = [ListingSetInline]
    model = Listing

admin.site.register(Store)
admin.site.register(Listing, ListingAdmin)
admin.site.register(Publishing)
<commit_msg>Enabled more features in admin publishing views<commit_after>from __future__ import unicode_literals
from django.contrib import admin

from .models import Listing, ListingSet, Publishing, Store

class ListingSetInline(admin.TabularInline):
    model = ListingSet
    extra = 1
    raw_id_fields = ('product',)

class ListingAdmin(admin.ModelAdmin):
    inlines = [ListingSetInline]
    model = Listing

class PublishingAdmin(admin.ModelAdmin):
    list_display = ('id', 'external_id', 'listing', 'price', 'available_units', 'pub_date', 'last_modified', 'status', 'store', )
    list_filter = ('status', 'pub_date', 'last_modified', )
    search_fields = ('external_id', 'listing__title')

admin.site.register(Store)
admin.site.register(Listing, ListingAdmin)
admin.site.register(Publishing, PublishingAdmin)
<|endoftext|>