# -*- coding: utf-8 -*-
from customlog import *
from ParseConfig import *
import commands
import thread
import signal
import os
import time
import subprocess
import traceback
import platform
import sys

from db_entities import *
from ladderdb import *
from match import *

if platform.system() == "Windows":
	import win32api

from utilities import *

class ReplayReporter:
	def  __init__ ( alchemyuri, alchemyverbose, springdedclientpath, springdatapath ):
		self.springdedclientpath = springdedclientpath
		self.springdatapath = springdatapath
		db = LadderDB( alchemyuri, alchemyverbose )

	def SubmitLadderReplay( replaypath, ladderid ):
		currentworkingdir = os.getcwd()
		try:
			output = ""
			doSubmit = ladderid != -1 and db.LadderExists( ladderid )
			if not doSubmit:
				Log.Error( red + "Error: ladder %d does not exist" % ( ladderid ) + normal, 'ReplayReporter' )
				return False
			st = time.time()
			Log.Info( "*** Starting spring: command line \"%s %s\"" % (self.springdedclientpath, replaypath ), 'ReplayReporter' )
			if platform.system() == "Windows":
				dedpath = "\\".join(self.springdedclientpath.replace("/","\\").split("\\")[:self.springdedclientpath.replace("/","\\").count("\\")])
				if not dedpath in sys.path:
					sys.path.append(dedpath)
			if self.springdatapath != None:
				if not self.springdatapath in sys.path:
					sys.path.append(self.springdatapath)
				os.chdir(self.springdatapath)
				os.environ['SPRING_DATADIR'] = self.springdatapath
			pr = subprocess.Popen( (self.springdedclientpath, replaypath ),stdout=subprocess.PIPE,stderr=subprocess.STDOUT,cwd=self.springdatapath )
			l = pr.stdout.readline()
			while len(l) > 0:
				output += l
				l = pr.stdout.readline()
			status = pr.wait()
			et = time.time()
			Log.Info(  "*** Spring has exited with status %i" % status, 'ReplayReporter' )
			if status != 0:
				Log.Error( output, 'ReplayReporter' )
			elif doSubmit:
				mr = MatchToDbWrapper( output, ladderid )
				try:
					db.ReportMatch( mr )
				except:
					Log.Error( 'reporting match failed', 'ReplayReporter' )
					return False
		except:
			exc = traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2])
			Log.Error( "*** EXCEPTION: BEGIN\n%s\nEXCEPTION: END"%exc, 'ReplayReporter' )
			os.chdir(currentworkingdir)
			return False
		os.chdir(currentworkingdir)
		return True


from ModFcfif.Fcfif import AdcDevice
from ModFcfif.Fcfif import ActionAdc
from ModFcfif.Fcfif import DeviceUnion

from ModFcfif.Fcfif import AxesAdc

from ModFcfif.Fcfif import ModeAdc

from pyfcs.core.api import (
        BaseDeviceSetup, ParamProperty,
        ParamProperty,  parser,
        setup_method, payload_maker, payload_parser,
        register_device, create_mal_if
    )

__all__ = ['AdcSetup', 'AdcCommand', 'AdcAsyncCommand']

# quick create a MalIf class
AdcMalIf = create_mal_if(
        AdcDevice, DeviceUnion.getAdc, DeviceUnion.setAdc,
        action = ( 'getAction', 'setAction'),
        pos = ( 'getPos', 'setPos'),
        enc = ( 'getEnc', 'setEnc'),
        unit = ( 'getUnit', 'setUnit'),
        name = ( 'getName', 'setName'),
        speed = ( 'getSpeed', 'setSpeed'),
        posang = ( 'getPos', 'setPos'),
        axis = ( 'getAxis', 'setAxis'),
        mode = ( 'getMode', 'setMode'),

    )

# This device class is registered at the end of this file
class AdcSetup(BaseDeviceSetup):
    devtype = "adc"
    MalIf = AdcMalIf

    # ~~~~~~~~~~~~~~~  Parameters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    action = ParamProperty( parser.EnumNameParser( ActionAdc, prefix='ADC_'),
                    description = "Adc action.",
                    required = True
                    )
    pos = ParamProperty( parser.FloatParser(),
                    description = "Motor position in user units.",
                    )
    enc = ParamProperty( parser.IntParser(),
                    description = "Motor position in encoders.",
                    )
    unit = ParamProperty( parser.StringParser(enum = ['UU', 'ENC']),
                    description = "Motor position unit.",
                    )
    name = ParamProperty( parser.StringParser(),
                    description = "Motor named position.",
                    )
    speed = ParamProperty( parser.FloatParser(),
                    description = "Motor speed.",
                    )
    posang = ParamProperty( parser.FloatParser(),
                    description = "Motor position angle.",
                    )
    axis = ParamProperty( parser.EnumNameParser(AxesAdc),
                    description = "Adc axis.",
                    )
    mode = ParamProperty( parser.EnumNameParser(ModeAdc, prefix='ADC_'),
                    description = "Adc mode.",
                    )

    # ~~~~~~~~~~~~~~~ Setup/Payload Methods  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    @setup_method
    @payload_parser(action= 'MOVE_ABS', unit= 'UU')
    def move_abs_pos(self, pos, axis):
        """ move_abs_pos

        Args:
            pos (float) : Motor position in user units.
            axis (str) : Adc axis.
        """
        self.pos = pos
        self.axis = axis

        self.action = "MOVE_ABS"
        self.unit = "UU"

    @payload_maker(action= 'MOVE_ABS', unit= 'UU')
    def dump_move_abs_pos(self):
        """ dump payload when action= 'MOVE_ABS', unit= 'UU'
        """
        return {
            "action" : "MOVE_ABS",
            "unit" : "UU",

            "pos" : self.pos,
            "axis" : self.axis,
        }

    @setup_method
    @payload_parser(action= 'MOVE_ABS', unit= 'ENC')
    def move_abs_enc(self, enc, axis):
        """ move_abs_enc

        Args:
            enc (int) : Motor position in encoders.
            axis (str) : Adc axis.
        """
        self.enc = enc
        self.axis = axis

        self.action = "MOVE_ABS"
        self.unit = "ENC"

    @payload_maker(action= 'MOVE_ABS', unit= 'ENC')
    def dump_move_abs_enc(self):
        """ dump payload when action= 'MOVE_ABS', unit= 'ENC'
        """
        return {
            "action" : "MOVE_ABS",
            "unit" : "ENC",

            "enc" : self.enc,
            "axis" : self.axis,
        }

    @setup_method
    @payload_parser(action= 'MOVE_REL', unit= 'UU')
    def move_rel_pos(self, pos, axis):
        """ move_rel_pos

        Args:
            pos (float) : Motor position in user units.
            axis (str) : Adc axis.
        """
        self.pos = pos
        self.axis = axis

        self.action = "MOVE_REL"
        self.unit = "UU"

    @payload_maker(action= 'MOVE_REL', unit= 'UU')
    def dump_move_rel_pos(self):
        """ dump payload when action= 'MOVE_REL', unit= 'UU'
        """
        return {
            "action" : "MOVE_REL",
            "unit" : "UU",

            "pos" : self.pos,
            "axis" : self.axis,
        }

    @setup_method
    @payload_parser(action= 'MOVE_REL', unit= 'ENC')
    def move_rel_enc(self, enc, axis):
        """ move_rel_enc

        Args:
            enc (int) : Motor position in encoders.
            axis (str) : Adc axis.
        """
        self.enc = enc
        self.axis = axis

        self.action = "MOVE_REL"
        self.unit = "ENC"

    @payload_maker(action= 'MOVE_REL', unit= 'ENC')
    def dump_move_rel_enc(self):
        """ dump payload when action= 'MOVE_REL', unit= 'ENC'
        """
        return {
            "action" : "MOVE_REL",
            "unit" : "ENC",

            "enc" : self.enc,
            "axis" : self.axis,
        }

    @payload_parser(action= 'MOVE_ABS')
    def _move_abs(self, axis , unit , __0__, *args):
        raise ValueError("un-complete payload")

    @payload_parser(action= 'MOVE_REL')
    def _move_rel(self, axis , unit , __0__, *args):
        raise ValueError("un-complete payload")

    @setup_method
    @payload_parser(action= 'MOVE_BY_SPEED')
    def move_by_speed(self, speed, axis):
        """ move_by_speed

        Args:
            speed (float) : Motor speed.
            axis (str) : Adc axis.
        """
        self.speed = speed
        self.axis = axis

        self.action = "MOVE_BY_SPEED"

    @payload_maker(action= 'MOVE_BY_SPEED')
    def dump_move_by_speed(self):
        """ dump payload when action= 'MOVE_BY_SPEED'
        """
        return {
            "action" : "MOVE_BY_SPEED",

            "speed" : self.speed,
            "axis" : self.axis,
        }

    @setup_method
    @payload_parser(action= 'MOVE_BY_NAME')
    def move_name_pos(self, name, axis):
        """ move_name_pos

        Args:
            name (str) : Motor named position.
            axis (str) : Adc axis.
        """
        self.name = name
        self.axis = axis

        self.action = "MOVE_BY_NAME"

    @payload_maker(action= 'MOVE_BY_NAME')
    def dump_move_name_pos(self):
        """ dump payload when action= 'MOVE_BY_NAME'
        """
        return {
            "action" : "MOVE_BY_NAME",

            "name" : self.name,
            "axis" : self.axis,
        }

    @setup_method
    @payload_parser(action= 'MOVE_BY_POSANG')
    def move_by_posang(self, posang):
        """ move_by_posang

        Args:
            posang (float) : Motor position angle.
        """
        self.posang = posang

        self.action = "MOVE_BY_POSANG"

    @payload_maker(action= 'MOVE_BY_POSANG')
    def dump_move_by_posang(self):
        """ dump payload when action= 'MOVE_BY_POSANG'
        """
        return {
            "action" : "MOVE_BY_POSANG",

            "posang" : self.posang,
        }

    @setup_method
    @payload_parser(action= 'START_TRACK')
    def start_track(self, posang):
        """ start_track

        Args:
            posang (float) : Motor position angle.
        """
        self.posang = posang

        self.action = "START_TRACK"

    @payload_maker(action= 'START_TRACK')
    def dump_start_track(self):
        """ dump payload when action= 'START_TRACK'
        """
        return {
            "action" : "START_TRACK",

            "posang" : self.posang,
        }

    @setup_method
    @payload_parser(action= 'STOP_TRACK')
    def stop_track(self, ):
        """ stop_track

        Args:

        """

        self.action = "STOP_TRACK"

    @payload_maker(action= 'STOP_TRACK')
    def dump_stop_track(self):
        """ dump payload when action= 'STOP_TRACK'
        """
        return {
            "action" : "STOP_TRACK",

        }

    @setup_method
    def move(self, pos_or_enc:float , type:str = "abs", unit: str ="uu", aux_motor=""):
        """ move to a target position

        Args:
            pos_or_enc (float): target position in user unit or encoder according to unit
            type (str, optional): Type of movement - absolute ("abs", default) or relative ("rel") case unsensitive
            unit (str, optional): User units ("uu") or encoders ("enc") case unsensitive
            aux_motor (str, optional): Auxiliar motor name : 'motor1' or 'motor2'

        """
        type = type.lower()
        unit = unit.lower()
        if type == "rel":
            self.action = "MOVE_REL"
        elif type == "abs":
            self.action = "MOVE_ABS"
        else:
            raise ValueError(f"provided movement type is unknown, expecting 'rel','REL', 'abs' or 'ABS' got {type!r}" )
        if unit == "uu":
            self.unit = "UU"
            self.pos = pos_or_enc
        elif unit == "enc":
            self.unit = "ENC"
            self.enc = pos_or_enc
        else:
            raise ValueError(f"provided unit is unknown, expecting 'uu', 'UU', 'enc' or 'ENC' got {unit!r}" )
        if aux_motor == "motor1":
            self.axis = "ADC1"
        elif aux_motor == "motor2":
            self.axis = "ADC2"
        else:
            raise ValueError(f"provided auxiliar motor ({aux_motor!r}) is unknown, please use either motor1 or motor2")

