<commit_before>from utils import Debuggable

from math import ceil, sqrt
from sys import stdout
import math

def pov(owner, who):
    if who == 1 or owner == 0:
        return owner
    else:
        return 2 if owner == 1 else 1

class Fleet(object):
    def __init__(self, owner, num_ships, source_planet=-1, destination_planet=-1,
                 total_trip_length=-1, turns_remaining=-1):
        self.owner = owner
        self.num_ships = num_ships
        self.src = source_planet
        self.dest = destination_planet
        self.total_trip_length = total_trip_length
        self.turns_remaining = turns_remaining

    def __repr__(self):
        return self.__str__()

    def __str__(self):
        return self.repr_for()

    def repr_for_enemy(self):
        return self.repr_for(2)

    def repr_for(self, who=1):
        return "F %d %d %d %d %d %d\n" % (pov(self.owner, who), self.num_ships,
                                          self.src, self.dest,
                                          self.total_trip_length, self.turns_remaining)

class PlanetWars(Debuggable):
    def __init__(self, game_state=None):
        super(PlanetWars, self).__init__()
        self.planets = []
        self.fleets = []
        self.turn = 0
        self.real_orders = []
        self.game_state = game_state
        self.debug_name = "planetwars"
        self.via_standard_io = True
        if game_state:
            self.parse_game_state()

    def load_data(self, game_state):
        self.game_state = game_state
        self.real_orders = []
        self.parse_game_state()

    @property
    def num_planets(self):
        return len(self.planets)

    def get_planet(self, planet_id):
        return self.planets[planet_id]

    @property
    def num_fleets(self):
        return len(self.fleets)

    def get_fleet(self, fleet_id):
        return self.fleets[fleet_id]

    def _objects_by_owners(self, objects, owners):
        lst = []
        for obj in objects:
            if obj.owner in owners:
                lst.append(obj)
        return lst

    def _planets_by_owners(self, *owners):
        return self._objects_by_owners(self.planets, owners)

    def _fleets_by_owners(self, *owners):
        return self._objects_by_owners(self.fleets, owners)

    def cache_immutable_info(self):
        self.my_planets = self._planets_by_owners(1)
        self.neutral_planets = self._planets_by_owners(0)
        self.enemy_planets = self._planets_by_owners(2)
        self.not_my_planets = self._planets_by_owners(0, 2)
        self.my_fleets = self._fleets_by_owners(self, 1)
        self.enemy_fleets = self._fleets_by_owners(self, 2)

    def __repr__(self):
        return "".join([str(pl) for pl in (self.planets + self.fleets)])

    def repr_for_enemy(self):
        return "".join([obj.repr_for_enemy() for obj in (self.planets + self.fleets)])

    def distance(self, src_id, dest_id):
        src = self.planets[src_id]
        dest = self.planets[dest_id]
        dx = src.x - dest.x
        dy = src.y - dest.y
        return int(ceil(sqrt(dx * dx + dy * dy)))

    def issue_order(self, src_id, dest_id, num_ships):
        order = (src_id, dest_id, num_ships)
        self.real_orders.append(order)
        if self.via_standard_io:
            self.debug("Order: %d %d %d" % order)
            stdout.write("%d %d %d\n" % order)
            stdout.flush()

    def total_ships(self, player_id):
        objs = self._planets_by_owners(player_id) + self._fleets_by_owners(player_id)
        return sum([obj.num_ships for obj in objs])

    def is_alive(self, player_id):
        return self.total_ships(player_id) > 0

    def is_game_over(self, max_turns):
        '''check for end of the game'''
        if not(all[self.is_alive(player) for player in range(1,3)]) or self.turn > max_turns:
            raise EndOfTheGame()

    @property
    def winner(self):
        pl1_ships = self.total_ships(1)
        pl2_ships = self.total_ships(2)
        self.debug("Player1: %d ships, Player2: %d ships" % (pl1_ships, pl2_ships))
        if pl1_ships > pl2_ships:
            return 1
        elif pl2_ships > pl1_ships:
            return 2
        else:
            return 0

    def load_turn_finish(self, map_data):
        turn_msg = "# %d" % self.turn
        self.debug(turn_msg)
        self.debug(turn_msg, 'server_io')
        self.turn += 1
        self.load_data(map_data)
        self.do_turn()
        self.finish_turn()

    <commit_msg>дописан planet_wars<commit_after>from utils import Debuggable

from math import ceil, sqrt
from sys import stdout
import math

def pov(owner, who):
    if who == 1 or owner == 0:
        return owner
    else:
        return 2 if owner == 1 else 1

class Fleet(object):
    def __init__(self, owner, num_ships, source_planet=-1, destination_planet=-1,
                 total_trip_length=-1, turns_remaining=-1):
        self.owner = owner
        self.num_ships = num_ships
        self.src = source_planet
        self.dest = destination_planet
        self.total_trip_length = total_trip_length
        self.turns_remaining = turns_remaining

    def __repr__(self):
        return self.__str__()

    def __str__(self):
        return self.repr_for()

    def repr_for_enemy(self):
        return self.repr_for(2)

    def repr_for(self, who=1):
        return "F %d %d %d %d %d %d\n" % (pov(self.owner, who), self.num_ships,
                                          self.src, self.dest,
                                          self.total_trip_length, self.turns_remaining)

class PlanetWars(Debuggable):
    def __init__(self, game_state=None):
        super(PlanetWars, self).__init__()
        self.planets = []
        self.fleets = []
        self.turn = 0
        self.real_orders = []
        self.game_state = game_state
        self.debug_name = "planetwars"
        self.via_standard_io = True
        if game_state:
            self.parse_game_state()

    def load_data(self, game_state):
        self.game_state = game_state
        self.real_orders = []
        self.parse_game_state()

    @property
    def num_planets(self):
        return len(self.planets)

    def get_planet(self, planet_id):
        return self.planets[planet_id]

    @property
    def num_fleets(self):
        return len(self.fleets)

    def get_fleet(self, fleet_id):
        return self.fleets[fleet_id]

    def _objects_by_owners(self, objects, owners):
        lst = []
        for obj in objects:
            if obj.owner in owners:
                lst.append(obj)
        return lst

    def _planets_by_owners(self, *owners):
        return self._objects_by_owners(self.planets, owners)

    def _fleets_by_owners(self, *owners):
        return self._objects_by_owners(self.fleets, owners)

    def cache_immutable_info(self):
        self.my_planets = self._planets_by_owners(1)
        self.neutral_planets = self._planets_by_owners(0)
        self.enemy_planets = self._planets_by_owners(2)
        self.not_my_planets = self._planets_by_owners(0, 2)
        self.my_fleets = self._fleets_by_owners(self, 1)
        self.enemy_fleets = self._fleets_by_owners(self, 2)

    def __repr__(self):
        return "".join([str(pl) for pl in (self.planets + self.fleets)])

    def repr_for_enemy(self):
        return "".join([obj.repr_for_enemy() for obj in (self.planets + self.fleets)])

    def distance(self, src_id, dest_id):
        src = self.planets[src_id]
        dest = self.planets[dest_id]
        dx = src.x - dest.x
        dy = src.y - dest.y
        return int(ceil(sqrt(dx * dx + dy * dy)))

    def issue_order(self, src_id, dest_id, num_ships):
        order = (src_id, dest_id, num_ships)
        self.real_orders.append(order)
        if self.via_standard_io:
            self.debug("Order: %d %d %d" % order)
            stdout.write("%d %d %d\n" % order)
            stdout.flush()

    def total_ships(self, player_id):
        objs = self._planets_by_owners(player_id) + self._fleets_by_owners(player_id)
        return sum([obj.num_ships for obj in objs])

    def is_alive(self, player_id):
        return self.total_ships(player_id) > 0

    def is_game_over(self, max_turns):
        '''check for end of the game'''
        if not(all[self.is_alive(player) for player in range(1,3)]) or self.turn > max_turns:
            raise EndOfTheGame()

    @property
    def winner(self):
        pl1_ships = self.total_ships(1)
        pl2_ships = self.total_ships(2)
        self.debug("Player1: %d ships, Player2: %d ships" % (pl1_ships, pl2_ships))
        if pl1_ships > pl2_ships:
            return 1
        elif pl2_ships > pl1_ships:
            return 2
        else:
            return 0

    def load_turn_finish(self, map_data):
        turn_msg = "# %d" % self.turn
        self.debug(turn_msg)
        self.debug(turn_msg, 'server_io')
        self.turn += 1
        self.load_data(map_data)
        self.do_turn()
        self.finish_turn()

    def parse_game_state(self):
        self.planets = []
        self.fleets = []
        planet_id = 0

        for line in self.game_state.split("\n"):
            line = line.split("#")[0] #remove comments
            tokens = line.split(" ")
            if len(tokens) == 1:
                continue
            if tokens[0] == "P":
                if len(tokens) != 6:
                    raise BadState("Planet line is wrong")
                p = Planet(planet_id,  # The ID of this planet
                           int(tokens[3]),  # Owner
                           int(tokens[4]),  # Num ships
                           int(tokens[5]),  # Growth rate
                           float(tokens[1]),  # X
                           float(tokens[2]))  # Y
                planet_id += 1
                self.planets.append(p)
            elif tokens[0] == "F":
                if len(tokens) != 7:
                    raise BadState("Fleet line is wrong")
                f = Fleet(int(tokens[1]),  # Owner
                          int(tokens[2]),  # Num ships
                          int(tokens[3]),  # Source
                          int(tokens[4]),  # Destination
                          int(tokens[5]),  # Total trip length
                          int(tokens[6]))  # Turns remaining
                self.fleets.append(f)
            else:
                raise BadState("Unsupported line came")
        self.cache_immutable_info()

    def finish_turn(self):
        stdout.write("go\n")
        stdout.flush()

    def issue_and_update(self, src, dest, ships):
        p = self.get_planet(src)
        total = p.num_ships
        if total < ships:
            self.debug("Bad order %d -> %d with %d, but have %d. Aborting" % (src, dest, ships, total))
            return
        self.debug("Sending %d ships from %d to %d" % (ships, src, dest))
        self.issue_order(src, dest, ships)
        #Updating planet
        p.num_ships = total - ships
        #Making fleet
        d = self.distance(src, dest)
        new_fleet = Fleet(1, ships, src, dest, d, d)
        self.fleets.append(new_fleet)

