from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

from copy import deepcopy
import re
import traceback
import ansible_collections.netapp.ontap.plugins.module_utils.netapp as netapp_utils

ZAPI_ONLY_DEPRECATION_MESSAGE = "This module only supports ZAPI and is deprecated.   "\
                                "It will no longer work with newer versions of ONTAP.  "\
                                "The final ONTAP version to support ZAPI is ONTAP 9.12.1."

def cmp(obj1, obj2):
    """
    Python 3 does not have a cmp function, this will do the cmp.
    :param obj1: first object to check
    :param obj2: second object to check
    :return:
    """
    # convert to lower case for string comparison.
    if obj1 is None:
        return -1
    if isinstance(obj1, str) and isinstance(obj2, str):
        obj1 = obj1.lower()
        obj2 = obj2.lower()
    # if list has string element, convert string to lower case.
    if isinstance(obj1, list) and isinstance(obj2, list):
        obj1 = [x.lower() if isinstance(x, str) else x for x in obj1]
        obj2 = [x.lower() if isinstance(x, str) else x for x in obj2]
        obj1.sort()
        obj2.sort()
    return (obj1 > obj2) - (obj1 < obj2)

class NetAppModule(object):
    '''
    Common class for NetApp modules
    set of support functions to derive actions based
    on the current state of the system, and a desired state
    '''

    def __init__(self, module=None):
        # we can call this with module set to self or self.module
        # self is a NetApp module, while self.module is the AnsibleModule object
        self.netapp_module = None
        self.ansible_module = module
        if module and getattr(module, 'module', None) is not None:
            self.netapp_module = module
            self.ansible_module = module.module
        # When using self or self.module, this gives access to:
        #       self.ansible_module.fail_json
        # When using self, this gives access to:
        #       self.netapp_module.rest_api.log_debug
        self.log = []
        self.changed = False
        self.parameters = {'name': 'not initialized'}
        self.zapi_string_keys = {}
        self.zapi_bool_keys = {}
        self.zapi_list_keys = {}
        self.zapi_int_keys = {}
        self.zapi_required = {}
        self.params_to_rest_api_keys = {}

    def module_deprecated(self, module):
        module.warn(ZAPI_ONLY_DEPRECATION_MESSAGE)

    def module_replaces(self, new_module, module):
        self.module_deprecated(module)
        module.warn('netapp.ontap.%s should be used instead.' % new_module)

    def set_parameters(self, ansible_params):
        self.parameters = {}
        for param in ansible_params:
            if ansible_params[param] is not None:
                self.parameters[param] = ansible_params[param]
        return self.parameters

    def fall_back_to_zapi(self, module, msg, parameters):
        if parameters['use_rest'].lower() == 'always':
            module.fail_json(msg='Error: %s' % msg)
        if parameters['use_rest'].lower() == 'auto':
            module.warn('Falling back to ZAPI: %s' % msg)
            return False

    def check_and_set_parameters(self, module):
        self.parameters = {}
        check_for_none = netapp_utils.has_feature(module, 'check_required_params_for_none')
        if check_for_none:
            required_keys = [key for key, value in module.argument_spec.items() if value.get('required')]
        for param in module.params:
            if module.params[param] is not None:
                self.parameters[param] = module.params[param]
            elif check_for_none and param in required_keys:
                module.fail_json(msg="%s requires a value, got: None" % param)
        return self.parameters

    @staticmethod
    def type_error_message(type_str, key, value):
        return "expecting '%s' type for %s: %s, got: %s" % (type_str, repr(key), repr(value), type(value))

    def get_value_for_bool(self, from_zapi, value, key=None):
        """
        Convert boolean values to string or vice-versa
        If from_zapi = True, value is converted from string (as it appears in ZAPI) to boolean
        If from_zapi = False, value is converted from boolean to string
        For get() method, from_zapi = True
        For modify(), create(), from_zapi = False
        :param from_zapi: convert the value from ZAPI or to ZAPI acceptable type
        :param value: value of the boolean attribute
        :param key: if present, force error checking to validate type, and accepted values
        :return: string or boolean
        """
        if value is None:
            return None
        if from_zapi:
            if key is not None and not isinstance(value, str):
                raise TypeError(self.type_error_message('str', key, value))
            if key is not None and value not in ('true', 'false'):
                raise ValueError('Unexpected value: %s received from ZAPI for boolean attribute: %s' % (repr(value), repr(key)))
            return value == 'true'
        if key is not None and not isinstance(value, bool):
            raise TypeError(self.type_error_message('bool', key, value))
        return 'true' if value else 'false'

    def get_value_for_int(self, from_zapi, value, key=None):
        """
        Convert integer values to string or vice-versa
        If from_zapi = True, value is converted from string (as it appears in ZAPI) to integer
        If from_zapi = False, value is converted from integer to string
        For get() method, from_zapi = True
        For modify(), create(), from_zapi = False
        :param from_zapi: convert the value from ZAPI or to ZAPI acceptable type
        :param value: value of the integer attribute
        :param key: if present, force error checking to validate type
        :return: string or integer
        """
        if value is None:
            return None
        if from_zapi:
            if key is not None and not isinstance(value, str):
                raise TypeError(self.type_error_message('str', key, value))
            return int(value)
        if key is not None and not isinstance(value, int):
            raise TypeError(self.type_error_message('int', key, value))
        return str(value)

    def get_value_for_list(self, from_zapi, zapi_parent, zapi_child=None, data=None):
        """
        Convert a python list() to NaElement or vice-versa
        If from_zapi = True, value is converted from NaElement (parent-children structure) to list()
        If from_zapi = False, value is converted from list() to NaElement
        :param zapi_parent: ZAPI parent key or the ZAPI parent NaElement
        :param zapi_child: ZAPI child key
        :param data: list() to be converted to NaElement parent-children object
        :param from_zapi: convert the value from ZAPI or to ZAPI acceptable type
        :return: list() or NaElement
        """
        if from_zapi:
            if zapi_parent is None:
                return []
            return [zapi_child.get_content() for zapi_child in zapi_parent.get_children()]

        zapi_parent = netapp_utils.zapi.NaElement(zapi_parent)
        for item in data:
            zapi_parent.add_new_child(zapi_child, item)
        return zapi_parent

    def get_cd_action(self, current, desired):
        ''' takes a desired state and a current state, and return an action:
            create, delete, None
            eg:
            is_present = 'absent'
            some_object = self.get_object(source)
            if some_object is not None:
                is_present = 'present'
            action = cd_action(current=is_present, desired = self.desired.state())
        '''
        desired_state = desired['state'] if 'state' in desired else 'present'
        if current is None and desired_state == 'absent':
            return None
        if current is not None and desired_state == 'present':
            return None
        # change in state
        self.changed = True
        return 'create' if current is None else 'delete'

    @staticmethod
    def check_keys(current, desired):
        ''' TODO: raise an error if keys do not match
            with the exception of:
            new_name, state in desired
        '''

    @staticmethod
    def compare_lists(current, desired, get_list_diff):
        ''' compares two lists and return a list of elements that are either the desired elements or elements that are
            modified from the current state depending on the get_list_diff flag
            :param: current: current item attribute in ONTAP
            :param: desired: attributes from playbook
            :param: get_list_diff: specifies whether to have a diff of desired list w.r.t current list for an attribute
            :return: list of attributes to be modified
            :rtype: list
        '''
        current_copy = deepcopy(current)
        desired_copy = deepcopy(desired)

        # get what in desired and not in current
        desired_diff_list = []
        for item in desired:
            if item in current_copy:
                current_copy.remove(item)
            else:
                desired_diff_list.append(item)

        # get what in current but not in desired
        current_diff_list = []
        for item in current:
            if item in desired_copy:
                desired_copy.remove(item)
            else:
                current_diff_list.append(item)

        if desired_diff_list or current_diff_list:
            # there are changes
            return desired_diff_list if get_list_diff else desired
        else:
            return None

    def get_modified_attributes(self, current, desired, get_list_diff=False):
        ''' takes two dicts of attributes and return a dict of attributes that are
            not in the current state
            It is expected that all attributes of interest are listed in current and
            desired.
            :param: current: current attributes in ONTAP
            :param: desired: attributes from playbook
            :param: get_list_diff: specifies whether to have a diff of desired list w.r.t current list for an attribute
            :return: dict of attributes to be modified
            :rtype: dict

            NOTE: depending on the attribute, the caller may need to do a modify or a
            different operation (eg move volume if the modified attribute is an
            aggregate name)
        '''
        # if the object does not exist,  we can't modify it
        modified = {}
        if current is None:
            return modified

        if not isinstance(desired, dict):
            raise TypeError("Expecting dict, got: %s with current: %s" % (desired, current))
        # error out if keys do not match
        self.check_keys(current, desired)

        # collect changed attributes
        for key, value in current.items():
            # if self.netapp_module:
            #     self.netapp_module.rest_api.log_debug('KDV', "%s:%s:%s" % (key, desired.get(key), value))
            if desired.get(key) is not None:
                modified_value = None
                if isinstance(value, list):
                    modified_value = self.compare_lists(value, desired[key], get_list_diff)  # get modified list from current and desired
                elif isinstance(value, dict):
                    modified_value = self.get_modified_attributes(value, desired[key]) or None
                else:
                    try:
                        result = cmp(value, desired[key])
                    except TypeError as exc:
                        raise TypeError("%s, key: %s, value: %s, desired: %s" % (repr(exc), key, repr(value), repr(desired[key])))
                    # if self.netapp_module:
                    #     self.netapp_module.rest_api.log_debug('RESULT', result)
                    if result != 0:
                        modified_value = desired[key]
                if modified_value is not None:
                    modified[key] = modified_value

        if modified:
            self.changed = True
        return modified

    def is_rename_action(self, source, target):
        ''' takes a source and target object, and returns True
            if a rename is required
            eg:
            source = self.get_object(source_name)
            target = self.get_object(target_name)
            action = is_rename_action(source, target)
            :return: None for error, True for rename action, False otherwise

            I'm not sure we need this function any more.
            I think a better way to do it is to:
            1. look if a create is required (eg the target resource does not exist and state==present)
            2. consider that a create can be fullfilled by different actions: rename, create from scratch, move, ...
            So for rename:
            cd_action = self.na_helper.get_cd_action(current, self.parameters)
            if cd_action == 'create' and self.parameters.get('from_name'):
                # creating new subnet by renaming
                current = self.get_subnet(self.parameters['from_name'])
                if current is None:
                    self.module.fail_json(msg="Error renaming: subnet %s does not exist" %
                                          self.parameters['from_name'])
                rename = True
                cd_action = None
        '''
        if source is None and target is None:
            # error, do nothing
            # cannot rename a non existent resource
            return None
        if target is None:
            # source is not None and target is None:
            # rename is in order
            self.changed = True
            return True
        # target is not None, so do nothing as the destination exists
        # if source is None, maybe we already renamed
        # if source is not None, maybe a new resource was created after being renamed
        return False

    @staticmethod
    def sanitize_wwn(initiator):
        ''' igroup initiator may or may not be using WWN format: eg 20:00:00:25:B5:00:20:01
            if format is matched, convert initiator to lowercase, as this is what ONTAP is using '''
        wwn_format = r'[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){7}'
        initiator = initiator.strip()
        if re.match(wwn_format, initiator):
            initiator = initiator.lower()
        return initiator

    def safe_get(self, an_object, key_list, allow_sparse_dict=True):
        ''' recursively traverse a dictionary or a any object supporting get_item or indexing
            (in our case, python dicts and NAElement responses, and lists)
            It is expected that some keys can be missing, this is controlled with allow_sparse_dict

            return value if the key chain is exhausted
            return None if a key is not found and allow_sparse_dict is True
            raise KeyError is a key is not found and allow_sparse_dict is False (looking for exact match)
            raise TypeError if an intermediate element cannot be indexed,
              unless the element is None and allow_sparse_dict is True
        '''
        if not key_list:
            # we've exhausted the keys, good!
            return an_object
        key_list = list(key_list)   # preserve original values
        key = key_list.pop(0)
        try:
            return self.safe_get(an_object[key], key_list, allow_sparse_dict=allow_sparse_dict)
        except (KeyError, IndexError) as exc:
            # error, key or index not found
            if allow_sparse_dict:
                return None
            raise exc
        except TypeError as exc:
            # error, we were expecting a dict or NAElement
            if allow_sparse_dict and an_object is None:
                return None
            raise exc

    def convert_value(self, value, convert_to):
        if convert_to is None:
            return value, None
        if not isinstance(value, str):
            return None, ('Unexpected type: %s for %s' % (type(value), str(value)))
        if convert_to == str:
            return value, None
        if convert_to == int:
            try:
                return int(value), None
            except ValueError as exc:
                return None, ('Unexpected value for int: %s, %s' % (str(value), str(exc)))
        if convert_to == bool:
            if value not in ('true', 'false'):
                return None, 'Unexpected value: %s received from ZAPI for boolean attribute' % value
            return value == 'true', None
        if convert_to == 'bool_online':
            return value == 'online', None
        self.ansible_module.fail_json(msg='Error: Unexpected value for convert_to: %s' % convert_to)

    def zapi_get_value(self, na_element, key_list, required=False, default=None, convert_to=None):
        """ read a value from na_element using key_list

            If required is True, an error is reported if a key in key_list is not found.
            If required is False and the value is not found, uses default as the value.
            If convert_to is set to str, bool, int, the ZAPI value is converted from str to the desired type.
                suported values: None, the python types int, str, bool, special 'bool_online'

        Errors: fail_json is called for:
            - a key is not found and required=True,
            - a format conversion error
        """

        # keep a copy, as the list is mutated
        saved_key_list = list(key_list)
        try:
            value = self.safe_get(na_element, key_list, allow_sparse_dict=not required)
        except (KeyError, TypeError) as exc:
            error = exc
        else:
            value, error = self.convert_value(value, convert_to) if value is not None else (default, None)
        if error:
            self.ansible_module.fail_json(msg='Error reading %s from %s: %s' % (saved_key_list, na_element.to_string(), error))
        return value

    def zapi_get_attrs(self, na_element, attr_dict, result):
        """ Retrieve a list of attributes from na_elements
        see na_ontap_volume for an example.
        na_element: xml element as returned by ZAPI.
        attr_dict:
            A dict of dict, with format:
                key: dict(key_list, required=False, default=None, convert_to=None, omitnone=False)
            The keys are used to index a result dictionary, values are read from a ZAPI object indexed by key_list.
            If required is True, an error is reported if a key in key_list is not found.
            If required is False and the value is not found, uses default as the value.
            If convert_to is set to str, bool, int, the ZAPI value is converted from str to the desired type.
            I'm not sure there is much value in omitnone, but it preserves backward compatibility.
            When the value is None, if omitnone is False, a None value is recorded, if True, the key is not set.
        result: an existing dictionary.  keys are added or updated based on attrs.

        Errors: fail_json is called for:
            - a key is not found and required=True,
            - a format conversion error
        """
        for key, kwargs in attr_dict.items():
            omitnone = kwargs.pop('omitnone', False)
            value = self.zapi_get_value(na_element, **kwargs)
            if value is not None or not omitnone:
                result[key] = value

    def _filter_out_none_entries_from_dict(self, adict, allow_empty_list_or_dict):
        """take a dict as input and return a dict without keys whose values are None
           return empty dicts or lists if allow_empty_list_or_dict otherwise skip empty dicts or lists.
        """
        result = {}
        for key, value in adict.items():
            if isinstance(value, (list, dict)):
                sub = self.filter_out_none_entries(value, allow_empty_list_or_dict)
                if sub or allow_empty_list_or_dict:
                    # allow empty dict or list if allow_empty_list_or_dict is set.
                    # skip empty dict or list otherwise
                    result[key] = sub
            elif value is not None:
                # skip None value
                result[key] = value
        return result

    def _filter_out_none_entries_from_list(self, alist, allow_empty_list_or_dict):
        """take a list as input and return a list without elements whose values are None
           return empty dicts or lists if allow_empty_list_or_dict otherwise skip empty dicts or lists.
        """
        result = []
        for item in alist:
            if isinstance(item, (list, dict)):
                sub = self.filter_out_none_entries(item, allow_empty_list_or_dict)
                if sub or allow_empty_list_or_dict:
                    # allow empty dict or list if allow_empty_list_or_dict is set.
                    # skip empty dict or list otherwise
                    result.append(sub)
            elif item is not None:
                # skip None value
                result.append(item)
        return result

    def filter_out_none_entries(self, list_or_dict, allow_empty_list_or_dict=False):
        """take a dict or list as input and return a dict/list without keys/elements whose values are None
           return empty dicts or lists if allow_empty_list_or_dict otherwise skip empty dicts or lists.
        """

        if isinstance(list_or_dict, dict):
            return self._filter_out_none_entries_from_dict(list_or_dict, allow_empty_list_or_dict)

        if isinstance(list_or_dict, list):
            return self._filter_out_none_entries_from_list(list_or_dict, allow_empty_list_or_dict)

        raise TypeError('unexpected type %s' % type(list_or_dict))

    @staticmethod
    def get_caller(depth):
        '''return the name of:
             our caller if depth is 1
             the caller of our caller if depth is 2
             the caller of the caller of our caller if depth is 3
             ...
        '''
        # one more caller in the stack
        depth += 1
        frames = traceback.extract_stack(limit=depth)
        try:
            function_name = frames[0].name
        except AttributeError:
            # python 2.7 does not have named attributes for frames
            try:
                function_name = frames[0][2]
            except Exception as exc:                                   # pylint: disable=broad-except
                function_name = 'Error retrieving function name: %s - %s' % (str(exc), repr(frames))
        return function_name

    def fail_on_error(self, error, api=None, stack=False, depth=1, previous_errors=None):
        '''depth identifies how far is the caller in the call stack'''
        if error is None:
            return
        # one more caller to account for this function
        depth += 1
        if api is not None:
            error = 'calling api: %s: %s' % (api, error)
        results = dict(msg='Error in %s: %s' % (self.get_caller(depth), error))
        if stack:
            results['stack'] = traceback.format_stack()
        if previous_errors:
            results['previous_errors'] = ' - '.join(previous_errors)
        if getattr(self, 'ansible_module', None) is not None:
            self.ansible_module.fail_json(**results)
        raise AttributeError('Expecting self.ansible_module to be set when reporting %s' % repr(results))

    def compare_chmod_value(self, current_permissions, desired_permissions):
        """
        compare current unix_permissions to desired unix_permissions.
        :return: True if the same, False it not the same or desired unix_permissions is not valid.
        """
        if current_permissions is None:
            return False
        if desired_permissions.isdigit():
            return int(current_permissions) == int(desired_permissions)
        # ONTAP will throw error as invalid field if the length is not 9 or 12.
        if len(desired_permissions) not in [12, 9]:
            return False
        desired_octal_value = ''
        # if the length is 12, first three character sets userid('s'), groupid('s') and sticky('t') attributes
        if len(desired_permissions) == 12:
            if desired_permissions[0] not in ['s', '-'] or desired_permissions[1] not in ['s', '-']\
                    or desired_permissions[2] not in ['t', '-']:
                return False
            desired_octal_value += str(self.char_to_octal(desired_permissions[:3]))
        # if the len is 9, start from 0 else start from 3.
        start_range = len(desired_permissions) - 9
        for i in range(start_range, len(desired_permissions), 3):
            if desired_permissions[i] not in ['r', '-'] or desired_permissions[i + 1] not in ['w', '-']\
                    or desired_permissions[i + 2] not in ['x', '-']:
                return False
            group_permission = self.char_to_octal(desired_permissions[i:i + 3])
            desired_octal_value += str(group_permission)
        return int(current_permissions) == int(desired_octal_value)

    def char_to_octal(self, chars):
        """
        :param chars: Characters to be converted into octal values.
        :return: octal value of the individual group permission.
        """
        total = 0
        if chars[0] in ['r', 's']:
            total += 4
        if chars[1] in ['w', 's']:
            total += 2
        if chars[2] in ['x', 't']:
            total += 1
        return total

    def ignore_missing_vserver_on_delete(self, error, vserver_name=None):
        """ When a resource is expected to be absent, it's OK if the containing vserver is also absent.
            This function expects self.parameters('vserver') to be set or the vserver_name argument to be passed.
            error is an error returned by rest_generic.get_xxxx.
        """
        if self.parameters.get('state') != 'absent':
            return False
        if vserver_name is None:
            if self.parameters.get('vserver') is None:
                self.ansible_module.fail_json(
                    msg='Internal error, vserver name is required, when processing error: %s' % error, exception=traceback.format_exc())
            vserver_name = self.parameters['vserver']
        if isinstance(error, str):
            pass
        elif isinstance(error, dict):
            if 'message' in error:
                error = error['message']
            else:
                self.ansible_module.fail_json(
                    msg='Internal error, error should contain "message" key, found: %s' % error, exception=traceback.format_exc())
        else:
            self.ansible_module.fail_json(
                msg='Internal error, error should be str or dict, found: %s, %s' % (type(error), error), exception=traceback.format_exc())
        return 'SVM "%s" does not exist.' % vserver_name in error

    def remove_hal_links(self, records):
        """ Remove all _links entries """
        if isinstance(records, dict):
            records.pop('_links', None)
            for record in records.values():
                self.remove_hal_links(record)
        if isinstance(records, list):
            for record in records:
                self.remove_hal_links(record)