# register the device. This will create the Command and AsyncCommand classes
adc_classes = register_device( AdcSetup )
AdcCommand = adc_classes.Command
AdcAsyncCommand = adc_classes.AsyncCommand


'''
Programming Challenge: String Reverser
For this challenge, you will be writing a program which uses a for loop to
reverse a string.

Start by creating a variable and assigning it a string as user input using
input().

Use a for loop to reverse the string.  You will need to use range with all
3 inputs for this.  In addition, you should create a variable before the for
loop and assign it an empty string.  The variable will be reassigned multiple
times within the for loop and end up holding the new reversed string.

Print the reversed string at the bottom of your program.
'''

def reverser(str):
    reverse = ''
    for l in range(0, len(str)):
        reverse = str[l] + reverse
    return reverse

line = input('Enter anything: \n>>> ').strip()
rline = reverser(line)
print('Reverse of {2}{0}{4} is: {3}{1}{4}'.format(line, rline, '\033[33m', '\033[35m', '\033[m'))

Solutions.New/Programming Challenge 12 - String Reverser.py


from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import json
import logging
import shlex
import six
import uuid

from flask import request

from dashboard.api import api_request_handler
from dashboard.api import api_auth
from dashboard.common import bot_configurations
from dashboard.common import cloud_metric
from dashboard.common import utils
from dashboard.pinpoint.models import change
from dashboard.pinpoint.models import errors
from dashboard.pinpoint.models import job as job_module
from dashboard.pinpoint.models import job_state
from dashboard.pinpoint.models import quest as quest_module
from dashboard.pinpoint.models import scheduler
from dashboard.pinpoint.models import task as task_module
from dashboard.pinpoint.models.tasks import performance_bisection
from dashboard.pinpoint.models.tasks import read_value

_ERROR_BUG_ID = 'Bug ID must be an integer.'
_ERROR_TAGS_DICT = 'Tags must be a dict of key/value string pairs.'
_ERROR_UNSUPPORTED = 'This benchmark (%s) is unsupported.'
_ERROR_PRIORITY = 'Priority must be an integer.'

_EXTRA_BROWSER_ARGS_PREFIX = '--extra-browser-args'
_ENABLE_FEATURES_PREFIX = '--enable-features'

REGULAR_TELEMETRY_TESTS = {
    'performance_webview_test_suite',
}
SUFFIXED_REGULAR_TELEMETRY_TESTS = {
    'performance_test_suite',
    'telemetry_perf_tests',
}
SUFFIXES = {
    '',
    '_android_chrome',
    '_android_monochrome',
    '_android_monochrome_bundle',
    '_android_webview',
    '_android_clank_chrome',
    '_android_clank_monochrome',
    '_android_clank_monochrome_64_32_bundle',
    '_android_clank_monochrome_bundle',
    '_android_clank_trichrome_bundle',
    '_android_clank_trichrome_chrome_google_64_32_bundle',
    '_android_clank_trichrome_webview',
    '_android_clank_trichrome_webview_bundle',
    '_android_clank_webview',
    '_android_clank_webview_bundle',
}
# Map from target to fallback target.
REGULAR_TELEMETRY_TESTS_WITH_FALLBACKS = {}
for test in SUFFIXED_REGULAR_TELEMETRY_TESTS:
  for suffix in SUFFIXES:
    REGULAR_TELEMETRY_TESTS_WITH_FALLBACKS[test + suffix] = test
# crbug/1439658:
# Add fallback from _android_clank_monochrome to _android_clank_chrome.
# We will use _android_clank_monochrome to replace _android_clank_chrome
# to reduce build time. The change in chromium will break pinpoint as pinpoint
# jobs running on the new commits will look for _android_clank_monochrome which
# pinpoint does not recognize.
# This will override the value set above, mapping from 'test+suffix' to 'test.
# The current logic was added two years ago to break performance_test_suite
# into smaller targets. It should be no longer is use. I added logs in
# find_isolate.py to catch possible issues.
_NEW_MONOCHROME_TARGET = 'performance_test_suite_android_clank_monochrome'
_OLD_CHROME_TARGET = 'performance_test_suite_android_clank_chrome'
REGULAR_TELEMETRY_TESTS_WITH_FALLBACKS[
    _NEW_MONOCHROME_TARGET] = _OLD_CHROME_TARGET

_NON_CHROME_TARGETS = ['v8']

def _CheckUser():
  if utils.IsDevAppserver():
    return
  api_auth.Authorize()
  if not utils.IsTryjobUser():
    raise api_request_handler.ForbiddenError()

@api_request_handler.RequestHandlerDecoratorFactory(_CheckUser)
@cloud_metric.APIMetric("pinpoint", "/api/new")
def NewHandlerPost():
  # TODO(dberris): Validate the inputs based on the type of job requested.
  job = _CreateJob(request)

  # We apply the cost-based scheduling at job creation time, so that we can
  # roll out the feature as jobs come along.
  scheduler.Schedule(job, scheduler.Cost(job))

  job.PostCreationUpdate()

  return {
      'jobId': job.job_id,
      'jobUrl': job.url,
  }

def _CreateJob(req):
  """Creates a new Pinpoint job from WebOb request arguments."""
  logging.debug('Received new job request: %s', req)
  original_arguments = utils.RequestParamsMixed(req)
  logging.debug('Received Params: %s', original_arguments)

  # This call will fail if some of the required arguments are not in the
  # original request.
  _ValidateRequiredParams(original_arguments)

  arguments = _ArgumentsWithConfiguration(original_arguments)
  if not arguments.get('target'):
    arguments['target'] = GetIsolateTarget(
        arguments.get('configuration', ''), arguments.get('benchmark'))
  logging.debug('Updated Params: %s', arguments)

  # Validate arguments and convert them to canonical internal representation.
  quests = _GenerateQuests(arguments)

  # Check target param here
  if not arguments.get('target'):
    raise ValueError('Parameter target must not be empty')

  # Validate the priority, if it's present.
  priority = _ValidatePriority(arguments.get('priority'))

  # Validate and find the associated issue.
  bug_id, project = _ValidateBugId(
      arguments.get('bug_id'), arguments.get('project', 'chromium'))
  comparison_mode = _ValidateComparisonMode(arguments.get('comparison_mode'))
  comparison_magnitude = _ValidateComparisonMagnitude(
      arguments.get('comparison_magnitude'))
  gerrit_server, gerrit_change_id = _ValidatePatch(
      arguments.get('patch', arguments.get('experiment_patch')))
  name = arguments.get('name')
  pin = _ValidatePin(arguments.get('pin'))
  tags = _ValidateTags(arguments.get('tags'))
  user = _ValidateUser(arguments.get('user'))
  changes = _ValidateChanges(comparison_mode, arguments)

  # If this is a try job, we assume it's higher priority than bisections, so
  # we'll set it at a negative priority.
  if not priority and comparison_mode == job_state.TRY:
    priority = -1

  # TODO(dberris): Make this the default when we've graduated the beta.
  use_execution_engine = (
      arguments.get('experimental_execution_engine')
      and arguments.get('comparison_mode') == job_state.PERFORMANCE)

  # Ensure that we have the required fields in tryjob requests.
  if comparison_mode == 'try':
    if 'benchmark' not in arguments:
      raise ValueError('Missing required "benchmark" argument.')

    # First we check whether there's a quest that's of type 'RunTelemetryTest'.
    is_telemetry_test = any(
        isinstance(q, quest_module.RunTelemetryTest) for q in quests)
    if is_telemetry_test and ('story' not in arguments
                              and 'story_tags' not in arguments):
      raise ValueError(
          'Missing either "story" or "story_tags" as arguments for try jobs.')

  batch_id = arguments.get('batch_id')
  if batch_id is None or batch_id == '':
    batch_id = str(uuid.uuid4())

  initial_attempt_count = arguments.get('initial_attempt_count')
  try:
    initial_attempt_count = int(initial_attempt_count)
  except (TypeError, ValueError):
    initial_attempt_count = None

  # Create job.
  try:
    job = job_module.Job.New(
        quests if not use_execution_engine else (),
        changes,
        arguments=original_arguments,
        bug_id=bug_id,
        comparison_mode=comparison_mode,
        comparison_magnitude=comparison_magnitude,
        gerrit_server=gerrit_server,
        gerrit_change_id=gerrit_change_id,
        name=name,
        pin=pin,
        tags=tags,
        user=user,
        priority=priority,
        use_execution_engine=use_execution_engine,
        project=project,
        batch_id=batch_id,
        initial_attempt_count=initial_attempt_count,
        dimensions=arguments.get('dimensions'),
        swarming_server=arguments.get('swarming_server'))
  except errors.SwarmingNoBots as e:
    six.raise_from(ValueError(str(e)), e)

  if use_execution_engine:
    # TODO(dberris): We need to figure out a way to get the arguments to be more
    # structured when it comes in from the UI, so that we don't need to do the
    # manual translation of options here.
    # TODO(dberris): Decide whether we can make some of these hard-coded options
    # be part of a template that's available in the UI (or by configuration
    # somewhere else, maybe luci-config?)
    start_change, end_change = changes
    target = arguments.get('target')
    task_options = performance_bisection.TaskOptions(
        build_option_template=performance_bisection.BuildOptionTemplate(
            builder=arguments.get('builder'),
            target=target,
            bucket=arguments.get('bucket', 'master.tryserver.chromium.perf'),
        ),
        test_option_template=performance_bisection.TestOptionTemplate(
            swarming_server=arguments.get('swarming_server'),
            dimensions=arguments.get('dimensions'),
            extra_args=arguments.get('extra_test_args'),
        ),
        read_option_template=performance_bisection.ReadOptionTemplate(
            benchmark=arguments.get('benchmark'),
            histogram_options=read_value.HistogramOptions(
                grouping_label=arguments.get('grouping_label'),
                story=arguments.get('story'),
                statistic=arguments.get('statistic'),
                histogram_name=arguments.get('chart'),
            ),
            graph_json_options=read_value.GraphJsonOptions(
                chart=arguments.get('chart'), trace=arguments.get('trace')),
            mode=('histogram_sets'
                  if target in performance_bisection.EXPERIMENTAL_TARGET_SUPPORT
                  else 'graph_json')),
        analysis_options=performance_bisection.AnalysisOptions(
            comparison_magnitude=arguments.get('comparison_magnitude'),
            min_attempts=10,
            max_attempts=60,
        ),
        start_change=start_change,
        end_change=end_change,
        pinned_change=arguments.get('patch'),
    )
    task_module.PopulateTaskGraph(
        job, performance_bisection.CreateGraph(task_options, arguments))
  return job

def _ParseExtraArgs(args):
  extra_args = []
  if args:
    try:
      extra_args = json.loads(args)
    except ValueError:
      extra_args = shlex.split(args)
  _RearrangeExtraArgs(extra_args)
  return extra_args

def _RearrangeExtraArgs(extra_args):
  n = len(extra_args)
  for i in range(n):
    if extra_args[i].startswith(_ENABLE_FEATURES_PREFIX):
      if i == 0 or extra_args[i-1] != _EXTRA_BROWSER_ARGS_PREFIX:
        extra_args[i] = _EXTRA_BROWSER_ARGS_PREFIX + '=' + extra_args[i]

def _ArgumentsWithConfiguration(original_arguments):
  # "configuration" is a special argument that maps to a list of preset
  # arguments. Pull any arguments from the specified "configuration", if any.
  new_arguments = original_arguments.copy()
  provided_args = new_arguments.get('extra_test_args', '')
  extra_test_args = []
  if provided_args:
    extra_test_args = _ParseExtraArgs(provided_args)
  new_arguments['extra_test_args'] = json.dumps(extra_test_args)
  configuration = original_arguments.get('configuration')
  if configuration:
    try:
      default_arguments = bot_configurations.Get(configuration)
    except ValueError as e:
      # Reraise with a clearer message.
      six.raise_from(
          ValueError("Bot Config: %s doesn't exist." % configuration), e)
    logging.info('Bot Config: %s', default_arguments)

    if default_arguments:
      for k, v in list(default_arguments.items()):
        # We special-case the extra_test_args argument to be additive, so that
        # we can respect the value set in bot_configurations in addition to
        # those provided from the UI.
        if k == 'extra_test_args':
          configured_args = _ParseExtraArgs(v)
          new_arguments['extra_test_args'] = json.dumps(
              extra_test_args + configured_args,)
        else:
          new_arguments.setdefault(k, v)

  return new_arguments