class Planet(object):
    def __init__(self, planet_id, owner, num_ships, growth_rate, x, y):
        self.id = planet_id
        self.owner = owner
        self.num_ships = num_ships
        self.growth_rate = growth_rate
        self.x = x
        self.y = y

    def add_ships(self, amount):
        self.num_ships += amount

    def remove_ships(self, amount):
        self.num_ships -= amount

    def __repr__(self):
        return self.__str__()

    def __str__(self):
        return self.repr_for()

    def repr_for_enemy(self):
        return self.repr_for(2)

    def repr_for(self, who=1):
        return "P %f %f %d %d %d\n" % (self.x, self.y, pov(self.owner, who), self.num_ships, self.growth_rate)

    def __eq__(self, other):
        return self.id == other.id

class Bot(PlanetWars):
    def __init__(self):
        super(Bot, self).__init__()
        self.debug_name = "bot"
        self.ships_key_getter = lambda a: a.num_ships

    def do_turn(self):
        pass

    def simple_estimate(self, src, dst):
        need = float(dst.num_ships)
        owner = dst.owner
        if owner > 1:
            need += self.distance(src.id, dst.id) * dst.growth_rate

        enemy_fleet_count = [fleet.num_ships for fleet in self.enemy_fleets if fleet.destination_planet == dst.id]
        need += sum(enemy_fleet_count)

        my_fleet = [fleet for fleet in self.my_fleets if fleet.destination_planet == dst.id]
        my_fleet.sort(key=lambda fleet: fleet.turns_remaining)
        for fleet in my_fleet:
            if owner > 1:
                need += dst.growth_rate + fleet.turns_remaining
            need -= fleet.num_ships

            if need <= 0:
                break

        return int(math.ceil(need * 1.10))

    def all_other_planets(self, src):
        self.debug("all_other_tables")
        planets = self.not_my_planets + []
        planets.sort(key=self.ships_key_getter)
        self.debug("all other planets %s" % [s.id for s in planets])
        return planets

    @property
    def my_sorted_planets(self):
        planets = self.my_planets + []
        planets.sort(key=self.ships_key_getter, reverse=True)
        self.debug("my planets %s" % [s.id for s in planets])
        return planets

    def attack(self, choose_targets, estimate, give_portion=0.66):
        self.debug("Attacking.")
        for src in self.my_sorted_planets:
            init_was = src.num_ships
            can_give = float(init_was * give_portion)
            self.debug("My planet %d can give %d ships" % (src.id, can_give))
            for dest in choose_targets(src):
                ships_to_send = estimate(src, dest)
                if ships_to_send > 0 and can_give >= ships_to_send:
                    self.debug("Sending %d ships to %d planet" % (ships_to_send, dest.id))
                    self.issue_and_update(src.id, dest.id, ships_to_send)
                    can_give -= ships_to_send
            self.debug("From %d in total sent %d ships" % (init_was - src.num_ships, src.id))

class EndOfTheGame(Exception):
    pass

class BadState(Exception):
    pass
<|endoftext|>


<commit_before>from django.contrib import admin
from models import UserPlan, Plan, PlanQuota, Quota, PlanPricing, Pricing, Order, BillingInfo
from ordered_model.admin import OrderedModelAdmin
from plans.models import Invoice

class PlanQuotaInline(admin.TabularInline):
    model = PlanQuota

class PlanPricingInline(admin.TabularInline):
    model = PlanPricing

class QuotaAdmin(OrderedModelAdmin):
    list_display = ('codename', 'name', 'description', 'unit', 'is_boolean', 'order', 'move_up_down_links', )

class PlanAdmin(OrderedModelAdmin):
    list_filter = ( 'available', 'customized' )
    list_display = ('name',   'description', 'customized', 'default', 'available', 'created', 'move_up_down_links')
    inlines = (PlanPricingInline, PlanQuotaInline)

    def queryset(self, request):
        return super(PlanAdmin, self).queryset(request).select_related('customized')

class BillingInfoAdmin(admin.ModelAdmin):
    list_display = ('user', 'name',  'street', 'zipcode', 'city', 'country')

class OrderAdmin(admin.ModelAdmin):
    list_filter = ( 'user', 'valid' )
    list_display = ('user', "created", "valid", "completed", "amount", "currency", "plan", "pricing")

    def queryset(self, request):
        return super(OrderAdmin, self).queryset(request).select_related('plan', 'pricing', 'user')

class InvoiceAdmin(admin.ModelAdmin):
    list_display = ('full_number', "issued", "total_net", "currency", "tax", "buyer_name", "buyer_city", "buyer_tax_number")

admin.site.register(Quota, QuotaAdmin)
admin.site.register(Plan, PlanAdmin)
admin.site.register(UserPlan)
admin.site.register(Pricing)
admin.site.register(Order, OrderAdmin)
admin.site.register(BillingInfo, BillingInfoAdmin)
admin.site.register(Invoice, InvoiceAdmin)

<commit_msg>Admin tweaks<commit_after>from django.contrib import admin
from models import UserPlan, Plan, PlanQuota, Quota, PlanPricing, Pricing, Order, BillingInfo
from ordered_model.admin import OrderedModelAdmin
from plans.models import Invoice

class PlanQuotaInline(admin.TabularInline):
    model = PlanQuota

class PlanPricingInline(admin.TabularInline):
    model = PlanPricing

class QuotaAdmin(OrderedModelAdmin):
    list_display = ('codename', 'name', 'description', 'unit', 'is_boolean',  'move_up_down_links', )

class PlanAdmin(OrderedModelAdmin):
    search_fields = ('customized__username', 'customized__email', )
    list_filter = ( 'available',  )
    list_display = ('name',   'description', 'customized', 'default', 'available', 'created', 'move_up_down_links')
    inlines = (PlanPricingInline, PlanQuotaInline)
    list_select_related = True

    def queryset(self, request):
        return super(PlanAdmin, self).queryset(request).select_related('customized')

class BillingInfoAdmin(admin.ModelAdmin):
    search_fields = ('user__username', 'user__email')
    list_display = ('user', 'name',  'street', 'zipcode', 'city', 'country')
    list_select_related = True

class OrderAdmin(admin.ModelAdmin):
    list_filter = ('status', "plan")
    search_fields = ('id', 'user__username', 'user__email')
    list_display = ("id", "created", "user", "status", "completed", "amount", "currency", "plan", "pricing")
    def queryset(self, request):
        return super(OrderAdmin, self).queryset(request).select_related('plan', 'pricing', 'user')

class InvoiceAdmin(admin.ModelAdmin):
    search_fields = ('full_number',  'buyer_tax_number', 'user__username', 'user__email')
    list_filter = ('type', )
    list_display = ('full_number', "issued", "total_net", "currency", 'user', "tax", "buyer_name", "buyer_city", "buyer_tax_number")
    list_select_related = True

class UserPlanAdmin(admin.ModelAdmin):
    list_filter = ('active', 'expire')
    search_fields = ('user__username', 'user__email')
    list_display = ('user', 'plan', 'expire', 'active')
    list_select_related = True

admin.site.register(Quota, QuotaAdmin)
admin.site.register(Plan, PlanAdmin)
admin.site.register(UserPlan, UserPlanAdmin)
admin.site.register(Pricing)
admin.site.register(Order, OrderAdmin)
admin.site.register(BillingInfo, BillingInfoAdmin)
admin.site.register(Invoice, InvoiceAdmin)

<|endoftext|>


<commit_before>import itertools
import six

from chainer import cuda
from chainer import function
from chainer.utils import type_check

def _tile_indices(reps, shape):
    """Return tile indices from reps and shape of input array."""
    tile_indices = []
    ranges = [six.moves.range(x) for x in reps]
    for index in itertools.product(*ranges):
        tile_index = tuple(slice(i * d, (i + 1) * d)
                           for i, d in zip(index, shape))
        tile_indices.append(tile_index)
    return tile_indices

class Tile(function.Function):
    """Tiling of an array."""

    def __init__(self, reps):
        if isinstance(reps, six.integer_types):
            self.reps = (reps,)
        elif isinstance(reps, tuple) and all(
                isinstance(x, six.integer_types) for x in reps):
            self.reps = reps
        else:
            raise TypeError('reps must be int or tuple of ints')

        if not all(x >= 0 for x in self.reps):
            raise ValueError('all elements in reps must be zero or larger')

    def check_type_forward(self, in_types):
        type_check.expect(in_types.size() == 1)

    def forward(self, inputs):
        xp = cuda.get_array_module(*inputs)
        return xp.tile(inputs[0], self.reps),

    def backward(self, inputs, grads):
        xp = cuda.get_array_module(*inputs)
        x = inputs[0]
        reps = self.reps

        # Ensure input and reps have the same length.
        if x.ndim > len(reps):
            reps = (1,) * (x.ndim - len(reps)) + reps
        elif x.ndim < len(reps):
            x = x.reshape((1,) * (len(reps) - x.ndim) + x.shape)

        gy = xp.zeros(x.shape).astype(x.dtype, copy=False)
        for index in _tile_indices(reps, x.shape):
            gy += grads[0][index]

        if inputs[0].ndim < len(reps):
            return gy.reshape(inputs[0].shape),
        else:
            return gy,

def tile(x, reps):
    """Construct an array by tiling a given array.

    Args:
        x (chainer.Variable or :class:`numpy.ndarray` or cupy.ndarray):
            Input data.
        reps (int or tuple of ints): The number of times for each axis with
            which x is replicated.

    Returns:
        ~chainer.Variable: Variable tiled the given array.
    """
    return Tile(reps)(x)
<commit_msg>Use numpy.sum instead of for-loop.<commit_after>import itertools
import six

from chainer import cuda
from chainer import function
from chainer.utils import type_check

def _tile_indices(reps, shape):
    """Return tile indices from reps and shape of input array."""
    tile_indices = []
    ranges = [six.moves.range(x) for x in reps]
    for index in itertools.product(*ranges):
        tile_index = tuple(slice(i * d, (i + 1) * d)
                           for i, d in zip(index, shape))
        tile_indices.append(tile_index)
    return tile_indices

class Tile(function.Function):
    """Tiling of an array."""

    def __init__(self, reps):
        if isinstance(reps, six.integer_types):
            self.reps = (reps,)
        elif isinstance(reps, tuple) and all(
                isinstance(x, six.integer_types) for x in reps):
            self.reps = reps
        else:
            raise TypeError('reps must be int or tuple of ints')

        if not all(x >= 0 for x in self.reps):
            raise ValueError('all elements in reps must be zero or larger')

    def check_type_forward(self, in_types):
        type_check.expect(in_types.size() == 1)

    def forward(self, inputs):
        xp = cuda.get_array_module(*inputs)
        return xp.tile(inputs[0], self.reps),

    def backward(self, inputs, grads):
        x = inputs[0]
        reps = self.reps

        # Ensure input and reps have the same length.
        if x.ndim > len(reps):
            reps = (1,) * (x.ndim - len(reps)) + reps
        elif x.ndim < len(reps):
            x = x.reshape((1,) * (len(reps) - x.ndim) + x.shape)

        if grads[0].shape == ():
            # This case should be treated differently because numpy.num would
            # return a scalar (even if keepdims=True).
            return grads[0],

        # Reshape so that base axis and reps axis can be distinguished.
        new_shape = []
        for i in range(grads[0].ndim):
            new_shape.append(reps[i])
            new_shape.append(x.shape[i])
        new_shape = tuple(new_shape)

        # Sum along reps axis
        reps_axis = tuple(range(0, 2 * grads[0].ndim, 2))
        gy = grads[0].respahe(new_shape).sum(axis=reps_axis)

        if inputs[0].ndim < len(reps):
            return gy.reshape(inputs[0].shape),
        else:
            return gy,