from __future__ import annotations
from typing import Optional
from msrc.appconfig.schema import Element, SchemaSource, interpret_type
import dataclasses

def inspect(schema: type) -> Optional[SchemaSource]:
    if not dataclasses.is_dataclass(schema):
        return None
    fields = dataclasses.fields(schema)

    def make_element(field: dataclasses.Field[object]) -> Element:
        element_type = interpret_type(field.type)
        if element_type is not None:
            return Element(
                help=field.metadata.get("help", None),
                element_type=element_type,
                is_secret=not field.repr,
                has_default=not (
                    field.default is dataclasses.MISSING
                    and field.default_factory  # type: ignore
                    is dataclasses.MISSING),
                default_value=field.default)
        else:
            raise ValueError("%s: type %s unsupported."
                             % (field.name, field.type))
    return tuple((field.name, make_element(field))
                 for field in fields
                 if not field.name.startswith('_'))


import sys
sys.setrecursionlimit(10000)

def move(cnt):
    if cnt > 1000:
        return -1

    for s in sorted(shark):
        x, y = shark[s]
        direc = direction[s-1]
        move_direc = prefer[(s-1)*4+direc-1]
        for d in move_direc:
            nx, ny = x+dx[d-1], y+dy[d-1]
            if 0 <= nx < N and 0 <= ny < N:
                if board[nx][ny][0] == 0:
                    if board[nx][ny][1] == 0 or board[nx][ny][1] < cnt:
                        board[x][y][0] = 0
                        board[nx][ny] = [s, K+cnt, s]
                        shark[s] = [nx, ny]
                        direction[s-1] = d
                        break
                elif board[nx][ny][1] < cnt and board[nx][ny] != s:
                    del shark[s]
                    board[x][y][0] = 0
                    break
        else:
            for d in move_direc:
                nx, ny = x+dx[d-1], y+dy[d-1]
                if 0 <= nx < N and 0 <= ny < N:
                    if board[nx][ny][2] == s:
                        board[x][y][0] = 0
                        board[nx][ny] = [s, K+cnt, s]
                        shark[s] = [nx, ny]
                        direction[s-1] = d
                        break
    print('------------', cnt)
    print(shark)
    for b in board:
        print(b)
    if len(shark) == 1:
        return cnt
    else:
        return move(cnt+1)