def _ValidateBugId(bug_id, project):
  if not bug_id:
    return None, None

  try:
    # TODO(dberris): Figure out a way to check the issue tracker if the project
    # is valid at creation time. That might involve a user credential check, so
    # we might need to update the scopes we're asking for. For now trust that
    # the inputs are valid.
    return int(bug_id), project
  except ValueError as e:
    raise ValueError(_ERROR_BUG_ID) from e

def _ValidatePriority(priority):
  if not priority:
    return None

  try:
    return int(priority)
  except ValueError as e:
    raise ValueError(_ERROR_PRIORITY) from e

def _ValidateChangesForTry(arguments):
  if 'base_git_hash' not in arguments:
    raise ValueError('base_git_hash is required for try jobs')

  commit_1 = change.Commit.FromDict({
      'repository': arguments.get('project') or arguments.get('repository'),
      'git_hash': arguments.get('base_git_hash'),
  })
  commit_2 = change.Commit.FromDict({
      'repository':
          arguments.get('project') or arguments.get('repository'),
      'git_hash':
          arguments.get(
              'end_git_hash',
              arguments.get(
                  'experiment_git_hash',
                  arguments.get('base_git_hash'),
              ),
          ),
  })

  # Now, if we have a patch argument, we need to handle the case where a patch
  # needs to be applied to both the 'end_git_hash' and the 'base_git_hash'.
  patch = arguments.get('patch')
  if patch:
    patch = change.GerritPatch.FromUrl(patch)

  exp_patch = arguments.get('experiment_patch')
  if exp_patch:
    exp_patch = change.GerritPatch.FromUrl(exp_patch)

  base_patch = arguments.get('base_patch')
  if base_patch:
    base_patch = change.GerritPatch.FromUrl(base_patch)

  if commit_1.git_hash != commit_2.git_hash and patch:
    base_patch = patch
    exp_patch = patch

  if not exp_patch:
    exp_patch = patch

  base_extra_args = _ParseExtraArgs(arguments.get('base_extra_args', ''))
  logging.debug('Base extra args: %s', base_extra_args)
  change_1 = change.Change(
      commits=(commit_1,),
      patch=base_patch,
      label='base',
      args=base_extra_args or None,
      variant=0)
  exp_extra_args = _ParseExtraArgs(arguments.get('experiment_extra_args', ''))
  logging.debug('Experiment extra args: %s', exp_extra_args)
  change_2 = change.Change(
      commits=(commit_2,),
      patch=exp_patch,
      label='exp',
      args=exp_extra_args or None,
      variant=1)
  return change_1, change_2

def _ValidateChanges(comparison_mode, arguments):
  try:
    changes = arguments.get('changes')
    if changes:
      # FromData() performs input validation.
      return [change.Change.FromData(c) for c in json.loads(changes)]

    # There are valid cases where a tryjob requests a base_git_hash and an
    # end_git_hash without a patch. Let's check first whether we're finding the
    # right combination of inputs here.
    if comparison_mode == job_state.TRY:
      return _ValidateChangesForTry(arguments)

    # Everything else that follows only applies to bisections.
    assert comparison_mode in (job_state.FUNCTIONAL, job_state.PERFORMANCE)

    if 'start_git_hash' not in arguments or 'end_git_hash' not in arguments:
      raise ValueError(
          'bisections require both a start_git_hash and an end_git_hash')

    commit_1 = change.Commit.FromDict({
        'repository': arguments.get('project') or arguments.get('repository'),
        'git_hash': arguments.get('start_git_hash'),
    })

    commit_2 = change.Commit.FromDict({
        'repository': arguments.get('project') or arguments.get('repository'),
        'git_hash': arguments.get('end_git_hash'),
    })

    if 'patch' in arguments:
      patch = change.GerritPatch.FromUrl(arguments['patch'])
    else:
      patch = None

    # If we find a patch in the request, this means we want to apply it even to
    # the start commit.
    change_1 = change.Change(commits=(commit_1,), patch=patch)
    change_2 = change.Change(commits=(commit_2,), patch=patch)

    return change_1, change_2
  except errors.BuildGerritURLInvalid as e:
    raise ValueError(str(e)) from e

def _ValidatePatch(patch_data):
  if patch_data:
    try:
      patch_details = change.GerritPatch.FromData(patch_data)
    except errors.BuildGerritURLInvalid as e:
      six.raise_from(ValueError(str(e)), e)
    return patch_details.server, patch_details.change
  return None, None

def _ValidateComparisonMode(comparison_mode):
  if not comparison_mode:
    comparison_mode = job_state.TRY
  if comparison_mode and comparison_mode not in job_module.COMPARISON_MODES:
    raise ValueError('`comparison_mode` should be one of %s. Got "%s".' %
                     (job_module.COMPARISON_MODES + (None,), comparison_mode))
  return comparison_mode

def _ValidateComparisonMagnitude(comparison_magnitude):
  if not comparison_magnitude:
    return 1.0
  return float(comparison_magnitude)

def GetIsolateTarget(bot_name, suite):
  if suite in _NON_CHROME_TARGETS:
    return ''

  # ChromeVR
  if suite.startswith('xr.'):
    return 'vr_perf_tests'

  # WebRTC perf tests
  if suite == 'webrtc_perf_tests':
    return 'webrtc_perf_tests'

  # This is a special-case for webview, which we probably don't need to handle
  # in the Dashboard (instead should just support in Pinpoint through
  # configuration).
  if 'webview' in bot_name.lower():
    return 'performance_webview_test_suite'

  # Special cases for CrOS tests -
  # performance_test_suites are device type specific.
  if 'eve' in bot_name.lower():
    return 'performance_test_suite_eve'
  if bot_name == 'lacros-x86-perf':
    return 'performance_test_suite_octopus'

  # WebEngine tests are specific to Fuchsia devices only.
  if 'fuchsia-perf' in bot_name.lower():
    return 'performance_web_engine_test_suite'

  # Each Android binary has its own target, and different bots use different
  # binaries. Mapping based off of Chromium's
  # //tools/perf/core/perf_data_generator.py
  if bot_name in ['android-go-perf', 'android-go-perf-pgo']:
    return 'performance_test_suite_android_clank_monochrome'
  if bot_name == 'android-go-wembley-perf':
    return 'performance_test_suite_android_clank_trichrome_bundle'
  if bot_name in ['android-new-pixel-perf', 'android-new-pixel-perf-pgo']:
    return ('performance_test_suite_android_clank_'
            'trichrome_chrome_google_64_32_bundle')
  if bot_name in [
      'android-new-pixel-pro-perf', 'android-new-pixel-pro-perf-pgo'
  ]:
    return ('performance_test_suite_android_clank_'
            'trichrome_chrome_google_64_32_bundle')
  if bot_name == 'android-pixel2-perf-calibration':
    return 'performance_test_suite_android_clank_monochrome_64_32_bundle'
  if bot_name == 'android-pixel2-perf-fyi':
    return 'performance_test_suite_android_clank_monochrome'
  if bot_name == 'android-pixel2-perf-aab-fyi':
    return 'performance_test_suite_android_clank_monochrome_bundle'
  if bot_name == 'android-pixel2-perf':
    return 'performance_test_suite_android_clank_monochrome_64_32_bundle'
  if bot_name in ['android-pixel4-perf', 'android-pixel4-perf-pgo']:
    return 'performance_test_suite_android_clank_trichrome_bundle'
  if bot_name in ['android-pixel6-perf', 'android-pixel6-perf-pgo']:
    return 'performance_test_suite_android_clank_trichrome_bundle'
  if bot_name in ['android-pixel6-pro-perf', 'android-pixel6-pro-perf-pgo']:
    return 'performance_test_suite_android_clank_trichrome_bundle'
  if 'android' in bot_name.lower():
    raise Exception(
        'Given Android bot %s does not have an isolate mapped to it' % bot_name)

  return 'performance_test_suite'

def _GenerateQuests(arguments):
  """Generate a list of Quests from a dict of arguments.

  GenerateQuests uses the arguments to infer what types of Quests the user wants
  to run, and creates a list of Quests with the given configuration.

  Arguments:
    arguments: A dict or MultiDict containing arguments.

  Returns:
    A tuple of (arguments, quests), where arguments is a dict containing the
    request arguments that were used, and quests is a list of Quests.
  """
  quests = arguments.get('quests')

  if quests:
    if isinstance(quests, six.string_types):
      quests = quests.split(',')
    quest_classes = []
    for quest in quests:
      if not hasattr(quest_module, quest):
        raise ValueError('Unknown quest: "%s"' % quest)
      quest_classes.append(getattr(quest_module, quest))
  else:
    target = arguments.get('target')
    logging.debug('Target: %s', target)

    if target in REGULAR_TELEMETRY_TESTS:
      quest_classes = (quest_module.FindIsolate, quest_module.RunTelemetryTest,
                       quest_module.ReadValue)
    elif target in REGULAR_TELEMETRY_TESTS_WITH_FALLBACKS:
      if 'fallback_target' not in arguments:
        fallback_target = REGULAR_TELEMETRY_TESTS_WITH_FALLBACKS[target]
        logging.debug('Adding "fallback_target" to params with value %s',
                      fallback_target)
        arguments['fallback_target'] = fallback_target
      quest_classes = (quest_module.FindIsolate, quest_module.RunTelemetryTest,
                       quest_module.ReadValue)
    elif ('performance_test_suite_eve' in target
          or 'performance_test_suite_octopus' in target):
      quest_classes = (quest_module.FindIsolate,
                       quest_module.RunLacrosTelemetryTest,
                       quest_module.ReadValue)
    elif 'performance_web_engine_test_suite' in target:
      quest_classes = (quest_module.FindIsolate,
                       quest_module.RunWebEngineTelemetryTest,
                       quest_module.ReadValue)
    elif target == 'vr_perf_tests':
      quest_classes = (quest_module.FindIsolate,
                       quest_module.RunVrTelemetryTest, quest_module.ReadValue)
    elif 'browser_test' in target:
      quest_classes = (quest_module.FindIsolate, quest_module.RunBrowserTest,
                       quest_module.ReadValue)
    elif 'instrumentation_test' in target:
      quest_classes = (quest_module.FindIsolate,
                       quest_module.RunInstrumentationTest,
                       quest_module.ReadValue)
    elif 'webrtc_perf_tests' in target:
      quest_classes = (quest_module.FindIsolate, quest_module.RunWebRtcTest,
                       quest_module.ReadValue)
    else:
      quest_classes = (quest_module.FindIsolate, quest_module.RunGTest,
                       quest_module.ReadValue)

  quest_instances = []
  for quest_class in quest_classes:
    # FromDict() performs input validation.
    quest_instances.append(quest_class.FromDict(arguments))

  return quest_instances

def _ValidatePin(pin):
  if not pin:
    return None
  return change.Change.FromData(pin)

def _ValidateTags(tags):
  if not tags:
    return {}

  tags_dict = json.loads(tags)

  if not isinstance(tags_dict, dict):
    raise ValueError(_ERROR_TAGS_DICT)

  for k, v in tags_dict.items():
    if not isinstance(k, six.string_types) or \
        not isinstance(v, six.string_types):
      raise ValueError(_ERROR_TAGS_DICT)

  return tags_dict

def _ValidateUser(user):
  return user or utils.GetEmail()

_REQUIRED_NON_EMPTY_PARAMS = {'benchmark'}