def tile(x, reps):
    """Construct an array by tiling a given array.

    Args:
        x (chainer.Variable or :class:`numpy.ndarray` or cupy.ndarray):
            Input data.
        reps (int or tuple of ints): The number of times for each axis with
            which x is replicated.

    Returns:
        ~chainer.Variable: Variable tiled the given array.
    """
    return Tile(reps)(x)
<|endoftext|>


<commit_before>from .responses import S3ResponseInstance

url_bases = [
    "https?://(?P<bucket_name>[a-zA-Z0-9\-_.]*)\.?s3.amazonaws.com"
]

url_paths = {
    '{0}/$': S3ResponseInstance.bucket_response,
    '{0}/(?P<key_name>[a-zA-Z0-9\-_.]+)': S3ResponseInstance.key_response,
}
<commit_msg>Fix S3 URL Regex to allow slashes in key names.<commit_after>from .responses import S3ResponseInstance

url_bases = [
    "https?://(?P<bucket_name>[a-zA-Z0-9\-_.]*)\.?s3.amazonaws.com"
]

url_paths = {
    '{0}/$': S3ResponseInstance.bucket_response,
    '{0}/(?P<key_name>.+)': S3ResponseInstance.key_response,
}
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
###
# Copyright (c) 2012, spline
# All rights reserved.
#
#
###

import urllib2
import re
from BeautifulSoup import BeautifulSoup
import collections
import string

import supybot.utils as utils
from supybot.commands import *
import supybot.plugins as plugins
import supybot.ircutils as ircutils
import supybot.callbacks as callbacks
#from supybot.i18n import PluginInternationalization, internationalizeDocstring

#_ = PluginInternationalization('Soccer')

#@internationalizeDocstring
class Soccer(callbacks.Plugin):
    """Add the help for "@plugin help Soccer" here
    This should describe *how* to use this plugin."""
    threaded = True

    def _b64decode(self, string):
        """Returns base64 decoded string."""
        import base64
        return base64.b64decode(string)

    def _validleagues(self, league=None):
        """Return string containing league string if valid, 0 if error. If no league given, return leagues as keys of tuple."""
        leagues = { 'MLS':'usa.1', 'EPL':'eng.1', 'LaLiga':'esp.1',
                    'SerieA':'ita.1', 'Bundesliga':'ger.1', 'Ligue1':'fra.1',
                    'Eredivise':'ned.1', 'LigaMX':'mex.1'
                  }

        if league is None:
            return leagues.keys() # return the keys here for an list to display.
        else:
            if league not in leagues:
                return "0" # to parse an error.
            else:
                return leagues[league]

    ####################
    # Public Functions #
    ####################

    def soccer(self, irc, msg, args, optleague):
        """[league]
        Display live/completed scores for various leagues.
        """

        leagueString = self._validleagues(league=optleague)

        if leagueString == "0":
            irc.reply("Must specify league. Leagues is one of: %s" % (self._validleagues(league=None)))
            return

        url = self._b64decode('aHR0cDovL20uZXNwbi5nby5jb20vc29jY2VyL3Njb3JlYm9hcmQ/') + 'leagueTag=%s&lang=EN&wjb=' % (leagueString)

        try:
            req = urllib2.Request(url)
            html = (urllib2.urlopen(req)).read()
        except:
            irc.reply("Failed to open %s" % url)
            return

        soup = BeautifulSoup(html)
        divs = soup.findAll('div', attrs={'class':'ind'})

        append_list = []

        for div in divs:
            if div.find('div', attrs={'style':'white-space: nowrap;'}):
                match = div.find('div', attrs={'style':'white-space: nowrap;'})
                if match:
                    match = match.getText().encode('utf-8') # do string formatting/color below. Ugly but it works.
                    match = match.replace('Final -',ircutils.mircColor('FT', 'red') + ' -')
                    match = match.replace('Postponed -',ircutils.mircColor('PP', 'yellow') + ' -')
                    match = match.replace('(ESPN, UK)','').replace('(ESPN3)','').replace(' ET','').replace(' CT','').replace(' PT','')
                    # 17' - Osasuna 1-0 Barcelona | 2:00 PM - Getafe vs Real Madrid
                    append_list.append(str(match).strip())

        if len(append_list) > 0:
            descstring = string.join([item for item in append_list], " | ")
            irc.reply(descstring)
        else:
            irc.reply("I did not find any matches going on for: %s" % leagueString)
    soccer = wrap(soccer, [('somethingWithoutSpaces')])

    #def soccerstats(self, irc, msg, args)

Class = Soccer

# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=250:
<commit_msg>Add in initial soccerstats.<commit_after># -*- coding: utf-8 -*-
###
# Copyright (c) 2012, spline
# All rights reserved.
#
#
###

import urllib2
import re
from BeautifulSoup import BeautifulSoup
import collections
import string

import supybot.utils as utils
from supybot.commands import *
import supybot.plugins as plugins
import supybot.ircutils as ircutils
import supybot.callbacks as callbacks
#from supybot.i18n import PluginInternationalization, internationalizeDocstring

#_ = PluginInternationalization('Soccer')

#@internationalizeDocstring
class Soccer(callbacks.Plugin):
    """Add the help for "@plugin help Soccer" here
    This should describe *how* to use this plugin."""
    threaded = True

    def _b64decode(self, string):
        """Returns base64 decoded string."""
        import base64
        return base64.b64decode(string)

    def _validleagues(self, league=None):
        """Return string containing league string if valid, 0 if error. If no league given, return leagues as keys of tuple."""
        leagues = { 'MLS':'usa.1', 'EPL':'eng.1', 'LaLiga':'esp.1',
                    'SerieA':'ita.1', 'Bundesliga':'ger.1', 'Ligue1':'fra.1',
                    'Eredivise':'ned.1', 'LigaMX':'mex.1'
                  }

        if league is None:
            return leagues.keys() # return the keys here for an list to display.
        else:
            if league not in leagues:
                return "0" # to parse an error.
            else:
                return leagues[league]

    ####################
    # Public Functions #
    ####################

    def soccer(self, irc, msg, args, optleague):
        """[league]
        Display live/completed scores for various leagues.
        """

        leagueString = self._validleagues(league=optleague)

        if leagueString == "0":
            irc.reply("Must specify league. Leagues is one of: %s" % (self._validleagues(league=None)))
            return

        url = self._b64decode('aHR0cDovL20uZXNwbi5nby5jb20vc29jY2VyL3Njb3JlYm9hcmQ/') + 'leagueTag=%s&lang=EN&wjb=' % (leagueString)

        try:
            req = urllib2.Request(url)
            html = (urllib2.urlopen(req)).read()
        except:
            irc.reply("Failed to open %s" % url)
            return

        soup = BeautifulSoup(html)
        divs = soup.findAll('div', attrs={'class':'ind'})

        append_list = []

        for div in divs:
            if div.find('div', attrs={'style':'white-space: nowrap;'}):
                match = div.find('div', attrs={'style':'white-space: nowrap;'})
                if match:
                    match = match.getText().encode('utf-8') # do string formatting/color below. Ugly but it works.
                    match = match.replace('Final -',ircutils.mircColor('FT', 'red') + ' -')
                    match = match.replace('Postponed -',ircutils.mircColor('PP', 'yellow') + ' -')
                    match = match.replace('(ESPN, UK)','').replace('(ESPN3)','').replace(' ET','').replace(' CT','').replace(' PT','')
                    # 17' - Osasuna 1-0 Barcelona | 2:00 PM - Getafe vs Real Madrid
                    append_list.append(str(match).strip())

        if len(append_list) > 0:
            descstring = string.join([item for item in append_list], " | ")
            irc.reply(descstring)
        else:
            irc.reply("I did not find any matches going on for: %s" % leagueString)
    soccer = wrap(soccer, [('somethingWithoutSpaces')])

    def soccerstats(self, irc, msg, args, optleague, optstat):
        """[league] [goals|assists|cards|fairplay]
        Display stats in league for stat. Ex: EPL goals
        """

        validstat = {'goals':'scorers', 'assists':'assists', 'cards':'discipline', 'fairplay':'fairplay'}

        leagueString = self._validleagues(league=optleague)

        if leagueString == "0":
            irc.reply("Must specify league. Leagues is one of: %s" % (self._validleagues(league=None)))
            return

        url = self._b64decode('aHR0cDovL3NvY2Nlcm5ldC5lc3BuLmdvLmNvbS9zdGF0cw==') + '/%s/_/league/%s/' % (validstat[optstat], leagueString)

        try:
            req = urllib2.Request(url)
            html = (urllib2.urlopen(req)).read()
        except:
            irc.reply("Failed to open %s" % url)
            return

        html = html.replace(' ','')

        if "There are no statistics available for this season." in html:
            irc.reply("I did not find any statistics for: %s in %s" % (optstat, optleague))
            return

        soup = BeautifulSoup(html)
        table = soup.find('table', attrs={'class':'tablehead'})
        header = table.find('tr', attrs={'class':'colhead'}).findAll('td')
        rows = table.findAll('tr', attrs={'class':re.compile('(^odd|^even)row')})[0:5] # int option

        del header[0] # no need for rank.

        append_list = []

        for row in rows:
            tds = row.findAll('td')
            del tds[0] # delete the first as it is the rank.
            mini_list = []
            for i,td in enumerate(tds):
                colname = header[i].getText().replace('Team','T').replace('Player','Plr').replace('Yellow','Y').replace('Red','R').replace('Points','Pts').replace('Assists','A').replace('Goals','G')
                colstat = td
                mini_list.append(ircutils.bold(colname) + ": " + colstat.getText()) # bold colname.
            append_list.append(" ".join(mini_list))

        descstring = string.join([item for item in append_list], " | ")
        output = "Leaders in {0} for {1} :: {2}".format(ircutils.mircColor(optstat, 'red'), ircutils.underline(optleague), descstring)
        irc.reply(output)

    soccerstats = wrap(soccerstats, [('somethingWithoutSpaces'), ('somethingWithoutSpaces')])