N, M, K = map(int, input().split())
board = [[[] for _ in range(N)] for _ in range(N)]
for i in range(N):
    arr = list(map(int, input().split()))
    for j in range(N):
        if arr[j] == 0:
            board[i][j] = [0, 0, 0]
        else:
            board[i][j] = [arr[j], K, arr[j]]
direction = list(map(int, input().split()))
prefer = [list(map(int, input().split())) for _ in range(M*4)]
dx, dy = [-1, 1, 0, 0], [0, 0, -1, 1]
shark = dict()
for i in range(N):
    for j in range(N):
        if board[i][j][0] != 0:
            shark[board[i][j][0]] = [i, j]
print(move(1))


__date__ = "2017-04-30T20:03:36+0300"
__author__ = "John Saturday <john.saturday.73@gmail.com>"
__credits__ = "Alan McIntyre <https://github.com/alanmcintyre>"

from http.client import OK as _HTTP_OK
from zlib import MAX_WBITS as _MAX_WBITS

#from Cookie import CookieError
from http.client import HTTPException, BadStatusLine
from socket import error as SocketError

#from Cookie import SimpleCookie
from decimal import Decimal
from hashlib import sha512 as _sha512
from hmac import new as newhash
from http.client import HTTPSConnection
from re import search
from urllib.parse import urlparse
from zlib import decompress as _zdecompress

try:
    from simplejson import loads as jsonloads
except ImportError:
    from json import loads as jsonloads

API_REFRESH = 2            # data refresh time
BTCE_HOST = 'wex.nz'    # BTC-e host (HTTP/SSL)
CF_COOKIE = '__cfduid'     # CloudFlare security cookie
HTTP_TIMEOUT = 10      # connection timeout (max: 60 sec)

class APIError(Exception):
    "Raise exception when the BTC-e API returned an error."
    pass

class BTCEConnection(object):
    """BTC-e Trade/Public API persistent HTTPS connection.
    @cvar conn: shared httplib.HTTPSConnection between instances"""
    _headers = {         # common HTTPS headers
        'Accept': 'application/json',
        'Accept-Charset': 'utf-8',
        'Accept-Encoding': 'identity',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
        }
    _post_headers = {    # common and POST headers
        'Content-Type': 'application/x-www-form-urlencoded',
        }
    conn = None    # type 'httplib.HTTPSConnection'
    resp = None    # type 'httplib.HTTPResponse'

    @classmethod
    def __init__(cls, compr=True, timeout=HTTP_TIMEOUT):
        """Initialization of shared HTTPS connection.
        @param compr: HTTPS compression (default: identity)
        @param timeout: HTTPS timeout (default/max: 30/60 sec)"""
        if compr is False:
            compr = 'identity'
        elif compr is True:
            compr = 'gzip, deflate'

        if not cls.conn:
            # Create a new connection.
            cls.conn = HTTPSConnection(BTCE_HOST, strict=True, timeout=timeout)
            cls._post_headers.update(cls._headers)
        elif timeout != cls.conn.timeout:
            # Update the connection timeout.
            cls.conn.timeout = timeout
            cls.conn.close()
        if compr and compr != cls._headers['Accept-Encoding']:
            # Update the connection compression.
            cls._headers['Accept-Encoding'] = compr
            cls._post_headers.update(cls._headers)
            cls.conn.close()

    @classmethod
    def _signature(cls, apikey, msg):
        """Calculation of the SHA-512 authentication signature.
        @param apikey: API-key dict {'Key': '...', 'Secret': '...'}
        @param msg: method and parameters (Trade API)"""
        sign = newhash(apikey['Secret'], msg=msg, digestmod=_sha512)
        cls._post_headers['Key'] = apikey['Key']
        cls._post_headers['Sign'] = sign.hexdigest()

    @classmethod
    def _setcookie(cls):
        "Get the CloudFlare cookie and update security."
        cookie_header = cls.resp.getheader('Set-Cookie')
        try:
            cf_cookie = SimpleCookie(cookie_header)[CF_COOKIE]
        except (CookieError, KeyError):
            pass    # with/out previous cookie
        else:
            cf_value = cf_cookie.OutputString('value')
            cls._headers['Cookie'] = cls._post_headers['Cookie'] = cf_value

    @classmethod
    def _decompress(cls, data):
        """Decompress connection response.
        @return: decompressed data <type 'str'>"""
        encoding = cls.resp.getheader('Content-Encoding')
        if encoding == 'gzip':
            data = _zdecompress(data, _MAX_WBITS+16)
        elif encoding == 'deflate':
            data = _zdecompress(data, -_MAX_WBITS)
        # else: failback to 'identity' encoding
        return data

    @classmethod
    def jsonrequest(cls, url, apikey=None, **params):
        """Create query to the BTC-e API (JSON response).
        @raise httplib.HTTPException, socket.error: connection errors
        @param url: plain URL without parameters (Trade/Public API)
        @param apikey: API-key dict {'Key': '...', 'Secret': '...'}
        @param **params: method and/or parameters (Trade/Public API)
        @return: API response (JSON data) <type 'str'>"""
        if apikey:    # args: Trade API
            method = 'POST'
            body = urlparse(params)
            cls._signature(apikey, body)
            headers = cls._post_headers
        else:         # args: Public API
            method = 'GET'
            if params:
                url = '{}?{}'.format(url, urlparse(params))
            body = None
            headers = cls._headers
        while True:
            # Make a HTTPS request.
            try:
                cls.conn.request(method, url, body=body, headers=headers)
                cls.resp = cls.conn.getresponse()
            except BadStatusLine:
                cls.conn.close()
                continue
            except (HTTPException, SocketError):
                cls.conn.close()
                raise
            cls._setcookie()
            break
        return cls._decompress(cls.resp.read())

    @classmethod
    def apirequest(cls, url, apikey=None, **params):
        """Create query to the BTC-e API (decoded response).
        @raise APIError, httplib.HTTPException: BTC-e and CloudFlare errors
        @param url: plain URL without parameters (Public/Trade API)
        @param apikey: API-key dict {'Key': '...', 'Secret': '...'}
        @param **params: method and/or parameters (Public/Trade API)
        @return: API response (decoded data) <type 'dict'>"""
        data = cls.jsonrequest(url, apikey, **params)
        try:
            data = jsonloads(data, parse_float=Decimal, parse_int=Decimal)
        except ValueError:
            if cls.resp.status == _HTTP_OK:
                # BTC-e API unknown errors.
                raise APIError(str(data) or "Unknown Error")
            else:
                # HTTP or CloudFlare errors.
                raise HTTPException("{} {}".format(
                    cls.resp.status, cls.resp.reason))
        else:
            if 'error' in data:
                # BTC-e API standard errors.
                raise APIError(str(data['error']))
        return data