def _ValidateRequiredParams(params):
  missing = _REQUIRED_NON_EMPTY_PARAMS - set(params.keys())
  if missing:
    raise ValueError('Missing required parameters: %s' % (list(missing)))
  # Check that they're not empty.
  empty_keys = [key for key in _REQUIRED_NON_EMPTY_PARAMS if not params[key]]
  if empty_keys:
    raise ValueError('Parameters must not be empty: %s' % (empty_keys))


"""Module with classes that encapsulate generation and extraction of benchmark run parameters."""
import os
import platform
import re
import socket
import subprocess
from typing import Dict, Any, Union, Pattern
import warnings

from timedf.benchmark_utils import get_max_memory_usage

def _get_host_info() -> Dict[str, str]:
    def get_basic_host_dict() -> Dict[str, Any]:
        return {
            "server_name": os.environ.get("HOST_NAME", socket.gethostname()),
            "architecture": platform.architecture()[0],
            "machine": platform.machine(),
            "node": platform.node(),
            "os": platform.system(),
            "cpu_count": os.cpu_count(),
        }

    def match_and_assign(pattern: Union[str, Pattern[str]], output: str) -> str:
        matches = re.search(pattern, output)
        if matches is not None and len(matches.groups()) == 1:
            return matches.groups()[0]
        else:
            return ""

    def get_lspcu_dict() -> Dict[str, str]:
        """System data from lscpu"""

        lscpu_patterns = {
            "cpu_model": re.compile("^Model name: +(.+)$", flags=re.MULTILINE),
            "cpu_mhz": re.compile("^CPU MHz: +(.+)$", flags=re.MULTILINE),
            "cpu_max_mhz": re.compile("^CPU max MHz: +(.+)$", flags=re.MULTILINE),
            "cpu_l1d_cache": re.compile("^L1d cache: +(.+)$", flags=re.MULTILINE),
            "cpu_l1i_cache": re.compile("^L1i cache: +(.+)$", flags=re.MULTILINE),
            "cpu_l2_cache": re.compile("^L2 cache: +(.+)$", flags=re.MULTILINE),
            "cpu_l3_cache": re.compile("^L3 cache: +(.+)$", flags=re.MULTILINE),
        }

        try:
            data = subprocess.Popen(["lscpu"], stdout=subprocess.PIPE)
            output = str(data.communicate()[0].strip().decode())
        except FileNotFoundError:
            warnings.warn(
                "Couldn't run `lscpu` is this linux? Description of host machine will be"
                " incomplete"
            )
            output = ""
        return {t: match_and_assign(p, output) for t, p in lscpu_patterns.items()}

    def get_meminfo_dict() -> Dict[str, str]:
        """System data from /proc/meminfo"""

        proc_meminfo_patterns = {
            "mem_total": re.compile("^MemTotal: +(.+)$", flags=re.MULTILINE),
            "mem_free": re.compile("^MemFree: +(.+)$", flags=re.MULTILINE),
            "mem_available": re.compile("^MemAvailable: +(.+)$", flags=re.MULTILINE),
            "swap_total": re.compile("^SwapTotal: +(.+)$", flags=re.MULTILINE),
            "swap_free": re.compile("^SwapFree: +(.+)$", flags=re.MULTILINE),
            "huge_pages_total": re.compile("^HugePages_Total: +(.+)$", flags=re.MULTILINE),
            "huge_pages_free": re.compile("^HugePages_Free: +(.+)$", flags=re.MULTILINE),
            "hugepage_size": re.compile("^Hugepagesize: +(.+)$", flags=re.MULTILINE),
        }

        try:
            with open("/proc/meminfo", "r") as proc_meminfo:
                output = proc_meminfo.read().strip()
        except FileNotFoundError:
            warnings.warn(
                "Couldn't open `/proc/meminfo` is this linux?\n"
                "Description of host machine will be incomplete"
            )
            output = ""

        return {t: match_and_assign(p, output) for t, p in proc_meminfo_patterns.items()}

    max_memory_mb = get_max_memory_usage()
    if max_memory_mb is not None:
        max_memory_mb = str(int(max_memory_mb))

    return {
        **get_basic_host_dict(),
        **get_lspcu_dict(),
        **get_meminfo_dict(),
        "max_memory_mb": max_memory_mb,
    }

class HostParams:
    fields = tuple(_get_host_info())

    def prepare_report_dict(self):
        return _get_host_info()

class RunParams:
    fields = (
        "data_file",
        "no_ml",
        "use_modin_xgb",
        "ray_tmpdir",
        "ray_memory",
        "num_threads",
        # Optional tag to label specific runs by user
        "tag",
    )

    def _validate_params(self, params):
        diff = set(self.fields) - set(params)
        if len(diff) > 0:
            raise ValueError(f"The following params are missing: {diff}")

    def prepare_report_dict(self, params):
        self._validate_params(params)
        return {name: params[name] for name in self.fields}


# Project Euler, problem #17
# If all the numbers from 1 to 1000 (one thousand)
# inclusive were written out in words, how many letters would be used?
from num2words import num2words

count = 0
to_remove = ' -'
table = str.maketrans(dict.fromkeys(to_remove))
for i in range(1, 1001):
    count += len(num2words(i).translate(table))
print(count)


#!/usr/bin/env python3
"""
@Filename:    model.py
@Author:      dulanj
@Time:        23/01/2022 12:12
"""
import numpy as np
import torch
from models.common import DetectMultiBackend
from utils.augmentations import letterbox
from utils.general import non_max_suppression, check_img_size, scale_coords
from utils.torch_utils import select_device

class YoloModel:
    def __init__(self, model_path, loader='yolo'):
        if loader == 'yolo':
            device = "cuda:0"
            imgsz = [640, 640]
            self.stride = 32
            self.img_size = check_img_size(imgsz, s=self.stride)
            self.auto = True
            self.device = select_device(device)
            self.model = self.load_yolo(model_path)

            self.ori_image_shape = None
            self.resized_image_shape = None

    def load_yolo(self, model_path):
        """
        :param model_path:
        :return:
        """
        dnn = False
        model = DetectMultiBackend([model_path], device=self.device, dnn=dnn)
        return model

    def pre_process(self, image):
        """

        :param image:
        :return:
        """
        half = False
        self.ori_image_shape = image.shape[:2]
        # Padded resize
        img = letterbox(image, self.img_size, stride=self.stride, auto=self.auto)[0]
        self.resized_image_shape = img.shape
        # Convert
        img = img.transpose((2, 0, 1))[::-1]  # HWC to CHW, BGR to RGB
        img = np.ascontiguousarray(img)

        im = torch.from_numpy(img).to(self.device)
        im = im.half() if half else im.float()  # uint8 to fp16/32
        im /= 255  # 0 - 255 to 0.0 - 1.0
        if len(im.shape) == 3:
            im = im[None]  # expand for batch dim

        return im

    def _inference(self, image):
        """

        :param image:
        :return:
        """
        augment = False
        visualize = False
        pred = self.model(image, augment=augment, visualize=visualize)
        return pred

    def _post_process(self, pred):
        """

        :param image:
        :param boxes:
        :param scores:
        :param classes:
        :return:
        """
        conf_thres = 0.25  # confidence threshold
        iou_thres = 0.45  # NMS IOU threshold
        agnostic_nms = False
        max_det = 1000
        classes = None
        pred_out = non_max_suppression(pred, conf_thres, iou_thres, classes, agnostic_nms, max_det=max_det)
        det = pred_out[0]
        det[:, :4] = scale_coords(self.resized_image_shape, det[:, :4], self.ori_image_shape)
        det[:, 0] = det[:, 0] / self.ori_image_shape[1]
        det[:, 1] = det[:, 1] / self.ori_image_shape[0]
        det[:, 2] = det[:, 2] / self.ori_image_shape[1]
        det[:, 3] = det[:, 3] / self.ori_image_shape[0]
        return det.cpu().numpy()

    def predict(self, image):
        """

        :param image:
        :return: xyxy, conf, class
        """
        return self._post_process(self._inference(self.pre_process(image)))


import numpy as np;
import cv2;
from scipy import ndimage;
from scipy import signal

def ridge_orient(im, gradientsigma, blocksigma, orientsmoothsigma):
    rows,cols = im.shape;
    #Calculate image gradients.
    sze = np.fix(6*gradientsigma);
    if np.remainder(sze,2) == 0:
        sze = sze+1;

    gauss = cv2.getGaussianKernel(np.int(sze),gradientsigma);
    f = gauss * gauss.T;

    fy,fx = np.gradient(f);     #Gradient of Gaussian

    #Gx = ndimage.convolve(np.double(im),fx);
    #Gy = ndimage.convolve(np.double(im),fy);

    Gx = signal.convolve2d(im,fx,mode='same');
    Gy = signal.convolve2d(im,fy,mode='same');

    Gxx = np.power(Gx,2);
    Gyy = np.power(Gy,2);
    Gxy = Gx*Gy;

    #Now smooth the covariance data to perform a weighted summation of the data.

    sze = np.fix(6*blocksigma);

    gauss = cv2.getGaussianKernel(np.int(sze),blocksigma);
    f = gauss * gauss.T;

    Gxx = ndimage.convolve(Gxx,f);
    Gyy = ndimage.convolve(Gyy,f);
    Gxy = 2*ndimage.convolve(Gxy,f);

    # Analytic solution of principal direction
    denom = np.sqrt(np.power(Gxy,2) + np.power((Gxx - Gyy),2)) + np.finfo(float).eps;

    sin2theta = Gxy/denom;            # Sine and cosine of doubled angles
    cos2theta = (Gxx-Gyy)/denom;

    if orientsmoothsigma:
        sze = np.fix(6*orientsmoothsigma);
        if np.remainder(sze,2) == 0:
            sze = sze+1;
        gauss = cv2.getGaussianKernel(np.int(sze),orientsmoothsigma);
        f = gauss * gauss.T;
        cos2theta = ndimage.convolve(cos2theta,f); # Smoothed sine and cosine of
        sin2theta = ndimage.convolve(sin2theta,f); # doubled angles

    orientim = np.pi/2 + np.arctan2(sin2theta,cos2theta)/2;
    return(orientim);


''' Generic bytestream operations.

    These are functions that deal with and convert between three
    different representations of files on microcomputer cassette
    tape stoarge systems:
    - _File bytestreams_ of the contents of files on tape.
    - _Block objects_ representing blocks on tape.
    - _Block bytestreams_ of the contents of blocks on tape.

    The API of the block modules and their classes is subject to change as
    we try to genericise it for different platforms.
'''

from    importlib  import  import_module
from    itertools  import chain
from    io  import BytesIO
import  wave

from    cmtconv.audio  import samples_to_pulses, pulses_to_samples, \
    filter_clicks, samples_to_pulses_via_edge_detection, \
    pulses_to_samples2
from    cmtconv.logging  import *
from    testmc.tool  import asl

def get_block_module(platform):
    ''' Find, load and return the module containing the block classes for
        `platform`. Upper-case letters in `platform` will be translated to
        lower-case and hyphens will be removed, E.g., ``JR-200`` will be
        translated to ``jr200``.
    '''
    pnames = __package__.split('.')         # parent package
    pnames.append('platform')               # package w/block modules
    pnames.append(platform.lower().replace('-', ''))
    return import_module('.'.join(pnames))

####################################################################
#   bytestream → blocks

def read_block_bytestream(platform, stream):
    ''' Read bytes from `stream`, parse them as tape blocks for `platform`
        and return a sequence of the block objects.
    '''
    bm = get_block_module(platform)
    return bm.read_block_bytestream(stream)

def native_filename(filename):
    ''' Ensure `filename` is a `bytes` to be interpreted in the
        platform-specific character set/encoding.

        If we're given an object that includes character encoding
        information (typically `str`), we convert it to ASCII (or raise an
        error if it cannot be converted). Otherwise we assume that it's
        something that can be converted to `bytes` without specifying
        encoding information.

        `filename` may be `None`, in which case `None` will be returned.
    '''
    if filename is None:    return filename
    try:                    return bytes(filename, encoding='ASCII')
    except TypeError:       return bytes(filename)