Class = Soccer

# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=250:
<|endoftext|>


<commit_before># This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from scipy.stats import binom, norm, rankdata
from scipy.special import comb
from chainladder.utils.cupy import cp
import pandas as pd
import copy

class DevelopmentCorrelation:
    """
    Mack (1997) test for correlations between subsequent development
    factors. Results should be within confidence interval range
    otherwise too much correlation

    Parameters
    ----------
    triangle: Triangle
        Triangle on which to estimate correlation between subsequent development
        factors.
    p_critical: float (default=0.10)
        Value between 0 and 1 representing the confidence level for the test. A
        value of 0.1 implies 90% confidence.

    Attributes
    ----------
    t_critical : DataFrame
        Boolean value for whether correlation is too high based on `p_critical`
        confidence level.
    t_expectation : DataFrame
        Values representing the Spearman rank correlation
    t_variance : float
        Variance measure of Spearman rank correlation
    range : tuple
        Range within which `t_expectation` must fall for independence assumption
        to be significant.
    """
    def __init__(self, triangle, p_critical=0.5):
        self.p_critical = p_critical
        xp = cp.get_array_module(triangle.values)
        m1 = triangle.link_ratio
        m1_val = xp.apply_along_axis(rankdata, 2, m1.values)*(m1.values*0+1)
        m2 = triangle[triangle.valuation<triangle.valuation_date].link_ratio
        m2.values = xp.apply_along_axis(rankdata, 2, m2.values)*(m2.values*0+1)
        m1 = copy.deepcopy(m2)
        m1.values = m1_val[..., :m2.shape[2], 1:]
        numerator = ((m1-m2)**2).sum('origin')
        numerator.values = numerator.values[..., :-1]
        numerator.ddims = numerator.ddims[:-1]
        I = triangle.shape[3]
        k = xp.array(range(2, 2+numerator.shape[3]))
        denominator = ((I - k)**3 - I + k)[None, None, None]
        self.t = 1-6*xp.nan_to_num(numerator.values)/denominator
        weight = (I-k-1)[None, None, None]
        t_expectation = (xp.sum(xp.nan_to_num(weight*self.t), axis=3) /
                         xp.sum(weight, axis=3))[..., None]
        idx = triangle._idx_table().index
        self.t_variance = 2/((I-2)*(I-3))
        self.t = pd.DataFrame(
            self.t[..., 0, 0], columns=triangle.vdims, index=idx)
        self.t_expectation = pd.DataFrame(
            t_expectation[..., 0, 0], columns=triangle.vdims, index=idx)
        self.range = (norm.ppf(0.5-(1-p_critical)/2)*xp.sqrt(self.t_variance),
                      norm.ppf(0.5+(1-p_critical)/2)*xp.sqrt(self.t_variance))
        self.t_critical = (self.t_expectation<self.range[0]) | \
                          (self.t_expectation>self.range[1])

class ValuationCorrelation:
    """
    Mack (1997) test for calendar year effect
    A calendar period has impact across developments if the probability of
    the number of small (or large) development factors, Z, in that period
    occurring randomly is less than p_critical

    Parameters
    ----------
    triangle: Triangle
        Triangle on which to test whether the calendar effects violate independence
        requirements of the chainladder method.
    p_critical: float (default=0.10)
        Value between 0 and 1 representing the confidence level for the test. 0.1
        implies 90% confidence.
    total: boolean
        Whether to calculate valuation correlation in total across all
        years (True) consistent with Mack 1993 or for each year separately
        (False) consistent with Mack 1997.

    Attributes
    ----------
    z : Triangle or DataFrame
        Z values for each Valuation Period
    z_critical : Triangle or DataFrame
        Boolean value for whether correlation is too high based on `p_critical`
        confidence level.
    z_expectation : Triangle or DataFrame
        The expected value of Z.
    z_variance : Triangle or DataFrame
        The variance value of Z.
    """
    def __init__(self, triangle, p_critical=.1, total=True):

        def pZlower(z,n,p=0.5):
            return min(1, 2*binom.cdf(z,n,p))

        self.p_critical = p_critical
        self.total = total
        xp = cp.get_array_module(triangle.values)
        lr = triangle.link_ratio
        m1 = xp.apply_along_axis(rankdata, 2, lr.values)*(lr.values*0+1)
        med = xp.nanmedian(m1, axis=2, keepdims=True)
        m1large = (xp.nan_to_num(m1) > med) + (lr.values*0)
        m1small = (xp.nan_to_num(m1) < med) + (lr.values*0)
        m2large = triangle.link_ratio
        m2large.values = m1large
        m2small = triangle.link_ratio
        m2small.values = m1small
        S = xp.nan_to_num(m2small.dev_to_val().sum(axis=2).values)
        L = xp.nan_to_num(m2large.dev_to_val().sum(axis=2).values)
        z = xp.minimum(L, S)
        n = L + S
        m = xp.floor((n - 1)/2)
        EZ = (n/2) - comb(n-1, m)*n/(2**n)
        VarZ = n*(n - 1) / 4 - comb(n-1, m)*n * (n-1) / (2**n) + EZ - EZ**2
        if not self.total:
            T=[]
            for i in range(0,xp.max(m1large.shape[2:])):
                T.append([pZlower(i,j,0.5) for j in range(0,xp.max(m1large.shape[2:]))])
            T=xp.array(T)
            self.probs = xp.array(T[z.astype(int),n.astype(int)])
            z_critical = triangle[triangle.valuation>triangle.valuation.min()]
            z_critical = z_critical.dev_to_val().dropna().sum('origin')*0
            z_critical.values = (xp.array(self.probs)<p_critical)
            z_critical.odims=['(All)']
            self.z_critical = z_critical
            self.z = copy.deepcopy(self.z_critical)
            self.z.values = z
            self.z_expectation = copy.deepcopy(self.z_critical)
            self.z_expectation.values = EZ
            self.z_variance = copy.deepcopy(self.z_critical)
            self.z_variance.values = VarZ
        else:
            ci2 = norm.ppf(0.5-(1-p_critical)/2)*xp.sqrt(xp.sum(VarZ, axis=-1))
            self.range = (xp.sum(VarZ, axis=-1) + ci2,
                          xp.sum(VarZ, axis=-1) - ci2)
            idx = triangle._idx_table().index
            self.z_critical = pd.DataFrame(
                ((self.range[0] > VarZ.sum(axis=-1)) | \
                (VarZ.sum(axis=-1) > self.range[1]))[..., 0],
                columns=triangle.vdims, index=idx)
            self.z =pd.DataFrame(
                z.sum(axis=-1)[..., 0], columns=triangle.vdims, index=idx)
            self.z_expectation =pd.DataFrame(
                EZ.sum(axis=-1)[..., 0], columns=triangle.vdims, index=idx)
            self.z_variance = pd.DataFrame(
                VarZ.sum(axis=-1)[..., 0], columns=triangle.vdims, index=idx)
<commit_msg>Update correlation.py<commit_after># This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from scipy.stats import binom, norm, rankdata
from scipy.special import comb
from chainladder.utils.cupy import cp
import pandas as pd
import copy

class DevelopmentCorrelation:
    """
    Mack (1997) test for correlations between subsequent development
    factors. Results should be within confidence interval range
    otherwise too much correlation

    Parameters
    ----------
    triangle: Triangle
        Triangle on which to estimate correlation between subsequent development
        factors.
    p_critical: float (default=0.10)
        Value between 0 and 1 representing the confidence level for the test. A
        value of 0.1 implies 90% confidence.

    Attributes
    ----------
    t_critical : DataFrame
        Boolean value for whether correlation is too high based on `p_critical`
        confidence level.
    t_expectation : DataFrame
        Values representing the Spearman rank correlation
    t_variance : float
        Variance measure of Spearman rank correlation
    range : tuple
        Range within which `t_expectation` must fall for independence assumption
        to be significant.
    """
    def __init__(self, triangle, p_critical=0.5):
        self.p_critical = p_critical
        xp = cp.get_array_module(triangle.values)
        m1 = triangle.link_ratio
        m1_val = xp.apply_along_axis(rankdata, 2, m1.values)*(m1.values*0+1)
        m2 = triangle[triangle.valuation<triangle.valuation_date].link_ratio
        m2.values = xp.apply_along_axis(rankdata, 2, m2.values)*(m2.values*0+1)
        m1 = copy.deepcopy(m2)
        m1.values = m1_val[..., :m2.shape[2], 1:]
        numerator = ((m1-m2)**2).sum('origin')
        numerator.values = numerator.values[..., :-1]
        numerator.ddims = numerator.ddims[:-1]
        I = triangle.shape[3]
        k = xp.array(range(2, 2+numerator.shape[3]))
        denominator = ((I - k)**3 - I + k)[None, None, None]
        self.t = 1-6*xp.nan_to_num(numerator.values)/denominator
        weight = (I-k-1)[None, None, None]
        t_expectation = (xp.sum(xp.nan_to_num(weight*self.t), axis=3) /
                         xp.sum(weight, axis=3))[..., None]
        idx = triangle._idx_table().index
        self.t_variance = 2/((I-2)*(I-3))
        self.t = pd.DataFrame(
            self.t[..., 0, 0], columns=triangle.vdims, index=idx)
        self.t_expectation = pd.DataFrame(
            t_expectation[..., 0, 0], columns=triangle.vdims, index=idx)
        self.range = (norm.ppf(0.5-(1-p_critical)/2)*xp.sqrt(self.t_variance),
                      norm.ppf(0.5+(1-p_critical)/2)*xp.sqrt(self.t_variance))
        self.t_critical = (self.t_expectation<self.range[0]) | \
                          (self.t_expectation>self.range[1])