class TradeAPIv1(BTCEConnection):
    "BTC-e Trade API v1 <https://btc-e.com/tapi/docs>."
    def __init__(self, apikey, **connkw):
        """Initialization of the BTC-e Trade API v1.
        @raise APIError: where no return an invalid nonce error
        @param apikey: API-key dict {'Key': '...', 'Secret': '...'}
        @param **connkw: compr, timeout (see: BTCEConnection class)"""
        super(TradeAPIv1, self).__init__(**connkw)
        self._apikey = apikey            # type 'dict' (keys: 'Key', 'Secret')
        self.nonce = self._getnonce()    # type 'long' (min/max: 1-4294967294)

    def _getnonce(self):
        """Get nonce value from BTC-e API error.
        @return: nonce parameter <type 'long'>"""
        try:
            self.apirequest('/tapi', self._apikey, nonce=None)
        except APIError as error:
            if 'invalid nonce' not in error.message:
                raise
            nonce = search(r'\d+', error.message).group()
        return int(nonce)

    def _nextnonce(self):
        """Increase and return next nonce parameter.
        @return: nonce parameter <type 'long'>"""
        self.nonce += 1
        return self.nonce

    def call(self, method, **params):
        """Create query to the BTC-e Trade API v1.
        @param method: getInfo | Trade | ActiveOrders | OrderInfo |
            CancelOrder | TradeHistory (max: 2000) | TransHistory (max: 2000)
        @param method*: WithdrawCoin | CreateCoupon | RedeemCoupon
        @param **params: param1=value1, param2=value2, ..., paramN=valueN
        @return: API response (see: online documentation) <type 'dict'>"""
        params['method'] = method
        params['nonce'] = self._nextnonce()
        return self.apirequest('/tapi', self._apikey, **params)['return']

class PublicAPIv3(BTCEConnection):
    "BTC-e Public API v3 <https://btc-e.com/api/3/docs>."
    def __init__(self, *pairs, **connkw):
        """Initialization of the BTC-e Public API v3.
        @param *pairs: [btc_usd[-btc_rur[-...]]] or arguments
        @param **connkw: compr, timeout (see: BTCEConnection class)"""
        super(PublicAPIv3, self).__init__(**connkw)
        self.pairs = pairs    # type 'str' (delimiter: '-')

        # Get and/or join all pairs.
        if not self.pairs:
            self.pairs = self.call('info')['pairs'].keys()
        if not isinstance(self.pairs, str):
            self.pairs = '-'.join(self.pairs)

    def call(self, method, pairs=None, **params):
        """Create query to the BTC-e Public API v3.
        @param method: info | ticker | depth | trades
        @param pairs: [btc_usd[-btc_rur[-...]]] <type 'str'>
        @param **params: limit=150 (max: 5000), ignore_invalid=1
        @return: API response (see: online documentation) <type 'dict'>"""
        if method == 'info':
            url = '/api/3/{}'.format(method)
        else:    # method: ticker, depth, trades
            pairs = pairs or self.pairs
            url = '/api/3/{}/{}'.format(method, pairs)
        return self.apirequest(url, **params)


'''
Service Two Convert The Given Timezone in IST

'''

from flask import Flask,request,jsonify
from datetime import datetime
import pytz
ist = pytz.timezone("Asia/Kolkata")

#Init App
app=Flask(__name__)

@app.route('/',methods=['GET'])
def getStatus():
    return jsonify({'message':'Service One Running'})

@app.route('/convert/<timestamp>',methods=['GET'])
def getTimestampIst(timestamp):
    #date = datetime.fromtimestamp(int(timestamp), ist).replace(tzinfo=None)

    try:
       date = datetime.fromtimestamp(int(timestamp), ist).replace(tzinfo=None)
       return jsonify({'date':str(date),'timezone':"IST"})
    except:
      print("An exception occurred")
      return jsonify({'error':'Please Insert Correct timezone'})

#Run server

if __name__=='__main__':
    app.run(host='0.0.0.0', port=5000,debug=True)


class Solution:
	def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
		min_x, max_x = 0, len(matrix[0]) - 1
		min_y, max_y = 0, len(matrix) - 1
		cur_x, cur_y = min_x, min_y
		phase = 1
		spiral = [matrix[cur_y][cur_x]]
		if len(matrix) == 1:
			return matrix[0]
		if len(matrix[0]) == 1:
			return [l[0] for l in matrix]
		while True:
			if phase == 1:
				if  cur_x < max_x:
					cur_x += 1
				elif cur_x == max_x:
					min_y += 1
					cur_y += 1
					phase = 2
				else:
					break
			elif phase == 2:
				if cur_y < max_y:
					cur_y += 1
				elif cur_y == max_y:
					max_x -= 1
					cur_x -= 1
					phase = 3
				else:
					break
			elif phase == 3:
				if cur_x > min_x:
					cur_x -= 1
				elif cur_x == min_x:
					max_y -= 1
					cur_y -= 1
					phase = 4
				else:
					break
			elif phase == 4:
				if cur_y > min_y:
					cur_y -= 1
				elif cur_y == min_y:
					min_x += 1
					cur_x += 1
					phase = 1
				else:
					break
			spiral.append(matrix[cur_y][cur_x])
		return spiral[:-1]


from argparse import REMAINDER, ArgumentParser
from typing import Any, List, Callable, Optional

from .command import (
    handle_hook,
    handle_list,
    handle_commit,
    handle_search,
    handle_no_subcommand,
)

parser = ArgumentParser("nonemoji", description="Simple gitmoji cli written in python")
parser.set_defaults(func=handle_no_subcommand)
_subparsers = parser.add_subparsers(title="subcommands")

# hook
hook_parser = _subparsers.add_parser("hook", help="Run as a git hook.")
hook_parser.add_argument("commit_msg_file", help="Path to the commit message file")
hook_parser.set_defaults(func=handle_hook)

# commit
commit_parser = _subparsers.add_parser("commit", help="Start to commit changes.")
commit_parser.add_argument("-e", "--emoji", help="Emoji to use")
commit_parser.add_argument("-m", "--message", help="Commit message")
commit_parser.add_argument(
    "--", nargs=REMAINDER, help="Argument to pass to the git", dest="args"
)
commit_parser.set_defaults(func=handle_commit)

# list
list_parser = _subparsers.add_parser("list", help="List all available emoji.")
list_parser.set_defaults(func=handle_list)

# search
search_parser = _subparsers.add_parser("search", help="Search for an emoji.")
search_parser.set_defaults(func=handle_search)

def main(argv: Optional[List[str]] = None):
    result = parser.parse_args(argv)
    result = vars(result)
    func: Callable[..., Any] = result.pop("func")
    func(**result)


import urllib2
import sys
import os.path

import lxml.html as html
import pandas as pd

reddit_url = 'https://reddit.com'
start_url = 'https://reddit.com/r/jokes'
headers = { 'User-Agent': '/u/Broscious' }
upvote_threshold = 100

def url_open(url):
    req = urllib2.Request(url, headers=headers)
    return urllib2.urlopen(req)

def retrieve_urls():
    root = html.parse(url_open(start_url)).getroot()
    scores = root.xpath('//div[@class="score unvoted"]/text()')
    relative_paths = root.xpath('//a[@class="title may-blank "]/@href')
    absolute_paths = [reddit_url + relative for relative in relative_paths]
    filtered_paths = []
    for url, upvotes in zip(absolute_paths, scores):
        try:
            value = int(upvotes)
        except:
            value = -1
        if value >= upvote_threshold:
            filtered_paths.append(url)
    return filtered_paths

def retrieve_joke(url):
    root = html.parse(url_open(url)).getroot()
    setup = root.xpath('//a[@class="title may-blank "]/text()')[0]
    content = root.xpath('//div[@class="expando expando-uninitialized"]//p/text()')
    return setup, content

def one_line_filter(setup, content):
    for paragraph in content[1:]:
        low_para = paragraph.lower()
        if low_para.startswith('edit:'):
            continue
        else:
            return None

    punchline = content[0]
    if punchline.count('.') > 1:
        return None

    return setup, punchline

def filter_results(urls, results):
    returns = []
    for url, result in zip(urls, results):
        title, content = result
        joke = one_line_filter(title, content)
        if joke is not None:
            returns.append((url, joke[0], joke[1]))
    return returns

def save_results(one_liners, joke_file, url_file):
    used_urls = pd.read_csv(url_file)
    added_urls = []
    added_jokes = []
    for url, setup, punchline in one_liners:
        if not (used_urls['url'] == url).any():
            added_urls.append(url)
            added_jokes.append((setup, punchline))
    url_df = pd.DataFrame(added_urls, columns=['url'])
    jokes_df = pd.DataFrame(added_jokes, columns=['Joke', 'Punchline'])

    with open(url_file, 'a') as f:
        url_df.to_csv(f, index=False, header=False, encoding='utf-8')

    with open(joke_file, 'a') as f:
        jokes_df.to_csv(f, index=False, header=False, encoding='utf-8')

def ensure_existance(joke_file, url_file):
    if not os.path.isfile(url_file):
        with open(url_file, 'w') as f:
            f.write(u'url\n')

    if not os.path.isfile(joke_file):
        with open(joke_file, 'w') as f:
            f.write(u'Joke, Punchline\n')

