#!/usr/bin/env python
import math
import numpy as np

def allrots(m):
    """ All rotations of a matrix """
    yield m
    yield np.rot90(m, k=1)
    yield np.rot90(m, k=2)
    yield np.rot90(m, k=3)

def all_rots_and_flips(m):
    """ All flips + rotations of a matrix """
    yield from allrots(m)
    yield from allrots(np.flipud(m))
    yield from allrots(np.fliplr(m))

# Blockshaped / Unblockshaped from StackOverflow
def blockshaped(arr, nrows, ncols):
    """
    Return an array of shape (n, nrows, ncols) where
    n * nrows * ncols = arr.size

    If arr is a 2D array, the returned array looks like n subblocks with
    each subblock preserving the "physical" layout of arr.
    """
    h, w = arr.shape
    return (
        arr.reshape(h // nrows, nrows, -1, ncols)
        .swapaxes(1, 2)
        .reshape(-1, nrows, ncols)
    )

def unblockshaped(arr, h, w):
    """
    Return an array of shape (h, w) where
    h * w = arr.size

    If arr is of shape (n, nrows, ncols), n sublocks of shape (nrows, ncols),
    then the returned array preserves the "physical" layout of the sublocks.
    """
    n, nrows, ncols = arr.shape
    return arr.reshape(h // nrows, -1, nrows, ncols).swapaxes(1, 2).reshape(h, w)

class Grid:
    def __init__(self, filename):
        self.grid = np.array([[0, 1, 0], [0, 0, 1], [1, 1, 1]])
        self.rules = None
        self.load_rules(filename)

    def load_rules(self, filename):
        self.rules = {}
        with open(filename) as file:
            for line in file:
                left, right = line.strip().split(" => ")
                left = self.str_to_matrix(left)
                right = self.str_to_matrix(right)

                for m in all_rots_and_flips(left):
                    self.rules[m.tobytes()] = right

    def str_to_matrix(self, string):
        rows = []
        for row_str in string.split("/"):
            row = np.array([1 if c == "#" else 0 for c in row_str])
            rows.append(row)
        return np.array(rows)

    def step(self):
        size_x, size_y = self.grid.shape
        if size_x != size_y:
            raise ValueError("Non-square grid")
        if size_x % 2 == 0:
            self.step2()
        elif size_x % 3 == 0:
            self.step3()
        else:
            raise ValueError("Don't know what rule to apply")

    def subgrids_to_square(self, subgrids):
        s = int(math.sqrt(subgrids.size))
        return unblockshaped(subgrids, s, s)

    def step2(self):
        # Split into 2x2 subgrids, Check how many made
        subgrids = blockshaped(self.grid, 2, 2)
        (num_sub, _, _) = subgrids.shape

        # Output is same # of 3x3 subgrids
        newgrid = np.zeros((num_sub, 3, 3), dtype=int)
        for i in range(num_sub):
            newgrid[i] = self.rules[subgrids[i].tobytes()]

        # Join together subgrids
        self.grid = self.subgrids_to_square(newgrid)

    def step3(self):
        # Split into 3x3 subgrids, Check how many made
        subgrids = blockshaped(self.grid, 3, 3)
        (num_sub, _, _) = subgrids.shape

        # Output is same # of 4x4 subgrids
        newgrid = np.zeros((num_sub, 4, 4), dtype=int)
        for i in range(num_sub):
            newgrid[i] = self.rules[subgrids[i].tobytes()]

        # Join together subgrids
        self.grid = self.subgrids_to_square(newgrid)

    def num_on(self):
        return self.grid[self.grid == 1].size

if __name__ == "__main__":
    print("Part 1:")
    g = Grid("../input.txt")
    for i in range(5):
        g.step()
    print(g.num_on())

    print("Part 2:")
    g = Grid("../input.txt")
    for i in range(18):
        g.step()
    print(g.num_on())


from sqlalchemy.sql import select
from sqlalchemy import or_, and_, func, desc, case
from pylons import config

import ckan
from ckan.logic import NotFound
from ckan.logic import check_access
from ckan.plugins import (PluginImplementations,
                          IGroupController,
                          IPackageController)
from ckan.authz import Authorizer
from ckan.lib.dictization import table_dictize
from ckan.lib.dictization.model_dictize import (package_dictize,
                                                resource_list_dictize,
                                                group_dictize,
                                                group_list_dictize,
                                                tag_dictize,
                                                user_dictize)

from ckan.lib.dictization.model_dictize import (package_to_api1,
                                                package_to_api2,
                                                group_to_api1,
                                                group_to_api2,
                                                tag_to_api1,
                                                tag_to_api2)
from ckan.lib.search import query_for, SearchError
import logging

log = logging.getLogger('ckan.logic')

def site_read(context,data_dict=None):
    check_access('site_read',context,data_dict)
    return True

def package_list(context, data_dict):
    '''Lists packages by name or id'''

    model = context["model"]
    user = context["user"]
    api = context.get("api_version", '1')
    ref_package_by = 'id' if api == '2' else 'name'

    check_access('package_list', context, data_dict)

    query = model.Session.query(model.PackageRevision)
    query = query.filter(model.PackageRevision.state=='active')
    query = query.filter(model.PackageRevision.current==True)

    packages = query.all()
    return [getattr(p, ref_package_by) for p in packages]

def current_package_list_with_resources(context, data_dict):
    model = context["model"]
    user = context["user"]
    limit = data_dict.get("limit")

    check_access('current_package_list_with_resources', context, data_dict)

    query = model.Session.query(model.PackageRevision)
    query = query.filter(model.PackageRevision.state=='active')
    query = query.filter(model.PackageRevision.current==True)

    query = query.order_by(model.package_revision_table.c.revision_timestamp.desc())
    if limit:
        query = query.limit(limit)
    pack_rev = query.all()
    package_list = []
    for package in pack_rev:
        result_dict = table_dictize(package, context)
        res_rev = model.resource_revision_table
        resource_group = model.resource_group_table
        query = select([res_rev], from_obj = res_rev.join(resource_group,
                   resource_group.c.id == res_rev.c.resource_group_id))
        query = query.where(resource_group.c.package_id == package.id)
        result = query.where(res_rev.c.current == True).execute()
        result_dict["resources"] = resource_list_dictize(result, context)
        license_id = result_dict['license_id']
        if license_id:
            try:
                isopen = model.Package.get_license_register()[license_id].isopen()
                result_dict['isopen'] = isopen
            except KeyError:
                # TODO: create a log message this error?
                result_dict['isopen'] = False
        else:
            result_dict['isopen'] = False
        package_list.append(result_dict)
    return package_list

def revision_list(context, data_dict):

    model = context['model']

    check_access('revision_list', context, data_dict)

    revs = model.Session.query(model.Revision).all()
    return [rev.id for rev in revs]

def package_revision_list(context, data_dict):
    model = context["model"]
    id = data_dict["id"]
    pkg = model.Package.get(id)
    if pkg is None:
        raise NotFound

    check_access('package_revision_list',context, data_dict)

    revision_dicts = []
    for revision, object_revisions in pkg.all_related_revisions:
        revision_dicts.append(model.revision_as_dict(revision,
                                                     include_packages=False,
                                                     include_groups=False))
    return revision_dicts

def group_list(context, data_dict):
    '''Returns a list of groups'''

    model = context['model']
    user = context['user']
    api = context.get('api_version') or '1'
    ref_group_by = 'id' if api == '2' else 'name';
    order_by = data_dict.get('order_by', 'name')
    if order_by not in set(('name', 'packages')):
        raise ValidationError('"order_by" value %r not implemented.' % order_by)
    all_fields = data_dict.get('all_fields',None)

    check_access('group_list',context, data_dict)

    query = model.Session.query(model.Group).join(model.GroupRevision)
    query = query.filter(model.GroupRevision.state=='active')
    query = query.filter(model.GroupRevision.current==True)

    if order_by == 'name':
        query = query.order_by(model.Group.name.asc())
        query = query.order_by(model.Group.title.asc())

    groups = query.all()

    if order_by == 'packages':
        groups = sorted(query.all(),
                        key=lambda g: len(g.packages),
                        reverse=True)

    if not all_fields:
        group_list = [getattr(p, ref_group_by) for p in groups]
    else:
        group_list = group_list_dictize(groups,context)

    return group_list

def group_list_authz(context, data_dict):
    '''
    Returns a list of groups which the user is allowed to edit

    If 'available_only' is specified, the existing groups in the package are
    removed.

    '''
    model = context['model']
    user = context['user']
    available_only = data_dict.get('available_only',False)

    check_access('group_list_authz',context, data_dict)

    from ckan.authz import Authorizer
    query = Authorizer().authorized_query(user, model.Group, model.Action.EDIT)
    groups = set(query.all())

    if available_only:
        package = context.get('package')
        if package:
            groups = groups - set(package.groups)

    return [{'id':group.id,'name':group.name} for group in groups]

def group_revision_list(context, data_dict):
    model = context['model']
    id = data_dict['id']
    group = model.Group.get(id)
    if group is None:
        raise NotFound

    check_access('group_revision_list',context, data_dict)

    revision_dicts = []
    for revision, object_revisions in group.all_related_revisions:
        revision_dicts.append(model.revision_as_dict(revision,
                                                     include_packages=False,
                                                     include_groups=False))
    return revision_dicts

def licence_list(context, data_dict):
    model = context["model"]

    check_access('licence_list',context, data_dict)

    license_register = model.Package.get_license_register()
    licenses = license_register.values()
    licences = [l.as_dict() for l in licenses]
    return licences

def tag_list(context, data_dict):
    '''Returns a list of tags'''

    model = context['model']
    user = context['user']

    all_fields = data_dict.get('all_fields',None)

    check_access('tag_list',context, data_dict)

    q = data_dict.get('q','')
    if q:
        limit = data_dict.get('limit',25)
        offset = data_dict.get('offset',0)
        return_objects = data_dict.get('return_objects',True)

        query = query_for(model.Tag)
        query.run(query=q,
                  limit=limit,
                  offset=offset,
                  return_objects=return_objects,
                  username=user)
        tags = query.results
    else:
        tags = model.Session.query(model.Tag).all()

    tag_list = []
    if all_fields:
        for tag in tags:
            result_dict = tag_dictize(tag, context)
            tag_list.append(result_dict)
    else:
        tag_list = [tag.name for tag in tags]

    return tag_list

def user_list(context, data_dict):
    '''Lists the current users'''
    model = context['model']
    user = context['user']

    check_access('user_list',context, data_dict)

    q = data_dict.get('q','')
    order_by = data_dict.get('order_by','name')

    query = model.Session.query(
        model.User,
        model.User.name.label('name'),
        model.User.fullname.label('fullname'),
        model.User.about.label('about'),
        model.User.about.label('email'),
        model.User.created.label('created'),
        select([func.count(model.Revision.id)], or_(
                model.Revision.author==model.User.name,
                model.Revision.author==model.User.openid
                )
        ).label('number_of_edits'),
        select([func.count(model.UserObjectRole.id)], and_(
            model.UserObjectRole.user_id==model.User.id,
            model.UserObjectRole.context=='Package',
            model.UserObjectRole.role=='admin'
            )
        ).label('number_administered_packages')
    )

    if q:
        query = model.User.search(q, query)

    if order_by == 'edits':
        query = query.order_by(desc(
            select([func.count(model.Revision.id)], or_(
                model.Revision.author==model.User.name,
                model.Revision.author==model.User.openid
                ))
        ))
    else:
        query = query.order_by(
            case([(or_(model.User.fullname == None, model.User.fullname == ''),
                   model.User.name)],
                 else_=model.User.fullname)
        )

    ## hack for pagination
    if context.get('return_query'):
        return query

    users_list = []

    for user in query.all():
        result_dict = user_dictize(user[0], context)
        del result_dict['apikey']
        users_list.append(result_dict)

    return users_list

def package_relationships_list(context, data_dict):

    ##TODO needs to work with dictization layer
    model = context['model']
    user = context['user']
    api = context.get('api_version') or '1'

    id = data_dict["id"]
    id2 = data_dict.get("id2")
    rel = data_dict.get("rel")
    ref_package_by = 'id' if api == '2' else 'name';
    pkg1 = model.Package.get(id)
    pkg2 = None
    if not pkg1:
        raise NotFound('First package named in request was not found.')
    if id2:
        pkg2 = model.Package.get(id2)
        if not pkg2:
            raise NotFound('Second package named in address was not found.')

    if rel == 'relationships':
        rel = None

    check_access('package_relationships_list',context, data_dict)

    # TODO: How to handle this object level authz?
    relationships = Authorizer().\
                    authorized_package_relationships(\
                    user, pkg1, pkg2, rel, model.Action.READ)

    if rel and not relationships:
        raise NotFound('Relationship "%s %s %s" not found.'
                                 % (id, rel, id2))

    relationship_dicts = [rel.as_dict(pkg1, ref_package_by=ref_package_by)
                          for rel in relationships]

    return relationship_dicts

def package_show(context, data_dict):

    model = context['model']
    api = context.get('api_version') or '1'
    id = data_dict['id']

    pkg = model.Package.get(id)

    context['package'] = pkg

    if pkg is None:
        raise NotFound

    check_access('package_show',context, data_dict)

    package_dict = package_dictize(pkg, context)

    for item in PluginImplementations(IPackageController):
        item.read(pkg)

    return package_dict

def revision_show(context, data_dict):
    model = context['model']
    api = context.get('api_version') or '1'
    id = data_dict['id']
    ref_package_by = 'id' if api == '2' else 'name'

    rev = model.Session.query(model.Revision).get(id)
    if rev is None:
        raise NotFound
    rev_dict = model.revision_as_dict(rev, include_packages=True,
                                      ref_package_by=ref_package_by)
    return rev_dict

def group_show(context, data_dict):
    '''Shows group details'''

    model = context['model']
    id = data_dict['id']
    api = context.get('api_version') or '1'

    group = model.Group.get(id)
    context['group'] = group

    if group is None:
        raise NotFound

    check_access('group_show',context, data_dict)

    group_dict = group_dictize(group, context)

    for item in PluginImplementations(IGroupController):
        item.read(group)

    return group_dict

def tag_show(context, data_dict):
    '''Shows tag details'''

    model = context['model']
    api = context.get('api_version') or '1'
    id = data_dict['id']

    tag = model.Tag.get(id)
    context['tag'] = tag

    if tag is None:
        raise NotFound

    check_access('tag_show',context, data_dict)

    tag_dict = tag_dictize(tag,context)
    extended_packages = []
    for package in tag_dict['packages']:
        extended_packages.append(_extend_package_dict(package,context))

    tag_dict['packages'] = extended_packages

    return tag_dict

def user_show(context, data_dict):
    '''Shows user details'''
    model = context['model']
    user = context['user']

    id = data_dict.get('id',None)
    provided_user = data_dict.get('user_obj',None)
    if id:
        user_obj = model.User.get(id)
        context['user_obj'] = user_obj
        if user_obj is None:
            raise NotFound
    elif provided_user:
        context['user_obj'] = user_obj = provided_user
    else:
        raise NotFound

    check_access('user_show',context, data_dict)

    user_dict = user_dictize(user_obj,context)

    if not (Authorizer().is_sysadmin(unicode(user)) or user == user_obj.name):
        # If not sysadmin or the same user, strip sensible info
        del user_dict['apikey']
        del user_dict['reset_key']

    revisions_q = model.Session.query(model.Revision
            ).filter_by(author=user_obj.name)

    revisions_list = []
    for revision in revisions_q.limit(20).all():
        revision_dict = revision_show(context,{'id':revision.id})
        revision_dict['state'] = revision.state
        revisions_list.append(revision_dict)

    user_dict['activity'] = revisions_list

    return user_dict

def package_show_rest(context, data_dict):

    check_access('package_show_rest',context, data_dict)

    package_show(context, data_dict)

    api = context.get('api_version') or '1'
    pkg = context['package']

    if api == '1':
        package_dict = package_to_api1(pkg, context)
    else:
        package_dict = package_to_api2(pkg, context)

    return package_dict

def group_show_rest(context, data_dict):

    check_access('group_show_rest',context, data_dict)

    group_show(context, data_dict)
    api = context.get('api_version') or '1'
    group = context['group']

    if api == '2':
        group_dict = group_to_api2(group, context)
    else:
        group_dict = group_to_api1(group, context)

    return group_dict

def tag_show_rest(context, data_dict):

    check_access('tag_show_rest',context, data_dict)

    tag_show(context, data_dict)
    api = context.get('api_version') or '1'
    tag = context['tag']

    if api == '2':
        tag_dict = tag_to_api2(tag, context)
    else:
        tag_dict = tag_to_api1(tag, context)

    return tag_dict

def package_autocomplete(context, data_dict):
    '''Returns packages containing the provided string'''

    model = context['model']
    session = context['session']
    user = context['user']
    q = data_dict['q']

    like_q = u"%s%%" % q

    check_access('package_autocomplete', context, data_dict)

    query = model.Session.query(model.PackageRevision)
    query = query.filter(model.PackageRevision.state=='active')
    query = query.filter(model.PackageRevision.current==True)
    query = query.filter(or_(model.PackageRevision.name.ilike(like_q),
                                model.PackageRevision.title.ilike(like_q)))
    query = query.limit(10)

    pkg_list = []
    for package in query:
        result_dict = {'name':package.name,'title':package.title}
        pkg_list.append(result_dict)

    return pkg_list

def tag_autocomplete(context, data_dict):
    '''Returns tags containing the provided string'''

    model = context['model']
    session = context['session']
    user = context['user']

    check_access('tag_autocomplete', context, data_dict)

    q = data_dict.get('q', None)
    if not q:
        return []

    limit = data_dict.get('limit',10)

    query = query_for('tag')
    query.run(query=q,
              return_objects=True,
              limit=10,
              username=user)

    return [tag.name for tag in query.results]

def format_autocomplete(context, data_dict):
    '''Returns formats containing the provided string'''
    model = context['model']
    session = context['session']
    user = context['user']

    check_access('format_autocomplete', context, data_dict)

    q = data_dict.get('q', None)
    if not q:
        return []

    limit = data_dict.get('limit', 5)
    like_q = u'%' + q + u'%'

    query = session.query(model.ResourceRevision.format,
        func.count(model.ResourceRevision.format).label('total'))\
        .filter(and_(
            model.ResourceRevision.state == 'active',
            model.ResourceRevision.current == True
        ))\
        .filter(model.ResourceRevision.format.ilike(like_q))\
        .group_by(model.ResourceRevision.format)\
        .order_by('total DESC')\
        .limit(limit)

    return [resource.format for resource in query]

def user_autocomplete(context, data_dict):
    '''Returns users containing the provided string'''
    model = context['model']
    session = context['session']
    user = context['user']
    q = data_dict.get('q',None)
    if not q:
        return []

    check_access('user_autocomplete', context, data_dict)

    limit = data_dict.get('limit',20)

    query = model.User.search(q).limit(limit)

    user_list = []
    for user in query.all():
        result_dict = {}
        for k in ['id', 'name', 'fullname']:
                result_dict[k] = getattr(user,k)

        user_list.append(result_dict)

    return user_list

def package_search(context, data_dict):
    model = context['model']
    session = context['session']
    user = context['user']

    check_access('package_search', context, data_dict)

    # return a list of package ids
    data_dict['fl'] = 'id'

    query = query_for(model.Package)
    query.run(data_dict)

    results = []
    for package in query.results:
        # get the package object
        pkg_query = session.query(model.PackageRevision)\
            .filter(model.PackageRevision.id == package)\
            .filter(and_(
                model.PackageRevision.state == u'active',
                model.PackageRevision.current == True
            ))
        pkg = pkg_query.first()

        ## if the index has got a package that is not in ckan then
        ## ignore it.
        if not pkg:
            log.warning('package %s in index but not in database' % package)
            continue

        result_dict = table_dictize(pkg, context)
        result_dict = _extend_package_dict(result_dict,context)
        results.append(result_dict)

    return {
        'count': query.count,
        'facets': query.facets,
        'results': results
    }

def _extend_package_dict(package_dict,context):
    model = context['model']

    resources = model.Session.query(model.Resource)\
                .join(model.ResourceGroup)\
                .filter(model.ResourceGroup.package_id == package_dict['id'])\
                .all()
    if resources:
        package_dict['resources'] = resource_list_dictize(resources, context)
    else:
        package_dict['resources'] = []
    license_id = package_dict.get('license_id')
    if license_id:
        try:
            isopen = model.Package.get_license_register()[license_id].isopen()
        except KeyError:
            isopen = False
        package_dict['isopen'] = isopen
    else:
        package_dict['isopen'] = False

    return package_dict

def resource_search(context, data_dict):
    model = context['model']
    session = context['session']

    fields = data_dict['fields']
    order_by = data_dict.get('order_by')
    offset = data_dict.get('offset')
    limit = data_dict.get('limit')

    # TODO: should we check for user authentication first?
    q = model.Session.query(model.Resource)
    resource_fields = model.Resource.get_columns()

    for field, terms in fields.items():
        if isinstance(terms, basestring):
            terms = terms.split()
        if field not in resource_fields:
            raise SearchError('Field "%s" not recognised in Resource search.' % field)
        for term in terms:
            model_attr = getattr(model.Resource, field)
            if field == 'hash':
                q = q.filter(model_attr.ilike(unicode(term) + '%'))
            elif field in model.Resource.get_extra_columns():
                model_attr = getattr(model.Resource, 'extras')

                like = or_(
                    model_attr.ilike(u'''%%"%s": "%%%s%%",%%''' % (field, term)),
                    model_attr.ilike(u'''%%"%s": "%%%s%%"}''' % (field, term))
                )
                q = q.filter(like)
            else:
                q = q.filter(model_attr.ilike('%' + unicode(term) + '%'))

    if order_by is not None:
        if hasattr(model.Resource, order_by):
            q = q.order_by(getattr(model.Resource, order_by))

    count = q.count()
    q = q.offset(offset)
    q = q.limit(limit)

    results = []
    for result in q:
        if isinstance(result, tuple) and isinstance(result[0], model.DomainObject):
            # This is the case for order_by rank due to the add_column.
            results.append(result[0])
        else:
            results.append(result)

    return {'count': count, 'results': results}

def tag_search(context, data_dict):
    model = context['model']
    session = context['session']

    query = data_dict.get('query')
    terms = [query] if query else []

    fields = data_dict.get('fields', {})
    offset = data_dict.get('offset')
    limit = data_dict.get('limit')

    # TODO: should we check for user authentication first?
    q = model.Session.query(model.Tag)
    q = q.distinct().join(model.Tag.package_tags)
    for field, value in fields.items():
        if field in ('tag', 'tags'):
            terms.append(value)

    if not len(terms):
        return

    for term in terms:
        q = q.filter(model.Tag.name.contains(term.lower()))

    count = q.count()
    q = q.offset(offset)
    q = q.limit(limit)
    results = [r for r in q]
    return {'count': count, 'results': results}

def status_show(context, data_dict):
    '''Provides information about the operation of this CKAN instance.'''
    return {
        'site_title': config.get('ckan.site_title'),
        'site_description': config.get('ckan.site_description'),
        'site_url': config.get('ckan.site_url'),
        'ckan_version': ckan.__version__,
        'error_emails_to': config.get('email_to'),
        'locale_default': config.get('ckan.locale_default'),
        }


#!/usr/bin/python
# -*- coding: UTF8 -*-
import unittest
import mock

import sys
import os
local = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.join(local, "..", ".."))
from ocr.setup import is_installed, create_tables, create_database, new_ong_dir
from ocr.config import ONG_FOLDER, BD_NAME

class TestSetup(unittest.TestCase):
    @mock.patch("os.path")
    def test_is_installed(self, mock_path):
        mock_path.abspath.return_value = "ocr/setup.py"
        mock_path.dirname.return_value = "ocr"
        mock_path.join.return_value = "ocr/" + ONG_FOLDER
        is_installed()
        mock_path.dirname.assert_called_with("ocr/setup.py")
        mock_path.join.assert_called_with("ocr", ONG_FOLDER)
        mock_path.isdir.assert_called_with("ocr/" + ONG_FOLDER)
        mock_path.isdir.return_value = True
        self.assertTrue(is_installed())
        mock_path.isdir.return_value = False
        self.assertFalse(is_installed())

    @mock.patch("ocr.setup.engine")
    @mock.patch("ocr.setup.Base")
    def test_create_tables(self, mock_base, mock_engine):
        create_tables()
        mock_engine.execute.assert_called_with("USE `%s`" % BD_NAME)
        mock_base.metadata.create_all.assert_called_with(mock_engine)

    @mock.patch("ocr.setup.engine")
    def test_create_database(self, mock_engine):
        create_database()
        mock_engine.execute.assert_called_with('CREATE DATABASE IF NOT EXISTS `%s`' % BD_NAME)

    @mock.patch("os.path")
    @mock.patch("os.mkdir")
    def test_new_ong_dir(self, mock_mkdir, mock_path):
        mock_path.abspath.return_value = "ocr/setup.py"
        mock_path.dirname.return_value = "ocr"
        mock_path.join.return_value = "ocr/" + ONG_FOLDER
        new_ong_dir()
        mock_path.dirname.assert_called_with("ocr/setup.py")
        mock_path.join.assert_called_with("ocr", ONG_FOLDER)
        mock_mkdir.assert_called_with("ocr/" + ONG_FOLDER)

if __name__ == '__main__':
    unittest.main(buffer=True)


# -*- coding: utf-8 -*-
# 39. Zipfの法則
# 単語の出現頻度順位を横軸，その出現頻度を縦軸として，両対数グラフをプロットせよ．
from chapter4 import read_mecab
import numpy as np
import matplotlib.pyplot as plt
filename = "neco.txt.mecab"

def frequency():
    mors = read_mecab(filename)
    mors_dic = {}
    for mor in mors:
        if mor["pos"] == "記号":
            continue
        mors_dic[mor["surface"]] = mors_dic.get(mor["surface"], 0) + 1

    #sort
    return sorted(map(lambda t:(t[0], t[1]/float(len(mors_dic))), mors_dic.items()), key=lambda i:i[1], reverse=True)

def main():
    freqs = frequency()
    x, y = range(1, len(freqs)+1), map(lambda t:t[1], freqs)

    plt.plot(x, y, "ro")
    plt.xscale("log")
    plt.yscale("log")
    # plt.tight_layout()
    plt.show()

if __name__ == '__main__':
    main()


from qtpy import QtCore, QtGui
from qtpy.QtWidgets import (
    QDialog, QApplication, QLabel, QLineEdit, QPushButton,
    QComboBox, QCheckBox, QHBoxLayout, QVBoxLayout, QGridLayout)
from pyNastran.gui.menus.menu_utils import eval_float_from_string
from pyNastran.gui.utils.qt.pydialog import QFloatEdit
from pyNastran.gui.utils.qt.checks.qlineedit import check_float
from pyNastran.utils.locale import func_str

class BCMap(QDialog):
    def __init__(self, data, win_parent=None):
        """
        +--------+
        | BC Map |
        +--------+---------------+
        |  Origin                |
        |     X       Y      Z   |
        |                        |
        |  Normal                |
        |    NX      NY     NZ   |
        |                        |
        |  Apply Normal          |
        |    NX      NY     NZ   |
        |                        |
        |    Apply   OK  Cancel  |
        +--------+---------------+
        """
        QDialog.__init__(self, win_parent)

        self._default_name = 'Plane'
        self.out_data = data
        self._axis = '?'
        self._plane = '?'

        ox_value, oy_value, oz_value = self.out_data['origin']
        nx_value, ny_value, nz_value = self.out_data['normal']
        ax_value, ay_value, az_value = self.out_data['a']
        bx_value, by_value, bz_value = self.out_data['b']

        self._origin_x_default = ox_value
        self._origin_y_default = oy_value
        self._origin_z_default = oz_value

        self._normal_x_default = nx_value
        self._normal_y_default = ny_value
        self._normal_z_default = nz_value

        self._ax_default = ax_value
        self._ay_default = ay_value
        self._az_default = az_value

        self._bx_default = bx_value
        self._by_default = by_value
        self._bz_default = bz_value

        self._default_is_apply = True

        self.name = QLabel("Title:")
        self.name_edit = QLineEdit(str(self._default_name))
        self.name_button = QPushButton("Default")

        self.axis = QLabel("Point on ? Axis:")
        self.combo_axis = QComboBox(self)
        self.combo_axis.addItem("X")
        self.combo_axis.addItem("Y")
        self.combo_axis.addItem("Z")

        self.plane = QLabel("Point on %s? Plane:" % self._axis)
        self.combo_plane = QComboBox(self)
        self.combo_plane.addItem("X")
        self.combo_plane.addItem("Y")
        self.combo_plane.addItem("Z")

        self.origin = QLabel("Origin:")
        self.origin_x_edit = QFloatEdit(func_str(self._origin_x_default))
        self.origin_y_edit = QFloatEdit(func_str(self._origin_y_default))
        self.origin_z_edit = QFloatEdit(func_str(self._origin_z_default))
        self.origin_default_button = QPushButton("Default")
        #self.name_button = QPushButton("Default")

        self.normal = QLabel("Normal:")
        self.normal_x_edit = QFloatEdit(func_str(self._normal_x_default))
        self.normal_y_edit = QFloatEdit(func_str(self._normal_y_default))
        self.normal_z_edit = QFloatEdit(func_str(self._normal_z_default))
        self.normal_default_button = QPushButton("Default")

        self.snap = QLabel("Snap Normal:")
        self.snap_normal_xy_button = QPushButton("XY Plane")
        self.snap_normal_yz_button = QPushButton("YZ Plane")
        self.snap_normal_xz_button = QPushButton("XZ Plane")

        self.point_a = QLabel("Point on %s Axis:" % self._axis)
        self.ax_edit = QFloatEdit(func_str(self._ax_default))
        self.ay_edit = QFloatEdit(func_str(self._ay_default))
        self.az_edit = QFloatEdit(func_str(self._az_default))

        self.point_b = QLabel("Point on %s%s Plane:" % (self._axis, self._plane))
        self.bx_edit = QFloatEdit(func_str(self._bx_default))
        self.by_edit = QFloatEdit(func_str(self._by_default))
        self.bz_edit = QFloatEdit(func_str(self._bz_default))

        self.check_apply = QCheckBox("Automatically apply results")
        self.check_apply.setChecked(self._default_is_apply)

        # closing
        self.apply_button = QPushButton("Apply")
        if self._default_is_apply:
            self.apply_button.setDisabled(True)

        self.ok_button = QPushButton("OK")
        self.cancel_button = QPushButton("Cancel")
        self.create_layout()
        self.set_connections()

    def create_layout(self):
        ok_cancel_box = QHBoxLayout()
        ok_cancel_box.addWidget(self.apply_button)
        ok_cancel_box.addWidget(self.ok_button)
        ok_cancel_box.addWidget(self.cancel_button)

        # x axis; yplane
        # x axis; zplane
        mode = 2

        grid = QGridLayout()

        irow = 0
        grid.addWidget(self.axis, irow, 0)
        grid.addWidget(self.combo_axis, irow, 1)
        irow += 1

        grid.addWidget(self.plane, irow, 0)
        grid.addWidget(self.combo_plane, irow, 1)
        irow += 1

        grid.addWidget(self.origin, irow, 0)
        grid.addWidget(self.origin_x_edit, irow, 1)
        grid.addWidget(self.origin_y_edit, irow, 2)
        grid.addWidget(self.origin_z_edit, irow, 3)
        grid.addWidget(self.origin_default_button, irow, 4)
        irow += 1

        grid.addWidget(self.normal, irow, 0)
        grid.addWidget(self.normal_x_edit, irow, 1)
        grid.addWidget(self.normal_y_edit, irow, 2)
        grid.addWidget(self.normal_z_edit, irow, 3)
        grid.addWidget(self.normal_default_button, irow, 4)
        irow += 1

        grid.addWidget(self.snap, irow, 0)
        grid.addWidget(self.snap_normal_xy_button, irow, 1)
        grid.addWidget(self.snap_normal_yz_button, irow, 2)
        grid.addWidget(self.snap_normal_xz_button, irow, 3)
        irow += 1

        grid.addWidget(self.point_a, irow, 0)
        grid.addWidget(self.ax_edit, irow, 1)
        grid.addWidget(self.ay_edit, irow, 2)
        grid.addWidget(self.az_edit, irow, 3)
        irow += 1

        grid.addWidget(self.point_b, irow, 0)
        grid.addWidget(self.bx_edit, irow, 1)
        grid.addWidget(self.by_edit, irow, 2)
        grid.addWidget(self.bz_edit, irow, 3)
        irow += 1

        vbox = QVBoxLayout()
        vbox.addWidget(self.name)

        vbox.addLayout(grid)
        vbox.addStretch()
        vbox.addWidget(self.check_apply)
        vbox.addLayout(ok_cancel_box)

        #Create central widget, add layout and set
        #central_widget = QtGui.QWidget()
        #central_widget.setLayout(vbox)
        #self.setCentralWidget(central_widget)
        self.setLayout(vbox)

    def set_connections(self):
        """creates the actions for the menu"""
        self.name_button.clicked.connect(self.on_default_name)
        #combo.activated[str].connect(self.onActivated)
        self.combo_axis.activated[str].connect(self.on_axis)
        self.combo_plane.activated[str].connect(self.on_plane)
        #self.combo_axis.connect(self.on_axis)
        #self.combo_plane.connect(self.on_plane)

        self.origin_default_button.clicked.connect(self.on_default_origin)
        self.normal_default_button.clicked.connect(self.on_default_normal)

        self.origin_x_edit.textChanged.connect(self.on_origin_x)  # was edited...
        self.origin_y_edit.textChanged.connect(self.on_origin_y)  # was edited...
        self.origin_z_edit.textChanged.connect(self.on_origin_z)  # was edited...

        self.snap_normal_xy_button.clicked.connect(self.on_snap_xy)
        self.snap_normal_yz_button.clicked.connect(self.on_snap_yz)
        self.snap_normal_xz_button.clicked.connect(self.on_snap_xz)

        self.check_apply.clicked.connect(self.on_check_apply)

        self.apply_button.clicked.connect(self.on_apply)
        self.ok_button.clicked.connect(self.on_ok)
        self.cancel_button.clicked.connect(self.on_cancel)

    def on_axis(self, text):
        #print(self.combo_axis.itemText())
        self._axis = str(text)
        self.plane.setText('Point on %s? Plane:' % self._axis)
        self.point_a.setText('Point on %s Axis:' % self._axis)
        self.point_b.setText('Point on %s%s Plane:' % (self._axis, self._plane))

    def on_plane(self, text):
        self._plane = str(text)
        self.point_b.setText('Point on %s%s Plane:' % (self._axis, self._plane))

    def on_check_apply(self):
        is_checked = self.check_apply.isChecked()
        self.apply_button.setDisabled(is_checked)

    def on_snap_xy(self):
        self.normal_x_edit.setText(func_str(0.0))
        self.normal_y_edit.setText(func_str(0.0))
        self.normal_z_edit.setText(func_str(1.0))

    def on_snap_yz(self):
        self.normal_x_edit.setText(func_str(1.0))
        self.normal_y_edit.setText(func_str(0.0))
        self.normal_z_edit.setText(func_str(0.0))

    def on_snap_xz(self):
        self.normal_x_edit.setText(func_str(0.0))
        self.normal_y_edit.setText(func_str(1.0))
        self.normal_z_edit.setText(func_str(0.0))

    def on_origin_x(self):
        _on_float(self.origin_x_edit)

    def on_origin_y(self):
        _on_float(self.origin_y_edit)

    def on_origin_z(self):
        _on_float(self.origin_z_edit)

    def on_normal_x(self):
        _on_float(self.normal_x_edit)

    def on_normal_y(self):
        _on_float(self.normal_y_edit)

    def on_normal_z(self):
        _on_float(self.normal_z_edit)

    def closeEvent(self, event):
        event.accept()

    def on_default_name(self):
        self.name_edit.setText(str(self._default_name))
        self.name_edit.setStyleSheet("QLineEdit{background: white;}")

    def on_default_origin(self):
        self.origin_x_edit.setText(str(self._origin_x_default))
        self.origin_y_edit.setText(str(self._origin_y_default))
        self.origin_z_edit.setText(str(self._origin_z_default))
        self.origin_x_edit.setStyleSheet("QLineEdit{background: white;}")
        self.origin_y_edit.setStyleSheet("QLineEdit{background: white;}")
        self.origin_z_edit.setStyleSheet("QLineEdit{background: white;}")

    def on_default_normal(self):
        self.normal_x_edit.setText(str(self._normal_x_default))
        self.normal_y_edit.setText(str(self._normal_y_default))
        self.normal_z_edit.setText(str(self._normal_z_default))
        self.normal_x_edit.setStyleSheet("QLineEdit{background: white;}")
        self.normal_y_edit.setStyleSheet("QLineEdit{background: white;}")
        self.normal_z_edit.setStyleSheet("QLineEdit{background: white;}")

    def check_name(self, cell):
        text = str(cell.text()).strip()
        if text:
            cell.setStyleSheet("QLineEdit{background: white;}")
            return text, True
        else:
            cell.setStyleSheet("QLineEdit{background: red;}")
            return None, False

    def on_validate(self):
        name_value, flag0 = self.check_name(self.name_edit)
        ox_value, flag1 = check_float(self.origin_x_edit)
        oy_value, flag2 = check_float(self.origin_y_edit)
        oz_value, flag3 = check_float(self.origin_z_edit)

        nx_value, flag4 = check_float(self.normal_x_edit)
        ny_value, flag5 = check_float(self.normal_y_edit)
        nz_value, flag6 = check_float(self.normal_z_edit)

        if flag0 and flag1 and flag2 and flag3 and flag4 and flag5 and flag6:
            self.out_data['origin'] = [ox_value, oy_value, oz_value]
            self.out_data['normal'] = [nx_value, ny_value, nz_value]
            self.out_data['clicked_ok'] = True

            return True
        return False

    def on_apply(self):
        passed = self.on_validate()
        if passed:
            self.win_parent.create_plane(self.out_data)
        return passed

    def on_ok(self):
        passed = self.on_apply()
        if passed:
            self.close()
            #self.destroy()

    def on_cancel(self):
        self.close()

def _on_float(field):
    try:
        eval_float_from_string(field.text())
        field.setStyleSheet("QLineEdit{background: white;}")
    except ValueError:
        field.setStyleSheet("QLineEdit{background: red;}")

def main():  # pragma: no cover
    # kills the program when you hit Cntl+C from the command line
    # doesn't save the current state as presumably there's been an error
    import signal
    signal.signal(signal.SIGINT, signal.SIG_DFL)

    import sys
    # Someone is launching this directly
    # Create the QApplication
    app = QApplication(sys.argv)
    #The Main window
    d = {
        'name' : 'plane_test',
        'origin': [1., 2., 3.],
        'normal' : [4., 5., 6.],
        'a' : [7., 8., 9.],
        'b' : [10., 11., 12.],
        'is_horizontal' : False,
    }
    main_window = BCMap(d, win_parent=None)
    main_window.show()
    # Enter the main loop
    app.exec_()

if __name__ == "__main__":  # pragma: no cover
    main()


import os

from django.conf import settings
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType
from django.contrib.postgres.fields import ArrayField
from django.core.files import File
from django.db import models
from django.db.models.signals import post_delete
from django.utils.timezone import now
from mptt.models import MPTTModel, TreeForeignKey

from bridge.vars import COMPARE_VERDICT, REPORT_ARCHIVE
from bridge.utils import WithFilesMixin, remove_instance_files

from users.models import User
from jobs.models import Job
from service.models import Decision

MAX_COMPONENT_LEN = 20
ORIGINAL_SOURCES_DIR = 'OriginalSources'
COVERAGE_STAT_COLOR = ['#f18fa6', '#f1c0b2', '#f9e19b', '#e4f495', '#acf1a8']

def get_component_path(instance, filename):
    curr_date = now()
    return os.path.join('Reports', instance.component, str(curr_date.year), str(curr_date.month), filename)

def get_coverage_arch_dir(instance, filename):
    curr_date = now()
    return os.path.join('Reports', instance.report.component, str(curr_date.year), str(curr_date.month), filename)

def get_images_path(instance, filename):
    curr_date = now()
    return os.path.join(
        'Reports', instance.report.component, str(curr_date.year), str(curr_date.month), 'Images', filename
    )

def get_coverage_dir(instance, filename):
    return os.path.join('Reports', 'CoverageCache', 'CovArch-%s' % instance.archive_id, filename)

def get_attr_data_path(instance, filename):
    return os.path.join('Reports', 'AttrData', 'Decision-%s' % str(instance.decision_id), filename)

def source_code_path(instance, filename):
    assert isinstance(filename, str)
    curr_date = now()
    return os.path.join(
        'SourceCode', str(curr_date.year), str(curr_date.month), str(curr_date.day),
        'src-{}.html'.format(instance.identifier[:16])
    )

class AttrBase(models.Model):
    name = models.CharField(max_length=64, db_index=True)
    value = models.CharField(max_length=255)

    class Meta:
        abstract = True

class Report(MPTTModel):
    decision = models.ForeignKey(Decision, models.CASCADE)
    parent = TreeForeignKey('self', models.CASCADE, null=True, related_name='children')
    identifier = models.CharField(max_length=255, db_index=True)
    cpu_time = models.BigIntegerField(null=True)
    wall_time = models.BigIntegerField(null=True)
    memory = models.BigIntegerField(null=True)

    def __str__(self):
        return self.identifier

    class Meta:
        db_table = 'report'
        unique_together = [('decision', 'identifier')]
        index_together = [('decision', 'identifier')]

class AttrFile(WithFilesMixin, models.Model):
    decision = models.ForeignKey(Decision, models.CASCADE)
    file = models.FileField(upload_to=get_attr_data_path)

    class Meta:
        db_table = 'report_attr_file'

class ReportAttr(AttrBase):
    report = models.ForeignKey(Report, models.CASCADE, related_name='attrs')
    compare = models.BooleanField(default=False)
    associate = models.BooleanField(default=False)
    data = models.ForeignKey(AttrFile, models.CASCADE, null=True)

    class Meta:
        db_table = 'report_attrs'
        indexes = [models.Index(fields=['name', 'value'])]

class Computer(models.Model):
    identifier = models.CharField(max_length=128, db_index=True)
    display = models.CharField(max_length=512)
    data = models.JSONField()

    class Meta:
        db_table = 'computer'

class OriginalSources(WithFilesMixin, models.Model):
    identifier = models.CharField(max_length=128, unique=True, db_index=True)
    archive = models.FileField(upload_to=ORIGINAL_SOURCES_DIR)

    def add_archive(self, fp, save=False):
        self.archive.save(REPORT_ARCHIVE['original_sources'], File(fp), save)
        if not os.path.isfile(os.path.join(settings.MEDIA_ROOT, self.archive.name)):
            raise RuntimeError('OriginalSources.archive was not saved')

    class Meta:
        db_table = 'report_original_sources'
        ordering = ('identifier',)

class AdditionalSources(WithFilesMixin, models.Model):
    decision = models.ForeignKey(Decision, models.CASCADE)
    archive = models.FileField(upload_to='Sources/%Y/%m')

    def add_archive(self, fp, save=False):
        self.archive.save(REPORT_ARCHIVE['additional_sources'], File(fp), save)
        if not os.path.isfile(os.path.join(settings.MEDIA_ROOT, self.archive.name)):
            raise RuntimeError('AdditionalSources.archive was not saved')

    class Meta:
        db_table = 'report_additional_sources'

class ReportComponent(WithFilesMixin, Report):
    computer = models.ForeignKey(Computer, models.CASCADE)
    component = models.CharField(max_length=MAX_COMPONENT_LEN)
    verification = models.BooleanField(default=False)

    start_date = models.DateTimeField(default=now)
    finish_date = models.DateTimeField(null=True)

    data = models.JSONField(null=True, default=list)
    log = models.FileField(upload_to=get_component_path, null=True)
    verifier_files = models.FileField(upload_to=get_component_path, null=True)

    # Sources for Verification reports
    original_sources = models.ForeignKey(OriginalSources, models.PROTECT, null=True)
    additional_sources = models.ForeignKey(AdditionalSources, models.CASCADE, null=True)

    def add_log(self, fp, save=False):
        self.log.save(REPORT_ARCHIVE['log'], File(fp), save)
        if not os.path.isfile(os.path.join(settings.MEDIA_ROOT, self.log.name)):
            raise RuntimeError('ReportComponent.log was not saved')

    def add_verifier_files(self, fp, save=False):
        self.verifier_files.save(REPORT_ARCHIVE['verifier_files'], File(fp), save)
        if not os.path.isfile(os.path.join(settings.MEDIA_ROOT, self.verifier_files.name)):
            raise RuntimeError('ReportComponent.verifier_files was not saved')

    class Meta:
        db_table = 'report_component'

class ReportComponentLeaf(models.Model):
    report = models.ForeignKey(ReportComponent, models.CASCADE, related_name='leaves')
    content_type = models.ForeignKey(ContentType, models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')

    class Meta:
        db_table = 'cache_report_component_leaf'

class CoverageArchive(WithFilesMixin, models.Model):
    report = models.ForeignKey(ReportComponent, models.CASCADE, related_name='coverages')
    name = models.CharField(max_length=128, default='-')
    identifier = models.CharField(max_length=128, default='')
    archive = models.FileField(upload_to=get_coverage_arch_dir)
    total = models.JSONField(null=True)
    has_extra = models.BooleanField(default=False)

    def add_coverage(self, fp, save=False):
        self.archive.save(REPORT_ARCHIVE['coverage'], File(fp), save=save)

    class Meta:
        db_table = 'report_coverage_archive'

class CoverageStatistics(models.Model):
    coverage = models.ForeignKey(CoverageArchive, models.CASCADE)
    identifier = models.PositiveIntegerField()
    parent = models.PositiveIntegerField(null=True)
    is_leaf = models.BooleanField()
    name = models.CharField(max_length=128)
    path = models.TextField(null=True)
    depth = models.PositiveIntegerField(default=0)

    lines_covered = models.PositiveIntegerField(default=0)
    lines_total = models.PositiveIntegerField(default=0)
    funcs_covered = models.PositiveIntegerField(default=0)
    funcs_total = models.PositiveIntegerField(default=0)

    lines_covered_extra = models.PositiveIntegerField(default=0)
    lines_total_extra = models.PositiveIntegerField(default=0)
    funcs_covered_extra = models.PositiveIntegerField(default=0)
    funcs_total_extra = models.PositiveIntegerField(default=0)

    def calculate_color(self, div):
        color_id = int(div * len(COVERAGE_STAT_COLOR))
        if color_id >= len(COVERAGE_STAT_COLOR):
            color_id = len(COVERAGE_STAT_COLOR) - 1
        elif color_id < 0:
            color_id = 0
        return COVERAGE_STAT_COLOR[color_id]

    @property
    def lines_percentage(self):
        if not self.lines_total:
            return '-'
        return '{}%'.format(round(100 * self.lines_covered / self.lines_total))

    @property
    def funcs_percentage(self):
        if not self.funcs_total:
            return '-'
        return '{}%'.format(round(100 * self.funcs_covered / self.funcs_total))

    @property
    def lines_color(self):
        if not self.lines_total:
            return None
        return self.calculate_color(self.lines_covered / self.lines_total)

    @property
    def funcs_color(self):
        if not self.funcs_total:
            return None
        return self.calculate_color(self.funcs_covered / self.funcs_total)

    @property
    def lines_percentage_extra(self):
        if not self.lines_total_extra:
            return '-'
        return '{}%'.format(round(100 * self.lines_covered_extra / self.lines_total_extra))

    @property
    def funcs_percentage_extra(self):
        if not self.funcs_total_extra:
            return '-'
        return '{}%'.format(round(100 * self.funcs_covered_extra / self.funcs_total_extra))

    @property
    def lines_color_extra(self):
        if not self.lines_total_extra:
            return None
        return self.calculate_color(self.lines_covered_extra / self.lines_total_extra)

    @property
    def funcs_color_extra(self):
        if not self.funcs_total_extra:
            return None
        return self.calculate_color(self.funcs_covered_extra / self.funcs_total_extra)

    @property
    def indentation(self):
        return '    ' * (self.depth - 1)

    @property
    def shown(self):
        if not hasattr(self, '_shown'):
            setattr(self, '_shown', False)
        return getattr(self, '_shown')

    @shown.setter
    def shown(self, value):
        setattr(self, '_shown', bool(value))

    class Meta:
        db_table = 'report_coverage_statistics'

class CoverageDataStatistics(models.Model):
    coverage = models.ForeignKey(CoverageArchive, models.CASCADE)
    name = models.CharField(max_length=255)
    data = models.JSONField()

    class Meta:
        db_table = 'report_coverage_data_statistics'

class ReportUnsafe(WithFilesMixin, Report):
    error_trace = models.FileField(upload_to='Unsafes/%Y/%m')
    leaves = GenericRelation(ReportComponentLeaf, related_query_name='unsafes')

    def add_trace(self, fp, save=False):
        self.error_trace.save(REPORT_ARCHIVE['error_trace'], File(fp), save)
        if not os.path.isfile(os.path.join(settings.MEDIA_ROOT, self.error_trace.name)):
            raise RuntimeError('ReportUnsafe.error_trace was not saved')

    class Meta:
        db_table = 'report_unsafe'

class ReportSafe(Report):
    leaves = GenericRelation(ReportComponentLeaf, related_query_name='safes')

    class Meta:
        db_table = 'report_safe'

class ReportUnknown(WithFilesMixin, Report):
    component = models.CharField(max_length=MAX_COMPONENT_LEN)
    problem_description = models.FileField(upload_to='Unknowns/%Y/%m')
    leaves = GenericRelation(ReportComponentLeaf, related_query_name='unknowns')

    def add_problem_desc(self, fp, save=False):
        self.problem_description.save(REPORT_ARCHIVE['problem_description'], File(fp), save)
        if not os.path.isfile(os.path.join(settings.MEDIA_ROOT, self.problem_description.name)):
            raise RuntimeError('ReportUnknown.problem_description was not saved')

    class Meta:
        db_table = 'report_unknown'

class CompareDecisionsInfo(models.Model):
    user = models.ForeignKey(User, models.CASCADE)
    decision1 = models.ForeignKey(Decision, models.CASCADE, related_name='+')
    decision2 = models.ForeignKey(Decision, models.CASCADE, related_name='+')
    names = ArrayField(models.CharField(max_length=64))

    class Meta:
        db_table = 'cache_report_decisions_compare_info'

class ComparisonObject(models.Model):
    info = models.ForeignKey(CompareDecisionsInfo, models.CASCADE)
    values = ArrayField(models.CharField(max_length=255))
    verdict1 = models.CharField(max_length=1, choices=COMPARE_VERDICT)
    verdict2 = models.CharField(max_length=1, choices=COMPARE_VERDICT)

    class Meta:
        db_table = 'cache_report_comparison_object'
        index_together = ["info", "verdict1", "verdict2"]

class ComparisonLink(models.Model):
    comparison = models.ForeignKey(ComparisonObject, models.CASCADE, related_name='links')
    content_type = models.ForeignKey(ContentType, models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')

    class Meta:
        db_table = 'cache_report_comparison_link'

class DecisionCache(models.Model):
    decision = models.ForeignKey(Decision, models.CASCADE)
    component = models.CharField(max_length=MAX_COMPONENT_LEN)
    cpu_time = models.BigIntegerField(default=0)
    wall_time = models.BigIntegerField(default=0)
    memory = models.BigIntegerField(default=0)

    total = models.IntegerField(default=0)
    finished = models.IntegerField(default=0)

    class Meta:
        db_table = 'cache_decision_data'
        index_together = ['component', 'decision']

class SourceCodeCache(WithFilesMixin, models.Model):
    identifier = models.CharField(max_length=256, db_index=True)
    file = models.FileField(upload_to=source_code_path)
    access_date = models.DateTimeField(auto_now=True)

    class Meta:
        db_table = 'cache_source_code'

class ReportImage(WithFilesMixin, models.Model):
    report = models.ForeignKey(ReportComponent, models.CASCADE, related_name='images')
    title = models.TextField()
    image = models.FileField(upload_to=get_images_path)
    data = models.FileField(upload_to=get_images_path)

    class Meta:
        db_table = 'report_component_images'

    def __lt__(self, other):
        return self.title < other.title

post_delete.connect(remove_instance_files, sender=AttrFile)
post_delete.connect(remove_instance_files, sender=OriginalSources)
post_delete.connect(remove_instance_files, sender=AdditionalSources)
post_delete.connect(remove_instance_files, sender=ReportComponent)
post_delete.connect(remove_instance_files, sender=ReportUnsafe)
post_delete.connect(remove_instance_files, sender=ReportUnknown)
post_delete.connect(remove_instance_files, sender=CoverageArchive)
post_delete.connect(remove_instance_files, sender=SourceCodeCache)
post_delete.connect(remove_instance_files, sender=ReportImage)


from time import sleep
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options

chrome_options = Options()
chrome_options.add_experimental_option("detach", True)

service = Service("./chromedriver.exe")
driver = webdriver.Chrome(service=service, chrome_options=chrome_options)

def visit_apple_homepage():
  url = "http://www.apple.com"
  driver.maximize_window()

  driver.get(url)

  link = driver.current_url
  title = driver.title

  print("your page title is: ", title)

  if "apple.com" in link:
    print("You are on ", link)
    driver.save_screenshot("./screenshots/apple.png")
  driver.quit()

def visit_etsy_homepage():
  url = "http://www.etsy.com"
  driver.maximize_window()

  driver.get(url)

  link = driver.current_url
  title = driver.title

  print("Your page title is: ", title)

  if "etsy" in link:
    print("You are on ", link)
    driver.save_screenshot("./screenshots/true_link_for_etsy.png")
  else:
    print("Wrong parameter. Parameter should be ", link)
    driver.save_screenshot("./screenshots/wrong_link_for_etsy.png")

  driver.quit()

visit_apple_homepage()
visit_etsy_homepage()


from django.conf.urls import url

from . import views
from views import mainPage, mapControl, experimentData, manageExperiment, manageReports, manageErrors

urlpatterns = [
    # main pages
    url(r'^$', mainPage.index, name='index'),
    url(r'edycja-mapy/$', mainPage.editMapPage, name='editMapPage'),
    url(r'badanie/$', mainPage.newExperimentPage, name='newExperimentPage'),
    url(r'badania/$', mainPage.experimentsPage, name='experimentsPage'),
    url(r'pytania-i-akcje/$', mainPage.questionsAndActionsPage, name='questionsAndActionsPage'),
    url(r'android/$', mainPage.androidApp, name='androidApp'),

    # # map control
    url(r'uploadImage/$', mapControl.uploadImage, name='uploadImage'),
    url(r'removeFloor/$', mapControl.removeFloor, name='removeFloor'),
    url(r'updateExhibitPosition/$', mapControl.updateExhibitPosition, name='updateExhibitPosition'),
    url(r'exhibit/$', mapControl.exhibit, name='exhibit'),
    #
    # # experiment data
    url(r'question/$', experimentData.question, name='question'),
    url(r'action/$', experimentData.action, name='action'),
    #
    #
    #experiment
    url(r'experiment/$', manageExperiment.experiment, name='experiment'),
    url(r'activeExperiment/$', manageExperiment.activeExperiment, name='activeExperiment'),
    url(r'cloneExperiment/$', manageExperiment.cloneExperiment, name='cloneExperiment'),
    url(r'removeExperiment/$', manageExperiment.removeExperiment, name='removeExperiment'),

    #reports
    url(r'getReport/$', manageReports.getReport, name='getReport'),
    url(r'getAllReports/$', manageReports.getAllReports, name='getAllReports'),

    #errors_reporting
    url(r'errorReporting/$', manageErrors.reportError, name='reportError'),
]


escolha = int(input('Deseja verificar uma P.A.? \n[1] - SIM \n[0] - NÃO \n'))
while escolha != 0:
    if escolha == 1:
        a1 = int(input('Digite o primeiro termo da P.A.: '))
        r = int(input('Digite qual vai ser a razão dessa P.A.: '))
        n = int(input('Digite até qual termo você quer ver: '))
        an = a1
        cont = 0
        while cont <= n - 1:
            print((an), end=' -> ')
            cont = cont + 1
            an = an + r
        print('Aguardando...')
        termosamais = int(input('Deseja adicionar quantos termos a mais? \n'))
        while termosamais != 0:
            while cont <= n + termosamais - 1:
                print((an), end=' -> ')
                cont = cont + 1
                an = an + r
            termosamais = int(input('Deseja adicionar quantos termos a mais?'))
        escolha = int(input('Deseja fazer mais alguma veficação? \n[1] - SIM \n[0] - NÃO \n'))
    elif escolha > 1:
        escolha = int(input('OPÇÃO INVÁLIDA! \nDeseja fazer mais alguma verificação? \n[1] - SIM \n[0] - NÃO \n'))
print('Programa finalizado com {} termos exibidos'.format(cont))


import os
from dotenv import load_dotenv
import requests
from datetime import datetime
import json

now = datetime.now()

load_dotenv('api_keys.env')
nutritionix_app_id = os.environ.get('NUTRITIONIX_APP_ID')
nutritionix_api_key = os.environ.get('NUTRITIONIX_API_KEY')
nutritionix_main_endpoint = "https://trackapi.nutritionix.com"
nutritionix_natural_nutrients_endpoint = "/v2/natural/nutrients"
nutritionix_search_instant_endpoint = "/v2/search/instant"
nutritionix_natural_exercise_endpoint = "/v2/natural/exercise"
nutritionix_headers = {
    "x-app-id": nutritionix_app_id,
    "x-app-key": nutritionix_api_key,
    "Content-Type": "application/json"
}
query = input("How did you workout?")
nutritionix_api_parameters = {
    "query": query,
    "gender": "male",
    "weight_kg": 95.00,
    "height_cm": 185.00,
    "age": 44
}

response = requests.post(url=nutritionix_main_endpoint+nutritionix_natural_exercise_endpoint,
                         json=nutritionix_api_parameters,
                         headers=nutritionix_headers)
response.raise_for_status()
workouts_full = json.loads(response.text)
# print(workouts_full)

sheety_bearer_token = os.environ.get('SHEETY_BEARER_TOKEN')
sheety_api_endpoint = os.environ.get("SHEETY_API_ENDPOINT")
workouts = []
sheety_headers = {
    "Content-Type": "application/json",
    "Authorization": sheety_bearer_token,
}

for workout in workouts_full['exercises']:
    workout_data = {
            "date": now.strftime("%d/%m/%Y"),
            "time": now.strftime("%H:%M:%S"),
            "exercise": workout["user_input"].title(),
            "duration": workout["duration_min"],
            "calories": workout["nf_calories"]
        }
    sheety_parameters = {
        "workout": workout_data
        }
    print('sheety parameters:', sheety_parameters)
    print(sheety_headers)
    sheety_response = requests.post(url=sheety_api_endpoint, json=sheety_parameters, headers=sheety_headers)
    sheety_response.raise_for_status()


from __future__ import division, print_function, absolute_import

from sklearn.model_selection import KFold
from sklearn.utils import resample
import numpy as np
import itertools
import random
from collections import defaultdict

DATA_BASE = '../../data/'
datasets_train = [ 'freefield1010', 'warblr']
datasets_challenge = ['badchallenge' ]
random_state = 0
num_folds = 10

negative_samples = []

def split_dataset(dataset_name, balance=False, shuffle=True):

    print('Spliting %s.' % dataset_name)

    names = []
    labels = []
    with open(DATA_BASE + dataset_name + '_labels.csv', 'r') as fb:
        fb.readline()
        for line in fb:
            name, label = line.split(',')
            label = label.strip()
            if label == '':
                label = '-1'
            names.append(dataset_name + '_audio/wav_22050/' + name)
            labels.append(label)

    print('Splitting into folds')
    kf = KFold(n_splits=num_folds, shuffle=shuffle, random_state=random_state)

    for counter, (_, fold_index) in enumerate(kf.split(names)):

        samples = defaultdict(list)

        # split into different classes
        for index in fold_index:
            samples[labels[index]].append((names[index],labels[index]))

        fold_filename = dataset_name + '_%02d.csv' % counter
        print('Exporting %s' % fold_filename)

        negative_samples.extend(samples['0'])

        if balance:
            print('Balancing each fold')
            n_pos = len(samples['1'])
            n_neg = len(samples['0'])
            if n_neg < n_pos:
                tmp = resample(samples['0'],n_samples=n_pos-n_neg)
                samples['0'].extend(tmp)
            elif n_pos < n_neg:
                tmp = resample(samples['1'],n_samples=n_neg-n_pos)
                samples['1'].extend(tmp)

        items = list(itertools.chain(*samples.values()))
        if shuffle:
            random.shuffle(items)

        # output items
        with open(fold_filename, 'w') as fid:
            for item in items:
                print("%s,%s" % item, file=fid)

# Assuming labels are downloaded at DATA_BASE location
for dataset_name in datasets_train:
    split_dataset(dataset_name, balance=True, shuffle=True)

for dataset_name in datasets_challenge:
    split_dataset(dataset_name, balance=False, shuffle=False)

# Shuffle and save all negative samples to a file
random.shuffle(negative_samples)
print('Writing negative samples')
with open('./negative_samples.csv', 'w') as fb:
    for sample in negative_samples:
        fb.write('%s,%s\n' % sample)


import cv2
import numpy as np
img=cv2.imread('1.jpg',cv2.IMREAD_GRAYSCALE)
image=cv2.imread('1.jpg')
img=cv2.resize(img,(200,600))
image=cv2.resize(image,(200,600))
img = cv2.GaussianBlur(img, (5,5), 3)
params = cv2.SimpleBlobDetector_Params()
params.filterByColor=1
params.filterByInertia = False
params.filterByConvexity = False
detector = cv2.SimpleBlobDetector_create(params)
keypoints = detector.detect(img)
img = cv2.drawKeypoints(image, keypoints, np.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
while True:
	cv2.imshow("original image",image)
	cv2.imshow("image",img)
	key = cv2.waitKey(1) & 0xFF
	if cv2.waitKey(33) == 27:
		break
cv2.destroyAllWindows()


#! /usr/bin/env python3
#  -*- coding: utf-8 -*-
#

"""
usb reset devices & reinit (power cycle) hubs (ports)

Versioning semantics:
    Major version: backward compatibility breaking changes
    Minor version: New functionality
    Patch version: Backwards compatible bug fixes

"""

__intname__ = "usb_resetter"
__author__ = "Orsiris de Jong"
__copyright__ = "Copyright (C) 2022-2023 Orsiris de Jong - NetInvent SASU"
__description__ = "USB resetter allows to reset all USB controllers or a single USB device, also emulates lsusb"
__licence__ = "BSD 3 Clause"
__version__ = "1.3.2"
__build__ = "2023052801"
__url__ = "https://github.com/netinvent/usb_resetter"
__compat__ = "python2.7+"

from typing import List
import fcntl
import re
import os
import sys
import glob
import argparse
from collections import namedtuple

if not "linux" in sys.platform:
    print("This script can only run on Linux")
    sys.exit(3)

# linux/usbdevice_fs.h equivalents
# #define USBDEVFS_RESET             _IO('U', 20)
# Basically we want to send 01010101 00010100
# ord("U") == 85 == 01010101 which we shift to the left by 8 then add 20 == 00010100
USBDEVFS_RESET = ord("U") << 8 | 20
USBDEVFS_DISCONNECT = ord("U") << 8 | 22
USBDEVFS_CONNECT = ord("U") << 8 | 23

# Glob style path to USB contollers including USB3
USB_CONTROLLER_PATHS = "/sys/bus/pci/drivers/[uoex]hci_hcd/*:*"

def hub_binder(hub_path, action):
    """
    bind or unbind a usb hub / controller
    path: full path to usb hub / controller

    Unbinding / binding is equivalent to a cold restart, but real usb power cannot be cut
    The device will still get power, but will not be able to talk to the computer

    action: bind|unbind
    """
    current_hub = os.path.basename(hub_path)
    basepath = os.path.dirname(hub_path)

    pci_unbind_path = "/sys/bus/pci/drivers"
    usb_unbind_path = "/sys/bus/usb/drivers/usb"

    # In case we get a /sys/bus/usb/device instead of a /sys/bus/usb/drivers path
    if basepath.startswith(pci_unbind_path) or basepath.startswith(usb_unbind_path):
        unbind_path = basepath
    else:
        unbind_path = usb_unbind_path

    print("{} hub {}/{}".format(action, basepath, current_hub))
    with open(os.path.join(unbind_path, action), "w") as file_handle:
        file_handle.write(current_hub)

def get_usb_hubs(vendor_id=None, product_id=None):
    """
    Get physical location of usb hub where given product is plugged in
    vendor_id and product_id are optional filters
    """

    hubs = []

    for entry in glob.glob("/sys/bus/usb/devices/**/idVendor"):
        hub_path = os.path.dirname(entry)
        abs_hub_path = os.path.abspath(hub_path)
        vendor_id_file = os.path.join(abs_hub_path, "idVendor")
        product_id_file = os.path.join(abs_hub_path, "idProduct")

        try:
            with open(vendor_id_file, "r") as file_handle:
                found_vendor_id = file_handle.read().strip()
            with open(product_id_file, "r") as file_handle:
                found_product_id = file_handle.read().strip()

            if (
                vendor_id == found_vendor_id
                and product_id == found_product_id
                or (not vendor_id and not product_id)
            ):
                hubs.append(hub_path)
        except OSError:
            print(
                "Cannot identify which vendor/product is plugged in hub {}".format(
                    hub_path
                )
            )

    return hubs

def list_usb_hubs(vendor_id=None, product_id=None):
    """
    vendor_id and product_id are optional filters
    """
    for hub in get_usb_hubs(vendor_id, product_id):
        print("Found hub {}".format(hub))

def reset_usb_hubs(hubs):
    for hub in hubs:
        hub_binder(hub, "unbind")
        hub_binder(hub, "bind")

def reset_usb_controllers():
    # type: () -> None
    """
    Allows to reset all USB controllers from a machine

    Reimplements the following bash script:

    for i in /sys/bus/pci/drivers/[uoex]hci_hcd/*:*; do
      [ -e "$i" ] || continue
      echo "Resetting ${i%/*}/${i##*/}"
      echo "${i##*/}" > "${i%/*}/unbind"
      echo "${i##*/}" > "${i%/*}/bind"
    done
    """
    reset_usb_hubs(glob.glob(USB_CONTROLLER_PATHS))

def get_usb_devices_paths(vendor_id=None, product_id=None, list_only=False):
    # type: (str, str, bool) -> List[str]
    """
    Emulates lsusb by reading from /sys/kernel/debug/usb/devices
    Does not require lsusb to be installed and should work on a fair share of recent kernels
    """

    found_devices = []
    device_paths = []
    Device = namedtuple(
        "Devices", "vendor_id, product_id, device_path, manufacturer, product"
    )
    kernel_usb_debug_path = "/sys/kernel/debug/usb/devices"  # see https://wiki.debian.org/HowToIdentifyADevice/USB

    if not os.path.isfile(kernel_usb_debug_path):
        # We could fallback to lsusb here if available, but then we need command_runner to deal with different subprocess.communicate outputs
        raise OSError(
            "Kernel path {} not found. Please run this script as root".format(
                kernel_usb_debug_path
            )
        )

    with open(kernel_usb_debug_path, "r", encoding="utf-8") as file_handle:
        first_device = True
        manufacturer = None
        product = None
        found_vendor_id = None
        found_product_id = None
        device_path = None
        while True:
            line = file_handle.readline()
            if not line:
                break
            match = re.match(r"T:\s+Bus=(\d+).*Dev#=\s+(\d+)", line, re.IGNORECASE)
            if match:
                if not first_device:
                    # New device (begins with T:), let's reset previous values that belong to earlier found devices
                    found_devices.append(
                        Device(
                            vendor_id=found_vendor_id,
                            product_id=found_product_id,
                            device_path=device_path,
                            manufacturer=manufacturer,
                            product=product,
                        )
                    )
                else:
                    first_device = False
                    manufacturer = None
                    product = None
                    found_vendor_id = None
                    found_product_id = None

                # bus and dev are always 3 digit numbers, ex 001, 003, 004
                bus = "{:03d}".format(int(match.group(1)))
                dev = "{:03d}".format(int(match.group(2)))
            match = re.match(r"S:\s+Manufacturer=(.*)", line, re.IGNORECASE)
            if match:
                manufacturer = match.group(1)
            match = re.match(r"S:\s+Product=(.*)", line, re.IGNORECASE)
            if match:
                product = match.group(1)
            match = re.match(
                r"P:\s+Vendor=([0-9A-F]{4})\s+ProdID=([0-9A-F]{4})", line, re.IGNORECASE
            )
            if match:
                found_vendor_id = match.group(1)
                found_product_id = match.group(2)
                device_path = os.path.join("/dev/bus/usb", bus, dev)
                if vendor_id == found_vendor_id and product_id == found_product_id:
                    if os.path.exists(device_path):
                        device_paths.append(device_path)
                    else:
                        print(
                            "Device path not existing for bus {} dev {}".format(
                                bus, dev
                            )
                        )
    # We need to add the final device if exists:
    if bus and dev:
        found_devices.append(
            Device(
                vendor_id=found_vendor_id,
                product_id=found_product_id,
                device_path=device_path,
                manufacturer=manufacturer,
                product=product,
            )
        )

    if list_only:
        for device in found_devices:
            print("Found device %s:%s at %s Manufacturer=%s, Product=%s" % device)
    return device_paths

def send_signal_usb_device(device_path, signal):
    # type: (str, str) -> bool
    """
    Resets a usb device by dending USBDEVFS_RESET IOCTL to device
    Device path is /dev/bus/usb/[bus_number]/[device_number]
    bus_number and device_number are given by lsusb or else
    signal = reset|connect|disconnect

    Disclaimer
    This is a pyusb emulation that doesn't have dependencies but is more messy, and allows sending disconnect/connect on top of reset commands
    from usb.core import find as finddev
    finddev(idVendor=0x0665, idProduct=0x5161).reset()
    """

    if signal == "reset":
        sig = USBDEVFS_RESET
    elif signal == "disconnect":
        sig = USBDEVFS_DISCONNECT
    elif signal == "connect":
        sig = USBDEVFS_CONNECT
    else:
        raise TypeError("Bad USB signal given")

    print("Sending signal {} to usb device {}".format(signal, device_path))
    try:
        # Would be easier if os.open would have an __enter__ function for using with context
        fd = os.open(device_path, os.O_WRONLY)
        fcntl.ioctl(fd, sig, 0)
        success = True
    except OSError:
        print("Cannot {} USB device at {}".format(signal, device_path))
        success = False
    finally:
        os.close(fd)
    return success

def interface():
    description = (
        "USB hub / controllers & devices reset tool v{}\n"
        "{}\n"
        "PRs are welcome - {}\n".format(__version__, __copyright__, __url__)
    )
    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description=description,
    )

    parser.add_argument(
        "-l",
        "--list",
        dest="list",
        action="store_true",
        help="List USB devices and paths",
    )

    parser.add_argument(
        "--list-hubs",
        action="store_true",
        help="Print a list of detected USB hubs. If --device is given, list only hubs on which device is connected",
    )

    parser.add_argument(
        "-d",
        "--device",
        type=str,
        required=False,
        dest="device",
        default=None,
        help="Device for which we want to execute an action. Requires vendor_id:product_id format. Example: 8086:0001",
    )

    parser.add_argument(
        "--hub",
        type=str,
        required=False,
        dest="hub",
        default=None,
        help="Full path of hub on which to perform hub actions",
    )

    parser.add_argument(
        "--reset-device",
        dest="reset_device",
        action="store_true",
        help="Reset device given by --device",
    )

    parser.add_argument(
        "--connect-device",
        dest="connect_device",
        action="store_true",
        help="Connect device given by --device",
    )

    parser.add_argument(
        "--disconnect-device",
        dest="disconnect_device",
        action="store_true",
        help="Disconnect device given by --device",
    )

    parser.add_argument(
        "-r",
        "--reset-all",
        dest="reset_all",
        action="store_true",
        help="Reset all USB controllers, including their dependent hubs and devices",
    )

    parser.add_argument(
        "--reset-hub",
        dest="reset_hub",
        action="store_true",
        help="Reset hubs given by --hub switch, or hubs on which device given by --device is connected",
    )

    parser.add_argument(
        "--disable-hub",
        dest="disable_hub",
        action="store_true",
        help="Disable hub given by --hub switch, or hubs on which device given by --device is connected",
    )

    parser.add_argument(
        "--enable-hub",
        dest="enable_hub",
        action="store_true",
        help="Enable hub given by --hub switch, or hubs on which device given by --device is connected",
    )

    args = parser.parse_args(args=None if sys.argv[1:] else ["--help"])

    vendor_id = None
    product_id = None

    if args.reset_all:
        reset_usb_controllers()

    if args.device:
        try:
            vendor_id, product_id = args.device.split(":")
        except (TypeError, ValueError):
            print("Bogus device {} given.".format(args.device))
            sys.exit(2)

    if (
        args.reset_device
        or args.disconnect_device
        or args.connect_device
        or args.disable_hub
        or args.enable_hub
        or args.reset_hub
    ):
        if args.reset_device or args.disconnect_device or args.connect_device:
            paths = get_usb_devices_paths(vendor_id, product_id)
            for path in paths:
                if args.reset_device:
                    send_signal_usb_device(path, "reset")
                if args.connect_device:
                    send_signal_usb_device(path, "connect")
                if args.disconnect_device:
                    send_signal_usb_device(path, "disconnect")
        else:
            if args.hub:
                hubs = [args.hub]
            else:
                hubs = get_usb_hubs(vendor_id, product_id)
            if args.disable_hub:
                for hub in hubs:
                    hub_binder(hub, "unbind")
            if args.enable_hub:
                for hub in hubs:
                    hub_binder(hub, "bind")
            if args.reset_hub:
                reset_usb_hubs(hubs)

    if args.list:
        get_usb_devices_paths(list_only=True)

    if args.list_hubs:
        list_usb_hubs(vendor_id, product_id)

def main():
    try:
        interface()
    except KeyboardInterrupt:
        print("Program interrupted by CTRL+C")
        sys.exit(200)
    except Exception as exc:
        print("Program failed with error %s" % exc)
        # We'll keep exit code consistent
        sys.exit(201)

if __name__ == "__main__":
    main()


class Solution:
    def watchedVideosByFriends(self, watchedVideos: List[List[str]], friends: List[List[int]], id: int, level: int) -> List[str]:
        visited = set()
        q = [(id, 0)]
        distance = {}
        while len(q) > 0:
            curr = q.pop(0)
            if curr[0] in visited:
                continue
            visited.add(curr[0])
            distance[curr[0]] = curr[1]
            for f in friends[curr[0]]:
                if f not in visited:
                    q.append((f, curr[1]+1))
        counts = {}
        for node in distance:
            if distance[node] == level:
                for vid in watchedVideos[node]:
                    if vid not in counts:
                        counts[vid] = 1
                    else:
                        counts[vid] += 1
        return [node[0] for node in sorted(counts.items(), key=lambda item: (item[1], item[0]))]


from itertools import chain

class MeanVal:

    @staticmethod
    def get_mean(dct):
        lst = list(chain(*dct.values()))
        return round(sum(lst) / len(lst), 1) if len(lst) > 0 else 0

class Student:

    def __init__(self, name, surname, gender):
        self.name = name
        self.surname = surname
        self.gender = gender
        self.finished_courses = []
        self.courses_in_progress = []
        self.grades = {}

    def add_courses(self, course_name):
        self.courses_in_progress.append(course_name)

    def estimate_lecturer(self, lecturer, course, value):
        if (isinstance(lecturer, Lecturer) and course in lecturer.courses_attached
                and course in self.courses_in_progress and 0 <= value <= 10):
            if course in lecturer.estimation:
                lecturer.estimation[course] += [value]
            else:
                lecturer.estimation[course] = [value]
        else:
            return 'Ошибка'

    def __str__(self):
        finished_courses_str =  str(self.finished_courses).strip('[]')
        courses_in_progress_str = str(self.courses_in_progress).strip('[]')
        str_to_return = (
            f'Имя: {self.name}\n'
            f'Фамилия: {self.surname}\n'
            f'Средняя оценка за д/з: {MeanVal.get_mean(self.grades)}\n'
            f'Курсы в процессе изучения: {courses_in_progress_str}\n'
            f'Завершенные курсы: {finished_courses_str}')
        return str_to_return

    def __lt__(self, some_stud):
        if isinstance(some_stud, Student):
            self_mean = MeanVal.get_mean(self.grades)
            some_stud_mean = MeanVal.get_mean(some_stud.grades)
            return self_mean < some_stud_mean
        return -1

    def __gt__(self, some_stud):
        if isinstance(some_stud, Student):
            self_mean = MeanVal.get_mean(self.grades)
            some_stud_mean = MeanVal.get_mean(some_stud.grades)
            return self_mean > some_stud_mean
        return -1

    def __le__(self, some_stud):
        if isinstance(some_stud, Student):
            self_mean = MeanVal.get_mean(self.grades)
            some_stud_mean = MeanVal.get_mean(some_stud.grades)
            return self_mean <= some_stud_mean
        return -1

    def __ge__(self, some_stud):
        if isinstance(some_stud, Student):
            self_mean = MeanVal.get_mean(self.grades)
            some_stud_mean = MeanVal.get_mean(some_stud.grades)
            return self_mean >= some_stud_mean
        return -1

    def __ne__(self, some_stud):
        if isinstance(some_stud, Student):
            self_mean = MeanVal.get_mean(self.grades)
            some_stud_mean = MeanVal.get_mean(some_stud.grades)
            return self_mean != some_stud_mean
        return -1

    def __eq__(self, some_stud):
        if isinstance(some_stud, Student):
            self_mean = MeanVal.get_mean(self.grades)
            some_stud_mean = MeanVal.get_mean(some_stud.grades)
            return self_mean == some_stud_mean
        return -1

class Mentor:

    def __init__(self, name, surname):
        self.name = name
        self.surname = surname
        self.courses_attached = []

class Lecturer(Mentor):

    def __init__(self, name, surname):
        super().__init__(name, surname)
        self.estimation = {}

    def __str__(self):
        str_to_return = (
            f'Имя: {self.name}\n'
            f'Фамилия: {self.surname}\n'
            f'Средняя оценка за лекции: {MeanVal.get_mean(self.estimation)}')
        return str_to_return

    def __lt__(self, some_lec):
        if isinstance(some_lec, Lecturer):
            self_mean = MeanVal.get_mean(self.estimation)
            some_lec_mean = MeanVal.get_mean(some_lec.estimation)
            return self_mean < some_lec_mean
        return -1

    def __gt__(self, some_lec):
        if isinstance(some_lec, Lecturer):
            self_mean = MeanVal.get_mean(self.estimation)
            some_lec_mean = MeanVal.get_mean(some_lec.estimation)
            return self_mean > some_lec_mean
        return -1

    def __le__(self, some_lec):
        if isinstance(some_lec, Lecturer):
            self_mean = MeanVal.get_mean(self.estimation)
            some_lec_mean = MeanVal.get_mean(some_lec.estimation)
            return self_mean <= some_lec_mean
        return -1

    def __ge__(self, some_lec):
        if isinstance(some_lec, Lecturer):
            self_mean = MeanVal.get_mean(self.estimation)
            some_lec_mean = MeanVal.get_mean(some_lec.estimation)
            return self_mean >= some_lec_mean
        return -1

    def __ne__(self, some_lec):
        if isinstance(some_lec, Lecturer):
            self_mean = MeanVal.get_mean(self.estimation)
            some_lec_mean = MeanVal.get_mean(some_lec.estimation)
            return self_mean != some_lec_mean
        return -1

    def __eq__(self, some_lec):
        if isinstance(some_lec, Lecturer):
            self_mean = MeanVal.get_mean(self.estimation)
            some_lec_mean = MeanVal.get_mean(some_lec.estimation)
            return self_mean == some_lec_mean
        return -1

class Reviewer(Mentor):

    def rate_hw(self, student, course, grade):
        if (isinstance(student, Student) and course in self.courses_attached
                and course in student.courses_in_progress):
            if course in student.grades:
                student.grades[course] += [grade]
            else:
                student.grades[course] = [grade]
        else:
            return 'Ошибка'

    def __str__(self):
        str_to_return = (
            f'Имя: {self.name}\n'
            f'Фамилия: {self.surname}')
        return str_to_return

def get_mean_for_hw(students_lst, course):
    grades_dct = {(stud.name, stud.surname): stud.grades.get(course)
                  for stud in students_lst
                  if course in stud.grades.keys()}
    return MeanVal.get_mean(grades_dct)

def get_mean_for_lections(lecturers_lst, course):
    values_dct = {(lec.name, lec.surname): lec.estimation.get(course)
                  for lec in lecturers_lst
                  if course in lec.estimation.keys()}
    return MeanVal.get_mean(values_dct)

s1 = Student('Alan', 'Wake', 'Male')
s2 = Student('Scorpion', 'Wins', 'Male')
r1 = Reviewer('Sean', 'Bean')
r2 = Reviewer('John', 'Rambo')
l1 = Lecturer('Alexander', 'The Great')
l2 = Lecturer('Ivan', 'The Terrible')
# print(s1)
# print(r1)
# print(l1)
s1.add_courses('Git')
s1.add_courses('Python Basics')
s1.add_courses('Python Advanced')
s2.add_courses('Git')
s2.add_courses('Python Basics')
s2.add_courses('Python Advanced')
r1.courses_attached = ['Git', 'Python Basics', 'Python Advanced']
r1.rate_hw(s1, 'Git', 5)
r1.rate_hw(s1, 'Python Basics', 10)
r1.rate_hw(s1, 'Python Advanced', 7)
r1.rate_hw(s1, 'Git', 8)
r1.rate_hw(s1, 'Python Basics', 9)
r1.rate_hw(s1, 'Python Advanced', 6)
r1.rate_hw(s1, 'Git', 10)
r1.rate_hw(s1, 'Python Basics', 5)
r1.rate_hw(s1, 'Python Advanced', 4)
r1.rate_hw(s2, 'Git', 4)
r1.rate_hw(s2, 'Python Basics', 5)
r1.rate_hw(s2, 'Python Advanced', 7)
r1.rate_hw(s2, 'Git', 7)
r1.rate_hw(s2, 'Python Basics', 10)
r1.rate_hw(s2, 'Python Advanced', 3)
r1.rate_hw(s2, 'Git', 8)
r1.rate_hw(s2, 'Python Basics', 6)
r1.rate_hw(s2, 'Python Advanced', 6)
# print(s1 > s2, s1 == s2, s1 != s2, sep=' : ')
# print(s1)
# print(s2)
print(s1.grades)
print(s2.grades)
print(get_mean_for_hw([s1, s2], 'Git'))
print(get_mean_for_hw([s1, s2], 'Python Basics'))


import random
from .fetch.spanish_trees import fetch_spanish_trees
from .fetch.syntactic_transfer_rules import fetch_syntactic_transfer_rules
from .utils.read_csv import read_csv
from .utils.write_csv import write_to_csv
from .utils.parse_arguments import parse_arguments
from .corpus_generation.remove_duplicates import remove_duplicates
from .transfer.guarani_tree import build_guarani_tree
from .corpus_generation.extract_words import extract_words
from .corpus_generation.post_process import post_process

def main():
    # Get CSV files
    nouns = read_csv("../../guarani/nouns/finished-nouns.csv")
    determiners = read_csv("../../guarani/determiners/determiners.csv")
    adjectives = read_csv("../../guarani/adjectives/matched-adjectives-guarani.csv")
    pronouns = read_csv("../../guarani/pronouns/pronouns.csv")
    verbs = read_csv("../../guarani/verbs/matched-verbs-guarani.csv")
    adpositions = read_csv("../../guarani/adpositions/adpositions.csv")
    connectors = read_csv("../../guarani/connectors/connectors.csv")

    lexicon = {
        'N' : nouns,
        'D' : determiners,
        'A' : adjectives,
        'P' : pronouns,
        'V' : verbs,
        'AA': adpositions,
        'PR': adpositions,
        'CON': connectors
    }

    args = parse_arguments()
    trees = fetch_spanish_trees(args.spanish_trees_file)
    transfer_rules = fetch_syntactic_transfer_rules(args.equivalence_rules_file)
    parallel_corpus = []

    if (not args.indices):
        raise Exception("Indices file not provided, needed for Ancora corpus")
    indices = read_csv(args.indices)
    out_indices = []

    for trees_index, spanish_tree in enumerate(trees):
        translations = build_guarani_tree(spanish_tree, transfer_rules, lexicon)
        spanish_sentence = extract_words(spanish_tree)

        if translations == []:
            print(spanish_sentence)
        else:
            # pick just one translation
            translations = random.sample(translations, 1)

        for (guarani_sentence, features) in translations:
            # sentence_pair = post_process([spanish_sentence, guarani_sentence])
            # Post-process should only be regarding Guarani,
            # Spanish side should not be altered at all for Ancora
            sentence_pair = [spanish_sentence, guarani_sentence]
            parallel_corpus.append(sentence_pair)
            out_indices.append(indices[trees_index])

    write_to_csv(args.output, parallel_corpus)
    write_to_csv(args.indices[:-4] + '_out.csv', out_indices)
    # remove_duplicates(args.output)

if __name__ == '__main__':
    main()


from norutil.config import get_config

from check_ssl import check_ssl_expire_date
from definitions import CONFIG_PATH
from exception import MemoError
from memo import Memo
from twitter import get_twitter

def _main():
    config = get_config(CONFIG_PATH)

    check_ssl_expire_date(config)

    get_twitter(config)

    memo = Memo(config)

    if memo.is_exist_today_memo():
        print("Today's memo file has been created already.")
    else:
        print("Today's memo file does not exist.\n"
              "The latest memo will be copied.")
        try:
            memo.copy_memo_from_newest()
        except MemoError as err:
            print('Failed to copy memo file: {}'.format(err))
            exit(1)

        print("Did you fill out yesterday's attendance?")
        memo.open_excel()
        memo.open_website_url()

    memo.open_today_memo()
    exit(0)

if __name__ == '__main__':
    _main()


from django.db import migrations, models

class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='Coins',
            fields=[
                ('id', models.IntegerField(primary_key=True, serialize=False)),
                ('name', models.CharField(max_length=31)),
                ('abbreviation', models.CharField(max_length=7, unique=True)),
                ('description', models.CharField(max_length=10000)),
                ('icon', models.CharField(max_length=27)),
            ],
            options={
                'db_table': 'coins',
            },
        ),
        migrations.CreateModel(
            name='CoinPrices',
            fields=[
                ('id', models.AutoField(primary_key=True, serialize=False)),
                ('rate_close', models.DecimalField(decimal_places=11, max_digits=24)),
                ('rate_high', models.DecimalField(decimal_places=11, max_digits=24)),
                ('rate_low', models.DecimalField(decimal_places=11, max_digits=24)),
                ('rate_open', models.DecimalField(decimal_places=11, max_digits=24)),
                ('time_close', models.DateTimeField()),
                ('time_open', models.DateTimeField()),
                ('time_period_end', models.DateTimeField()),
                ('time_period_start', models.DateTimeField()),
                ('coin', models.ForeignKey(on_delete=models.deletion.CASCADE, to='coins.coins')),
            ],
            options={
                'db_table': 'coin_prices',
            },
        ),
        migrations.CreateModel(
            name='CurrentPrices',
            fields=[
                ('id', models.AutoField(primary_key=True, serialize=False)),
                ('rate_close', models.DecimalField(decimal_places=11, max_digits=24)),
                ('rate_open', models.DecimalField(decimal_places=11, max_digits=24)),
                ('time_period_start', models.DateTimeField()),
                ('time_period_end', models.DateTimeField()),
                ('coin', models.OneToOneField(on_delete=models.deletion.CASCADE, to='coins.coins')),
            ],
            options={
                'db_table': 'current_prices',
            },
        ),
    ]


# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os

from pifpaf import drivers

class ZooKeeperDriver(drivers.Driver):

    DEFAULT_PORT = 2181

    PATH = ["/usr/share/zookeeper/bin",
            "/usr/local/opt/zookeeper/libexec/bin"]

    def __init__(self, port=DEFAULT_PORT, **kwargs):
        """Create a new ZooKeeper server."""
        super(ZooKeeperDriver, self).__init__(**kwargs)
        self.port = port

    @classmethod
    def get_options(cls):
        return [
            {"param_decls": ["--port"],
             "type": int,
             "default": cls.DEFAULT_PORT,
             "help": "port to use for ZooKeeper"},
        ]

    def _setUp(self):
        super(ZooKeeperDriver, self)._setUp()

        cfgfile = os.path.join(self.tempdir, "zoo.cfg")
        with open(cfgfile, "w") as f:
            f.write("""dataDir=%s
clientPort=%s
4lw.commands.whitelist=*""" % (self.tempdir, self.port))

        logdir = os.path.join(self.tempdir, "log")
        os.mkdir(logdir)

        self.putenv("ZOOCFGDIR", self.tempdir, True)
        self.putenv("ZOOCFG", cfgfile, True)
        self.putenv("ZOO_LOG_DIR", logdir, True)

        c, _ = self._exec(
            ["zkServer.sh", "start", cfgfile],
            wait_for_port=self.port,
            path=self.PATH)

        self.addCleanup(self._exec,
                        ["zkServer.sh", "stop", cfgfile],
                        path=self.PATH)

        self.putenv("ZOOKEEPER_PORT", str(self.port))
        self.putenv("URL", "zookeeper://localhost:%d" % self.port)