class ValuationCorrelation:
    """
    Mack (1997) test for calendar year effect
    A calendar period has impact across developments if the probability of
    the number of small (or large) development factors, Z, in that period
    occurring randomly is less than p_critical

    Parameters
    ----------
    triangle: Triangle
        Triangle on which to test whether the calendar effects violate independence
        requirements of the chainladder method.
    p_critical: float (default=0.10)
        Value between 0 and 1 representing the confidence level for the test. 0.1
        implies 90% confidence.
    total: boolean
        Whether to calculate valuation correlation in total across all
        years (True) consistent with Mack 1993 or for each year separately
        (False) consistent with Mack 1997.

    Attributes
    ----------
    z : Triangle or DataFrame
        Z values for each Valuation Period
    z_critical : Triangle or DataFrame
        Boolean value for whether correlation is too high based on `p_critical`
        confidence level.
    z_expectation : Triangle or DataFrame
        The expected value of Z.
    z_variance : Triangle or DataFrame
        The variance value of Z.
    """
    def __init__(self, triangle, p_critical=.1, total=True):

        def pZlower(z,n,p=0.5):
            return min(1, 2*binom.cdf(z,n,p))

        self.p_critical = p_critical
        self.total = total
        xp = cp.get_array_module(triangle.values)
        lr = triangle.link_ratio
        m1 = xp.apply_along_axis(rankdata, 2, lr.values)*(lr.values*0+1)
        med = xp.nanmedian(m1, axis=2, keepdims=True)
        m1large = (xp.nan_to_num(m1) > med) + (lr.values*0)
        m1small = (xp.nan_to_num(m1) < med) + (lr.values*0)
        m2large = triangle.link_ratio
        m2large.values = m1large
        m2small = triangle.link_ratio
        m2small.values = m1small
        S = xp.nan_to_num(m2small.dev_to_val().sum(axis=2).values)
        L = xp.nan_to_num(m2large.dev_to_val().sum(axis=2).values)
        z = xp.minimum(L, S)
        n = L + S
        m = xp.floor((n - 1)/2)
        EZ = (n/2) - comb(n-1, m)*n/(2**n)
        VarZ = n*(n - 1) / 4 - comb(n-1, m)*n * (n-1) / (2**n) + EZ - EZ**2
        if not self.total:
            T=[]
            for i in range(0,xp.max(m1large.shape[2:])+1):
                T.append([pZlower(i,j,0.5) for j in range(0,xp.max(m1large.shape[2:])+1)])
            T=xp.array(T)
            self.probs = xp.array(T[z.astype(int),n.astype(int)])
            z_critical = triangle[triangle.valuation>triangle.valuation.min()]
            z_critical = z_critical.dev_to_val().dropna().sum('origin')*0
            z_critical.values = (xp.array(self.probs)<p_critical)
            z_critical.odims=['(All)']
            self.z_critical = z_critical
            self.z = copy.deepcopy(self.z_critical)
            self.z.values = z
            self.z_expectation = copy.deepcopy(self.z_critical)
            self.z_expectation.values = EZ
            self.z_variance = copy.deepcopy(self.z_critical)
            self.z_variance.values = VarZ
        else:
            ci2 = norm.ppf(0.5-(1-p_critical)/2)*xp.sqrt(xp.sum(VarZ, axis=-1))
            self.range = (xp.sum(VarZ, axis=-1) + ci2,
                          xp.sum(VarZ, axis=-1) - ci2)
            idx = triangle._idx_table().index
            self.z_critical = pd.DataFrame(
                ((self.range[0] > VarZ.sum(axis=-1)) | \
                (VarZ.sum(axis=-1) > self.range[1]))[..., 0],
                columns=triangle.vdims, index=idx)
            self.z =pd.DataFrame(
                z.sum(axis=-1)[..., 0], columns=triangle.vdims, index=idx)
            self.z_expectation =pd.DataFrame(
                EZ.sum(axis=-1)[..., 0], columns=triangle.vdims, index=idx)
            self.z_variance = pd.DataFrame(
                VarZ.sum(axis=-1)[..., 0], columns=triangle.vdims, index=idx)
<|endoftext|>


<commit_before>"""Holds various Version strings of MPF.

This modules holds the MPF version strings, including the version of BCP it
needs and the config file version it needs.

It's used internally for all sorts of things, from printing the output of the
`mpf --version` command, to making sure any processes connected via BCP are
the proper versions, to automatically triggering new builds and deployments to
PyPI.

"""

__version__ = '0.54.0-dev.77'
'''The full version of MPF.'''

__short_version__ = '0.54'
'''The major.minor version of MPF.'''

__bcp_version__ = '1.1'
'''The version of BCP this build of MPF uses.'''

__config_version__ = '5'
'''The config file version this build of MPF uses.'''

__show_version__ = '5'
'''The show format version this build of MPF uses.'''

# pylint: disable-msg=invalid-name
version = "MPF v{}".format(__version__)
'''A friendly version string for this build of MPF.'''

# pylint: disable-msg=invalid-name
extended_version = "MPF v{}, Config version:{}, Show version: {}, " \
                   "BCP version:{}".format(__version__, __config_version__,
                                           __show_version__, __bcp_version__)
'''An extended version string that includes the MPF version, show version,
and BCP versions used in this build of MPF.'''

if "dev" in __version__:
    # pylint: disable-msg=invalid-name
    log_url = "https://docs.missionpinball.org/en/dev/logs/{}.html"
else:
    # pylint: disable-msg=invalid-name
    log_url = "https://docs.missionpinball.org/en/{}/logs/{{}}.html".format(__short_version__)

__api__ = ['version',
           '__short_version__',
           '__bcp_version__',
           '__config_version__',
           '__show_version__',
           'version',
           'extended_version',
           'log_url']
<commit_msg>0.54.0-dev.78<commit_after>"""Holds various Version strings of MPF.

This modules holds the MPF version strings, including the version of BCP it
needs and the config file version it needs.

It's used internally for all sorts of things, from printing the output of the
`mpf --version` command, to making sure any processes connected via BCP are
the proper versions, to automatically triggering new builds and deployments to
PyPI.

"""

__version__ = '0.54.0-dev.78'
'''The full version of MPF.'''

__short_version__ = '0.54'
'''The major.minor version of MPF.'''

__bcp_version__ = '1.1'
'''The version of BCP this build of MPF uses.'''

__config_version__ = '5'
'''The config file version this build of MPF uses.'''

__show_version__ = '5'
'''The show format version this build of MPF uses.'''

# pylint: disable-msg=invalid-name
version = "MPF v{}".format(__version__)
'''A friendly version string for this build of MPF.'''

# pylint: disable-msg=invalid-name
extended_version = "MPF v{}, Config version:{}, Show version: {}, " \
                   "BCP version:{}".format(__version__, __config_version__,
                                           __show_version__, __bcp_version__)
'''An extended version string that includes the MPF version, show version,
and BCP versions used in this build of MPF.'''

if "dev" in __version__:
    # pylint: disable-msg=invalid-name
    log_url = "https://docs.missionpinball.org/en/dev/logs/{}.html"
else:
    # pylint: disable-msg=invalid-name
    log_url = "https://docs.missionpinball.org/en/{}/logs/{{}}.html".format(__short_version__)

__api__ = ['version',
           '__short_version__',
           '__bcp_version__',
           '__config_version__',
           '__show_version__',
           'version',
           'extended_version',
           'log_url']
<|endoftext|>


<commit_before># This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

from scipy.special import comb
from chainladder.utils.cupy import cp
import pandas as pd
import copy

class DevelopmentCorrelation:
    """
    Mack (1997) test for correlations between subsequent development
    factors. Results should be within confidence interval range
    otherwise too much correlation

    Parameters
    ----------
    triangle: Triangle
        Triangle on which to estimate correlation between subsequent development
        factors.
    p_critical: float (default=0.10)
        Value between 0 and 1 representing the confidence level for the test. A
        value of 0.1 implies 90% confidence.

    Attributes
    ----------
    t_critical : DataFrame
        Boolean value for whether correlation is too high based on `p_critical`
        confidence level.
    t_expectation : DataFrame
        Values representing the Spearman rank correlation
    t_variance : float
        Variance measure of Spearman rank correlation
    range : tuple
        Range within which `t_expectation` must fall for independence assumption
        to be significant.
    """
    def __init__(self, triangle, p_critical=0.5):
        self.p_critical = p_critical
        xp = cp.get_array_module(triangle.values)
        m1 = triangle.link_ratio
        m1_val = xp.apply_along_axis(rankdata, 2, m1.values)*(m1.values*0+1)
        m2 = triangle[triangle.valuation<triangle.valuation_date].link_ratio
        m2.values = xp.apply_along_axis(rankdata, 2, m2.values)*(m2.values*0+1)
        m1 = copy.deepcopy(m2)
        m1.values = m1_val[..., :m2.shape[2], 1:]
        numerator = ((m1-m2)**2).sum('origin')
        numerator.values = numerator.values[..., :-1]
        numerator.ddims = numerator.ddims[:-1]
        I = triangle.shape[3]
        k = xp.array(range(2, 2+numerator.shape[3]))
        denominator = ((I - k)**3 - I + k)[None, None, None]
        self.t = 1-6*xp.nan_to_num(numerator.values)/denominator
        weight = (I-k-1)[None, None, None]
        t_expectation = (xp.sum(xp.nan_to_num(weight*self.t), axis=3) /
                         xp.sum(weight, axis=3))[..., None]
        idx = triangle._idx_table().index
        self.t_variance = 2/((I-2)*(I-3))
        self.t = pd.DataFrame(
            self.t[..., 0, 0], columns=triangle.vdims, index=idx)
        self.t_expectation = pd.DataFrame(
            t_expectation[..., 0, 0], columns=triangle.vdims, index=idx)
        self.range = (norm.ppf(0.5-(1-p_critical)/2)*xp.sqrt(self.t_variance),
                      norm.ppf(0.5+(1-p_critical)/2)*xp.sqrt(self.t_variance))
        self.t_critical = (self.t_expectation<self.range[0]) | \
                          (self.t_expectation>self.range[1])