def main():
    joke_file = sys.argv[1]
    url_file = sys.argv[2]
    ensure_existance(joke_file, url_file)
    urls = retrieve_urls()
    results = [retrieve_joke(url) for url in urls]
    one_liners = filter_results(urls, results)
    save_results(one_liners, joke_file, url_file)

if __name__ == '__main__':
    main()


def findJoltDiff(inputList):
    joltDiffCount = [0, 0, 0, 0]
    curJoltCount = 0
    for adapter in inputList:
        diff = adapter - curJoltCount
        if diff <= 3  and diff > 0:
            joltDiffCount[diff] += 1
            curJoltCount += diff
            print(joltDiffCount, diff)
        else:
            raise ValueError("can't use all adapters, diff: " + diff + ", adapter: " + adapter)

    # max adapter jolttage:
    diff = 3
    joltDiffCount[diff] += 1
    curJoltCount += diff
    return (joltDiffCount[1], joltDiffCount[3])

def findContiguousInterval(inputList, numToFind):
    startIndex = 0

    totSum = 0
    i = startIndex
    while i < len(inputList):
        totSum += inputList[i]
        while totSum > numToFind:
            totSum -= inputList[startIndex]
            startIndex += 1
        if totSum == numToFind:
            print( (startIndex, i))
            return (startIndex, i)
        i += 1
    return "notFound"

inputList = []
with open("input.txt") as file_in:
    for line in file_in:
        line = int(line.rstrip())
        inputList.append(line)

inputList.sort()
jolt1, jolt3 = findJoltDiff(inputList)
print(jolt1 * jolt3)


import requests
from lxml import etree
from retrying import retry
import json
'''
循环爬取百度贴吧 手机 极速版
'''

class TiebaSpider(object):
    def __init__(self,name):
        self.url = 'http://tieba.baidu.com/mo/q---FA77541F561680C166FF4B9C2A85CA24%3AFG%3D1--1-3-0--2--wapp_1507619411320_819/m?kw={}'.format(name)
        self.headers = {"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1"}
        self.base_url = 'http://tieba.baidu.com/mo/q---FA77541F561680C166FF4B9C2A85CA24%3AFG%3D1--1-3-0--2--wapp_1507619411320_819/'

    @retry(stop_max_attempt_number=3)
    def parse_url(self,url):
        try:
            response = requests.get(url=url,headers=self.headers,timeout=2)
            html_str = response.content
            return etree.HTML(html_str)
        except:
            return None

    def get_data_list(self,element):
        if element is None:
            return
        div_list = element.xpath('//div[@class="i"]')
        data_list = []
        for div in div_list:
            data={
                'title':div.xpath('./a/text()')[0].replace('\xa0','') if div.xpath('./a/text()') else None,
                'href': self.base_url + div.xpath('./a/@href')[0] if div.xpath('./a/@href') else None
            }
            data_list.append(data)
        next_url = self.base_url + element.xpath('//a[text()="下一页"]/@href')[0] if element.xpath('//a[text()="下一页"]/@href') else None
        print(next_url)
        return data_list,next_url

    def get_content_and_pictures(self,data_list):
        for data in data_list:
            element = self.parse_url(data['href'])
            div = element.xpath('//div[@class="d"]')[0]
            data['content'] = div.xpath('./div[@class="i"]/text()')[0]
            data['pic_list']= [ requests.utils.unquote(i.split('src=')[1]) for i in div.xpath("./div[@class='i']/a/@href") if i.startswith('http') ]

    def save(self,data_list):
        with open('./tieba.txt','a') as f:
            for d in data_list:
                f.write(json.dumps(d,ensure_ascii=False,indent=2))
                f.write('\n')

    def run(self):
        next_url = self.url
        while next_url is not None:
            # 1 获取 首页的url地址
            # 2发送请求获取响应
            element = self.parse_url(next_url)
            # 3 提取title href 下一页的urli地址
            data_list,next_url = self.get_data_list(element)
            # 4 发送帖子href的请求，获取帖子里面的图片
            self.get_content_and_pictures(data_list)
            # 5 保存到本地
            self.save(data_list)
            # 6 请求下一页url  循环

if __name__ == '__main__':
    spider = TiebaSpider( '哈尔滨工业大学' )
    spider.run()

01 循环爬取百度贴吧.py


#encoding = 'utf-8'
import json
import os
file_dir = 'file/'
list = os.listdir(file_dir)
for eachone in list:
    origin_dir = os.path.join(file_dir, eachone)
    dir = os.path.join(origin_dir, "json")
    json_file_list = os.listdir(dir)
    for each in json_file_list:
        txt_file = open(os.path.join(origin_dir, eachone + ".txt"), "r")
        #path = os.path.join(dir, each)
        path ="file\haiyun\json\/1.json"
        json_file = open(path)
        file = json.load(json_file)
        for line in txt_file:
            if(len(line.strip())!=0):
                print(line.strip())
                if(file.__contains__(line.strip()) == False):
                    file[line[:-1]] = [{'flag':True,'time':'1-2','special':[]},
                                       {'flag':True,'time':'3-4','special':[]},
                                       {'flag':True,'time':'5-6','special':[]},
                                       {'flag':True,'time':'7-8','special':[]},
                                       {'flag':True,'time':'9-11','special':[]}]
        json_file.close()
        json_file = open(os.path.join(origin_dir,each),"w+")
        json_file.write(json.dumps(file,  indent=4, separators=(',', ': ')))
        json_file.close()
        txt_file.close()


'''
ADMINFINDER.PY : Used to find possible admin panels of a site by concentating suffixes to the
base URL one by one. Uses asyncio.
This file is a part of the Witch Project
By Cryptonian007 [24|11|21::08:43]
'''

from core.formatting import *
from urllib.parse import urlparse
import asyncio,aiohttp,sys
#import progressbar

ok_sites = []
failed = 0
total = 0

def check_suffixes(lst):
    # yeah ik it's stupid
    lol = []
    for i in lst:
        if i[0] == '/':lol.append(i)
        else:lol.append('/'+i)
    return lol

async def check(url,suffix,client,boolean):
    global failed
    # checks the HTTP response (if site is good or bad)
    if boolean:
        if url.endswith('/'):
            url = url[0:-1]
            nurl = url + suffix
        else:
            nurl = url + suffix
    else:nurl = urlparse(url).scheme + '://' + urlparse(url).netloc + suffix
    try:
        resp = await client.get(nurl)
        code = resp.status
        if code == 200:
            ok(nurl)
            ok_sites.append(nurl)
        else:failed += 1;minus(f'{nurl}')
    except:failed += 1;minus(f'{nurl}')

async def check_urllist(url,suffixes,boolean):
    # intuitive
    global total
    async with aiohttp.ClientSession() as session:
        tasks = []
        for suffix in suffixes:
            total += 1
            task = asyncio.create_task(check(url,suffix,session,boolean))
            tasks.append(task)
        await asyncio.gather(*tasks)

def adminFinder(url,suffixfile,boolean):
    # main function
    try:
        f = open(suffixfile)
        lst = f.read().splitlines()
        new_lst = check_suffixes(lst)
        asyncio.new_event_loop().run_until_complete(check_urllist(url,new_lst,boolean))
    except Exception as e:
        error(f'Exception! [{e}]')
    return ok_sites,total,failed