def blocks_from_bin(platform, stream, **args):
    ''' Read file content bytes from `stream` and create a sequence of tape
        block objects representing that file as a machine-langauge program
        as it would be saved on `platform`. `loadaddr` is the default load
        address for the file; this may be ignored if load addresses are not
        supported.

        If `filename` is `None`, a default (perhaps empty) filename
        will be generated. Otherwise `filename` will be processed with
        `native_filename()`.
    '''
    bm = get_block_module(platform)
    return bm.blocks_from_bin(stream, **args)

def blocks_from_obj(platform, stream, filename=None):
    '''Read an as object and create the corresponding blocks.'''
    bm = get_block_module(platform)
    if "blocks_from_obj" in dir(bm):
        return bm.blocks_from_obj(stream, filename=filename)
    else:
        image = asl.parse_obj(stream)
        length = image.contiglen()
        start = image.startaddr
        data = image.contigbytes()
        bin_stream = BytesIO(data)
        return blocks_from_bin(platform, bin_stream, loadaddr=start,
            filename=filename)

def blocks_from_audio(platform, stream):
    '''Convert from audio to a sequence of blocks'''
    bm = get_block_module(platform)
    w = wave.open(stream, 'rb')
    if w.getnchannels() != 1 or w.getsampwidth() != 1:
        raise ValueError('Only mono 8-bit wav files are supported')
    rate = w.getframerate()
    n_samples = w.getnframes()
    samples = w.readframes(n_samples)
    sample_dur = 1.0 / rate
    v2('Rate: %d' % rate)
    v2('Duration: %f' % (sample_dur * n_samples))
    v3('Sample duration: %f microseconds' % (1000000 * sample_dur))
    v3('Samples: %d' % n_samples)
    v2('Samples min: %d' % min(samples))
    v2('Samples max: %d' % max(samples))
    # pulses = samples_to_pulses(samples, sample_dur)
    params = bm.parameters()
    gf = params.get("edge_gradient_factor", 0.5)
    pulses = samples_to_pulses_via_edge_detection(samples, sample_dur, gf)
    pulses = filter_clicks(pulses, sample_dur)
    v2('Number of pulses: %d ' % len(pulses))
    pulse_widths = [dur for (_,_,dur) in pulses]
    v2('Min pulse: %f' % min(pulse_widths))
    v2('Max pulse: %f' % max(pulse_widths))
    fr = bm.FileReader()
    (_,blocks) = fr.read_file(pulses, 0)
    return blocks

####################################################################
#   blocks → bytestream

def write_block_bytestream(platform, blocks, stream):
    ' Write out the bytes of the blocks, as they would be recorded on tape. '
    bm = get_block_module(platform)
    if 'write_block_bytestream' in dir(bm):
        return bm.write_block_bytestream(blocks, stream)
    else:
        stream.write(get_block_bytestream(blocks))

def get_block_bytestream(blocks):
    ''' Return a `bytes` containing the contents of the blocks as they
        would be recorded on tape.
    '''
    return bytes(chain(*( b.to_bytes() for b in blocks )))

def write_file_bytestream(platform, blocks, stream):
    bm = get_block_module(platform)
    if 'write_file_bytestream' in dir(bm):
        return bm.write_file_bytestream(blocks, stream)
    else:
        stream.write(get_file_bytestream(blocks))

def get_file_bytestream(blocks):
    ''' Return a `bytes` containing the contents of the file represented
        by the list of blocks.
    '''
    return bytes(chain(*( b.filedata for b in blocks )))

def blocks_to_audio(platform, blocks, stream):
    '''Write out the blocks as audio'''
    bm = get_block_module(platform)
    # Convert File to pulses
    pulses = bm.FileEncoder().encode_file(blocks)

    # Convert pulses to samples
    rate        = 44100
    sample_dur  = 1.0 / rate
    amp         = 127
    mid         = 128
    #samples     = pulses_to_samples(pulses, sample_dur, mid, mid-amp, mid+amp)
    samples     = pulses_to_samples2(pulses, sample_dur, mid-amp, mid, mid+amp)

    # Write out WAV file
    w = wave.open(stream,'wb')
    w.setnchannels(1)
    w.setsampwidth(1)
    w.setframerate(rate)
    w.writeframes(bytes(samples))


def function(s):
    if len(s) == 1 and ('lios' in s[0] or 'etra' in s[0] or 'inites' in s[0] or 'liala' in s[0] or 'etr' in s[0] or 'initis' in s[0]):
        return 'YES'
    Am = []
    Vm = []
    Nm = []
    Aw = []
    Vw = []
    Nw = []
    i = 0
    for si in s:
        if 'etra' in si:
            Nw.append([i,si])
        elif 'inites' in si:
            Vw.append([i,si])
        elif 'liala' in si:
            Aw.append([i,si])
        elif 'etr' in si:
            Nm.append([i,si])
        elif 'initis' in si:
            Vm.append([i,si])
        elif 'lios' in si:
            Am.append([i,si])
        else:
            return 'NO'
        i += 1
    if len(Nm) == 1 and len(Vm) >= 0 and len(Am) >= 0 and len(Nw) == 0 and len(Vw) == 0 and len(Aw) == 0:
        gt = 1
    elif len(Nm) == 0 and len(Vm) == 0 and len(Am) == 0 and len(Nw) == 1 and len(Vw) >= 0 and len(Aw) >= 0:
        gt = 0
    else:
        return 'NO'
    if gt == 1:
        for i in range(len(Am)):
            if Am[i][0] > Nm[0][0]:
                return 'NO'
        for i in range(len(Vm)):
            if Vm[i][0] < Nm[0][0]:
                return 'NO'
        return 'YES'
    elif gt == 0:
        for i in range(len(Aw)):
            if Aw[i][0] > Nw[0][0]:
                return 'NO'
        for i in range(len(Vm)):
            if Vw[i][0] < Nw[0][0]:
                return 'NO'
        return 'YES'
s = list(input().split())
print(function(s))

WeCode Assignments/Tuan 1.2 - tang toc tu tu/NgonNguCuaLan.py


#First we have to import all the necessary modules and functions
import matplotlib.pyplot as plt
from scipy import *
from sympy import *
from matplotlib.animation import FuncAnimation
import pandas as pd
import numpy as np

print("WELCOME !!!")
print("Wave Equation Finite-Difference")
print("Software to approximate the solution to the wave equation")

print("Please enter the values requested below.")

x = Symbol("x")
# INPUT. values that user have to enter manually
f = input("Enter u(x,0): ")
g = input("Enter du/dy(x,0): ")
l = input("Enter endpoint: ")                    # Endpont
t = eval(input("Enter Maximum Time: "))                # Maximun Time
alpha = eval(input("Enter alpha constant: "))    # constant: 1/v  v:propagation speed
m = int(input("Enter m value: "))                # number of rows,
n = int(input("Enter n value: "))                # number of columns

h = float(l)/float(m)
k = float(t)/float(n)
lam = (k*alpha)/h

def evalfun(fun,num):
    if "x" in str(fun):
        val = float(eval(str(fun.replace("x",str(num)))))
    else:
        val = float(fun)

    return val

#Create a matriz of m+1 rows and n+1 columns, cause it starst from zero
matrix = np.zeros(shape=(m+1,n+1))

# Step 2
for j in range (1,n+1):
    matrix[0][j] = 0
    matrix[m][j] = 0

# Step 3
matrix[0][0] = evalfun(f,0)
matrix[m][0] = evalfun(f,l)

# Step 4 - Initialize for t = 0 and t=k
for i in range(1,m):
    matrix[i][0] = evalfun(f,i*h)
    matrix[i][1] = (1-lam**2)*evalfun(f,i*h) + ((lam**2)/2)*(evalfun(f,(i+1)*h) + evalfun(f,(i-1)*h)) + (k*evalfun(g,i*h))

# Step 5 - Perform Matrix Multiplication
for j in range(1,n):
    for i in range(1,m):
        matrix[i][j+1] = 2*(1-lam**2)*matrix[i][j] + (lam**2)*(matrix[i+1][j]+matrix[i-1][j]) - matrix[i][j-1]

# Step 6
for j in range(0,n+1):
    t = j*k
    for i in range(0,m+1):
        x = i*h

excel_name = input("Enter the name you want for the .xlsx file:")

#save the array in an .xlsx file
df = pd.DataFrame (matrix)
filepath = excel_name + '.xlsx'
df.to_excel(filepath, index=False)

#we create a figure and its axis.
fig, ax = plt.subplots()
xdata = [0] * (m+1)                 # Create an array of zeros of size  m+1
xi = 0
for i in range(0,m+1):
    xdata[i] =xi
    xi += h                        # the distance between one dot an another

ydata = [0] * (m+1)                 # Create an array to the points in y axis
ln, = plt.plot([], [], 'r', animated=True)

yn = 0 - (float(1.5)) #+ 0.1)
yp = float(1.5) #+ 0.1

for j in range(0,n+1):
    for i in range(0,m+1):
        ydata[i] = matrix[i][j]
    plt.plot(xdata, ydata, "r")

# naming the x axis
plt.xlabel('x')
# naming the y axis
plt.ylabel('displacement')
# giving a title to my graph
plt.title('Wave Equation Finite-Difference')
ax.set_ylim(yn, yp)
plt.show()

"""
def init():
    ax.set_xlim(0, float(l))
    ax.set_ylim(yn, yp)
    ln.set_data(xdata,ydata)
    return ln,

def update(frame):
    for i in range(0,m+1):
        ydata[i] = matrix[i][frame]  # itearate trough the matrix to change the value for each frame
    ln.set_data(xdata, ydata)
    return ln,

ani = FuncAnimation(fig, update, frames=n+1,
                    init_func=init, blit=True, interval = 200,repeat=False)
plt.show()

print("Finished program!!!")

print("\nDeveloped by:")
print("Brian F. Morales A.")
print("Jose A. Carvajal B.")
print("José O. Rengifo C.")
print("Nicolás Restrepo L.")
print("Nicholas Rose")
"""

"""
\frac{\partial ^ 2 u}{\partial t ^ 2}-522^2 \frac{\partial ^ 2 u}{\partial x ^ 2}=0, \quad 0<x<1,\;0<t
"""


from __future__ import print_function

import base64
import collections
import functools
import isodate
import json
import re
import six
import sys
import time

from copy import deepcopy
from datetime import datetime, timedelta, date, time as datetime_time
from urlparse import urljoin
from urllib import quote
from itertools import tee, izip
from uuid import UUID
from uuid import uuid5 as new_uuid_mirror
from plone.uuid.interfaces import IUUID, IUUIDAware
from plone import api

import pytz

from plone.dexterity.utils import SchemaNameEncoder

from App.config import getConfiguration
from Acquisition import aq_inner
from zope.component import getMultiAdapter
from zope.component.hooks import getSite
from zope import i18n
from zope import interface
from Products.CMFCore.utils import getToolByName
from Products.CMFPlone.i18nl10n import weekdayname_msgid_abbr, monthname_msgid
from z3c.form.interfaces import ActionExecutionError
from plone.i18n.locales.languages import _languagelist
from plone.app.textfield.value import RichTextValue

from OFS.interfaces import IApplication
from Products.CMFPlone.interfaces import IPloneSiteRoot

import sedate

from seantis.reservation import error
from seantis.reservation import _

# avoid circular import of settings
_settings = None

def settings():
    global _settings

    if _settings is None:
        from seantis.reservation import settings
        _settings = settings

    return _settings

try:
    from collections import OrderedDict  # python >= 2.7
    OrderedDict  # Pyflakes
except ImportError:
    from ordereddict import OrderedDict  # python < 2.7
    OrderedDict  # Pyflakes

dexterity_encoder = SchemaNameEncoder()

class ConfigurationError(Exception):
    pass

def maybe_call(value):
    return value() if callable(value) else value

def profile(fn):
    """ Naive profiling of a function.. on unix systems only. """

    @functools.wraps(fn)
    def wrapper(*args, **kwargs):
        start = time.time()

        result = fn(*args, **kwargs)
        print(fn.__name__, 'took', (time.time() - start) * 1000, 'ms')

        return result

    return wrapper