class ValuationCorrelation:
    """
    Mack (1997) test for calendar year effect
    A calendar period has impact across developments if the probability of
    the number of small (or large) development factors, Z, in that period
    occurring randomly is less than p_critical

    Parameters
    ----------
    triangle: Triangle
        Triangle on which to test whether the calendar effects violate independence
        requirements of the chainladder method.
    p_critical: float (default=0.10)
        Value between 0 and 1 representing the confidence level for the test. 0.1
        implies 90% confidence.
    total: boolean
        Whether to calculate valuation correlation in total across all
        years (True) consistent with Mack 1993 or for each year separately
        (False) consistent with Mack 1997.

    Attributes
    ----------
    z : Triangle or DataFrame
        Z values for each Valuation Period
    z_critical : Triangle or DataFrame
        Boolean value for whether correlation is too high based on `p_critical`
        confidence level.
    z_expectation : Triangle or DataFrame
        The expected value of Z.
    z_variance : Triangle or DataFrame
        The variance value of Z.
    """
    def __init__(self, triangle, p_critical=.1, total=True):

        def pZlower(z,n,p=0.5):
            return min(1, 2*binom.cdf(z,n,p))

        self.p_critical = p_critical
        self.total = total
        xp = cp.get_array_module(triangle.values)
        lr = triangle.link_ratio
        m1 = xp.apply_along_axis(rankdata, 2, lr.values)*(lr.values*0+1)
        med = xp.nanmedian(m1, axis=2, keepdims=True)
        m1large = (xp.nan_to_num(m1) > med) + (lr.values*0)
        m1small = (xp.nan_to_num(m1) < med) + (lr.values*0)
        m2large = triangle.link_ratio
        m2large.values = m1large
        m2small = triangle.link_ratio
        m2small.values = m1small
        S = xp.nan_to_num(m2small.dev_to_val().sum(axis=2).values)
        L = xp.nan_to_num(m2large.dev_to_val().sum(axis=2).values)
        z = xp.minimum(L, S)
        n = L + S
        m = xp.floor((n - 1)/2)
        VarZ = (n/2) - comb(n-1, m)*n/(2**n)
        VarZ = n*(n - 1) / 4 - comb(n-1, m)*n * (n-1) / (2**n) + VarZ - VarZ**2
        if not self.total:
            self.probs = xp.array(
                [[[pZlower(z[i, c, 0, d], n[i, c, 0, d]) for d in range(S.shape[3])]
                  for c in range(S.shape[1])] for i in range(S.shape[0])])[:,:,None,:]
            z_critical = triangle[triangle.valuation>triangle.valuation.min()]
            z_critical = z_critical.dev_to_val().dropna().sum('origin')*0
            z_critical.values = (xp.array(self.probs)<p_critical)
            z_critical.odims=['(All)']
            self.z_critical = z_critical
            self.z = copy.deepcopy(self.z_critical)
            self.z.values = z
            self.z_expectation = copy.deepcopy(self.z_critical)
            self.z_expectation.values = EZ
            self.z_variance = copy.deepcopy(self.z_critical)
            self.z_variance.values = VarZ
        else:
            ci2 = norm.ppf(0.5-(1-p_critical)/2)*xp.sqrt(xp.sum(VarZ, axis=-1))
            self.range = (xp.sum(VarZ, axis=-1) + ci2,
                          xp.sum(VarZ, axis=-1) - ci2)
            idx = triangle._idx_table().index
            self.z_critical = pd.DataFrame(
                ((self.range[0] > VarZ.sum(axis=-1)) | \
                (VarZ.sum(axis=-1) > self.range[1]))[..., 0],
                columns=triangle.vdims, index=idx)
            self.z =pd.DataFrame(
                z.sum(axis=-1)[..., 0], columns=triangle.vdims, index=idx)
            self.z_expectation =pd.DataFrame(
                VarZ.sum(axis=-1)[..., 0], columns=triangle.vdims, index=idx)
            self.z_variance = pd.DataFrame(
                VarZ.sum(axis=-1)[..., 0], columns=triangle.vdims, index=idx)
<commit_msg>Update correlation.py<commit_after># This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from scipy.stats import binom, norm, rankdata
from scipy.special import comb
from chainladder.utils.cupy import cp
import pandas as pd
import copy

class DevelopmentCorrelation:
    """
    Mack (1997) test for correlations between subsequent development
    factors. Results should be within confidence interval range
    otherwise too much correlation

    Parameters
    ----------
    triangle: Triangle
        Triangle on which to estimate correlation between subsequent development
        factors.
    p_critical: float (default=0.10)
        Value between 0 and 1 representing the confidence level for the test. A
        value of 0.1 implies 90% confidence.

    Attributes
    ----------
    t_critical : DataFrame
        Boolean value for whether correlation is too high based on `p_critical`
        confidence level.
    t_expectation : DataFrame
        Values representing the Spearman rank correlation
    t_variance : float
        Variance measure of Spearman rank correlation
    range : tuple
        Range within which `t_expectation` must fall for independence assumption
        to be significant.
    """
    def __init__(self, triangle, p_critical=0.5):
        self.p_critical = p_critical
        xp = cp.get_array_module(triangle.values)
        m1 = triangle.link_ratio
        m1_val = xp.apply_along_axis(rankdata, 2, m1.values)*(m1.values*0+1)
        m2 = triangle[triangle.valuation<triangle.valuation_date].link_ratio
        m2.values = xp.apply_along_axis(rankdata, 2, m2.values)*(m2.values*0+1)
        m1 = copy.deepcopy(m2)
        m1.values = m1_val[..., :m2.shape[2], 1:]
        numerator = ((m1-m2)**2).sum('origin')
        numerator.values = numerator.values[..., :-1]
        numerator.ddims = numerator.ddims[:-1]
        I = triangle.shape[3]
        k = xp.array(range(2, 2+numerator.shape[3]))
        denominator = ((I - k)**3 - I + k)[None, None, None]
        self.t = 1-6*xp.nan_to_num(numerator.values)/denominator
        weight = (I-k-1)[None, None, None]
        t_expectation = (xp.sum(xp.nan_to_num(weight*self.t), axis=3) /
                         xp.sum(weight, axis=3))[..., None]
        idx = triangle._idx_table().index
        self.t_variance = 2/((I-2)*(I-3))
        self.t = pd.DataFrame(
            self.t[..., 0, 0], columns=triangle.vdims, index=idx)
        self.t_expectation = pd.DataFrame(
            t_expectation[..., 0, 0], columns=triangle.vdims, index=idx)
        self.range = (norm.ppf(0.5-(1-p_critical)/2)*xp.sqrt(self.t_variance),
                      norm.ppf(0.5+(1-p_critical)/2)*xp.sqrt(self.t_variance))
        self.t_critical = (self.t_expectation<self.range[0]) | \
                          (self.t_expectation>self.range[1])

class ValuationCorrelation:
    """
    Mack (1997) test for calendar year effect
    A calendar period has impact across developments if the probability of
    the number of small (or large) development factors, Z, in that period
    occurring randomly is less than p_critical

    Parameters
    ----------
    triangle: Triangle
        Triangle on which to test whether the calendar effects violate independence
        requirements of the chainladder method.
    p_critical: float (default=0.10)
        Value between 0 and 1 representing the confidence level for the test. 0.1
        implies 90% confidence.
    total: boolean
        Whether to calculate valuation correlation in total across all
        years (True) consistent with Mack 1993 or for each year separately
        (False) consistent with Mack 1997.

    Attributes
    ----------
    z : Triangle or DataFrame
        Z values for each Valuation Period
    z_critical : Triangle or DataFrame
        Boolean value for whether correlation is too high based on `p_critical`
        confidence level.
    z_expectation : Triangle or DataFrame
        The expected value of Z.
    z_variance : Triangle or DataFrame
        The variance value of Z.
    """
    def __init__(self, triangle, p_critical=.1, total=True):

        def pZlower(z,n,p=0.5):
            return min(1, 2*binom.cdf(z,n,p))

        self.p_critical = p_critical
        self.total = total
        xp = cp.get_array_module(triangle.values)
        lr = triangle.link_ratio
        m1 = xp.apply_along_axis(rankdata, 2, lr.values)*(lr.values*0+1)
        med = xp.nanmedian(m1, axis=2, keepdims=True)
        m1large = (xp.nan_to_num(m1) > med) + (lr.values*0)
        m1small = (xp.nan_to_num(m1) < med) + (lr.values*0)
        m2large = triangle.link_ratio
        m2large.values = m1large
        m2small = triangle.link_ratio
        m2small.values = m1small
        S = xp.nan_to_num(m2small.dev_to_val().sum(axis=2).values)
        L = xp.nan_to_num(m2large.dev_to_val().sum(axis=2).values)
        z = xp.minimum(L, S)
        n = L + S
        m = xp.floor((n - 1)/2)
        VarZ = (n/2) - comb(n-1, m)*n/(2**n)
        VarZ = n*(n - 1) / 4 - comb(n-1, m)*n * (n-1) / (2**n) + VarZ - VarZ**2
        if not self.total:
            self.probs = xp.array(
                [[[pZlower(z[i, c, 0, d], n[i, c, 0, d]) for d in range(S.shape[3])]
                  for c in range(S.shape[1])] for i in range(S.shape[0])])[:,:,None,:]
            z_critical = triangle[triangle.valuation>triangle.valuation.min()]
            z_critical = z_critical.dev_to_val().dropna().sum('origin')*0
            z_critical.values = (xp.array(self.probs)<p_critical)
            z_critical.odims=['(All)']
            self.z_critical = z_critical
            self.z = copy.deepcopy(self.z_critical)
            self.z.values = z
            self.z_expectation = copy.deepcopy(self.z_critical)
            self.z_expectation.values = EZ
            self.z_variance = copy.deepcopy(self.z_critical)
            self.z_variance.values = VarZ
        else:
            ci2 = norm.ppf(0.5-(1-p_critical)/2)*xp.sqrt(xp.sum(VarZ, axis=-1))
            self.range = (xp.sum(VarZ, axis=-1) + ci2,
                          xp.sum(VarZ, axis=-1) - ci2)
            idx = triangle._idx_table().index
            self.z_critical = pd.DataFrame(
                ((self.range[0] > VarZ.sum(axis=-1)) | \
                (VarZ.sum(axis=-1) > self.range[1]))[..., 0],
                columns=triangle.vdims, index=idx)
            self.z =pd.DataFrame(
                z.sum(axis=-1)[..., 0], columns=triangle.vdims, index=idx)
            self.z_expectation =pd.DataFrame(
                VarZ.sum(axis=-1)[..., 0], columns=triangle.vdims, index=idx)
            self.z_variance = pd.DataFrame(
                VarZ.sum(axis=-1)[..., 0], columns=triangle.vdims, index=idx)
<|endoftext|>


<commit_before>"""Holds various Version strings of MPF.

This modules holds the MPF version strings, including the version of BCP it
needs and the config file version it needs.

It's used internally for all sorts of things, from printing the output of the
`mpf --version` command, to making sure any processes connected via BCP are
the proper versions, to automatically triggering new builds and deployments to
PyPI.

"""

__version__ = '0.50.0-dev.82'
'''The full version of MPF.'''

__short_version__ = '0.50'
'''The major.minor version of MPF.'''

__bcp_version__ = '1.1'
'''The version of BCP this build of MPF uses.'''

__config_version__ = '5'
'''The config file version this build of MPF uses.'''

__show_version__ = '5'
'''The show format version this build of MPF uses.'''

version = "MPF v{}".format(__version__)
'''A friendly version string for this build of MPF.'''

extended_version = "MPF v{}, Config version:{}, Show version: {}, " \
                   "BCP version:{}".format(__version__, __config_version__,
                                           __show_version__, __bcp_version__)
'''An extended version string that includes the MPF version, show version,
and BCP versions used in this build of MPF.'''

__api__ = ['version',
           '__short_version__',
           '__bcp_version__',
           '__config_version__',
           '__show_version__',
           'version',
           'extended_version']