"""miniappservice URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.9/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib.auth.decorators import login_required
from django.views.generic.list import ListView
import django.contrib.auth.views as auth_views

from .models import Trabajo

urlpatterns = [
    url(
        r'^$',
        login_required(ListView.as_view(
                template_name='inicio.html',
                queryset=Trabajo.objects.all(),
                context_object_name='trabajos_list'
            )
        ),
        name='home'
    ),
]


name = input("What is your name? ").capitalize() # this will capitilize the input that we get from the user
male_names = open("male_names","r")#there is a file calles male_name from which i am going to read data
Write_in_males = open("male_names","a+")#No i also want to add some data in male_name also that's why created this varible
female_names = open("female_names","r")
write_in_females = open("female_names","a+")

if name in male_names.read():# making a condition that if the user name is in the file male_names
    print("You are a male")
elif name in female_names.read(): #making a elif condition that if  name is in female_names
    print("You are a female")
else:
    if name.endswith("i") or name.endswith("a") or name.endswith("u"):
        print("Maybe you are a female")
        is_gender_correct = input("Is your gender correct y/n:- ")
        if is_gender_correct == "n":
            print("Thanks for your feedback we will try our best to improve ourselves")
            Write_in_males.write(name + "\n")
        else:
            print("Thanks for your feedback")
            write_in_females.write(name + "\n")
    else:
        print("Maybe you are male")
        is_gender_correct = input("Is your gender correct y/n:- ")
        if is_gender_correct == "n":
            print("Thanks for your feedback we will try our best to improve ourselves")
            write_in_females.write(name + "\n")
        else:
            print("Thanks for your feedback")
            Write_in_males.write(name + "\n")
#Now we end up are full project


#Linked List

#To create a node - node_name = node(data)
class node:
    def __init__(self, data=None, next=None):
        self.data = data
        self.next = next

    #To print a node - node_name.print_node()
    def print_node(self):
        print(self.data)

#To create a linked list - name = linked_list()
class linked_list:
    def __init__(self):
        self.head = None

    #To append node - list.append_node(data)
    def append_node(self, data):
        if not self.head:
            self.head = node(data)
            return
        else:
            current = self.head
            while current.next:
                current = current.next
            current.next = node(data)

    #To search for a node - list.search(data)
    def search(self, target):
        current = self.head
        while current != None:
            if current.data == target:
                print("Found it!")
                return True

            else:
                current = current.next
        print("Not here.")
        return False

    #To print the linked list - list.print_list()
    def print_list(self):
        node = self. head
        while node is not None:
            print(node.data, end =" ")
            node = node.next
        print("\n")


from fastapi import APIRouter, status
import requests

router = APIRouter(
    tags=['GET']
)

@router.get('/tasks', status_code=status.HTTP_202_ACCEPTED)
def get_all():
    r = requests.get('http://localhost:4001/tasks/all')
    return r.json()
#ByField
@router.get('/tasks/byField', status_code=status.HTTP_202_ACCEPTED)
def get_by_method(field:str, payload:str ):
    r = requests.get('http://localhost:4001/tasks/byField',json={"field":field,"payload":payload})
    return r.json()

@router.get('/tasks/{pk}', status_code=status.HTTP_202_ACCEPTED)
def get_by_pk(pk:str):
    r = requests.get('http://localhost:4001/tasks/byPK',json={"pk_id_task":pk})
    return r.json()

@router.get('/tasks/allByFk/{payload}', status_code=status.HTTP_202_ACCEPTED)
def get_by_method( payload:str ):
    r = requests.get('http://localhost:4001/tasks/allByFk',json={"field":"fk_id_user","payload":payload})
    return r.json()


from __future__ import print_function
from pyimagesearch.shapedetector import ShapeDetector
from imutils.video import WebcamVideoStream
from imutils.video import FPS
import cv2
import numpy as np
import os
import subprocess as sp
import serial
import time
import imutils
import RPi.GPIO as GPIO

#sets up variables:
ser = serial.Serial('/dev/ttyACM0', 9600)
stateDelivering = False
lowPower = 0
lookingForSign = 0
stateChecking = 0
print("starting python")
print("sleeping for 2 sec...")

#sets up threaded image loading and custom picture width "w"
w = 200
vs = WebcamVideoStream(src=0).start()

# Defines color filters for different color ranes
lr_b = 0
lg_b = 120
lb_b = 190

hr_b = 50
hg_b = 230
hb_b = 255

############## OLD VALUES USED
#lr_b = 0
#lg_b = 130
#lb_b = 160

#hr_b = 130
#hg_b = 255
#hb_b = 255

lr_r = 200
lg_r = 0
lb_r = 0

hr_r = 255
hg_r = 100
hb_r = 145

lr_g = 0
lg_g = 125
lb_g = 0

hr_g = 130
hg_g = 255
hb_g = 165

# Defines numpy array with color filter values
lower_color_blue = np.array([lb_b, lg_b, lr_b], dtype=np.uint8)
upper_color_blue = np.array([hb_b, hg_b, hr_b], dtype=np.uint8)
lower_color_green = np.array([lb_g, lg_g, lr_g], dtype=np.uint8)
upper_color_green = np.array([hb_g, hg_g, hr_g], dtype=np.uint8)
lower_color_red = np.array([lb_r, lg_r, lr_r], dtype=np.uint8)
upper_color_red = np.array([hb_r, hg_r, hr_r], dtype=np.uint8)

#image filtering parameter
max_slider = 40

# current robot line coordinates is defined with null values.
hx1 = 0
hx2 = 0
hy1 = 0
hy2 = 0
# highLineY is a temporary value which remembers max Y value of previous line. A line can not be selected unless it has a higher Y value than this line.
# This variable is slowly decreased in the code if the robot does not detect any valid lines, until it eventually reaches 0 and the robot will detect and blue line it sees.
highLineY = 0
tempX = 320
old_tempX = 320

# Sets up GPIO (hardware pins on raspberrypi)
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(17,GPIO.IN,pull_up_down=GPIO.PUD_UP)

GPIO.setup(18, GPIO.OUT)
GPIO.setup(27,GPIO.OUT)
GPIO.outout(27,0)
servoPWM = GPIO.PWM(18, 50) # channel 0, 50hz PWM frequency.
servoPWM.start(93.2)
servoPWM.ChangeDutyCycle(93.2)

time.sleep(2)

def sendLineInfo(newX,oldX,width):
    try:
        if (newX != oldX): # if tempX has changed from last instance, new line has been found / line has moved
            ser.write(chr(int(newX*(126/width))+1).encode())
            #print("writing serial value: " + str(int(newX*(126/width))+1)).

    except:
        print("No new line info. No serial written.")

def cleanUp():
    cv2.destroyAllWindows()
    vs.stop()
    GPIO.cleanup()

def arduinoCallback1(channel):
    global lookingForSign
    global lowPower
    global stateDelivering
    global count
    global stateChecking
    ser.reset_output_buffer()
    print("interrupt triggered...")
    read = ser.read()
    time.sleep(1)
    if read == b'\x01':
        lookingForSign = 1
        stateChecking = 0
        print("metal detected.")
        #ser.write(chr(int(3)).encode())####################################################################################################################################
    elif read == b'\x02':
        stateChecking = 1
        lookingForSign = 0

GPIO.add_event_detect(17, GPIO.FALLING, callback=arduinoCallback1, bouncetime=2000)

 #0: following line, 1: looking for sign, 2: picking up package, 3: delivering package.
# While loop for main logic

while True:
    packageSymbol = "triangle" # to predefine packagename, enter something other than ""
    image = vs.read()
    image = imutils.resize(image, width=w)
    # Image parameters / set-up for selecting colors and finding liness
    if stateChecking == 1:
        if packageSymbol == "":
            #TURN CAMERA UP
            compare = 0
            foundSign = 0
            triangles = 0
            squares = 0

            for i in range(10):
                image = vs.read()

                mask1 = cv2.inRange(image, lower_color_red, upper_color_red)
                resized = imutils.resize(mask1, width=300)
                ratio = mask1.shape[0] / float(resized.shape[0])

                # convert the resized image to grayscale, blur it slightly,
                # and threshold it
                #gray = cv2.cvtColor(resized, cv2.COLOR_BGR2GRAY)
                gray = resized
                blurred = cv2.GaussianBlur(gray, (7, 7), 0)
                thresh = cv2.threshold(blurred, 200, 255, cv2.THRESH_BINARY)[1] #60, 255 default

                # find contours in the thresholded image and initialize the
                # shape detector
                cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
                    cv2.CHAIN_APPROX_SIMPLE)
                cnts = imutils.grab_contours(cnts)
                sd = ShapeDetector()
                try:
                    # loop over the contours
                    for c in cnts:
                        # compute the center of the contour, then detect the name of the
                        # shape using only the contour
                        M = cv2.moments(c)
                        cX = int((M["m10"] / M["m00"]) * ratio)
                        cY = int((M["m01"] / M["m00"]) * ratio)
                        shape = sd.detect(c)

                        if shape=="triangle":
                            triangles += 1
                        elif shape =="rectangle" or shape == "square":
                            squares += 1
                        compare += 1

                        # multiply the contour (x, y)-coordinates by the resize ratio,
                        # then draw the contours and the name of the shape on the image
                        c = c.astype("float")
                        c *= ratio
                        c = c.astype("int")
                        #cv2.drawContours(image, [c], -1, (0, 0, 255), 2)
                        #cv2.putText(image, shape, (cX, cY), cv2.FONT_HERSHEY_SIMPLEX,
                        #    0.5, (0, 0, 0), 2)

                except:
                    pass
                cv2.imshow("thresh",thresh)
                #cv2.imshow("Image1", image)
                #cv2.imshow("mask1", mask1)
                if cv2.waitKey(1) & 0xFF == ord('q'):
                    ser.write(chr(int(0)).encode()) # sending 0 over serial to stop movement.
                    break # Stops program if button "q" is pressed.
                time.sleep(.200)
            #analyse colors here..
            print("detected following shapes:")
            print(compare)
            print(squares)
            print(triangles)

            if compare < 20 and compare > 6:
                if triangles > squares:
                    packageSymbol = "triangle"
                    print("detected triangle!")
                if triangles < squares:
                    packageSymbol = "rectangle"
                    print("detected rectangle!")
                #stateChecking = 0
                # MOVE CAMERA DOWN
            else:
                print("didn't find sign, checking again...")

            if not packageSymbol == "":
                stateChecking = 0
                GPIO.outout(27,1)
                ser.write(chr(int(63)))
                time.sleep(0.5)
                GPIO.outout(27,0)
                ser.write(chr(int(0)))
        if not packageSymbol == "":
            print("package already defined as: " + packageSymbol)
            stateChecking = 0
            GPIO.outout(27,1)
            ser.write(chr(int(63)))
            time.sleep(0.5)
            GPIO.outout(27,0)
            ser.write(chr(int(0)))

    elif lookingForSign == 1:
        green = 0
        red = 0
        compare = 0
        for i in range(10):
            for l in range(2):
                image = vs.read()

                if l == 0:
                    mask1 = cv2.inRange(image, lower_color_green, upper_color_green)
                elif l == 1:
                    mask1 = cv2.inRange(image, lower_color_red, upper_color_red)
                resized = imutils.resize(mask1, width=300)
                ratio = mask1.shape[0] / float(resized.shape[0])

                # convert the resized image to grayscale, blur it slightly,
                # and threshold it
                #gray = cv2.cvtColor(resized, cv2.COLOR_BGR2GRAY)
                gray = resized
                blurred = cv2.GaussianBlur(gray, (7, 7), 0)
                thresh = cv2.threshold(blurred, 200, 255, cv2.THRESH_BINARY)[1] #60, 255 default

                # find contours in the thresholded image and initialize the
                # shape detector
                cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
                    cv2.CHAIN_APPROX_SIMPLE)
                cnts = imutils.grab_contours(cnts)
                sd = ShapeDetector()

                try:
                    # loop over the contours
                    for c in cnts:
                        # compute the center of the contour, then detect the name of the
                        # shape using only the contour
                        M = cv2.moments(c)
                        cX = int((M["m10"] / M["m00"]) * ratio)
                        cY = int((M["m01"] / M["m00"]) * ratio)
                        shape = sd.detect(c)

                        if (shape==packageSymbol and l==0):
                            green = green + 1
                        elif (shape==packageSymbol and l==1):
                            red = red + 1

                        compare = compare + 1

                        # multiply the contour (x, y)-coordinates by the resize ratio,
                        # then draw the contours and the name of the shape on the image
                        c = c.astype("float")
                        c *= ratio
                        c = c.astype("int")
                        #cv2.drawContours(image, [c], -1, (0, 0, 255), 2)
                        #cv2.putText(image, shape, (cX, cY), cv2.FONT_HERSHEY_SIMPLEX,
                        #    0.5, (0, 0, 0), 2)

                except:
                    pass

                cv2.imshow("thresh",thresh)
                #cv2.imshow("Image1", image).
                #cv2.imshow("mask1", mask1)
                time.sleep(.200)
        #analyse colors here..
        print("shape info:")
        print(compare)
        print(green)
        print(red)

        if compare > 30 and compare < 55:
            if (compare / (green+1)) < 5:
                print("turning right...")
                GPIO.outout(27,1)
                ser.write(chr(int(126)).encode())
                lookingForSign = 0
                time.sleep(0.6)
                GPIO.outout(27,0)
                packageSymbol = ""
            elif (compare / (red+1)) < 5:
                print("turn left...")
                GPIO.outout(27,1)
                ser.write(chr(int(2)).encode())
                lookingForSign = 0
                time.sleep(0.6)
                GPIO.outout(27,0)
                packageSymbol = ""
            else:
                print("bad shapes...")
        else:
            print("too many or not enough!")

    elif lookingForSign == 0 and stateChecking == 0:

        mask = cv2.inRange(image, lower_color_blue, upper_color_blue) # find colors between the color limits defined earlier. This image is black and white.

        edges = cv2.Canny(mask,50,100) # Find edges from the previously defined mask.
        lines = cv2.HoughLinesP(edges, 1, np.pi/180, max_slider, minLineLength=60, maxLineGap=100) # This command finds lines from the edges found previously. Lines becomes an array of line start/end coordinates

        try:
            for index, line in enumerate(lines): # This for-loop finds the line with the highest (lowest on screen) Y-coordinate. This will become the line the robot will follow as it's the line closest to the robot.
                #print("a")
                x1, y1, x2, y2 = line[0]
                if (y1 > y2):
                    if (y1 > highLineY): # If new Y coordinate is higher than previously highest Y coordinate, dump previous line and replace its line coordinates with the newly found line.
                        #print("")
                        hx1 = x1
                        tempX = x1
                        hx2 = x2
                        hy1 = y1
                        hy2 = y2
                        highLineY = y1
                elif (y2 > y1):
                    if (y2 > highLineY):
                        #print("")
                        hx1 = x1
                        hx2 = x2
                        tempX = x2
                        hy1 = y1
                        hy2 = y2
                        highLineY = y2
                else:
                    #print("what")
                    cv2.line(image, (hx1, hy1), (hx2, hy2), (255, 0, 255), 5)
            if (highLineY > 10): # This slowly reduces the previously highest Y coordinate. This mechanism is neccesary as the robot would otherwise quickly select a new totally different line, if it for a moment can't see it's previous line.
                highLineY = highLineY - 5

            cv2.line(image, (hx1, hy1), (hx2, hy2), (255, 0, 255), 5) # Draws the new line on the "img" windows.

        except:
            #print("can't find line.")
            if (highLineY > 10):
                highLineY = highLineY - 5

        if not stateChecking and not lookingForSign:
            sendLineInfo(newX = tempX, oldX = old_tempX, width = w)

        old_tempX = tempX

        try:
            cv2.imshow("Res1", image) # Displays image windows
            cv2.imshow("mask", mask) # Displays the masked window (black and white filter)
        except:
            print("can't show camera...")

    if cv2.waitKey(1) & 0xFF == ord('q'):
        ser.write(chr(int(0)).encode()) # sending 0 over serial to stop movement.
        break # Stops program if button "q" is pressed.

cleanUp()


from typing import List

from src.chain.Pool import Pool
from src.chain.blockchain import BlockChain
from src.chain.pojos import Transaction, TxType

class SwapPath:
    def __init__(self,pools:List[Pool],inToken,outToken):
        self.pools= pools
        self.inToken= inToken
        self.outToken= outToken

class CompositeSwap(Transaction):

    def __init__(self, owner: str, to: str, tokenFrom:str, tokenTo:str, pools:List[Pool], amount:float):
        super().__init__(owner=owner, type=TxType.CompositeSwap)
        self.to = to
        self.tokenFrom= tokenFrom
        self.tokenTo = tokenTo
        self.pools= pools
        self.amount = amount

    def calcPriceOnPath(swapPath:SwapPath):
        inToken = swapPath.inToken
        result = 1
        for pool in swapPath.pools:
            AtoB = pool.tokenA.symbol == inToken
            result *= pool.getSwapValueAfterFees(AtoB)
            inToken = pool.tokenB.symbol if AtoB else pool.tokenA.symbol
        return 1/result

    def checkValid(self, chain: BlockChain):
        if self.owner not in chain.wallets or self.to not in chain.wallets\
                or self.tokenFrom not in chain.tokens or self.tokenTo not in chain.tokens:
            return False

        inToken= self.tokenFrom
        for pool in self.pools:
            if inToken != pool.tokenA.symbol and inToken != pool.tokenB.symbol:
                return False
            inToken = pool.tokenB.symbol if pool.tokenA.symbol == inToken else pool.tokenA.symbol

        if inToken != self.tokenTo:
            return False

        owner = chain.wallets[self.owner]
        if self.tokenFrom not in owner.balances:
            return False
        if owner.balances[self.tokenFrom] < self.amount:
            return False

        return True

    def applyToChain(self, chain: BlockChain):
        fromWallet = chain.wallets[self.owner]
        toWallet = chain.wallets[self.to]
        inVolume= self.amount
        inToken= self.tokenFrom
        for pool in self.pools:
            inVolume= pool.swap(inToken,inVolume)
            inToken= pool.tokenB.symbol if inToken == pool.tokenA.symbol else pool.tokenA.symbol

        fromWallet.balances[self.tokenFrom] -= self.amount
        if self.tokenTo not in toWallet.balances:
            toWallet.balances[self.tokenTo]= 0
        toWallet.balances[self.tokenTo] += inVolume


# A Christmas carol in Python

lyrics = "Angels we have heard on high,\n"
lyrics += 'Sweetly singing o\'er the plains.\n'
lyrics += "And the mountains in reply,\n"
lyrics += "Echoing their joyous strains!\n"

for n in range (2):
    for i in range (3):
        if i == 0:
            lyrics += "Glor-"

        else:
            lyrics += "orrrrrr-"

        for j in range (4):
             lyrics += "o-"

    lyrics += "oria!\n"

    lyrics += "In excelsis deo!"

    if n == 0:
        lyrics += "\n"

print ( lyrics )


from collections import OrderedDict
from odoo import fields, http, _
from odoo.exceptions import AccessError
from odoo.http import request, request, route
from odoo.addons.portal.controllers.portal import CustomerPortal, pager as portal_pager
from odoo.osv.expression import OR

class CustomerPortal(CustomerPortal):

    def _prepare_portal_layout_values(self):
        values = super(CustomerPortal, self)._prepare_portal_layout_values()
        expense_sheet = request.env['hr.expense.sheet']
        user = request.env.user
        employee = request.env['hr.employee'].sudo().search([('user_id', '=', user.id)])
        expense_sheet_count = expense_sheet.sudo().search_count([('employee_id', '=', employee.id)])
        values.update({
            'expense_sheet_count': expense_sheet_count,

        })
        return values

    @http.route(['/expence_sheet/list/expenses', '/expence_sheet/list/expenses/page/<int:page>'], type='http',
                auth="public", website=True)
    def portal_expense_sheet(self, page=1, date_begin=None, date_end=None, sortby=None, filterby=None, search=None,
                             search_in='content', **kw):
        expenses_sheet = request.env['hr.expense.sheet']
        domain = []
        values = {}
        user = request.env.user
        employee = request.env['hr.employee'].sudo().search([('user_id', '=', user.id)])
        if search and search_in:
            search_domain = []
            if search_in in ('content', 'all'):
                search_domain = OR([search_domain, [('name', 'ilike', search)]])
            domain += search_domain

        domain += ([('employee_id', '=', employee.id)])
        expense_sheet_record = request.env['hr.expense.sheet'].sudo().search(domain)
        searchbar_sortings = {
            'accounting_date': {'label': _('Newest'), 'order': 'accounting_date desc'},
            'name': {'label': _('Title'), 'order': 'name'},
            'status': {'label': _('Status'), 'order': 'state'},
        }

        searchbar_filters = {
            'all': {'label': _('All'), 'domain': []},
        }

        searchbar_inputs = {
            'content': {'input': 'content', 'label': _('Search  (in Content)')},
            'employee_id': {'input': 'employee_id', 'label': _('Search in Employee')},
            'accounting_date': {'input': 'accounting_date', 'label': _('Search in Date')},
            'all': {'input': 'all', 'label': _('Search in All')},
        }

        if not sortby:
            sortby = 'name'
        order = searchbar_sortings[sortby]['order']
        if not filterby:
            filterby = 'all'
        domain += searchbar_filters[filterby]['domain']

        if search and search_in:
            search_domain = []
            if search_in in ('content', 'all'):
                search_domain = OR([search_domain, [('name', 'ilike', search)]])
            if search_in in ('employee_id', 'all'):
                search_domain = OR([search_domain, [('employee_id', 'ilike', search)]])
            if search_in in ('accounting_date', 'all'):
                search_domain = OR([search_domain, [('accounting_date', 'ilike', search)]])
            domain += search_domain

        expense_sheet_count = expenses_sheet.sudo().search_count([('employee_id', '=', employee.id)])
        pager = portal_pager(
            url="/expence_sheet/list/expenses",
            url_args={'sortby': sortby, 'filterby': filterby},
            total=expense_sheet_count,
            page=page,
            step=self._items_per_page
        )
        expenses_sheet = request.env['hr.expense.sheet'].sudo().search(domain, order=order, limit=self._items_per_page,
                                                                       offset=pager['offset'])

        values.update({
            'date': date_begin,
            'page_name': 'expenses_sheet',
            'pager': pager,
            'default_url': '/expence_sheet/list/expenses',
            'searchbar_sortings': searchbar_sortings,
            'expense_sheet_record': expenses_sheet,
            'searchbar_inputs': searchbar_inputs,
            'search_in': search_in,
            'sortby': sortby,
            'searchbar_filters': OrderedDict(sorted(searchbar_filters.items())),
            'filterby': filterby,
        })
        return request.render("portal_user_expense_submit.list_expenses_sheet", values)

    @http.route(['/my/expense_sheet_form/<int:order>'], type='http', auth="public", website=True)
    def my_sheet_expense(self, order=None, **kw):
        values = {}
        expense_sheet_form = http.request.env['hr.expense.sheet']
        values.update({
            'page_name': 'form_expense',
            'expense_sheet_form': expense_sheet_form.sudo().browse([order]),
        })

        return http.request.render('portal_user_expense_submit.expences_sheet_form_view', values)

    @http.route(['/my/expense_sheet/<int:order>'], type='http', auth="user", website=True)
    def expense_sheet_print(self, order, **kw):
        pdf, _ = request.env.ref('hr_expense.action_report_hr_expense_sheet').sudo().render_qweb_pdf([order])
        pdfhttpheaders = [
            ('Content-Type', 'application/pdf'),
            ('Content-Length', len(pdf)),
        ]
        return request.make_response(pdf, headers=pdfhttpheaders)

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:


'''
	Author: Eric Ames
	Date: 2016-03-08
	Command-line psql db manager.
	Facilitates custom queries on calibration_instruments table, along with
	cluster save/load features for recovery.
'''

import mos
import ui as screen
from instrument_manager import instrumentMenu ,reloadConnConfig
from state_manager import stateMenu ,viewConnStatus ,changeConnConfig

def changeConnStatus():
	changeConnConfig()
	reloadConnConfig()

def mainMenu():
	main = [
		["HBM CalStand Database Manager" ,None]
 		,['Update CalStand instruments' ,instrumentMenu]
 		,['Save/Load CalStand Database' ,stateMenu]
 		,['View Connection Setup' ,viewConnStatus]
 		,['Change Connection Setup' ,changeConnStatus]]
	screen.menuSelection( main)

mos.setupDir()

screen.show( '''
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\//////////////////////
Welcome to the HBM CalStand Database Manager!
//////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
''' ,True)

screen.get( 'If PCE is closed, please press ENTER.')

mainMenu()

mos.exit()


from models import Player, Vote, Team, UpdateRun
from django.conf import settings
from django.db.models import Count, Sum
import re
import json
import urllib
import os
import logging
import time

logger = logging.getLogger(__name__)

def update():
    logger.info('Starting database update...')
    start = time.time()
    init_teams()
    no_new_p = update_players()
    no_new_v, no_new_o = update_votes()
    update_orphan_players()
    end = time.time()
    duration = float('%.1f' % (end-start))
    update_run = UpdateRun(duration=duration,
                           no_new_votes=no_new_v,
                           no_new_players=no_new_p,
                           no_new_orphans=no_new_o)
    update_run.save()
    logger.info('Database updated!')
    logger.info(update_run)

def drop_db():
    Team.objects.all().delete()
    Player.objects.all().delete()
    Vote.objects.all().delete()

def init_teams():
    '''
    Initialize the Team table with the team names retrieved from Kimono.
    It removes all the entries and re-adds them.
    '''
    logger.info('Initializing teams...')
    url = settings.KIMONO['teams_url']
    teams = _get_results_collection1(url)
    teams_name = [team['name'] for team in teams]
    for team_name in teams_name:
        if not Team.objects.filter(name__iexact=team_name).exists():
            t = Team()
            t.name = team_name
            t.save()

def update_players():
    '''
    Updates the Player table with the json retrieved from Kimono.
    If a player is not in the table it creates one.
    Returns the number of new palyers added to the db
    '''
    logger.info('Updating players...')
    url = settings.KIMONO['players_url']
    players = _get_results_collection1(url)
    logger.info(' - Updating database...')
    no_new_players = 0
    for player in players:
        p = Player()
        # If the player is already in the db, using the same pk end up updating
        # the past value
        p.id = _id_from_url(player['name']['href'])
        if not Player.objects.filter(pk=p.id).exists():
            no_new_players += 1
        p.name = player['name']['text']
        p.role = _fix_role(player['role'])
        p.team = Team.objects.get(name__iexact=player['team'])
        p.price = player['price']
        # Replacing the '-' character with 0 in remaining fields
        p.attendances = _fix_zero(player['attendances'])
        p.gol = _fix_zero(player['gol'])
        p.assist = _fix_zero(player['assist'])
        p.yellow_cards = _fix_zero(player['yellow_cards'])
        p.red_cards = _fix_zero(player['red_cards'])
        p.penalties_kicked = _fix_zero(player['penalties_kicked'])
        p.penalties_scored = _fix_zero(player['penalties_scored'])
        p.penalties_missed = _fix_zero(player['penalties_missed'])
        p.penalties_saved = _fix_zero(player['penalties_saved'])
        p.vote_avg = _fix_zero(player['vote_avg'])
        p.magicvote_avg = _fix_zero(player['magicvote_avg'])
        # Storing on the db
        p.save()
    return no_new_players

def update_votes():
    '''
    Updates the Vote table with the json retrieved from Kimono.
    If a vote is not in the table it creates one.
    Returns the number of new votes and new orphan players added to the db
    '''
    logger.info('Updating votes...')
    url = settings.KIMONO['votes_url']
    votes = _get_results_collection1(url)
    # Keeping a list of players with votes but not present in the Player table
    # so that they could be added later
    logger.info(' - Updating database...')
    no_new_votes = 0
    no_new_orphans = 0
    for vote in votes:
        p_id = _id_from_url(vote['name']['href'])
        v_day = _day_from_url(vote['url'])
        # Checking if the vote already exists. If not, creates a new one, if it
        # exists it will get the current vote and update it
        try:
            v = Vote.objects.get(player__pk=p_id, day=v_day)
        except Vote.DoesNotExist:
            v = Vote()
            no_new_votes += 1
        # Creating a orphan player if there is not a player for this vote
        try:
            p = Player.objects.get(pk=p_id)
        except Player.DoesNotExist:
            p = Player(pk=p_id)
            p.role = _fix_role(vote['role'])
            p.save()
            no_new_orphans += 1
        v.player = p
        v.vote = _fix_zero(vote['vote'])
        v.gol = _fix_zero(vote['gol'])
        v.assist = _fix_zero(vote['assists'])
        v.penalties_scored_saved = _fix_zero(vote['penalties_scored_saved'])
        v.penalties_missed = _fix_zero(vote['penalties_missed'])
        v.own_gol = _fix_zero(vote['own_gol'])
        v.yellow_cards = _fix_zero(vote['yellow_cards'])
        v.red_cards = _fix_zero(vote['red_cards'])
        v.magicvote = _fix_zero(vote['own_gol'])
        v.day = v_day
        v.sub_in = _sub_in(vote['in']['class'])
        v.sub_out = _sub_out(vote['out']['class'])
        # Storing on the db
        v.save()
    return no_new_votes, no_new_orphans

def update_orphan_players():
    '''
    Finds players with no team and updates their stats querying the votes
    table
    '''
    orphans = Player.objects.exclude(team__isnull=False)
    for p in orphans:
        p.name = _name_from_id(p.id)
        p.seriea = False
        p.price = 0
        v = Vote.objects
        ag = v.filter(player__pk=p.id).aggregate(Count('pk'),
                                                 Sum('gol'),
                                                 Sum('assist'),
                                                 Sum('penalties_scored_saved'),
                                                 Sum('penalties_missed'),
                                                 Sum('own_gol'),
                                                 Sum('yellow_cards'),
                                                 Sum('red_cards'),
                                                 Sum('vote'),
                                                 Sum('magicvote'),)
        p.attendances = ag['pk__count']
        p.gol = ag['gol__sum']
        p.assist = ag['assist__sum']
        if p.role == 'P':
            p.penalties_saved = ag['penalties_scored_saved__sum']
        else:
            p.penalties_scored = ag['penalties_scored_saved__sum']
        p.penalties_missed = ag['penalties_missed__sum']
        p.own_gol = ag['own_gol__sum']
        p.yellow_cards = ag['yellow_cards__sum']
        p.red_cards = ag['red_cards__sum']
        p.vote = ag['vote__sum'] / p.attendances
        p.magicvote = ag['magicvote__sum'] / p.attendances
        p.save()

def _name_from_id(p_id):
    '''
    Uses the id to generate the name of the Player
    '''
    return ' '.join(p_id.split('_')[:-1]).title()

def _get_results_collection1(url, offset=0):
    '''
    Given an url it returns the the array 'collection1' that is present in the
    results from Kimono
    Kimono has a result limit of 2500 rows. If that limit is reached
    it recursively calls the API with increasing offsets
    '''
    logger.info(' - Contacting Kimono %s with offset %s' % (url, offset))
    key = os.environ.get('KIMONO_API_KEY')
    fp = urllib.urlopen(url + '?apikey=' + key + '&kimoffset=%i' % (offset))
    results = json.load(fp)
    collection1 = results['results']['collection1']
    if results['count'] == 2500:
        new_collection1 = _get_results_collection1(url, offset=offset + 2500)
        collection1.extend(new_collection1)
    return collection1

def _fix_zero(value):
    '''
    Replaces the character '-' with the '0'
    '''
    # Match the '-' which are not followed by a number
    regex = '-(?![0-9])'
    return re.sub(regex, '0', value)

def _fix_role(value):
    '''
    Converting 'T (C)' or 'T (A)' to 'A' or 'C'. If there is no PDCA, it return
    the same value
    '''
    result = re.sub('[^PDCA]', '', value)
    return value if not result else result

def _id_from_url(url):
    '''
    Uses the last token of the URL to generate the id to use as a primary key
    '''
    return url.split('/')[-1]

def _day_from_url(url):
    '''
    Uses the last token of the URL to generate the number of the day
    '''
    return url.split('/')[-1].split('-')[-1]

def _sub_in(sub_class):
    return "in" in sub_class

def _sub_out(sub_class):
    return "out" in sub_class