def additional_data_dictionary(data, fti):
    """ Takes the data from a post request and puts the relevant bits into
    a dictionary with the following structure:

    {
        "form_key": {
            "desc": "Form Description",
            "interface": "The interface used",
            "values": [
                {
                    "key": "value_key",
                    "sortkey": 1-n,
                    "value": "value",
                    "desc": "Value Description"
                },
                ...
            ]
        }
    }

    Interfaces used in the reservation data are the interfaces with the
    IReservationFormSet marker set.

    The dictionary is later converted to JSON and stored on the reservation.
    """

    result = dict()
    used_data = dict([(k, v) for k, v in data.items() if v is not None])

    def values(iface, ifacekey):
        for key, value in used_data.items():
            if not key.startswith(ifacekey + '.'):
                continue

            subkey = key.split('.')[1]
            desc = iface.getDescriptionFor(subkey).title
            sortkey = iface.get(subkey).order

            yield dict(key=subkey, desc=desc, value=value, sortkey=sortkey)

    for key, info in fti.items():
        desc, iface = info[0], info[1]

        record = dict()
        record['desc'] = desc
        record['interface'] = iface.getName()
        record['values'] = list(values(iface, key))

        if not record['values']:
            continue

        result[key] = record

    return result

def merge_data_dictionaries(base, extra):
    """ Merges the given data dictionaries. The extra dictionary will overwrite
    matching keys in the base dictionary.

    """

    merged = deepcopy(base)

    for extra_form in extra:
        if extra_form in base:
            merged[extra_form]['desc'] = extra[extra_form]['desc']
            merged[extra_form]['interface'] = extra[extra_form]['interface']

            # this really should be a dict, since the key matters...
            base_values = dict(
                (i['key'], i) for i in base[extra_form]['values']
            )
            extra_values = dict(
                (i['key'], i) for i in extra[extra_form]['values']
            )

            merged[extra_form]['values'] = []

            for value in base[extra_form]['values']:
                if value['key'] in extra_values:
                    merged[extra_form]['values'].append(
                        extra_values[value['key']]
                    )
                else:
                    merged[extra_form]['values'].append(
                        base_values[value['key']]
                    )

            for value in extra[extra_form]['values']:
                if value['key'] in base_values:
                    continue
                else:
                    merged[extra_form]['values'].append(value)
        else:
            merged[extra_form] = extra[extra_form]

    return merged

def additional_data_objects(data):
    """ Takes the additional data dictionary and returns a new dictionary
    with the keys being the formsets, and the values being objects.

    An 'address' formset with 'street' and 'town' will produce this:

    {'address': obj}

    Where obj can be acccessed like this:

    obj.street
    obj.town

    """
    result = {}

    class DynamicObject(object):
        pass

    for formset in data:
        obj = DynamicObject()
        for item in data[formset]['values']:
            setattr(obj, item['key'], item['value'])

        result[formset] = obj

    return result

def zope_root():
    this = getSite()

    while not IApplication.providedBy(this):
        this = this.aq_inner.aq_parent

    return this

def plone_sites(root=None):
    root = root or zope_root()

    sites = []
    for id, item in root.items():
        if not IPloneSiteRoot.providedBy(item):
            continue

        sites.append(item)
        sites.extend(plone_sites(item))

    return sites

def mock_data_dictionary(data, formset_key='mock', formset_desc='Mocktest'):
    """ Given a dictionary of key values this function returns a dictionary
    with the same structure as additional_data_dictionary, without the use
    of interfaces.

    This function exists for testing purposes.
    """

    records = list()

    formset = dict()
    formset['desc'] = formset_desc
    formset['interface'] = 'mockinterface'
    formset['values'] = records

    for i, item in enumerate(data.items()):
        records.append(
            dict(key=item[0], sortkey=i, value=item[1], desc=item[0])
        )

    return {formset_key: formset}

def count_overlaps(dates, start, end):
    count = 0

    for otherstart, otherend in dates:
        count += overlaps(start, end, otherstart, otherend) and 1 or 0

    return count

def overlaps(start, end, otherstart, otherend):
    if otherstart <= start and start <= otherend:
        return True

    if start <= otherstart and otherstart <= end:
        return True

    return False

_requestid_expr = re.compile(r'\d')

def request_id_as_int(string):
    """Returns the id of a request as int without throwing an error if invalid
    characters are in the requested string (like ?id=11.11).

    """
    if string is None:
        return 0

    return int(''.join(re.findall(_requestid_expr, string)))

class memoize(object):
    """Decorator that caches a function's return value each time it is called.
    If called later with the same arguments, the cached value is returned, and
    not re-evaluated.
    """
    def __init__(self, func):
        self.func = func
        self.cache = {}

    def __call__(self, *args):
        try:
            return self.cache[args]
        except KeyError:
            value = self.func(*args)
            self.cache[args] = value
            return value
        except TypeError:
            # uncachable -- for instance, passing a list as an argument.
            # Better to not cache than to blow up entirely.
            return self.func(*args)

    def __repr__(self):
        """Return the function's docstring."""
        return self.func.__doc__

    def __get__(self, obj, objtype):
        """Support instance methods."""
        return functools.partial(self.__call__, obj)

@memoize
def _exposure():
    # keep direct imports out of utils as it will lead to circular imports
    from seantis.reservation import exposure
    return exposure

def compare_link(resources):
    """Builds the compare link for the given list of resources. """

    # limit the resources already on the link, as the view needs
    # at least two visible resources to be even callable
    # (another check for security is made in the resources module later)
    resources = _exposure().limit_resources(resources)

    if len(resources) < 2:
        return ''

    link = resources[0:1][0].absolute_url_path() + '?'
    compare_to = [string_uuid(r) for r in resources[1:]]

    for uuid in compare_to:
        link += 'compare_to=' + string_uuid(uuid) + '&'

    return link.rstrip('&')

def export_link(context, request, resources):
    """Builds the reservations excel export link for the
    given list of resources.

    """

    if not resources:
        return ''

    if not _exposure().for_views(context, request)('reservation-exports'):
        return ''

    return ''.join((
        context.absolute_url(),
        '/reservation-exports?uuid=',
        '&uuid='.join(
            map(string_uuid, resources)
        )
    ))

def monthly_report_link(context, request, resources):
    """Builds the monthly report link given the list of the resources
    using the current year and month."""

    if not resources:
        return ''

    # ensure that the view may be called
    if not _exposure().for_views(context, request)('monthly_report'):
        return ''

    today = datetime.now()

    url = context.absolute_url()

    # note that 'monthly_report' is copied in reports.py
    url += '/monthly_report'
    url += '?year=' + str(today.year)
    url += '&month=' + str(today.month)

    for resource in resources:
        url += '&uuid=' + string_uuid(resource)

    return url

def latest_reservations_link(context, request, resources):
    """Builds the latest reservations report link. """
    if not resources:
        return ''

    # ensure that the view may be called
    if not _exposure().for_views(context, request)('latest_reservations'):
        return ''

    return '{}/{}?uuid={}'.format(
        context.absolute_url(), 'latest_reservations',
        '&uuid='.join(map(string_uuid, resources))
    )

def get_current_language(context, request):
    """Returns the current language of the request"""
    context = aq_inner(context)
    portal_state = getMultiAdapter(
        (context, request), name=u'plone_portal_state'
    )
    return portal_state.language()

def get_current_site_language():
    """Returns the current language of the current site"""

    context = getSite()
    portal_languages = getToolByName(context, 'portal_languages')
    langs = portal_languages.getSupportedLanguages()

    return langs and langs[0] or u'en'

def get_site_email_sender():
    """Returns the default sender of emails of the current site in the
    following format: 'sendername<sender@domain>'.

    """

    site = getSite()
    address = site.getProperty('email_from_address')
    name = site.getProperty('email_from_name')

    if not address:
        return None

    if name:
        return '%s<%s>' % (name, address)
    else:
        return address

def translator(context, request):
    """Returns a function which takes a single string and translates it using
    the curried values for context & request.

    """
    def curried(text):
        return translate(context, request, text)
    return curried

def translate(context, request, text, domain=None):
    """Translates the given text using context & request."""

    # xx-xx languages will not work here, though they work when Plone does
    # it in a template. For now it does not matter as we have no country
    # specific translation available
    lang = get_current_language(context, request).split('-')[0]
    return i18n.translate(text, target_language=lang, domain=domain)

def translate_workflow(context, request, text):
    return translate(context, request, text, domain='plone')

def native_language_name(code):
    return _languagelist[code]['native']

def handle_action(action=None, success=None, message_handler=None):
    """Calls 'action' and then 'success' if everything went well or
    'message_handler' with a message if an exception happened.

    If no message_handler is given, an ActionExecutionError is raised
    with the message attached.

    """
    try:
        result = None
        if action:
            result = action()
        if success:
            success()

        return result

    except Exception as e:
        e = hasattr(e, 'orig') and e.orig or e
        handle_exception(e, sys.exc_info(), message_handler)

def form_error(msg):
    raise ActionExecutionError(interface.Invalid(msg))

def handle_exception(ex, exception_info, message_handler=None):
    if isinstance(ex, error.CustomReservationError):
        form_error(ex.msg)

    msg = error.errormap.get(type(ex))

    if not msg:
        six.reraise(*exception_info)

    if message_handler:
        message_handler(msg)
    else:
        form_error(msg)

_uuid_regex = re.compile(
    '[a-f0-9]{8}-?[a-f0-9]{4}-?[a-f0-9]{4}-?[a-f0-9]{4}-?[a-f0-9]{12}'
)

def is_uuid(obj):
    """Returns true if the given obj is a uuid. The obj may be a string
    or of type UUID. If it's a string, the uuid is checked with a regex.
    """
    if isinstance(obj, six.string_types):
        return re.match(_uuid_regex, six.text_type(obj))

    return isinstance(obj, UUID)

def string_uuid(obj):
    """ Returns the uuid as string without hyphens. Takes either UUIDs, strings
    with hyphens, objects which are IUUIDAware or objects which have a UID
    attribute. (The latter works for catalog brains). """

    if isinstance(obj, six.string_types):
        obj = str(obj)
    elif hasattr(obj, 'UID'):
        if callable(obj.UID):
            obj = obj.UID()  # plone 4.3, because
        else:
            obj = obj.UID
    elif IUUIDAware.providedBy(obj):
        obj = IUUID(obj)
    elif callable(obj):
        obj = obj()

    return UUID(str(obj)).hex

def real_uuid(obj):
    """ Same as string_uuid but casted to uuid.UUID. """
    return UUID(string_uuid(obj))

# TODO cache this incrementally
def generate_uuids(uuid, quota):
    mirror = lambda n: new_uuid_mirror(uuid, str(n))
    return [mirror(n) for n in range(1, quota)]

def uuid_query(uuid):
    """ Returns a tuple of uuids for querying the zodb. See why:
    http://stackoverflow.com/questions/10137632/
    querying-portal-catalog-using-typed-uuids-instead-of-string-uuids

    """

    uuid = string_uuid(uuid)

    if '-' in uuid:
        return (uuid.replace('-', ''), uuid)
    return (uuid, '-'.join([
        uuid[:8], uuid[8:12], uuid[12:16], uuid[16:20], uuid[20:]]))

def get_resource_by_uuid(
    uuid, ensure_portal_type='seantis.reservation.resource'
):
    """Returns the zodb object with the given uuid."""
    catalog = getToolByName(getSite(), 'portal_catalog')

    if ensure_portal_type:
        results = catalog(UID=uuid_query(uuid), portal_type=ensure_portal_type)
    else:
        results = catalog(UID=uuid_query(uuid))

    return len(results) == 1 and results[0] or None

def get_resource_title(resource, title_prefix=''):
    if hasattr(resource, '__parent__'):
        parent = resource.__parent__.title
    elif hasattr(resource, 'parent'):
        parent = resource.parent().title
    else:
        return title_prefix + resource.title

    return ' - '.join((parent, title_prefix + resource.title))