<commit_msg>dev-83<commit_after>"""Holds various Version strings of MPF.

This modules holds the MPF version strings, including the version of BCP it
needs and the config file version it needs.

It's used internally for all sorts of things, from printing the output of the
`mpf --version` command, to making sure any processes connected via BCP are
the proper versions, to automatically triggering new builds and deployments to
PyPI.

"""

__version__ = '0.50.0-dev.83'
'''The full version of MPF.'''

__short_version__ = '0.50'
'''The major.minor version of MPF.'''

__bcp_version__ = '1.1'
'''The version of BCP this build of MPF uses.'''

__config_version__ = '5'
'''The config file version this build of MPF uses.'''

__show_version__ = '5'
'''The show format version this build of MPF uses.'''

version = "MPF v{}".format(__version__)
'''A friendly version string for this build of MPF.'''

extended_version = "MPF v{}, Config version:{}, Show version: {}, " \
                   "BCP version:{}".format(__version__, __config_version__,
                                           __show_version__, __bcp_version__)
'''An extended version string that includes the MPF version, show version,
and BCP versions used in this build of MPF.'''

__api__ = ['version',
           '__short_version__',
           '__bcp_version__',
           '__config_version__',
           '__show_version__',
           'version',
           'extended_version']
<|endoftext|>


<commit_before>import requests
import urllib.request
import os
from util import Events
import sqlite3
import traceback
import operator
import discord

class Plugin(object):
    def __init__(self, pm):
        self.pm = pm
        self.api_key = self.pm.botPreferences.get_config_value("OSU", "apikey")
        # base_url controls parameters for lammmy generation. Use python string format to change mode/username
        self.base_url = "http://lemmmy.pw/osusig/sig.php?mode={}&pp=0&removemargin&darktriangles&colour=pink&uname={}"

    @staticmethod
    def register_events():
        return [Events.Command("osu", desc="Get the osu!standard details for a user"),
                Events.Command("ctb", desc="Get the osu!catch the beat details for a user"),
                Events.Command("taiko", desc="Get the osu!taiko details for a user"),
                Events.Command("mania", desc="Get the osu!mania details for a user"),
                Events.Command("leaderboard", desc="Get the server leaderboard for a mode (osu, ctb, taiko, mania)"),
                Events.Command("setosu", desc="Register your osu! username to your discord account. "
                                              "Will add you to the leaderboards"),
                Events.Command("deleteosu", desc="Staff command to remove a user from the leaderboard")]

    async def handle_command(self, message_object, command, args):
        if command == "osu":
            await self.osu(message_object, args[1].strip())
        if command == "ctb":
            await self.taiko(message_object, args[1].strip())
        if command == "taiko":
            await self.taiko(message_object, args[1].strip())
        if command == "mania":
            await self.mania(message_object, args[1].strip())
        if command == "leaderboard":
            await self.leaderboard(message_object, args[1].strip())
        if command == "setosu":
            await self.set_osu(message_object, args[1])
        if command == "deleteosu":
            id = message_object.mentions[0].id
            await self.delete_osu(id)

    async def osu(self, message_object, username):
        try:
            await self.get_badge(message_object.channel, username, 0)
            display_data = await self.get_data(username, 0)
            await self.pm.client.send_message(message_object.channel,
                                              "Username: " + display_data["username"] + "\n" + "Rank: " + display_data[
                                                  "pp_rank"] + "\n" + "Accuracy: " + display_data[
                                                  "accuracy"] + "\n" + "PP: " + display_data[
                                                  "pp_raw"] + "\n" + "Country: " + display_data[
                                                  "country"] + "\n" + "Rank in country: " + display_data[
                                                  "pp_country_rank"])
        except:
            await self.pm.client.send_message(message_object.channel, "Error unknown user **" + username + "**")

    async def taiko(self, message_object, username):
        try:
            await self.get_badge(message_object.channel, username, 1)
            display_data = await self.get_data(username, 1)
            await self.pm.client.send_message(message_object.channel,
                                              "Username: " + display_data["username"] + "\n" + "Rank: " + display_data[
                                                  "pp_rank"] + "\n" + "Accuracy: " + display_data[
                                                  "accuracy"] + "\n" + "PP: " + display_data[
                                                  "pp_raw"] + "\n" + "Country: " + display_data[
                                                  "country"] + "\n" + "Rank in country: " + display_data[
                                                  "pp_country_rank"])
        except:
            await self.pm.client.send_message(message_object.channel, "Error unknown user **" + username + "**")

    async def ctb(self, message_object, username):
        try:
            await self.get_badge(message_object.channel, username, 2)
            display_data = await self.get_data(username, 2)
            await self.pm.client.send_message(message_object.channel,
                                              "Username: " + display_data["username"] + "\n" + "Rank: " + display_data[
                                                  "pp_rank"] + "\n" + "Accuracy: " + display_data[
                                                  "accuracy"] + "\n" + "PP: " + display_data[
                                                  "pp_raw"] + "\n" + "Country: " + display_data[
                                                  "country"] + "\n" + "Rank in country: " + display_data[
                                                  "pp_country_rank"])
        except:
            await self.pm.client.send_message(message_object.channel, "Error unknown user **" + username + "**")

    async def mania(self, message_object, username):
        try:
            await self.get_badge(message_object.channel, username, 3)
            display_data = await self.get_data(username, 3)
            # Update leaderboard
            await self.pm.client.send_message(message_object.channel,
                                              "Username: " + display_data["username"] + "\n" + "Rank: " + display_data[
                                                  "pp_rank"] + "\n" + "Accuracy: " + display_data[
                                                  "accuracy"] + "\n" + "PP: " + display_data[
                                                  "pp_raw"] + "\n" + "Country: " + display_data[
                                                  "country"] + "\n" + "Rank in country: " + display_data[
                                                  "pp_country_rank"])
        except:
            await self.pm.client.send_message(message_object.channel, "Error unknown user **" + username + "**")

    async def get_badge(self, channel, username, id):
        directory = os.path.join(os.path.dirname(os.path.abspath(__file__)), "temp")
        if not os.path.exists(directory):
            os.makedirs(directory)
        filename = os.path.join(directory, username + "test.jpg")
        image_url = self.base_url.format(id, username)
        urllib.request.urlretrieve(image_url, filename)
        await self.pm.client.send_file(channel, filename)
        os.remove(filename)

    async def get_data(self, username, id):
        api_key = self.api_key
        url = 'https://osu.ppy.sh/api/get_user?m=' + str(id) + '&k=' + api_key + '&u=' + username
        response = requests.get(url, verify=True)
        return response.json()[0]

    async def leaderboard(self, message_object, mode):
        if not os.path.exists("cache/"):
            os.makedirs("cache")
        if mode is "":
            await self.pm.client.send_message(message_object.channel,
                                              "Please specify the gamemode (osu, taiko, ctb, mania)")
            return
        try:
            lb_msg = await self.pm.client.send_message(message_object.channel, "Loading leaderboard...")
            if mode == "osu":
                id = 0
            elif mode == "taiko":
                id = 1
            elif mode == "ctb":
                id = 2
            elif mode == "mania":
                id = 3
            else:
                id = 0
            con = sqlite3.connect("cache/osu_leaderboard.sqlite",
                                  detect_types=sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES)
            with con:
                cur = con.cursor()
                cur.execute("SELECT * FROM users")
                rows = cur.fetchall()
                index = 1
                msg = "Leaderboard for " + mode + ":\n"
                unsorted = list()

                for row in rows:
                    try:
                        data = await self.get_data(row[1], id)
                        if data["pp_rank"] != "0":
                            data["discord_id"] = row[0]
                            unsorted.append(data)
                    except:
                        continue

                sortedusers = sorted(unsorted, key=operator.itemgetter("pp_rank"))
                for data in sortedusers:
                    try:
                        user = await self.pm.client.get_user_info(data["discord_id"])
                        member = discord.utils.find(lambda m: m.name == user.name,
                                                    message_object.channel.server.members)
                        if member is None:
                            await self.delete_osu(data["discord_id"])
                            continue

                        # fetch correct display name
                        if hasattr(user, 'nick') and user.nick != "":
                            name = user.nick
                        else:
                            name = user.name

                        # get an emoji for top 3
                        emoji = ""
                        if index is 1:
                            emoji = ":first_place:"
                        elif index is 2:
                            emoji = ":second_place:"
                        elif index is 3:
                            emoji = ":third_place:"
                        else:
                            emoji = str(index) + "#:"

                        msg += emoji + " " + data["username"] + "  #" + data["pp_rank"] + " (" + str(int(float(data[
                            "pp_raw"]))) + "pp)" + " (" + name + ") \n"
                        index += 1
                    except:
                        traceback.print_exc()
                await self.pm.client.edit_message(lb_msg, msg)
        except:
            traceback.print_exc()

    async def set_osu(self, message_object, name):
        user_id = message_object.author.id
        if name is not "" and name is not None:
            if not os.path.exists("cache/"):
                os.makedirs("cache")
            try:
                con = sqlite3.connect("cache/osu_leaderboard.sqlite",
                                      detect_types=sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES)
                with con:
                    cur = con.cursor()
                    cur.execute(
                        "CREATE TABLE IF NOT EXISTS users(Id TEXT PRIMARY KEY, Username TEXT)")
                    cur.execute(
                        'INSERT OR IGNORE INTO users(Id, Username) VALUES(?, ?)',
                        (str(user_id), name))

                    cur.execute("UPDATE users SET Username = ? WHERE Id = ?",
                                (name, str(user_id)))
            except:
                traceback.print_exc()
        else:
            await self.delete_osu(user_id)

    async def delete_osu(self, id):
        if not os.path.exists("cache/"):
            os.makedirs("cache")
        try:
            con = sqlite3.connect("cache/osu_leaderboard.sqlite",
                                  detect_types=sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES)
            with con:
                cur = con.cursor()
                cur.execute("DELETE FROM users WHERE Id=?", (id,))
        except:
            traceback.print_exc()
<commit_msg>Fix sort, I think?<commit_after>import requests
import urllib.request
import os
from util import Events
import sqlite3
import traceback
import operator
import discord