def get_reservation_quota_statement(quota):
    if quota > 1:
        return _(u'${quota} reservations', mapping={'quota': quota})
    else:
        return _(u'1 reservation')

def json_loads_object_hook(dictionary):
    for key, value in dictionary.items():
        if isinstance(value, six.string_types):
            dictionary[key] = userformdata_decode(value)
        elif isinstance(value, (list, tuple)):
            dictionary[key] = map(userformdata_decode, value)
    return dictionary

def json_loads(value):
    if value is not None:
        return json.loads(value, object_hook=json_loads_object_hook)
    else:
        return {}

def json_dumps(value):
    if value is not None:
        return json.dumps(value, cls=UserFormDataEncoder)
    else:
        return ''

class UUIDEncoder(json.JSONEncoder):
    """Encodes UUID objects as string in JSON."""
    def default(self, obj):
        if isinstance(obj, UUID):
            return string_uuid(obj)
        return json.JSONEncoder.default(self, obj)

class UserFormDataEncoder(json.JSONEncoder):
    """Encodes additional user data."""

    def default(self, obj):

        if isinstance(obj, set):
            return list(obj)

        if isinstance(obj, datetime):
            return u'__datetime__@%s' % isodate.datetime_isoformat(obj)

        if isinstance(obj, date):
            return u'__date__@%s' % isodate.date_isoformat(obj)

        if isinstance(obj, datetime_time):
            return u'__time__@%s' % isodate.time_isoformat(obj)

        if isinstance(obj, RichTextValue):
            return u'__richtext__@%s' % base64.b64encode(json.dumps(dict(
                raw=obj.raw,
                encoding=obj.encoding,
                mime=obj.mimeType,
                output_mime=obj.outputMimeType
            )))

        return json.JSONEncoder.default(self, obj)

def userformdata_decode(string):
    if not isinstance(string, six.string_types):
        return string

    if string.startswith(u'__date__@'):
        return isodate.parse_date(string[9:])

    if string.startswith(u'__datetime__@'):
        return isodate.parse_datetime(string[13:])

    if string.startswith(u'__time__@'):
        return isodate.parse_time(string[9:])

    if string.startswith(u'__richtext__@'):
        data = json.loads(base64.b64decode(string[13:]))
        return RichTextValue(
            raw=data['raw'],
            mimeType=data['mime'],
            outputMimeType=data['output_mime'],
            encoding=data['encoding']
        )

    return string

def as_human_readable_string(value):
    if isinstance(value, six.string_types):
        return value

    if isinstance(value, datetime):
        # don't use strftime here because users may end up entering year '3'
        # strftime does not suppport years before 1900, which is just lame
        # in this case we just use the German locale for now..
        if value.year < 1900:
            return '%02d.%02d.%04d %02d:%02d' % (
                value.day,
                value.month,
                value.year,
                value.hour,
                value.minute
            )
        else:
            return localize_date(value, long_format=True)

    if isinstance(value, date):
        if value.year < 1900:
            return '%02d.%02d.%04d' % (
                value.day,
                value.month,
                value.year
            )
        else:
            dt = datetime(value.year, value.month, value.day)
            return localize_date(dt, long_format=False)

    if isinstance(value, RichTextValue):
        return value.output

    if value is True:
        return _(u'Yes')

    if value is False:
        return _(u'No')

    if value is None:
        return u''

    if isinstance(value, (list, tuple)):
        return ', '.join(as_human_readable_string(v) for v in value)

    return value

def event_class(availability):
    """Returns the event class to be used depending on the availability."""

    s = settings()

    available = s.get('available_threshold')
    partly = s.get('partly_available_threshold')

    if availability >= available:
        return 'event-available'
    elif partly <= availability and availability < available:
        return 'event-partly-available'
    else:
        return 'event-unavailable'

def allocation_class(allocation):
    """Returns the class set on the fullcalendar event for the allocation."""
    if allocation.approve_manually:
        return 'approve-manually'
    else:
        return 'approve-automatically'

def event_availability(
    context, request, scheduler, allocation, start=None, end=None
):
    """ Returns the availability, the text with the availability and the class
    for the availability to display on the calendar view.

    If start and end are given and the allocation is partly_available
    the availability is set to 100% if the scheduler's find_spot method
    returns True. That is if the timespan between start and end
    is completely reservable.

    This is very involved and slow, so you probably shouldn't use that.
    This feature tries to account for the fact that parts of allocations
    can be reserved in search, where the user gets the impression that
    the time he entered is the actual allocation, when that timespan might
    only refer to a part of the allocation.

    For now this will be a new features which we'll test against. In the
    future this needs to be made much faster => TODO.

    """
    translate = translator(context, request)

    if start and end and allocation.partly_available:
        availability = allocation.find_spot(start, end) and 100 or 0
    else:
        availability = scheduler.availability(allocation.start, allocation.end)

    spots = int(round(allocation.quota * availability / 100))

    # get the title shown on the calendar block
    if allocation.partly_available:
        text = translate(_(u'%i%% Free')) % availability
    else:
        if allocation.quota > 1:
            text = translate(_(u'%i/%i Spots Available')) % (
                spots, allocation.quota
            )
        else:
            text = translate(_(u'%i/%i Spot Available')) % (
                spots, allocation.quota
            )

    # with approval the number of people in the waitinglist have to be shown
    if allocation.approve_manually:
        length = allocation.waitinglist_length
        if length == 0:
            text += '\n' + translate(_(u'Waitinglist is Free'))
        elif length == 1:
            text += '\n' + translate(_(u'One Person Waiting'))
        else:
            text += '\n' + translate(_(u'%i People Waiting')) % length

    return (
        availability,
        text,
        ' '.join((event_class(availability), allocation_class(allocation)))
    )

def flatten(l):
    """Generator for flattening irregularly nested lists. 'Borrowed' from here:

    http://stackoverflow.com/questions/2158395/
    flatten-an-irregular-list-of-lists-in-python
    """
    for el in l:
        if isinstance(el, collections.Iterable) and \
                not isinstance(el, six.string_types):
            for sub in flatten(el):
                yield sub
        else:
            yield el

def pack(v):
    """Puts v in a list if not already an iterator."""
    return [v] if not hasattr(v, '__iter__') else v

def pairs(l):
    """Takes any list and returns pairs:
    ((a,b),(c,d)) => ((a,b),(c,d))
    (a,b,c,d) => ((a,b),(c,d))

    http://opensourcehacker.com/2011/02/23/
    tuplifying-a-list-or-pairs-in-python/
    """
    l = list(flatten(l))
    return zip(*[l[x::2] for x in (0, 1)])

def pairwise(iterable):
    """Almost like pairs, but not quite:
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    """
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

def safe_parse_int(value, default):
    try:
        return int(value)
    except (ValueError, TypeError):
        return default

def get_config(key):
    config = getConfiguration()
    if not hasattr(config, 'product_config'):
        raise ConfigurationError('No configuration found.')

    configuration = config.product_config.get('seantis.reservation', dict())
    return configuration.get(key)

# obsolete in python 2.7
def total_timedelta_seconds(td):
    return (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10 ** 6) / \
        10 ** 6

def utc_mktime(utc_tuple):
    """Returns number of seconds elapsed since epoch

    Note that no timezone are taken into consideration.

    utc tuple must be: (year, month, day, hour, minute, second)

    """

    if len(utc_tuple) == 6:
        utc_tuple += (0, 0, 0)
    return time.mktime(utc_tuple) - time.mktime((1970, 1, 1, 0, 0, 0, 0, 0, 0))

def utctimestamp(dt):
    dt = dt.replace(tzinfo=pytz.utc)
    return utc_mktime(dt.timetuple())

def utcnow():
    """Returns the utc now function result with the correct timezone set. """
    return datetime.utcnow().replace(tzinfo=pytz.utc)

def merge_reserved_slots(slots):
    """Given a list of reserved slots a list of tuples with from-to datetimes
    is formed, with adjacent slots being combined into one continious timespan.
    Usually this leaves reserved_slots be, but if the slots in the list come
    from a partially available allocation the reserved_slots of such an
    allocation can be merged into one timespan.

    So instead of
    08:00 - 08:14:59:59
    08:15 - 08:29:59:59

    You'll get
    08:00 - 08:30

    for this, the display_start and display_end of ResourceSlot are used."""

    class Timespan(object):
        def __init__(self, start, end):
            self.start = start
            self.end = end

    if len(slots) == 1:
        return [Timespan(slots[0].start, slots[0].end)]

    slots = sorted(slots, key=lambda s: s.start)

    merged = []
    current = Timespan(None, None)

    for this, next in pairwise(slots):

        if abs((next.start - this.end).seconds) <= 1:
            current.start = current.start and current.start or this.start
            current.end = next.end
        else:
            merged.append(current)
            current = Timespan(None, None)

    if current.start:
        merged.append(current)

    return merged

def urlparam(base, url, params):
    """Joins an url, adding parameters as query parameters."""
    if not base.endswith('/'):
        base += '/'

    urlquote = lambda fragment: quote(six.text_type(fragment).encode('utf-8'))
    querypair = lambda pair: pair[0] + '=' + urlquote(pair[1])

    query = '?' + '&'.join(map(querypair, params.items()))
    return ''.join(functools.reduce(urljoin, (base, url, query)))

class EventUrls(object):
    def __init__(self, resource, request, exposure):
        self.resource = resource
        self.base = resource.absolute_url_path()
        self.request = request
        self.translate = translator(resource, request)
        self.menu = {}
        self.order = []
        self.exposure = exposure
        self.default = ""
        self.move = ""

    @memoize
    def restricted_url(self, view):
        """Returns a function which can be used to build an url with optional
        parameters. The function only builds the url if the current user has
        the right to do so.

        """
        base = self.resource.absolute_url_path()
        is_exposed = self.exposure.for_views(self.resource, self.request)

        def build(params):
            if is_exposed(view):
                return urlparam(base, view, params)
            else:
                return None

        # return closure
        return build

    @memoize
    def get_restricted(self, view, params):
        urlfactory = self.restricted_url(view)
        if not urlfactory:
            return None

        return urlfactory(params)

    def menu_add(self, group, name, view, params, target):
        url = self.get_restricted(view, params)
        if not url:
            return

        group = self.translate(group)
        name = self.translate(name)

        if group not in self.menu:
            self.menu[group] = []
            self.order.append(group)

        self.menu[group].append(dict(name=name, url=url, target=target))

    def default_url(self, view, params):
        url = self.get_restricted(view, params)
        if not url:
            return

        self.default = url

    def move_url(self, view, params):
        url = self.get_restricted(view, params)
        if not url:
            return

        self.move = url

def get_date_range(day, start_time, end_time):
    """Returns the date-range of a date a start and an end time."""
    start = datetime.combine(day, start_time)
    end = datetime.combine(day, end_time)

    # since the user can only one date with separate times it is assumed
    # that an end before a start is meant for the following day
    if end < start:
        end += timedelta(days=1)

    return start, end

def flash(context, message, type='info'):
    context.plone_utils.addPortalMessage(message, type)

def month_name(context, request, month):
    """Returns the text for the given month (1-12)."""
    assert (1 <= month and month <= 12)
    msgid = monthname_msgid(month)
    return translate(context, request, msgid, 'plonelocales')

def weekdayname_abbr(context, request, day):
    """Returns the text for the given day (0-6), 0 being sunday.
    Since 0 is sunday in the plone function and monday in the python stdlib
    you might want to shift the day.weekday() result"""
    assert (0 <= day and day <= 6)
    msgid = weekdayname_msgid_abbr(day)
    return translate(context, request, msgid, 'plonelocales')

def shift_day(stdday):
    return abs(0 - (stdday + 1) % 7)

def whole_day(start, end):
    """Returns true if the given start, end range should be considered
    a whole-day range. This is so if the start time is 0:00:00 and the end
    time either 0:59:59 or 0:00:00 and if there is at least a diff
    erence of 23h 59m 59s / 86399 seconds between them.

    This is relevant for the calendar-display for now. This might very well be
    replaced again in the future when we introduce timezones.

    """

    assert start <= end, "The end needs to be equal or greater than the start"

    if isinstance(start, datetime_time):
        start = datetime(2000, 1, 1, start.hour, start.minute, start.second)

    if isinstance(end, datetime_time):
        end = datetime(2000, 1, 1, end.hour, end.minute, end.second)

    if (start.hour, start.minute, start.second) != (0, 0, 0):
        return False

    if (end.hour, end.minute, end.second) not in ((0, 0, 0), (23, 59, 59)):
        return False

    if (end - start).total_seconds() < 86399:
        return False

    return True

def context_path(context):
    """Returns the physical path for brains and objects alike."""

    if hasattr(context, 'getPath'):
        return context.getPath().split('/')  # same as getPhysicalPath
    else:
        return context.getPhysicalPath()

def portal_type_in_site(portal_type):
    catalog = getToolByName(getSite(), 'portal_catalog')
    results = catalog(portal_type=portal_type)

    return results

def portal_type_in_context(context, portal_type, depth=1):
    """Returns the given portal types _within_ the current context."""

    path = '/'.join(context_path(context))

    catalog = getToolByName(context, 'portal_catalog')
    results = catalog(
        portal_type=portal_type,
        path={'query': path, 'depth': depth}
    )
    return results

def portal_type_by_context(context, portal_type):
    """Returns the given portal_type _for_ the current context. Portal types
    for a context are required by traversing up the acquisition context.

    """

    # As this code is used for backend stuff that needs to be callable for
    # every user the idea is to do an unrestricted traverse.

    # Calling unrestrictedTraverse first seems to work with the supposedly
    # restricted catalog.

    path = context_path(context)
    context = context.aq_inner.unrestrictedTraverse(path)

    def traverse(context, portal_type):
        frames = portal_type_in_context(context, portal_type)
        if frames:
            return [f.getObject() for f in frames]
        else:
            if not hasattr(context, 'portal_type'):
                return []
            if context.portal_type == 'Plone Site':
                return []

            parent = context.aq_inner.aq_parent
            return traverse(parent, portal_type)

    return traverse(context, portal_type)

def align_date_to_day(date, direction):
    """ Aligns the given date to the beginning or end of the day, depending on
    the direction.

    E.g.
    2012-1-24 10:00 down -> 2012-1-24 00:00
    2012-1-24 10:00 up   -> 2012-1-24 23:59:59'999999

    """
    assert direction in ('up', 'down')

    aligned = (0, 0, 0, 0) if direction == 'down' else (23, 59, 59, 999999)

    if (date.hour, date.minute, date.second, date.microsecond) == aligned:
        return date

    if direction == 'down':
        return date.replace(hour=0, minute=0, second=0, microsecond=0)
    else:
        date = date.replace(hour=0, minute=0, second=0, microsecond=0)
        return date + timedelta(days=1, microseconds=-1)

def align_range_to_day(start, end):
    assert start <= end, "{} - {} is an invalid range".format(start, end)

    return align_date_to_day(start, 'down'), align_date_to_day(end, 'up')

def localize_date(
    datetime, long_format=False, time_only=False, local_tz=False
):
    """ Like plone.api.get_localized_time, but with the ability to ignore
    the timezone (which is considered by get_localized_time if present).

    """

    if not local_tz:
        datetime = datetime.replace(tzinfo=None)

    return api.portal.get_localized_time(datetime, long_format, time_only)

def display_date(start, end):
    """ Formates the date range given for display. """

    timezone = settings().timezone()

    start = sedate.to_timezone(start, timezone)
    end = sedate.to_timezone(end, timezone)

    if end.microsecond != 999999:
        end -= timedelta(microseconds=1)

    if (start, end) == align_range_to_day(start, end):
        if start.date() == end.date():
            return localize_date(start, long_format=False)
        else:
            return ' - '.join((
                localize_date(start, long_format=False),
                localize_date(end, long_format=False)
            ))

    end += timedelta(microseconds=1)

    if start.date() == end.date():
        return ' - '.join((
            localize_date(start, long_format=True),
            localize_date(end, time_only=True)
        ))
    else:
        return ' - '.join((
            localize_date(start, long_format=True),
            localize_date(end, long_format=True)
        ))

class United(object):
    """ Puts items added through 'append' into the same group as the last
    item which was appended, as long as the matchfn which is passed the last
    and the current item returns true.

    e.g.

    united = United(lambda last, current: last == current)

    united.append(1)
    -> united.groups => [[1]]

    united.append(1)
    -> united.groups => [[1, 1]]

    united.append(2)
    -> united.groups => [[1, 1], [2]]

    united.append(1)
    -> united.groups => [[1, 1], [2], [1]]

    """

    def __init__(self, matchfn):
        self.matchfn = matchfn
        self.groups = []
        self.new_group()

    def new_group(self):
        self.groups.append([])

    @property
    def current_group(self):
        return self.groups[-1]

    def append(self, item):
        if not self.current_group:
            self.current_group.append(item)
        else:
            if not self.matchfn(self.current_group[-1], item):
                self.new_group()

            self.current_group.append(item)

def unite(iterator, matchfn):
    """ Iterates through the given records and groups the records if two
    records passed to the match function result in True.

    e.g.

    unite([1, 1, 1, 2, 2], lambda last, current: last == current)

    -> [[1, 1, 1], [2, 2]]

    Note that for this to work the records need to be sorted, not unlike
    when using the collection's group function. See 'United' doc above to
    learn why.
    """

    united = United(matchfn)

    for item in iterator:
        united.append(item)

    return united.groups

def unite_dates(dates):
    """ Takes a list of start / end date tuples and compacts it by merging
    dates which can be considered an unbroken range.

    So given a list like this:

        [
            (01.01.2012 00:00, 02.01.2012 00:00),
            (02.01.2012 00:00, 03.01.2012 00:00),
            (05.01.2012 00:00, 06.01.2012 00:00)
        ]

    (Where the dates are actually datetime instances)

    We should get this result:

        [
            (01.01.2012 00:00, 03.01.2012 00:00),
            (05.01.2012 00:00, 06.01.2012 00:00)
        ]

    """
    sorted_dates = sorted(dates, key=lambda pair: pair[0])
    for group in unite(sorted_dates, lambda this, next: this[1] == next[0]):
        yield group[0][0], group[-1][1]

class cached_property(object):
    """A read-only @property that is only evaluated once. The value is cached
    on the object itself rather than the function or class; this should prevent
    memory leakage."""

    def __init__(self, fget, doc=None):
        self.fget = fget
        self.__doc__ = doc or fget.__doc__
        self.__name__ = fget.__name__
        self.__module__ = fget.__module__

    def __get__(self, obj, cls):
        if obj is None:
            return self
        obj.__dict__[self.__name__] = result = self.fget(obj)
        return result


import json
# cycle types are "compound" or "withdraw"

class Iteration:
    def __init__(self, id, type, endTimerAt, minimumBnb):
        self.id = id
        self.type = type
        self.endTimerAt = endTimerAt
        self.minimumBnb = minimumBnb

def build_cycle_from_config():
    cycle = []
    cycle_file = open('cycle_config.json')
    cycle_json = json.load(cycle_file)
    for iteration in cycle_json['cycle']:
        iterationClass = Iteration(**iteration)
        cycle.append(iterationClass)
    return cycle

def getNextCycleId():
    cycle_file = open('cycle_config.json')
    cycle_json = json.load(cycle_file)
    return cycle_json['nextCycleId']

def updateNextCycleId(newId):
    with open("cycle_config.json", "r+") as cycle_file:
        data = json.load(cycle_file)

        # The change
        data['nextCycleId'] = newId

        cycle_file.seek(0)
        json.dump(data, cycle_file)
        cycle_file.truncate()


import json

#将数据加载到一个列表上
#采用相对路径
filename = './download_data/btc_json_2017.json'
with open(filename, 'r') as f_json:
    btc_data = json.load(f_json)
#打印每一天的信息
for btc_dir in btc_data:
    date = btc_dir['date']
    month = int(btc_dir['month'])
    week = int(btc_dir['week'])
    weekday = btc_dir['weekday']
    close = float(btc_dir['close'])
    print("{} is month {} week {}, {}, the close price is {} RMB".format(date, month, week, weekday, close))


import numpy as np
from csdl import Model
import csdl
from csdl_om import Simulator

class AtmosphereModel(Model):
    def initialize(self):
        self.parameters.declare('shape', types=tuple)
    def define(self):
        shape = self.parameters['shape']
        h = self.declare_variable('z',shape=shape, val=0) * 1e-3 # value in meters; then convert to km
        L = 6.5 # K/km
        R = 287
        T0 = 288.16
        P0 = 101325
        g0 = 9.81
        mu0 = 1.735e-5
        S1 = 110.4
        gamma = 1.4

        # Temperature
        T           =  - h * L + T0

        # Pressure
        P           = P0 * (T/T0)**(g0/(L * 1e-3)/R)

        # Density
        rho         = P/R/T

        # Dynamic viscosity (using Sutherland's law)
        mu          = mu0 * (T/T0)**(3/2) * (T0 + S1)/(T + S1)

        # speed of sound
        a = (gamma * R * T)**0.5

        self.register_output('temperature',T)
        self.register_output('pressure',P)
        self.register_output('density',rho)
        self.register_output('dynamic_viscosity',mu)
        self.register_output('speed_of_sound', a)

# sim = Simulator(AtmosphereModel(
#     shape=(1,),
# ))
# sim.run()

# sim.prob.check_totals(of='temperature',wrt='altitude')
# sim.prob.check_totals(of='pressure',wrt='altitude')
# sim.prob.check_totals(of='density',wrt='altitude')
# sim.prob.check_totals(of='dynamic_viscosity',wrt='altitude')
# sim.prob.check_totals(of='speed_of_sound',wrt='altitude')

# print('temperature [K]: ', sim['temperature'])
# print('pressure [Pa]: ',sim['pressure'])
# print('density [kg/m^3]: ',sim['density'])
# print('dynamic_viscosity [N s/m^2]: ',sim['dynamic_viscosity'])
# print('speed_of_sound [m/s]: ', sim['speed_of_sound'])


# image_route

from db import get_session
import io

def fetch_images(sid:str, num_imgs:int = 1):

    query = _build_image_query(sid, num_imgs)
    with get_session() as session:
        res = session.execute(query)
    return _build_response(res)

def _build_image_query(sid, num_imgs):
    return f"""
            SELECT
                time, attachment
            FROM
                data.sdata
            WHERE
                sid='{sid}'
                AND
                attachment is NOT NULL
            ORDER BY
                time desc
            LIMIT {num_imgs};
            """

def _build_response(result):
    resp = {}
    for row in result:
        resp[str(row.time)] = row.attachment.tobytes()
    return io.BytesIO(row.attachment.tobytes())
"""
29	"c_contiguous"
30	"cast"
31	"contiguous"
32	"f_contiguous"
33	"format"
34	"hex"
35	"itemsize"
36	"nbytes"
37	"ndim"
38	"obj"
39	"readonly"
40	"release"
41	"shape"
42	"strides"
43	"suboffsets"
44	"tobytes"
45	"tolist"
46	"toreadonly"
"""


import json
from pathlib import Path
from typing import Union

class FlowFile(object):
    def __init__(self, file_path: Union[str, Path]) -> None:
        if not isinstance(file_path, Path):
            file_path = Path(file_path)

        with file_path.open("r") as data:
            self._flow = json.load(data)

    @property
    def input_file_path(self) -> str:
        return self._flow["nodes"][0]["parameters"]["dataset_definition"][
            "s3ExecutionContext"
        ]["s3Uri"]

    @property
    def output_name(self) -> str:
        node_name = f"{self._flow['nodes'][-1]['node_id']}"
        output_name = f"{self._flow['nodes'][-1]['outputs'][0]['name']}"
        return f"{node_name}.{output_name}"

    @property
    def input_name(self) -> str:
        return self._flow["nodes"][0]["parameters"]["dataset_definition"]["name"]