class Plugin(object):
    def __init__(self, pm):
        self.pm = pm
        self.api_key = self.pm.botPreferences.get_config_value("OSU", "apikey")
        # base_url controls parameters for lammmy generation. Use python string format to change mode/username
        self.base_url = "http://lemmmy.pw/osusig/sig.php?mode={}&pp=0&removemargin&darktriangles&colour=pink&uname={}"

    @staticmethod
    def register_events():
        return [Events.Command("osu", desc="Get the osu!standard details for a user"),
                Events.Command("ctb", desc="Get the osu!catch the beat details for a user"),
                Events.Command("taiko", desc="Get the osu!taiko details for a user"),
                Events.Command("mania", desc="Get the osu!mania details for a user"),
                Events.Command("leaderboard", desc="Get the server leaderboard for a mode (osu, ctb, taiko, mania)"),
                Events.Command("setosu", desc="Register your osu! username to your discord account. "
                                              "Will add you to the leaderboards"),
                Events.Command("deleteosu", desc="Staff command to remove a user from the leaderboard")]

    async def handle_command(self, message_object, command, args):
        if command == "osu":
            await self.osu(message_object, args[1].strip())
        if command == "ctb":
            await self.taiko(message_object, args[1].strip())
        if command == "taiko":
            await self.taiko(message_object, args[1].strip())
        if command == "mania":
            await self.mania(message_object, args[1].strip())
        if command == "leaderboard":
            await self.leaderboard(message_object, args[1].strip())
        if command == "setosu":
            await self.set_osu(message_object, args[1])
        if command == "deleteosu":
            id = message_object.mentions[0].id
            await self.delete_osu(id)

    async def osu(self, message_object, username):
        try:
            await self.get_badge(message_object.channel, username, 0)
            display_data = await self.get_data(username, 0)
            await self.pm.client.send_message(message_object.channel,
                                              "Username: " + display_data["username"] + "\n" + "Rank: " + display_data[
                                                  "pp_rank"] + "\n" + "Accuracy: " + display_data[
                                                  "accuracy"] + "\n" + "PP: " + display_data[
                                                  "pp_raw"] + "\n" + "Country: " + display_data[
                                                  "country"] + "\n" + "Rank in country: " + display_data[
                                                  "pp_country_rank"])
        except:
            await self.pm.client.send_message(message_object.channel, "Error unknown user **" + username + "**")

    async def taiko(self, message_object, username):
        try:
            await self.get_badge(message_object.channel, username, 1)
            display_data = await self.get_data(username, 1)
            await self.pm.client.send_message(message_object.channel,
                                              "Username: " + display_data["username"] + "\n" + "Rank: " + display_data[
                                                  "pp_rank"] + "\n" + "Accuracy: " + display_data[
                                                  "accuracy"] + "\n" + "PP: " + display_data[
                                                  "pp_raw"] + "\n" + "Country: " + display_data[
                                                  "country"] + "\n" + "Rank in country: " + display_data[
                                                  "pp_country_rank"])
        except:
            await self.pm.client.send_message(message_object.channel, "Error unknown user **" + username + "**")

    async def ctb(self, message_object, username):
        try:
            await self.get_badge(message_object.channel, username, 2)
            display_data = await self.get_data(username, 2)
            await self.pm.client.send_message(message_object.channel,
                                              "Username: " + display_data["username"] + "\n" + "Rank: " + display_data[
                                                  "pp_rank"] + "\n" + "Accuracy: " + display_data[
                                                  "accuracy"] + "\n" + "PP: " + display_data[
                                                  "pp_raw"] + "\n" + "Country: " + display_data[
                                                  "country"] + "\n" + "Rank in country: " + display_data[
                                                  "pp_country_rank"])
        except:
            await self.pm.client.send_message(message_object.channel, "Error unknown user **" + username + "**")

    async def mania(self, message_object, username):
        try:
            await self.get_badge(message_object.channel, username, 3)
            display_data = await self.get_data(username, 3)
            # Update leaderboard
            await self.pm.client.send_message(message_object.channel,
                                              "Username: " + display_data["username"] + "\n" + "Rank: " + display_data[
                                                  "pp_rank"] + "\n" + "Accuracy: " + display_data[
                                                  "accuracy"] + "\n" + "PP: " + display_data[
                                                  "pp_raw"] + "\n" + "Country: " + display_data[
                                                  "country"] + "\n" + "Rank in country: " + display_data[
                                                  "pp_country_rank"])
        except:
            await self.pm.client.send_message(message_object.channel, "Error unknown user **" + username + "**")

    async def get_badge(self, channel, username, id):
        directory = os.path.join(os.path.dirname(os.path.abspath(__file__)), "temp")
        if not os.path.exists(directory):
            os.makedirs(directory)
        filename = os.path.join(directory, username + "test.jpg")
        image_url = self.base_url.format(id, username)
        urllib.request.urlretrieve(image_url, filename)
        await self.pm.client.send_file(channel, filename)
        os.remove(filename)

    async def get_data(self, username, id):
        api_key = self.api_key
        url = 'https://osu.ppy.sh/api/get_user?m=' + str(id) + '&k=' + api_key + '&u=' + username
        response = requests.get(url, verify=True)
        return response.json()[0]

    async def leaderboard(self, message_object, mode):
        if not os.path.exists("cache/"):
            os.makedirs("cache")
        if mode is "":
            await self.pm.client.send_message(message_object.channel,
                                              "Please specify the gamemode (osu, taiko, ctb, mania)")
            return
        try:
            lb_msg = await self.pm.client.send_message(message_object.channel, "Loading leaderboard...")
            if mode == "osu":
                id = 0
            elif mode == "taiko":
                id = 1
            elif mode == "ctb":
                id = 2
            elif mode == "mania":
                id = 3
            else:
                id = 0
            con = sqlite3.connect("cache/osu_leaderboard.sqlite",
                                  detect_types=sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES)
            with con:
                cur = con.cursor()
                cur.execute("SELECT * FROM users")
                rows = cur.fetchall()
                index = 1
                msg = "Leaderboard for " + mode + ":\n"
                unsorted = list()

                for row in rows:
                    try:
                        data = await self.get_data(row[1], id)
                        if data["pp_rank"] != "0":
                            data["discord_id"] = row[0]
                            data["pp_rank"] = int(data["pp_rank"])
                            unsorted.append(data)
                    except:
                        continue

                sortedusers = sorted(unsorted, key=operator.itemgetter("pp_rank"))
                for data in sortedusers:
                    try:
                        user = await self.pm.client.get_user_info(data["discord_id"])
                        member = discord.utils.find(lambda m: m.name == user.name,
                                                    message_object.channel.server.members)
                        if member is None:
                            await self.delete_osu(data["discord_id"])
                            continue

                        # fetch correct display name
                        if hasattr(user, 'nick') and user.nick != "":
                            name = user.nick
                        else:
                            name = user.name

                        # get an emoji for top 3
                        emoji = ""
                        if index is 1:
                            emoji = ":first_place:"
                        elif index is 2:
                            emoji = ":second_place:"
                        elif index is 3:
                            emoji = ":third_place:"
                        else:
                            emoji = str(index) + "#:"

                        msg += emoji + " " + data["username"] + "  #" + str(data["pp_rank"]) + " (" + str(
                            int(float(data[
                                          "pp_raw"]))) + "pp)" + " (" + name + ") \n"
                        index += 1
                    except:
                        traceback.print_exc()
                await self.pm.client.edit_message(lb_msg, msg)
        except:
            traceback.print_exc()

    async def set_osu(self, message_object, name):
        user_id = message_object.author.id
        if name is not "" and name is not None:
            if not os.path.exists("cache/"):
                os.makedirs("cache")
            try:
                con = sqlite3.connect("cache/osu_leaderboard.sqlite",
                                      detect_types=sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES)
                with con:
                    cur = con.cursor()
                    cur.execute(
                        "CREATE TABLE IF NOT EXISTS users(Id TEXT PRIMARY KEY, Username TEXT)")
                    cur.execute(
                        'INSERT OR IGNORE INTO users(Id, Username) VALUES(?, ?)',
                        (str(user_id), name))

                    cur.execute("UPDATE users SET Username = ? WHERE Id = ?",
                                (name, str(user_id)))

                    await self.pm.client.send_message(message_object.channel,
                                                      message_object.author.mention +
                                                      " your osu! username has been set to **" + name + "**")
            except:
                traceback.print_exc()
        else:
            await self.delete_osu(user_id)

    async def delete_osu(self, id):
        if not os.path.exists("cache/"):
            os.makedirs("cache")
        try:
            con = sqlite3.connect("cache/osu_leaderboard.sqlite",
                                  detect_types=sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES)
            with con:
                cur = con.cursor()
                cur.execute("DELETE FROM users WHERE Id=?", (id,))
        except:
            traceback.print_exc()
<|endoftext|>


<commit_before>"""Holds various Version strings of MPF.

This modules holds the MPF version strings, including the version of BCP it
needs and the config file version it needs.

It's used internally for all sorts of things, from printing the output of the
`mpf --version` command, to making sure any processes connected via BCP are
the proper versions, to automatically triggering new builds and deployments to
PyPI.

"""

__version__ = '0.53.0-dev.35'
'''The full version of MPF.'''

__short_version__ = '0.53'
'''The major.minor version of MPF.'''

__bcp_version__ = '1.1'
'''The version of BCP this build of MPF uses.'''

__config_version__ = '5'
'''The config file version this build of MPF uses.'''

__show_version__ = '5'
'''The show format version this build of MPF uses.'''

version = "MPF v{}".format(__version__)
'''A friendly version string for this build of MPF.'''

extended_version = "MPF v{}, Config version:{}, Show version: {}, " \
                   "BCP version:{}".format(__version__, __config_version__,
                                           __show_version__, __bcp_version__)
'''An extended version string that includes the MPF version, show version,
and BCP versions used in this build of MPF.'''

__api__ = ['version',
           '__short_version__',
           '__bcp_version__',
           '__config_version__',
           '__show_version__',
           'version',
           'extended_version']
<commit_msg>0.53.0-dev.36<commit_after>"""Holds various Version strings of MPF.

This modules holds the MPF version strings, including the version of BCP it
needs and the config file version it needs.

It's used internally for all sorts of things, from printing the output of the
`mpf --version` command, to making sure any processes connected via BCP are
the proper versions, to automatically triggering new builds and deployments to
PyPI.

"""

__version__ = '0.53.0-dev.36'
'''The full version of MPF.'''

__short_version__ = '0.53'
'''The major.minor version of MPF.'''

__bcp_version__ = '1.1'
'''The version of BCP this build of MPF uses.'''

__config_version__ = '5'
'''The config file version this build of MPF uses.'''

__show_version__ = '5'
'''The show format version this build of MPF uses.'''

version = "MPF v{}".format(__version__)
'''A friendly version string for this build of MPF.'''

extended_version = "MPF v{}, Config version:{}, Show version: {}, " \
                   "BCP version:{}".format(__version__, __config_version__,
                                           __show_version__, __bcp_version__)
'''An extended version string that includes the MPF version, show version,
and BCP versions used in this build of MPF.'''

__api__ = ['version',
           '__short_version__',
           '__bcp_version__',
           '__config_version__',
           '__show_version__',
           'version',
           'extended_version']
<|endoftext|>