from snovault import (
    AuditFailure,
    audit_checker,
)
from .conditions import (
    rfa,
)
from .standards_data import pipelines_with_read_depth

current_statuses = ['released', 'in progress']
not_current_statuses = ['revoked', 'obsolete', 'deleted']
raw_data_formats = [
    'fastq',
    'csfasta',
    'csqual',
    'rcc',
    'idat',
    'CEL',
    ]

paired_end_assays = [
    'RNA-PET',
    'ChIA-PET',
    'DNA-PET',
    ]

# def audit_file_pipeline_status(value, system): removed at release 56
# http://redmine.encodedcc.org/issues/5017

# def audit_file_md5sum_integrity(value, system): # removed release 55

@audit_checker('File', frame=['derived_from'])
def audit_file_processed_derived_from(value, system):
    if value['output_category'] in ['raw data',
                                    'reference']:
        return
    if 'derived_from' not in value or \
       'derived_from' in value and len(value['derived_from']) == 0:
            detail = 'derived_from is a list of files that were used to create a given file; ' + \
                     'for example, fastq file(s) will appear in the derived_from list of an alignments file. ' + \
                     'Processed file {} '.format(value['@id']) + \
                     'is missing the requisite file specification in its derived_from list.'
            yield AuditFailure('missing derived_from',
                               detail, level='INTERNAL_ACTION')
            return

    if value['file_format'] != 'bam':
        return

    derived_from_files = value.get('derived_from')
    fastq_bam_counter = 0
    for f in derived_from_files:
        if f['status'] not in ['deleted', 'replaced', 'revoked'] and \
           (f['file_format'] == 'bam' or
            f['file_format'] == 'fastq' or (f['file_format'] == 'fasta' and
                                            f['output_type'] == 'reads' and
                                            f['output_category'] == 'raw data')):
            fastq_bam_counter += 1
            if f['dataset'] != value['dataset']:
                detail = 'derived_from is a list of files that were used to create a given file; ' + \
                         'for example, fastq file(s) will appear in the derived_from list of an alignments file. ' + \
                         'Alignments file {} '.format(value['@id']) + \
                         'from experiment {} '.format(value['dataset']) + \
                         'specifies a file {} '.format(f['@id']) + \
                         'from a different experiment {} '.format(f['dataset']) + \
                         'in its derived_from list.'
                yield AuditFailure('inconsistent derived_from',
                                   detail, level='INTERNAL_ACTION')
    if fastq_bam_counter == 0:
        detail = 'derived_from is a list of files that were used to create a given file; ' + \
                 'for example, fastq file(s) will appear in the derived_from list of an alignments file. ' + \
                 'Alignments file {} '.format(value['@id']) + \
                 'is missing the requisite file specification in its derived_from list.'
        yield AuditFailure('missing derived_from',
                           detail, level='INTERNAL_ACTION')

# def audit_file_derived_from_revoked(value, system): removed at release 56
# http://redmine.encodedcc.org/issues/5018

@audit_checker('File', frame=['derived_from'])
def audit_file_assembly(value, system):
    if 'derived_from' not in value:
        return
    for f in value['derived_from']:
        if f.get('assembly') and value.get('assembly') and \
           f.get('assembly') != value.get('assembly'):
                detail = 'Processed file {} '.format(value['@id']) + \
                         'assembly {} '.format(value['assembly']) + \
                         'does not match assembly {} of the file {} '.format(
                         f['assembly'],
                         f['@id']) + \
                    'it was derived from.'
                yield AuditFailure('inconsistent assembly',
                                   detail, level='INTERNAL_ACTION')
                return

@audit_checker('File', frame=['replicate', 'replicate.experiment',
                              'derived_from', 'derived_from.replicate',
                              'derived_from.replicate.experiment'])
def audit_file_biological_replicate_number_match(value, system):

    if 'replicate' not in value:
        return

    if 'derived_from' not in value or len(value['derived_from']) == 0:
        return

    bio_rep_number = value['replicate']['biological_replicate_number']
    tech_rep_number = value['replicate']['technical_replicate_number']
    file_replicate = (bio_rep_number, tech_rep_number)
    file_exp_accession = value['replicate']['experiment']['accession']
    derived_from_files = value['derived_from']

    for derived_from_file in derived_from_files:
        if 'replicate' in derived_from_file:

            # excluding control files from different experiments
            if derived_from_file['replicate']['experiment']['accession'] != file_exp_accession:
                continue

            derived_bio_rep_num = derived_from_file['replicate']['biological_replicate_number']
            derived_tech_rep_num = derived_from_file['replicate']['technical_replicate_number']
            derived_replicate = (derived_bio_rep_num, derived_tech_rep_num)
            if file_replicate != derived_replicate:
                detail = 'File {} '.format(value['@id']) + \
                         'is associated with replicate [{},{}] '.format(file_replicate[0],
                                                                        file_replicate[1]) + \
                         ', but it was derived from file {} '.format(derived_from_file['@id']) + \
                         'which is associated with a replicate [{},{}].'.format(
                             derived_replicate[0],
                             derived_replicate[1])
                yield AuditFailure('inconsistent replicate',
                                   detail, level='ERROR')
                return

@audit_checker('File', frame=['replicate', 'dataset', 'replicate.experiment'])
def audit_file_replicate_match(value, system):
    '''
    A file's replicate should belong to the same experiment that the file
    does.  These tend to get confused when replacing objects.
    '''

    if 'replicate' not in value:
        return

    rep_exp = value['replicate']['experiment']['uuid']
    file_exp = value['dataset']['uuid']

    if rep_exp != file_exp:
        detail = 'File {} from experiment {} '.format(value['@id'], value['dataset']['@id']) + \
                 'is associated with replicate [{},{}] '.format(
                     value['replicate']['biological_replicate_number'],
                     value['replicate']['technical_replicate_number']) + \
                 '{}, but that replicate is associated with a different '.format(
                     value['replicate']['@id']) + \
                 'experiment {}.'.format(value['replicate']['experiment']['@id'])
        yield AuditFailure('inconsistent replicate', detail, level='ERROR')
        return

# def audit_file_platform(value, system): removed from release v56

def check_presence(file_to_check, files_list):
    for f in files_list:
        if f['accession'] == file_to_check['accession']:
            return True
    return False

@audit_checker('File',
               frame=['dataset',
                      'dataset.target',
                      'platform',
                      'controlled_by',
                      'controlled_by.replicate',
                      'controlled_by.dataset',
                      'controlled_by.paired_with',
                      'controlled_by.platform'])
def audit_file_controlled_by(value, system):
    '''
    A fastq in a ChIP-seq experiment should have a controlled_by
    '''

    if value['dataset'].get('assay_term_name') not in ['ChIP-seq',
                                                       'RAMPAGE',
                                                       'CAGE',
                                                       'shRNA knockdown followed by RNA-seq',
                                                       'siRNA knockdown followed by RNA-seq',
                                                       'CRISPR genome editing followed by RNA-seq']:

        return

    if value['file_format'] not in ['fastq']:
        return

    if 'target' in value['dataset'] and \
       'control' in value['dataset']['target'].get('investigated_as', []):
        return

    if 'controlled_by' not in value:
        value['controlled_by'] = []

    if value['controlled_by'] == []:
        detail = 'controlled_by is a list of files that are used as controls for a given experimental file. ' + \
                 'Fastq files generated in a {} assay require the '.format(
                     value['dataset']['assay_term_name']) + \
                 'specification of control fastq file(s) in the controlled_by list. ' + \
                 'Fastq file {} '.format(
                     value['@id']) + \
                 'is missing the requisite file specification in controlled_by list.'
        yield AuditFailure('missing controlled_by', detail, level='NOT_COMPLIANT')
        return

    if value['dataset'].get('assay_term_name') in ['ChIP-seq',
                                                   'RAMPAGE']:
        bio_rep_numbers = set()
        pe_files = []
        if len(value['controlled_by']) > 0:
            for control_file in value['controlled_by']:
                if 'replicate' in control_file:
                    bio_rep_numbers.add(control_file['replicate']['biological_replicate_number'])
                if 'run_type' in control_file:
                    if control_file['run_type'] == 'paired-ended':
                        pe_files.append(control_file)
        for pe_file in pe_files:
            if 'paired_with' not in pe_file:
                detail = 'Fastq file {} '.format(value['@id']) + \
                         'from experiment {} '.format(value['dataset']['@id']) + \
                         'contains in controlled_by list PE fastq file ' + \
                         '{} with missing paired_with property.'.format(pe_file['@id'])
                yield AuditFailure('missing paired_with in controlled_by',
                                   detail, level='INTERNAL_ACTION')
            elif check_presence(pe_file['paired_with'], pe_files) is False:
                detail = 'Fastq file {} '.format(value['@id']) + \
                         'from experiment {} '.format(value['dataset']['@id']) + \
                         'contains in controlled_by list PE fastq file ' + \
                         '{} which is paired to a file {} '.format(pe_file['@id'],
                                                                   pe_file['paired_with']['@id']) + \
                         'that is not included in the controlled_by list'
                yield AuditFailure('missing paired_with in controlled_by', detail,
                                   level='INTERNAL_ACTION')

        if len(bio_rep_numbers) > 1:
            detail = 'Fastq file {} '.format(value['@id']) + \
                     'from experiment {} '.format(value['dataset']['@id']) + \
                     'contains in controlled_by list fastq files ' + \
                     'from diferent biological replicates {}.'.format(list(bio_rep_numbers))
            yield AuditFailure('inconsistent controlled_by replicates', detail, level='ERROR')

    possible_controls = value['dataset'].get('possible_controls')
    biosample = value['dataset'].get('biosample_term_id')
    biosample_term_name = value['dataset'].get('biosample_term_name')
    run_type = value.get('run_type', None)
    read_length = value.get('read_length', None)

    if value['controlled_by']:
        for ff in value['controlled_by']:
            control_bs = ff['dataset'].get('biosample_term_id')
            control_run = ff.get('run_type', None)
            control_length = ff.get('read_length', None)

            if control_bs != biosample:
                detail = 'controlled_by is a list of files that are used as controls for a given file. ' + \
                         'This experiment was performed using {}, but '.format(biosample_term_name) + \
                         'file {} contains in controlled_by list a file '.format(value['@id']) + \
                         '{} that belongs to experiment with different biosample {}.'.format(
                             ff['@id'],
                             ff['dataset'].get('biosample_term_name'))
                yield AuditFailure('inconsistent control', detail, level='ERROR')
                return

            if ff['file_format'] != value['file_format']:
                detail = 'controlled_by is a list of files that are used as controls for a given file. ' + \
                         'File {} with file_format {} contains in controlled_by list '.format(
                             value['@id'],
                             value['file_format'],) + \
                         'a file {} with different file_format {}.'.format(
                             ff['@id'],
                             ff['file_format'])
                yield AuditFailure('inconsistent control', detail, level='ERROR')
                return

            if (possible_controls is None) or (ff['dataset']['@id'] not in possible_controls):
                detail = 'possible_controls is a list of experiment(s) that can serve as ' + \
                         'analytical controls for a given experiment. ' + \
                         'controlled_by is a list of files that are used as ' + \
                         'controls for a given file. ' + \
                         'File {} contains in controlled_by list a file {} '.format(
                             value['@id'],
                             ff['@id']) + \
                         'that belongs to an experiment {} that '.format(ff['dataset']['@id']) + \
                         'is not specified in possible_controls list of this experiment.'

                yield AuditFailure('inconsistent control', detail, level='ERROR')
                return

            if (run_type is None) or (control_run is None):
                continue

            if (read_length is None) or (control_length is None):
                continue

            if run_type != control_run and \
               value['dataset'].get('assay_term_name') not in ['RAMPAGE', 'CAGE']:
                detail = 'File {} is {} but its control file {} is {}'.format(
                    value['@id'],
                    run_type,
                    ff['@id'],
                    control_run
                    )
                yield AuditFailure('inconsistent control run_type',
                                   detail, level='WARNING')

            if read_length != control_length and \
               abs(read_length - control_length) > 2 and \
               value['dataset'].get('assay_term_name') not in \
                    ['shRNA knockdown followed by RNA-seq',
                     'siRNA knockdown followed by RNA-seq',
                     'CRISPR genome editing followed by RNA-seq']:

                detail = 'File {} is {} but its control file {} is {}'.format(
                    value['@id'],
                    value['read_length'],
                    ff['@id'],
                    ff['read_length']
                    )
                yield AuditFailure('inconsistent control read length',
                                   detail, level='WARNING')
                return

# def audit_file_flowcells(value, system): # removed in version 56
# http://redmine.encodedcc.org/issues/5060

@audit_checker('File', frame=['paired_with'])
def audit_paired_with(value, system):
    '''
    A file with a paired_end needs a paired_with.
    Should be handled in the schema.
    A paired_with should be the same replicate
    '''

    if 'paired_end' not in value:
        return

    if value['paired_end'] in ['1,2']:
        return

    if 'paired_with' not in value:
        return

    if 'replicate' not in value['paired_with']:
        return

    if 'replicate' not in value:
        detail = 'File {} has paired_end = {}. It requires a replicate'.format(
            value['@id'],
            value['paired_end'])
        yield AuditFailure('missing replicate', detail, level='INTERNAL_ACTION')
        return

    if value['replicate'] != value['paired_with']['replicate']:
        detail = 'File {} has replicate {}. It is paired_with file {} with replicate {}'.format(
            value['@id'],
            value.get('replicate'),
            value['paired_with']['@id'],
            value['paired_with'].get('replicate'))
        yield AuditFailure('inconsistent paired_with', detail, level='ERROR')
        return

    if value['paired_end'] == '1':
        context = system['context']
        paired_with = context.get_rev_links('paired_with')
        if len(paired_with) > 1:
            detail = 'Paired end 1 file {} paired_with by multiple paired end 2 files: {!r}'.format(
                value['@id'],
                paired_with,
            )
            yield AuditFailure('multiple paired_with', detail, level='ERROR')
            return

'''
@audit_checker('file', frame=['step_run',
                              'dataset'], condition=rfa('modERN'))
def audit_modERN_ChIP_pipeline_steps(value, system):

    expt = value['dataset']
    if 'Experiment' not in expt['@type']:
        return

    if expt['assay_term_name'] != 'ChIP-seq':
        return

    if value['status'] in ['archived', 'revoked', 'deleted', 'replaced']:
        return

    if value['file_format'] == 'fastq':
        if 'step_run' in value:
            detail = 'Fastq file {} should not have an associated step_run'.format(value['@id'])
            yield AuditFailure('unexpected step_run', detail, level='ERROR')
        return

    if 'step_run' not in value:
        detail = 'File {} is missing a step_run'.format(value['@id'])
        yield AuditFailure('missing step_run', detail, level='WARNING')
        return

    if (value['file_format'] != 'fastq') and ('derived_from' not in value):
        detail = 'File {} is missing its derived_from'.format(value['@id'])
        return

    step = value['step_run']
    if (value['file_format'] == 'bam') and step['aliases'][0] != 'modern:chip-seq-bwa-alignment-step-run-v-1-virtual':
        detail = 'Bam {} is linked to the wrong step_run: {}'.format(value['@id'], step['aliases'][0])
        yield AuditFailure('wrong step_run ChIP-seq bam', detail, level='WARNING')

    if (value['output_type'] == 'normalized signal of all reads'):
        if not ((step['aliases'][0] != 'modern:chip-seq-unique-read-signal-generation-step-run-v-1-virtual') or (step['aliases'][0] != 'modern:chip-seq-replicate-pooled-unique-read-signal-generation-step-run-v-1-virtual')):
            detail = 'Normalized signal of all reads {} is linked to the wrong step_run: {}'.format(value['@id'], step['aliases'][0])
            yield AuditFailure('wrong step_run for unique signal', detail, level='WARNING')

    if (value['output_type']) == 'read-depth normalized signal':
        if not ((step['aliases'][0] != 'modern:chip-seq-read-depth-normalized-signal-generation-step-run-v-1-virtual') or (step['aliases'][0] != 'modern:chip-seq-replicate-pooled-read-depth-normalized-signal-generation-step-run-v-1-virtual')):
            detail = 'Read depth normalized signal {} is linked to the wrong step_run: {}'.format(value['@id'], step['aliases'][0])
            yield AuditFailure('wrong step_run for depth signal', detail, level='WARNING')

    if (value['output_type']) == 'control normalized signal':
        if not ((step['aliases'][0] != 'modern:chip-seq-control-normalized-signal-generation-step-run-v-1-virtual') or (step['aliases'][0] != 'modern:chip-seq-replicate-pooled-control-normalized-signal-generation-step-run-v-1-virtual')):
            detail = 'Control normalized signal {} is linked to the wrong step_run: {}'.format(value['@id'], step['aliases'][0])
            yield AuditFailure('wrong step_run for control signal', detail, level='WARNING')

    if (value['file_format'] == 'bigBed'):
        if not ((step['aliases'][0] != 'modern:chip-seq-peaks-to-bigbed-step-run-v-1-virtual') or (step['aliases'][0] != 'modern:chip-seq-optimal-idr-thresholded-peaks-to-bigbed-step-run-v-1-virtual')):
            detail = 'bigBed {} is linked to the wrong step_run: {}'.format(value['@id'], step['aliases'][0])
            yield AuditFailure('wrong step_run for bigBed peaks', detail, level='WARNING')

    if (value['output_type'] == 'peaks') and (value['file_format'] == 'bed'):
        if (value['file_format_type'] == 'narrowPeak') and (step['aliases'][0] != 'modern:chip-seq-spp-peak-calling-step-run-v-1-virtual'):
            detail = 'Peaks {} is linked to the wrong step_run: {}'.format(value['@id'], step['aliases'][0])
            yield AuditFailure('wrong step_run for peaks', detail, level='WARNING')

    if (value['output_type'] == 'optimal idr thresholded peaks') and (value['file_format'] == 'bed'):
        if (value['file_format_type'] == 'narrowPeak') and (step['aliases'][0] != 'modern:chip-seq-optimal-idr-step-run-v-1-virtual'):
            detail = 'Optimal IDR thresholded peaks {} is linked to the wrong step_run: {}'.format(value['@id'], step['aliases'][0])
            yield AuditFailure('wrong step_run for IDR peaks', detail, level='WARNING')
'''

@audit_checker('File', frame=['file_format_specifications'],)
def audit_file_format_specifications(value, system):

    for doc in value.get('file_format_specifications', []):
        if doc['document_type'] != "file format specification":
            detail = 'File {} has document {} not of type file format specification'.format(
                value['@id'],
                doc['@id']
                )
            raise AuditFailure('inconsistent document_type', detail, level='ERROR')

def get_chip_seq_bam_read_depth(bam_file):
    if bam_file['status'] in ['deleted', 'replaced', 'revoked']:
        return False

    if bam_file['file_format'] != 'bam' or bam_file['output_type'] != 'alignments':
        return False

    # Check to see if bam is from ENCODE or modERN pipelines
    if bam_file['lab'] not in ['/labs/encode-processing-pipeline/', '/labs/kevin-white/']:
        return False

    if has_pipelines(bam_file) is False:
        return False

    quality_metrics = bam_file.get('quality_metrics')

    if (quality_metrics is None) or (quality_metrics == []):
        return False

    read_depth = 0

    for metric in quality_metrics:
        if ('total' in metric and
            (('processing_stage' in metric and metric['processing_stage'] == 'filtered') or
             ('processing_stage' not in metric))):
                if "read1" in metric and "read2" in metric:
                    read_depth = int(metric['total']/2)
                else:
                    read_depth = metric['total']
                break

    if read_depth == 0:
        return False

    return read_depth

def get_control_bam(experiment_bam, pipeline_name):
    #  get representative FASTQ file
    if 'derived_from' not in experiment_bam or len(experiment_bam['derived_from']) < 1:
        return False

    derived_from_fastqs = experiment_bam['derived_from']
    control_fastq = False
    for entry in derived_from_fastqs:
        if 'controlled_by' in entry and len(entry['controlled_by']) > 0:
            control_fastq = entry['controlled_by'][0]  # getting representative FASTQ
            break

    # get representative FASTQ from control
    if control_fastq is False:
        return False
    else:
        if 'original_files' not in control_fastq['dataset']:
            return False

        control_bam = False
        control_files = control_fastq['dataset']['original_files']
        for control_file in control_files:
            if control_file['status'] in ['deleted', 'replaced', 'revoked']:
                continue
            if control_file['file_format'] == 'bam' and \
               control_file['output_type'] == 'alignments' and \
               'assembly' in control_file and 'assembly' in experiment_bam and \
               control_file['assembly'] == experiment_bam['assembly']:
                #  we have BAM file, now we have to make sure it was created by pipeline
                #  with similar pipeline_name

                is_same_pipeline = False
                if has_pipelines(control_file) is True:
                    for pipeline in \
                            control_file['analysis_step_version']['analysis_step']['pipelines']:
                        if pipeline['title'] == pipeline_name:
                            is_same_pipeline = True
                            break

                if is_same_pipeline is True and \
                   'derived_from' in control_file and \
                   len(control_file['derived_from']) > 0:
                    derived_list = control_file['derived_from']
                    for entry in derived_list:
                        if entry['accession'] == control_fastq['accession']:
                            control_bam = control_file
                            break
        return control_bam

def has_pipelines(bam_file):
    if 'analysis_step_version' not in bam_file:
        return False
    if 'analysis_step' not in bam_file['analysis_step_version']:
        return False
    if 'pipelines' not in bam_file['analysis_step_version']['analysis_step']:
        return False
    return True

def get_target_name(bam_file):
    if 'dataset' in bam_file and 'target' in bam_file['dataset'] and \
       'name' in bam_file['dataset']['target']:
            return bam_file['dataset']['target']['name']
    return False

def extract_award_version(bam_file):
    if 'dataset' in bam_file and 'award' in bam_file['dataset'] and \
       'rfa' in bam_file['dataset']['award']:
        if bam_file['dataset']['award']['rfa'] in ['ENCODE2-Mouse', 'ENCODE2']:
            return 'ENC2'
    return 'ENC3'

@audit_checker('File', frame=[
    'award',
    'quality_metrics',
    'analysis_step_version',
    'analysis_step_version.analysis_step',
    'analysis_step_version.analysis_step.pipelines',
    'analysis_step_version.software_versions',
    'analysis_step_version.software_versions.software',
    'dataset',
    'dataset.target',
    'derived_from',
    'derived_from.controlled_by',
    'derived_from.controlled_by.dataset',
    'derived_from.controlled_by.dataset.target',
    'derived_from.controlled_by.dataset.original_files',
    'derived_from.controlled_by.dataset.original_files.quality_metrics',
    'derived_from.controlled_by.dataset.original_files.dataset',
    'derived_from.controlled_by.dataset.original_files.dataset.target',
    'derived_from.controlled_by.dataset.original_files.derived_from',
    'derived_from.controlled_by.dataset.original_files.analysis_step_version',
    'derived_from.controlled_by.dataset.original_files.analysis_step_version.analysis_step',
    'derived_from.controlled_by.dataset.original_files.analysis_step_version.analysis_step.pipelines',
    'derived_from.controlled_by.dataset.original_files.analysis_step_version.software_versions',
    'derived_from.controlled_by.dataset.original_files.analysis_step_version.software_versions.software'])
def audit_file_chip_seq_control_read_depth(value, system,
                                           condition=rfa('ENCODE3',
                                                         'ENCODE2-Mouse',
                                                         'ENCODE2',
                                                         'ENCODE',
                                                         'HPAP',
                                                         'LungMap',
                                                         'AMP-T2D',
                                                         'Roadmap')):
    '''
    An alignment file from the LungMap Processing Pipeline should have read depth
    in accordance with the criteria
    '''

    if value['status'] in ['deleted', 'replaced', 'revoked']:
        return

    if value['file_format'] != 'bam':
        return

    if value['output_type'] in ['transcriptome alignments', 'unfiltered alignments']:
        return

    if value['lab'] not in ['/labs/encode-processing-pipeline/']:
        return

    if 'analysis_step_version' not in value:
        detail = 'LungMap Processed alignment file {} has '.format(value['@id']) + \
            'no analysis step version'
        yield AuditFailure('missing analysis step version', detail, level='INTERNAL_ACTION')
        return

    if 'analysis_step' not in value['analysis_step_version']:
        detail = 'LungMap Processed alignment file {} has '.format(value['@id']) + \
            'no analysis step in {}'.format(value['analysis_step_version']['@id'])
        yield AuditFailure('missing analysis step', detail, level='INTERNAL_ACTION')
        return

    if 'pipelines' not in value['analysis_step_version']['analysis_step']:
        detail = 'LungMap Processed alignment file {} has '.format(value['@id']) + \
            'no pipelines in {}'.format(value['analysis_step_version']['analysis_step']['@id'])
        yield AuditFailure('missing pipelines in analysis step', detail, level='INTERNAL_ACTION')
        return

    if 'software_versions' not in value['analysis_step_version']:
        detail = 'LungMap Processed alignment file {} has '.format(value['@id']) + \
            'no software_versions in {}'.format(value['analysis_step_version']['@id'])
        yield AuditFailure('missing software versions', detail, level='INTERNAL_ACTION')
        return

    if value['analysis_step_version']['software_versions'] == []:
        detail = 'LungMap Processed alignment file {} has no '.format(value['@id']) + \
            'softwares listed in software_versions,' + \
            ' under {}'.format(value['analysis_step_version']['@id'])
        yield AuditFailure('missing software', detail, level='INTERNAL_ACTION')
        return

    chip_flag = False
    for p in value['analysis_step_version']['analysis_step']['pipelines']:
        if p['title'] == 'ChIP-seq read mapping':
            chip_flag = True
        if p['title'] == 'Raw mapping with no filtration':
            return

    if chip_flag is False:
        return

    quality_metrics = value.get('quality_metrics')

    if (quality_metrics is None) or (quality_metrics == []):
        return

    derived_from_files = value.get('derived_from')
    if (derived_from_files is None) or (derived_from_files == []):
        return

    target_name = 'empty'
    target_investigated_as = 'empty'

    if 'dataset' in value:
        if 'target' in value['dataset'] and 'name' in value['dataset']['target']:
            target_name = value['dataset']['target']['name']
            target_investigated_as = value['dataset']['target']['investigated_as']

    if target_name not in ['Control-human', 'Control-mouse']:
        control_bam = get_control_bam(value, 'ChIP-seq read mapping')
        if control_bam is not False:
            control_depth = get_chip_seq_bam_read_depth(control_bam)
            control_target = get_target_name(control_bam)
            standards_version = extract_award_version(control_bam)
            if control_depth is not False and control_target is not False:
                for failure in check_control_read_depth_standards(control_bam,
                                                                  control_depth,
                                                                  control_target,
                                                                  True,
                                                                  target_name,
                                                                  target_investigated_as,
                                                                  standards_version):
                    yield failure

def check_control_read_depth_standards(value,
                                       read_depth,
                                       target_name,
                                       is_control_file,
                                       control_to_target,
                                       target_investigated_as,
                                       standards_version):

    marks = pipelines_with_read_depth['ChIP-seq read mapping']

    if is_control_file is True:  # treat this file as control_bam -
        # raising insufficient control read depth
        if target_name not in ['Control-human', 'Control-mouse']:
            detail = 'Control alignment file {} '.format(value['@id']) + \
                     'has a target {} that is neither '.format(target_name) + \
                     'Control-human nor Control-mouse.'
            yield AuditFailure('inconsistent target of control experiment', detail, level='WARNING')
            return

        if control_to_target == 'empty':
            return

        elif 'broad histone mark' in target_investigated_as: #  control_to_target in broad_peaks_targets:
            if 'assembly' in value:
                detail = 'Control alignment file {} mapped to {} assembly has {} '.format(
                    value['@id'],
                    value['assembly'],
                    read_depth) + \
                    'usable fragments. ' + \
                    'The minimum LungMap standard for a control of ChIP-seq assays targeting broad ' + \
                    'histone mark {} '.format(control_to_target) + \
                    'is 40 million usable fragments, the recommended number of usable ' + \
                    'fragments is > 45 million. (See /data-standards/chip-seq/ )'
            else:
                detail = 'Control alignment file {} has {} '.format(
                    value['@id'],
                    read_depth) + \
                    'usable fragments. ' + \
                    'The minimum LungMap standard for a control of ChIP-seq assays targeting broad ' + \
                    'histone mark {} '.format(control_to_target) + \
                    'is 40 million usable fragments, the recommended number of usable ' + \
                    'fragments is > 45 million. (See /data-standards/chip-seq/ )'
            if read_depth >= 40000000 and read_depth < marks['broad']:
                yield AuditFailure('control low read depth', detail, level='WARNING')
            elif read_depth >= 5000000 and read_depth < 40000000:
                yield AuditFailure('control insufficient read depth', detail, level='NOT_COMPLIANT')
            elif read_depth < 5000000:
                yield AuditFailure('control extremely low read depth', detail, level='ERROR')
        elif 'narrow histone mark' in target_investigated_as:  # else:
            if 'assembly' in value:
                detail = 'Control alignment file {} mapped to {} assembly has {} '.format(
                    value['@id'],
                    value['assembly'],
                    read_depth) + \
                    'usable fragments. ' + \
                    'The minimum LungMap standard for a control of ChIP-seq assays targeting narrow ' + \
                    'histone mark {} '.format(control_to_target) + \
                    'is 10 million usable fragments, the recommended number of usable ' + \
                    'fragments is > 20 million. (See /data-standards/chip-seq/ )'
            else:
                detail = 'Control alignment file {} has {} '.format(
                    value['@id'],
                    read_depth) + \
                    'usable fragments. ' + \
                    'The minimum LungMap standard for a control of ChIP-seq assays targeting narrow ' + \
                    'histone mark {} '.format(control_to_target) + \
                    'is 10 million usable fragments, the recommended number of usable ' + \
                    'fragments is > 20 million. (See /data-standards/chip-seq/ )'
            if read_depth >= 10000000 and read_depth < marks['narrow']:
                yield AuditFailure('control low read depth', detail, level='WARNING')
            elif read_depth >= 5000000 and read_depth < 10000000:
                yield AuditFailure('control low read depth', detail, level='NOT_COMPLIANT')
            elif read_depth < 5000000:
                yield AuditFailure('control extremely low read depth', detail, level='ERROR')

        else:
            if 'assembly' in value:
                detail = 'Control alignment file {} mapped to {} assembly has {} '.format(
                    value['@id'],
                    value['assembly'],
                    read_depth) + \
                    'usable fragments. ' + \
                    'The minimum LungMap standard for a control of ChIP-seq assays targeting ' + \
                    '{} and investigated as a transcription factor '.format(control_to_target) + \
                    'is 10 million usable fragments, the recommended number of usable ' + \
                    'fragments is > 20 million. (See /data-standards/chip-seq/ )'
            else:
                detail = 'Control alignment file {} has {} '.format(
                    value['@id'],
                    read_depth) + \
                    'usable fragments. ' + \
                    'The minimum LungMap standard for a control of ChIP-seq assays targeting ' + \
                    '{} and investigated as a transcription factor '.format(control_to_target) + \
                    'is 10 million usable fragments, the recommended number of usable ' + \
                    'fragments is > 20 million. (See /data-standards/chip-seq/ )'
            if read_depth >= 10000000 and read_depth < marks['narrow']:
                yield AuditFailure('control low read depth', detail, level='WARNING')
            elif read_depth >= 3000000 and read_depth < 10000000:
                yield AuditFailure('control low read depth', detail, level='NOT_COMPLIANT')
            elif read_depth < 3000000:
                yield AuditFailure('control extremely low read depth', detail, level='ERROR')
        return


# Exercise 8b

import re

# You want to filter a list of strings for those containing valid email addresses.
# First write a regular expression that checks for a string containing:
# (1) some alphanumeric stuff
# (2) @ sign
# (3) domain name (alphanumeric)
# (4) .com, .org, .edu or .net (Okay, this isn't all valid email addresses)

email_regex = r'\w+@\w+\.(com|org|edu|net)' # replace this with your regex

# Now replace the ellipsis in the code below with some Python code
# that refers to email_regex

def filter_lines_with_email(list_of_lines):
    filtered_lines = list()
    for line in list_of_lines:
        if re.search(email_regex, line): # replace ellipsis with your code
            filtered_lines.append(line)
    return filtered_lines

line0 = 'This line contains a valid email address amy@gmail.com'
line1 = 'This isn\'t a valid email: @gmail.com'
line2 = 'You can contact me at maf@mit.edu, anytime'
line3 = 'If you tried to send an email to @@(@$@gmail.com I\'m sure it would be rejected'

assert filter_lines_with_email([line0, line1, line2, line3]) == [line0, line2]
# will print nothing if correct


import smtplib
import imghdr
import glob
from email.message import EmailMessage
from email.mime.text import MIMEText

def enviar_correo(id, contenido):
    html = """\

            Estimado

            Se ha detectado un error en los servicios web:

    """

    msg = EmailMessage()
    msg['Subject'] = 'ALERTA: Monitor de servicios'
    me = 'scastroar@est.ups.edu.ec'
    destinatarios = ['scastroa1@ups.edu.ec']
    msg['From'] = me
    msg['To'] = ', '.join(destinatarios)
    msg.preamble = 'You will not see this in a MIME-aware mail reader.\n'
    # Adjuntar las imágenes de las capturas de pantalla
    pngfiles = glob.glob('imagenes/error_%s_*.png' % id)
    for file in pngfiles:
        with open(file, 'rb') as fp:
            img_data = fp.read()
        msg.add_attachment(img_data, maintype='image',
                           subtype=imghdr.what(None, img_data),
                           filename=file.replace('imagenes/', ''))

    with smtplib.SMTP(host='smtp.office365.com', port=587) as s:
        s.starttls()
        s.login('scastroar@est.ups.edu.ec', 'Motepillo90')

        html = html + "
" + contenido + "
" + "
"

        msg.attach(MIMEText(html, 'html'))
        s.send_message(msg)


class Solution(object):
    def numberToWords(self, num):
        """
        :type num: int
        :rtype: str
        """
        d = {0: "", 1: "One", 2: "Two", 3: "Three", 4: "Four", 5: "Five", 6: "Six", 7: "Seven", 8: "Eight",
             9: "Nine", 10: "Ten", 11: "Eleven", 12: "Twelve", 13: "Thirteen", 14: "Fourteen", 15: "Fifteen",
             16: "Sixteen", 17: "Seventeen", 18: "Eighteen", 19: "Nineteen", 20: "Twenty", 30: "Thirty", 40: "Forty",
             50: "Fifty", 60: "Sixty", 70: "Seventy", 80: "Eighty", 90: "Ninety"}
        if num == 0:
            return "Zero"

        def word(num):
            if num < 20:
                if num == 0:
                    return []
                return [d[num]]
            if num < 100:
                return [d[num - num % 10]] + word(num % 10)
            if num < 1000:
                return [d[int(num / 100)], "Hundred"] + word(num % 100)
            if num < 1000000:
                return word(int(num / 1000)) + ["Thousand"] + word(num % 1000)
            if num < 1000000000:
                return word(int(num / 1000000)) + ["Million"] + word(num % 1000000)
            if num <= 2 ** 31 - 1:
                return word(int(num / 1000000000)) + ["Billion"] + word(num % 1000000000)
            else: return "Out of number range!!!"

        return " ".join(word(num))

sol = Solution()
print(sol.numberToWords(100))


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models

class Migration(migrations.Migration):

    dependencies = [
        ('cms', '0013_urlconfrevision'),
        ('polls', '0006_auto_20160202_1612'),
    ]

    operations = [
        migrations.CreateModel(
            name='PollListPluginModel',
            fields=[
                ('cmsplugin_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='cms.CMSPlugin')),
                ('polls', models.ManyToManyField(default=None, to='polls.Question', null=True, blank=True)),
            ],
            options={
                'abstract': False,
            },
            bases=('cms.cmsplugin',),
        ),
        migrations.AlterField(
            model_name='pollresultspluginmodel',
            name='ordering',
            field=models.CharField(default='pk', max_length=32, choices=[('pk', 'natural'), ('-votes,choice_text', 'vote (descending)'), ('votes,choice_text', 'vote (ascending)'), ('choice_text', 'choice (a-z)')]),
        ),
    ]


#!/usr/bin/env python3

class Structure:
    def __init__(self, **entries):
        self.__dict__.update(entries)

# helpers
import pprint
pp = pprint.PrettyPrinter(indent=4)

# get script path
import os
py_path = os.path.dirname(os.path.realpath(__file__))

# read config
import json
cfg_file = os.path.join(py_path, 'config.json')
with open(cfg_file) as fh:
    jsn = json.load(fh)
    cfg = Structure(**jsn)

# load database
import importlib
modname = 'data.{}.envrc'.format(cfg.context)
env = importlib.import_module(modname).env

# render scripts
import sys
script = ''
if len(sys.argv) < 2:
    print('nothing to do, abort!')
    exit(1)

for x in sys.argv[1:]:
    if hasattr(env, x):
        script += getattr(env, x)

# done
print(script)


from forta_agent import Finding, FindingType, FindingSeverity, Label, EntityType, get_labels
import pandas as pd
import json
import os
import logging
import traceback
import forta_agent
import hashlib

from src.constants import ATTACK_DETECTOR_BOT_ID, ATTACK_DETECTOR_BETA_BOT_ID
from src.utils import Utils

class AlertCombinerFinding:

    @staticmethod
    def get_bot_name() -> str:
        package = json.load(open("package.json"))
        return package["name"]

    @staticmethod
    def create_finding(block_chain_indexer, addresses: str, victim_address: str, victim_name, anomaly_score: float, severity: FindingSeverity, alert_id: str,
        alert_event: forta_agent.alert_event.AlertEvent, alert_data: pd.DataFrame, victim_metadata: dict, anomaly_scores_by_stage: pd.DataFrame, chain_id: int, bot_source: str) -> Finding:
        # alert_data -> 'stage', 'created_at', 'anomaly_score', 'alert_hash', 'bot_id', 'alert_id', 'addresses', 'transaction_hash', 'address_filter' (+ 'chain_id' for L2s)

        #only emit ATTACK-DETECTOR-4 and ATTACK-DETECTOR-5 alerts in test local or beta environments, but not production
        if ((alert_id == "ATTACK-DETECTOR-4" or alert_id == "ATTACK-DETECTOR-5" or alert_id == "ATTACK-DETECTOR-6") and "beta" not in AlertCombinerFinding.get_bot_name() and ('NODE_ENV' in os.environ and 'production' in os.environ.get('NODE_ENV'))):
            return None

        anomaly_scores = {}
        for index, row in anomaly_scores_by_stage.iterrows():
            anomaly_scores[f'anomaly_score_stage_{row["stage"]}'] = row["anomaly_score"]
        attacker_address = {"attacker_address": addresses}
        anomaly_score_dict = {"anomaly_score": anomaly_score}
        bot_source_dict = {"bot_source": bot_source}
        involved_addresses = set()
        alert_data["addresses"].apply(lambda x: [involved_addresses.add(item) for item in x])
        involved_addresses = list(involved_addresses)[0:500]
        involved_addresses = {"involved_addresses_" + str(i): address for i, address in enumerate(involved_addresses, 1)}

        alerts = alert_data[['bot_id', 'alert_id', 'alert_hash']].drop_duplicates(inplace=False)
        alerts = alerts.head(100)
        involved_alerts = {"involved_alerts_" + str(index): ','.join([row['bot_id'], row['alert_id'], row['alert_hash']]) for index, row in alerts.iterrows()}

        # Extract Bloom filters per involved alert
        involved_address_bloom_filters = {}
        for index, row in alerts.iterrows():
            filter_data = alert_data.loc[alert_data['alert_hash'] == row['alert_hash'], 'address_filter'].values
            if filter_data[0] is not None:
                involved_address_bloom_filters[f'involved_address_bloom_filter_{index}'] = ','.join(str(item) for item in filter_data[0])
            else:
                involved_address_bloom_filters[f'involved_address_bloom_filter_{index}'] = ''

        meta_data = {**attacker_address, **victim_metadata, **anomaly_scores, **anomaly_score_dict, **involved_addresses, **involved_alerts, **involved_address_bloom_filters, **bot_source_dict}
        victim_clause = f" on {victim_name} ({victim_address.lower()})" if victim_address else ""
        anomaly_clause = f" Anomaly score: {anomaly_score}" if anomaly_score > 0 else ""

        confidence = 0.2
        if bot_source == "BlockSec":
            confidence = 0.8

        labels = []
        for address in addresses.split(','):
            labels.append(Label({
                'entityType': EntityType.Address,
                'label': "attacker-eoa",
                'entity': address,
                'confidence': confidence,
                'metadata': {
                    'alert_id': alert_id,
                    'chain_id': chain_id,
                    'threat_description_url': 'https://forta.org/attacks/'
                }
            }))

            try:
                contracts = block_chain_indexer.get_contracts(address, chain_id)
                for contract in contracts:
                    labels.append(Label({
                        'entityType': EntityType.Address,
                        'label': "attacker-contract",
                        'entity': contract,
                        'confidence': confidence,
                        'metadata': {
                            'alert_ids': alert_id,
                            'chain_id': chain_id,
                            'threat_description_url': 'https://forta.org/attacks/'
                        }
                    }))
            except Exception as e:
                logging.warning(f"Error getting contracts for {address} {e}")
                Utils.ERROR_CACHE.add(Utils.alert_error(str(e), "findings.create_finding", traceback.format_exc()))

        unique_key = hashlib.sha256(f'{addresses},{victim_clause},{alert_id}'.encode()).hexdigest()
        logging.info(f"Unique key of {addresses},{victim_clause},{alert_id}: {unique_key}")

        if alert_id == "ATTACK-DETECTOR-PREPARATION":
            description = f'{addresses} likely involved in an attack preparation ({alert_event.alert_hash}){victim_clause}. {anomaly_clause}'
        else:
            description = f'{addresses} likely involved in an attack ({alert_event.alert_hash}){victim_clause}. {anomaly_clause}'

        return Finding({
                       'name': 'Attack detector identified an EOA with behavior consistent with an attack',
                       'description': description,
                       'alert_id': alert_id,
                       'type': FindingType.Exploit,
                       'severity': severity,
                       'metadata': meta_data,
                       'unique_key': unique_key,
                       'labels': labels
                       })

    @staticmethod
    def alert_FP(address: str, label: str, metadata: dict) -> Finding:

        labels = []
        labels.append(Label({
                'entityType': EntityType.Address,
                'label': label,
                'entity': address,
                'confidence': 0.99,
                'remove': "true",
                'metadata': metadata

            }))

        return Finding({
            'name': 'Attack detector identified an address that was incorrectly alerted on. Emitting false positive alert.',
            'description': f'{address} likely not involved in an attack (ATTACK-DETECTOR-FALSE-POSITIVE)',
            'alert_id': 'ATTACK-DETECTOR-FALSE-POSITIVE',
            'type': FindingType.Info,
            'severity': FindingSeverity.Info,
            'metadata': {},
            'labels': labels
        })

    @staticmethod
    def attack_finding_manual(block_chain_indexer, attacker_cluster: str, reported_by: str, chain_id: int, test_flag = False) -> Finding:
        label_doesnt_exist = False
        labels = []

        for attacker_address in attacker_cluster.split(","):
            source_id = ATTACK_DETECTOR_BETA_BOT_ID if Utils.is_beta() else ATTACK_DETECTOR_BOT_ID
            label_query_options_dict = {
                "entities": [attacker_address],
                "source_ids": [source_id],
                "state": True,
                "first": 10,
            }

            logging.info(f"Querying for existing label: {label_query_options_dict}")
            labels_response = get_labels(label_query_options_dict)
            if test_flag or not labels_response.labels:
                logging.info(f"Label doesn't exist for {attacker_address}")
                label_doesnt_exist = True
            else:
                logging.info(f"Label exists for {attacker_address}")

            labels.append(Label({
                'entityType': EntityType.Address,
                'label': 'attacker-eoa',
                'entity': attacker_address,
                'confidence': 1,
                'metadata': {
                    'address_type': 'EOA',
                    'chain_id': chain_id,
                    'reported_by': reported_by,
                }
            }))

            contracts = block_chain_indexer.get_contracts(attacker_cluster, chain_id)
            for contract in contracts:
                labels.append(Label({
                    'entityType': EntityType.Address,
                    'label': 'attacker-contract',
                    'entity': contract,
                    'confidence': 1,
                    'metadata': {
                        'address_type': 'contract',
                        'chain_id': chain_id,
                        'reported_by': reported_by,
                        'deployer_info': f"Deployer {attacker_address} involved in attack; this contract may or may not be related to this particular attack, but was created by the attacker.",
                    }
                }))

        if label_doesnt_exist:
            return Finding({
                'name': 'Attack detector identified an EOA with past alerts mapping to attack behavior',
                'description': f'{attacker_cluster} likely involved in an attack (ATTACK-DETECTOR-MANUAL)',
                'alert_id': "ATTACK-DETECTOR-MANUAL",
                'type': FindingType.Exploit,
                'severity': FindingSeverity.Critical,
                'metadata': {"reported_by": reported_by},
                'labels': labels
            })


validTokens = ["push","pop","add","sub","mul", "div", "mod","skip","save", "get"]

def Tokenize(str):
    inputsplit = str.split()

    for x in inputsplit:
        if (x not in validTokens) and (isNumber(x) is False) :
            raise ValueError("Unexpected Token: " +x)

    return inputsplit

    #def isValid(str):
     #  return x in validTokens or x.isdigit()

       #raise ValueError("Unexpect Token: " + invalid[0])

def isNumber(s):
   try:
        int(s)
        return True
   except ValueError:
        return False

def isValid(str):
    return x in isNumber(x) or validTokens

# --------

def Parse(tokens):

    validTokens1 = ["pop","add","sub","mul","div","mod","skip"]
    validTokens2 = ["push","save","get"]
    for x in tokens:
       # next = tokens.index(x) + 1
        if len(tokens) == 1:
            if tokens[0] in validTokens1:
                return True

        if len(tokens) == 2 :
            if tokens[0] in validTokens2:
                if (isNumber(tokens[1]) is True) :
                    return True

        else:
            raise ValueError("Parse error at: " +x)


from flask_restplus import Resource, fields, reqparse, Namespace
from sqlalchemy.resources.injectors import ins_creation

parselevel=reqparse.RequestParser()
parselevel.add_argument('directorname', type=str, required=True, help='Enter the director name')

namespace = Namespace('Movies', description='to movies from file')

movieschema = namespace.model('Movies', {
    'Director': fields.String(description='Director name', required=True),
    'Movie Name': fields.String(description='Movie name', required=True),
    'Release Year': fields.Integer(description='Year of release', required=True)
})

@namespace.route('/movies')
class TodoSimple(Resource):
    @namespace.response(200, 'success')
    @namespace.response(400, 'Bad request')
    @namespace.response(500, 'Internal server error')
    @namespace.response(404, 'Not found')
    @namespace.response(403, 'Unauthorized')
    # @namespace.doc(parser=awsparselevel)
    def get(self):

        mov_db_ins, mov_ins = ins_creation()
        result = mov_ins.getallmovies(movies_ins=mov_db_ins)
        if not result:
            return {"movies": "movies not found"}, 404
        else:
            return {"movies": result}, 200

    @namespace.response(201, 'success')
    @namespace.response(400, 'Bad request')
    @namespace.response(500, 'Internal server error')
    @namespace.response(404, 'Not found')
    @namespace.response(403, 'Unauthorized')
    @namespace.expect(movieschema)
    def post(self):
        payload = self.parsing_args()
        print(payload)
        movies_db_ins, movies_ops_ins = ins_creation()
        insert_db = movies_ops_ins.insertintodb(payload,movies_db_ins)
        if insert_db == 'success':
            return 'success', 201

    @staticmethod
    def parsing_args():
        parselevel = reqparse.RequestParser()
        parselevel.add_argument('Director', type=str, required=True)
        parselevel.add_argument('Movie Name', type=str, required=True)
        parselevel.add_argument('Release Year', type=int, required=True)
        return parselevel.parse_args()

@namespace.route('/directorname')
class TodoSimpleDirector(Resource):
    @namespace.response(200, 'success')
    @namespace.response(400, 'Bad request')
    @namespace.response(500, 'Internal server error')
    @namespace.response(404, 'Not found')
    @namespace.response(403, 'Unauthorized')
    @namespace.doc(parser=parselevel)
    def get(self):
        payload = parselevel.parse_args()
        print(payload)
        directorname = payload.get('directorname')
        movies_db_ins, movies_ops_ins = ins_creation()
        result = movies_ops_ins.getmoviesbydir(directorname, movies_db_ins)
        if not result:
            return {"movies": "movies not found"}, 404
        else:
            return {"movies": result}, 200


#!/usr/bin/python3

import pandas as pd
import datetime
import numpy as np
import sys
import argparse
import os

OK           = 0
WARNING      = 1
CRITICAL     = 2
UNKNOWN      = 3

def DataFileReady(datafile):

    try:
        f = open(datafile)
        f.close()
    except IOError:
        print("UNKNOWN - Waiting for historical data file - " + str(datafile))
        sys.exit(UNKNOWN)

cmd_arg_help = "This plugin checks the correlation between two instrumenets"

if __name__ == "__main__":

    parser = argparse.ArgumentParser(description=cmd_arg_help)
    parser.add_argument("-t1", "--ticker1", help="Ticker code of the first intrument to test correlation")
    parser.add_argument("-t2", "--ticker2", help="Ticker code of the second intrument to test correlation ")
    parser.add_argument("-f", "--provider", help="Which provider to the histocal data come from (e.g. yahoo_finance)")
    args = parser.parse_args()

    if not args.ticker1:
        print ("UNKNOWN - No ticker found")
        sys.exit(UNKNOWN)

    if not args.ticker2:
        print ("UNKNOWN - No ticker2 found")
        sys.exit(UNKNOWN)

    if not args.provider:
        print ("UNKNOWN - Data provider not supplied")
        sys.exit(UNKNOWN)

    ticker1 = args.ticker1
    ticker2 = args.ticker2

    history_dir = "/shark/historical/"

    datafile1 = ""
    datafile2 = ""

    if args.provider == "yahoo_finance_data":
        datafile1 = history_dir + args.provider + "/" + ticker1 + ".csv"
        datafile2 = history_dir + args.provider + "/" + ticker2 + ".csv"

    DataFileReady(datafile1)
    DataFileReady(datafile2)

    data1 = pd.read_csv(datafile1)
    data2 = pd.read_csv(datafile2)

    dataFrame1 = data1['Adj Close']
    dataFrame2 = data2['Adj Close']

    correlation = dataFrame1.corr(dataFrame2)

    corr_abs = abs(correlation)

    exitcode = OK

    if corr_abs > .5:
        print("CRITICAL - Strong correlation of " + str(correlation))
        exitcode = CRITICAL
    else:
        print("OK - Weak correlation of " + str(correlation))

    sys.exit(exitcode)


import sys
input=sys.stdin.readline

# N은 앞마당 길이, M은 대회의 시간
N, M = map(int, input().split())

# 첫 시작이 0부터 이므로 0을 추가하고 입력
A = [0] + list(map(int, input().split()))

def DFS(index, size, time):
    # 나중에 반환할 정답
    global ret

    #시간이 M을 초과하면 끝
    if time > M : return

    #시간을 초과하지 않으면 눈덩이 크기 비교해서 최대값 저장
    if time <= M :
        ret = max(ret, size)

    #눈덩이 굴리기
    if index <=N-1:
        DFS(index+1, size+A[index+1], time+1)

    #눈덩이 던지기
    if index <= N-2:
        #눈덩이 크기는 절반
        DFS(index+2, size//2 + A[index+2], time+1)

ret = -1

DFS(0,1,0)

print(ret)


import os
import datetime

import aspose.pdf as ap

import sql_manipulation as sqlm
import my_fractions as frac
import periodical_decimal as perd
import operations as op
import questions as qst

SUBJECT = "Fractions"

TODAY = str(datetime.date.today())
NOW = str(datetime.datetime.now())[11:19].replace(":", "-")
FILE_NAME = f"Avaliação de {SUBJECT} (Data {TODAY} # Hora {NOW}).tex"

ABS_PATH = os.path.dirname(os.path.dirname(__file__))
FILE_PATH = os.path.join(ABS_PATH, "exams", FILE_NAME)

def main():

    consult = sqlm.Consultation(SUBJECT, data_type="subject")

    begin_document()

    with open(FILE_PATH, "a+", encoding="UTF-8") as latex_file:

        for data in consult.infos:

            quest = qst.Question(data)

            question_to_be_writted = quest.write_question_in_latex()

            latex_file.write(question_to_be_writted)

    end_document()

    print("Concluído!!!")

def begin_document():

    file = open(FILE_PATH, "w", encoding="UTF-8")

    document_beggining = "\\documentclass{article}\n\n\\usepackage{graphicx}\n\\usepackage[brazilian]{babel}\n\n\\title{Avaliação}\n\\author{Lucas L. Valente}\
        \n\\date{%s}\n\n\\begin{document}\n\maketitle\n\\newpage\n\n\\begin{enumerate}\n" % (str(datetime.date.today()))

    file.write(document_beggining)

    file.close()

def end_document():

    file = open(FILE_PATH, "a+", encoding="UTF-8")

    document_ending = "\\end{enumerate}\n\\end{document}"

    file.write(document_ending)

    file.close()

main()


import slack
import logging

class Slack():

    def __init__(self, token, channel, username, icon_url):
        self.slack_client = None
        self.slack_channel_id = None

        self.slack_token = token
        self.slack_channel = channel
        self.slack_username = username
        self.slack_icon_url = icon_url

        self.setup_client()

    def setup_client(self):
        self.slack_client = slack.WebClient(token=self.slack_token)
        self.find_slack_channel()

    def find_slack_channel(self):
        channels = self.slack_client.conversations_list(
            types='public_channel,private_channel',
            exclude_archived=1
        )

        channel_id = None
        for channel in channels['channels']:
            if channel['name'] and channel['name'] == self.slack_channel:
                channel_id = channel['id']

        if channel_id is None:
            logging.error(f'Could not find channel: {self.slack_channel} from channel list')
            exit(1)

        self.slack_channel_id = channel_id
        logging.debug(f'Found Slack channel ID for channel: {self.slack_channel} = {self.slack_channel_id}')

    def send_message_to_channel(self, message=None, attachments=None, thread_ts=None):
        post_message = self.slack_client.chat_postMessage(
            text=message,
            channel=self.slack_channel_id,
            as_user=False,
            unfurl_links=True,
            username=self.slack_username,
            icon_url=self.slack_icon_url,
            thread_ts=thread_ts,
            attachments=attachments
        )

        logging.debug(f'Slack message result: {post_message}')
        return post_message


# -*- coding: utf-8 -*-
"""
Created on Tue Aug  7 15:21:26 2018

@author: hassanyf and nabeelyousfi
"""
from __future__ import print_function
from myo.utils import TimeInterval
import myo
import sys
import pandas as pd

# Implementing DeviceListener for EMG.
class Listener(myo.DeviceListener):

    def __init__(self):
        self.interval = TimeInterval(None, 0.05)
        self.orientation = None
        self.pose = myo.Pose.rest
        self.emg_enabled = False
        self.locked = False
        self.emg = None

    def output(self):
        if not self.interval.check_and_reset():
            return

        parts = []

        if self.emg:
            for comp in self.emg:
                parts.append(str(comp).ljust(5))
        print('\r' + ','.join('{}'.format(p) for p in parts), end='')
        sys.stdout.flush()

    def on_connected(self, event):
        event.device.request_rssi()

    def on_pose(self, event):
        event.device.stream_emg(True)
        self.emg_enabled = True
        self.emg = None
        self.output()

    def on_emg(self, event):
        self.emg = event.emg
        self.output()

dataset = pd.read_csv('dataset.csv')
X = dataset.iloc[:, [0,1,2,3,4,5,6,7]].values
y = dataset.iloc[:, 8].values

# Encoding categorical data
from sklearn.preprocessing import LabelEncoder
labelencoder_y= LabelEncoder()
y = labelencoder_y.fit_transform(y)
y=y.reshape(-1,1)

# Splitting the dataset into the Training set and Test set
from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0)

# Feature Scaling
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)

# Fitting Logistic Regression to the Training set
from sklearn.ensemble import RandomForestClassifier
classifier =RandomForestClassifier(n_estimators =500,criterion='entropy',random_state = 0)
classifier.fit(X_train, y_train)

# Predicting the Test set results
y_pred = classifier.predict(X_test)

# Making the Confusion Matrix
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)

# Displaying EMG data
if __name__ == '__main__':
    myo.init()
    hub = myo.Hub()
    listener = Listener()
    while hub.run(listener.on_event, 500):
        pass


# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import unittest

import models.base as mbase
import models.test_suite as mtsuite

class TestTestSuiteModel(unittest.TestCase):

    def test_suite_doc_valid_instance(self):
        test_suite = mtsuite.TestSuiteDocument(
            "name", "lab_name", "defconfig_id", "1.0")
        self.assertIsInstance(test_suite, mbase.BaseDocument)

    def test_suite_doc_to_dict(self):
        test_suite = mtsuite.TestSuiteDocument(
            "name", "lab_name", "defconfig_id", "1.0")

        test_suite.arch = "arm"
        test_suite.board = "board"
        test_suite.board_instance = 1
        test_suite.boot_id = "boot_id"
        test_suite.created_on = "now"
        test_suite.defconfig = "defconfig"
        test_suite.defconfig_id = "another_defconfig_id"
        test_suite.definition_uri = "uri"
        test_suite.id = "id"
        test_suite.job = "job"
        test_suite.job_id = "job_id"
        test_suite.kernel = "kernel"
        test_suite.lab_name = "another_lab"
        test_suite.metadata = {"foo": "bar"}
        test_suite.test_case = ["foo"]
        test_suite.test_set = ["bar"]
        test_suite.time = 10
        test_suite.vcs_commit = "1234"
        test_suite.version = "1.1"

        expected = {
            "_id": "id",
            "arch": "arm",
            "board": "board",
            "board_instance": 1,
            "boot_id": "boot_id",
            "created_on": "now",
            "defconfig": "defconfig",
            "defconfig_full": "defconfig",
            "defconfig_id": "another_defconfig_id",
            "definition_uri": "uri",
            "job": "job",
            "job_id": "job_id",
            "kernel": "kernel",
            "lab_name": "another_lab",
            "metadata": {"foo": "bar"},
            "name": "name",
            "test_case": ["foo"],
            "test_set": ["bar"],
            "time": 10,
            "vcs_commit": "1234",
            "version": "1.1"
        }

        self.assertDictEqual(expected, test_suite.to_dict())

    def test_suite_doc_from_json_missing_key(self):
        test_suite = {
            "_id": "id",
            "version": "1.0",
            "defconfig_id": "defconfig_id"
        }

        self.assertIsNone(mtsuite.TestSuiteDocument.from_json(test_suite))

    def test_suite_doc_from_json_wrong_type(self):
        self.assertIsNone(mtsuite.TestSuiteDocument.from_json([]))
        self.assertIsNone(mtsuite.TestSuiteDocument.from_json(()))
        self.assertIsNone(mtsuite.TestSuiteDocument.from_json(""))

    def test_suite_doc_from_json(self):
        suite_json = {
            "_id": "id",
            "arch": "arm",
            "board": "board",
            "board_instance": 1,
            "boot_id": "boot_id",
            "created_on": "now",
            "defconfig": "defconfig",
            "defconfig_full": "defconfig",
            "defconfig_id": "defconfig_id",
            "definition_uri": "uri",
            "job": "job",
            "job_id": "job_id",
            "kernel": "kernel",
            "lab_name": "lab_name",
            "metadata": {"foo": "bar"},
            "name": "name",
            "test_case": ["foo"],
            "test_set": ["bar"],
            "time": 10,
            "vcs_commit": "1234",
            "version": "1.0",
        }

        test_suite = mtsuite.TestSuiteDocument.from_json(suite_json)

        self.assertIsInstance(test_suite, mtsuite.TestSuiteDocument)
        self.assertDictEqual(suite_json, test_suite.to_dict())


import torch.nn as nn
from algo.memory import ReplayMemory, Experience

import torch, os
import numpy as np, random

from algo.random_process import OrnsteinUhlenbeckProcess
from algo.utils import soft_update, hard_update, device
from algo.commnet.network import CommNetWork_Actor, CommNetWork_Critic

class CommNet():

    def __init__(self, s_dim, a_dim, n_agents, args):
        self.s_dim = s_dim
        self.a_dim = a_dim
        self.config = args
        self.batch_size = self.config.batch_size
        self.n_agents = n_agents
        self.device = device
        # Networks
        self.actor = CommNetWork_Actor(s_dim,self.config.batch_size,a_dim)#Actor(s_dim, a_dim, n_agents)
        self.actor_target = CommNetWork_Actor(s_dim,self.config.batch_size,a_dim)#Actor(s_dim, a_dim, n_agents)
        self.critic = CommNetWork_Critic(s_dim,self.config.batch_size,a_dim)#Actor(s_dim, a_dim, n_agents)
        self.critic_target = CommNetWork_Critic(s_dim,self.config.batch_size,a_dim)#Actor(s_dim, a_dim, n_agents)

        self.actor.to(self.device)
        self.actor_target.to(self.device)
        self.critic.to(self.device)
        self.critic_target.to(self.device)

        self.actor_optimizer = torch.optim.Adam(self.actor.parameters(), lr=self.config.a_lr)
        self.critic_optimizer = torch.optim.Adam(self.critic.parameters(), lr=self.config.a_lr)

        self.random_process = OrnsteinUhlenbeckProcess(size=self.a_dim,
                                                       theta=self.config.ou_theta,
                                                       mu=self.config.ou_mu,
                                                       sigma=self.config.ou_sigma)
        self.replay_buffer = list()
        self.epsilon = 1.
        self.depsilon = self.epsilon / self.config.epsilon_decay

        self.c_loss = None
        self.a_loss = None
        self.action_log = list()
        self.memory = ReplayMemory(1e5)
        self.GAMMA = self.config.gamma
        self.var = [1.0 for i in range(n_agents)]
        self.episode = 0

    def load_model(self):
        model_actor_path = "./trained_model/" + str(self.config.algo) + "/actor_" + str(self.config.model_episode) + ".pth"
        model_critic_path = "./trained_model/" + str(self.config.algo) + "/critic_" + str(self.config.model_episode) + ".pth"
        if os.path.exists(model_critic_path) and os.path.exists(model_actor_path):
            print("load model!")
            actor = torch.load(model_actor_path)
            critic = torch.load(model_critic_path)
            self.actor.load_state_dict(actor)
            self.critic.load_state_dict(critic)

    def save_model(self, episode):
        if not os.path.exists("./trained_model/" + str(self.config.algo) + "/"):
            os.mkdir("./trained_model/" + str(self.config.algo) + "/")
        torch.save(self.actor.state_dict(),
                   "./trained_model/" + str(self.config.algo) + "/actor_" + str(episode) + ".pth"),
        torch.save(self.critic.state_dict(),
                   "./trained_model/" + str(self.config.algo) + "/critic_" + str(episode) + ".pth"),

    def choose_action(self, obs, noisy=True):
        obs = torch.Tensor([obs]).to(self.device)

        action = self.actor(obs).cpu().detach().numpy()
        self.action_log.append(action)

        if noisy:
            for agent_idx in range(self.n_agents):
                action[agent_idx] += np.random.randn(2) * self.var[agent_idx]

                if self.var[agent_idx] > 0.05:
                    self.var[agent_idx] *= 0.999998#0.999998

        action = np.clip(action, -1., 1.)
        # print(action)
        return action

    def reset(self):
        self.random_process.reset_states()
        self.action_log.clear()

    def prep_train(self):
        self.actor.train()
        self.critic.train()

    def prep_eval(self):
        self.actor.eval()
        self.critic.eval()

    def random_action(self):
        return np.random.uniform(low=-1, high=1, size=(self.n_agents, 2))

    def get_batches(self):
        experiences = random.sample(self.replay_buffer, self.config.batch_size)

        state_batches = np.array([_[0] for _ in experiences])
        action_batches = np.array([_[1] for _ in experiences])
        reward_batches = np.array([_[2] for _ in experiences])
        next_state_batches = np.array([_[3] for _ in experiences])
        done_batches = np.array([_[4] for _ in experiences])

        return state_batches, action_batches, reward_batches, next_state_batches, done_batches

    def update(self,i_episode):

        if len(self.memory.memory) < self.batch_size:
            return None, None

        self.use_cuda = torch.cuda.is_available()

        FloatTensor = torch.cuda.FloatTensor if self.use_cuda else torch.FloatTensor

        c_loss = []
        a_loss = []

        transitions = self.memory.sample(self.batch_size)
        batch = Experience(*zip(*transitions))

        state_batch = torch.stack(batch.states).type(FloatTensor)
        action_batch = torch.stack(batch.actions).type(FloatTensor)
        reward_batch = torch.stack(batch.rewards).type(FloatTensor)
        non_final_next_states = torch.stack(batch.next_states).type(FloatTensor)#torch.stack([s for s in batch.next_states if s is not None]).type(FloatTensor)
        whole_state = state_batch.view(self.batch_size, self.n_agents, -1)
        whole_action = action_batch.view(self.batch_size, self.n_agents, -1)
        action_batch.view(self.batch_size, self.n_agents, -1)
        next_whole_batch = self.actor_target(non_final_next_states).view(self.batch_size, self.n_agents, -1)

        self.actor_optimizer.zero_grad()
        self.critic_optimizer.zero_grad()
        self.actor.zero_grad()
        self.critic.zero_grad()
        current_Q = self.critic(whole_state,whole_action).view(-1, self.n_agents).cuda()
        target_Q = self.critic_target(non_final_next_states,next_whole_batch).view(-1, self.n_agents).cuda() # .view(-1, self.n_agents * self.n_actions)
        target_Q = target_Q * self.GAMMA + reward_batch
        loss_Q = nn.MSELoss()(current_Q, target_Q.detach())
        loss_Q.backward()
        torch.nn.utils.clip_grad_norm_(self.critic.parameters(), 1)
        self.critic_optimizer.step()

        self.actor_optimizer.zero_grad()
        self.critic_optimizer.zero_grad()
        self.actor.zero_grad()
        self.critic.zero_grad()
        whole_action = self.actor(whole_state).view(self.batch_size, self.n_agents, -1)
        actor_loss = -self.critic(whole_state, whole_action).mean()*100
        actor_loss.backward()
        torch.nn.utils.clip_grad_norm_(self.actor.parameters(), 1)
        torch.nn.utils.clip_grad_norm_(self.critic.parameters(), 1)
        self.actor_optimizer.step()
        c_loss.append(loss_Q.item())
        a_loss.append(actor_loss.item())
        self.train_num = i_episode
        if self.train_num % 200 == 0:
            soft_update(self.actor, self.actor_target, self.config.tau)
            soft_update(self.critic, self.critic_target, self.config.tau)

        return sum(c_loss) / len(c_loss), sum(a_loss) / len(a_loss)

    def get_loss(self):
        return self.c_loss, self.a_loss

    def get_action_std(self):
        return np.array(self.action_log).std(axis=-1).mean()


"""
# Sample code to perform I/O:

name = input()                  # Reading input from STDIN
print('Hi, %s.' % name)         # Writing output to STDOUT

# Warning: Printing unwanted or ill-formatted data to output will cause the test cases to fail
"""

# Write your code here
from collections import deque

x1, y1, x2, y2 = map(int, input().strip().split())
dx = [2, -2, 2, -2, 1, 1, -1, -1]
dy = [1, 1, -1, -1, 2, -2, 2, -2]
visited = [[False] * 8 for _ in range(8)]
poss = [[0] * 8 for _ in range(8)]
x1 -= 1
y1 -= 1
x2 -= 1
y2 -= 1
q = deque()
q.append((x1, y1))
visited[x1][y1] = True
while q:
    x, y = q.popleft()
    for i in range(8):
        px = x + dx[i]
        py = y + dy[i]
        if 0 <= px < 8 and 0 <= py < 8 and not visited[px][py]:
            visited[px][py] = True
            poss[px][py] = poss[x][y] + 1
            q.append((px, py))
print(poss[x2][y2])

hackerearth/Algorithms/Harry Potter and the Sorcerer's Stone/solution.py


if True:  # \/ # PyVersion // assert sys.version_info[:2] == (3, 11)
  if __import__('sys').version_info[:2] != (3, 11):
    msg = 'Use py311'
    raise ValueError(msg)

if True:  # \/ # Imports
  from db import backup_all_databases, db
  from execute import execute
  from imports import *

if True:  # \/ # BotApp
  bot = lb.BotApp(
    token=token(),
    #   banner=None,
    default_enabled_guilds=S.DEFAULT_ENABLED_GUILDS,
  )

if True:  # \/ # Utilities
  if True:  # \/ # Synchronous

    def F(item: str) -> str:
      return eval(f'f{item!r}')

    def embed(
      title: str,
      description: str,
      *,
      url=None,
      color=None,
      timestamp=None,
      thumbnail=None,
      footer=None,
      footer_icon=None,
      author: dict | None = None,
      image=None,
      fields: list | None = None,
    ) -> hikari.Embed:
      if (title is not Null and not title.strip()) or (
        description is not Null and not description.strip()
      ):
        msg = f'Both title and description must be non-whitespace-only strings unless explicitly specified the title to be Null, got Title: {title!r}, Description: {description!r}'
        raise ValueError(msg)

      if fields is None:
        fields = []

      if author is None:
        author = {}

      out = hikari.Embed(
        title=title if title is not Null else None,
        description=description if description is not Null else None,
        color=color,
        timestamp=timestamp,
        url=url,
      )

      if thumbnail:
        out = out.set_thumbnail(thumbnail)

      if footer:
        out = out.set_footer(text=footer, icon=footer_icon)
      if author:
        out = out.set_author(**author)
      if image:
        out = out.set_image(image)

      for field in fields:
        if len(field) == 2:
          field = (*field, False)
        out = out.add_field(field[0], field[1], inline=field[2])
      return out

    def get_prefix(guild_id: int | str | None = None) -> str:
      """Return guild prefix, if no `guild_id` is passed in, return default (and DM) prefix."""
      if guild_id is None:
        return default.db_guild_data['prefix']
      return db.guild.read(guild_id)['prefix']

    def get_prefix_case_sensitivity(guild_id: int | str | None = None) -> bool:
      """Return guild prefix's case sensitivity, if no `guild_id` is passed in, return default (and DM) prefix's case sensitivity."""
      if guild_id is None:
        return default.db_guild_data['prefix_case_sensitive']
      return db.guild.read(guild_id)['prefix_case_sensitive']

    def is_dm_event(event: hikari.Event) -> bool:
      """Return True if the event is a DM-related event, else return False."""
      return hasattr(event, 'guild_id')

    def get_author_from_event(event: hikari.Event):
      """Try to return an author or member from an event."""
      try:
        return event.author
      except AttributeError:
        try:
          return event.member
        except AttributeError:
          return event.old_member

  if True:  # \/ # Assynchronous

    async def debug_send(
      channel_id_or_responder: int | str | Callable,
      text_or_dictmessage: list | str | types.DictMessage,
      *,
      as_dictmessage=False,
    ) -> hikari.Message:
      def debug_prepare(content: str | int | Iterable) -> str:
        if isinstance(content, str):
          return codeblock(f'{content!r}', langcode='py')
        elif isinstance(content, Iterable):
          return codeblock(tcr.print_iterable(content, raw=True), langcode='py')
        return codeblock(repr(content))

      if not as_dictmessage:
        text_or_dictmessage = {'content': text_or_dictmessage}
      text_or_dictmessage['content'] = debug_prepare(text_or_dictmessage['content'])
      if channel_id_or_responder in ['raw', 'return']:
        return text_or_dictmessage
      if isinstance(channel_id_or_responder, int | str):
        channel_id_or_responder = int(channel_id_or_responder)
        return await bot.rest.create_message(channel=channel_id_or_responder, **text_or_dictmessage)
      else:
        return await channel_id_or_responder(**text_or_dictmessage)

    async def error_send(): ...

if True:  # \/ # Prefix Commands
  if True:  # \/ # Guild

    def parse_guild_prefix_event(event: hikari.GuildMessageCreateEvent) -> types.ParsedPrefixEvent:
      prefix = get_prefix(event.guild_id)
      prefixed = event.content.startswith(prefix)
      message = event.content.removeprefix(prefix)
      return {
        'prefix': prefix,
        'message': message,
        'prefixed': prefixed,
      }

  if True:  # \/ # DMs

    def parse_DM_prefix_event(event: hikari.DMMessageCreateEvent) -> types.ParsedPrefixEvent:
      prefix = get_prefix()
      prefixed = event.content.startswith(prefix)
      message = event.content.removeprefix(prefix)
      return {
        'prefix': prefix,
        'message': message,
        'prefixed': prefixed,
      }

if True:  # \/ # Event listeners
  if True:  # \/ # Messages

    async def on_message(
      event: hikari.GuildMessageCreateEvent | hikari.DMMessageCreateEvent, *, in_dms: bool
    ):
      if not event.is_human:
        return
      parsed = parse_DM_prefix_event(event) if in_dms else parse_guild_prefix_event(event)
      await debug_send(event.message.respond, parsed)

    @bot.listen(hikari.GuildMessageCreateEvent)
    async def on_GuildMessageCreateEvent(event: hikari.GuildMessageCreateEvent):
      await on_message(event, in_dms=False)

    @bot.listen(hikari.DMMessageCreateEvent)
    async def on_DMMessageCreateEvent(event: hikari.DMMessageCreateEvent):
      await on_message(event, in_dms=True)

  if True:  # \/ # Globals

    @bot.listen(hikari.StartingEvent)
    async def on_StartingEvent(event: hikari.StartingEvent): ...

    @bot.listen(hikari.StartedEvent)
    async def on_StartedEvent(event: hikari.StartedEvent): ...

    @bot.listen(hikari.StoppingEvent)
    async def on_StoppingEvent(event: hikari.StoppingEvent): ...

    @bot.listen(hikari.StoppedEvent)
    async def on_StoppedEvent(event: hikari.StoppedEvent): ...

if True:  # \/ # Run
  if testmode:
    text = ''.join(
      [
        f'{c("RED", "Black") if i % 2 == 0 else c("YELLOW", "white")}{x}'
        for i, x in enumerate(f' Running in testmode ')
      ]
    ) + c('reset')
    kon.log(text)
  bot.run(status=STATUS, activity=ACTIVITY)


# 敌方飞船，生成于屏幕顶端的随机位置
import pygame
import random

class Enemy(pygame.sprite.Sprite):
    def __init__(self, screen, setting):
        super(Enemy, self).__init__()
        self.screen = screen
        self.image = pygame.image.load("images/img-plane_1.png")
        self.rect = self.image.get_rect()
        self.scr_rect = self.screen.get_rect()
        self.rect.x = random.randint(0, self.scr_rect.width - self.rect.width)
        self.rect.bottom = 0
        self.speed = random.randint(1, 2) * setting.enemy_factor

    # 敌机向下移动
    def update(self):
        self.rect.y += self.speed

    # 将其绘制在屏幕上
    def draw(self):
        self.screen.blit(self.image, self.rect)


CLEAN = 0
WEAKENED = 1
INFECTED = 2
FLAGGED = 3

UP = 0
DOWN = 1
LEFT = 2
RIGHT = 3

START_POS = (0, 0)
START_DIR = UP

grid = dict()
with open("inputs/[Day22]input.txt", "r") as f:
    lines = [x.strip() for x in f.readlines()]

    offset = int(len(lines)/2)

    for row in range(len(lines)):
        for col in range(len(lines)):
            grid[(col - offset, row - offset)] = INFECTED if lines[row][col] == "#" else CLEAN

# I could arrange the number values of the directions to label them in a clockwise order, then simply adding -1
# (modulo 4) would give the new direction.  But I like spelling it out in this fashion.

def turn_left(direction):
    return {
        UP: LEFT,
        LEFT: DOWN,
        DOWN: RIGHT,
        RIGHT: UP
    }[direction]

def turn_right(direction):
    return {
        UP: RIGHT,
        RIGHT: DOWN,
        DOWN: LEFT,
        LEFT: UP
    }[direction]

def reverse(direction):
    return {
        UP: DOWN,
        DOWN: UP,
        RIGHT: LEFT,
        LEFT: RIGHT
    }[direction]

def is_infected(state):
    return state == CLEAN or state == WEAKENED

def move(pos, direction):
    x, y = pos
    return {
        UP: (x, y - 1),
        DOWN: (x, y + 1),
        LEFT: (x - 1, y),
        RIGHT: (x + 1, y)
    }[direction]

def get_pos(g: dict, pos: tuple) -> int:
    if pos not in g:
        g[pos] = CLEAN
    return g[pos]

def set_pos(g, pos, val):
    g[pos] = val

def process_node(g: dict, pos: tuple, direction: int) -> (tuple, int, int):

    state = get_pos(g, pos)

    # Turn and update state

    if state == CLEAN:
        direction = turn_left(direction)
        state = WEAKENED

    elif state == WEAKENED:
        state = INFECTED

    elif state == INFECTED:
        direction = turn_right(direction)
        state = FLAGGED

    elif state == FLAGGED:
        direction = reverse(direction)
        state = CLEAN

    set_pos(g, pos, state)

    # Move
    pos = move(pos, direction)

    return pos, direction, state

def process_bursts(g, pos, direction, iters):

    count = 0
    for _ in range(iters):
        pos, direction, state = process_node(g, pos, direction)
        if state == INFECTED:
            count += 1

    return count

infections = process_bursts(grid, START_POS, START_DIR, 10000000)

print("INFECTIONS = " + str(infections))


import csv
import sys

from util import Node, StackFrontier, QueueFrontier

# Maps names to a set of corresponding person_ids
names = {}

# Maps person_ids to a dictionary of: name, birth, movies (a set of movie_ids)
people = {}

# Maps movie_ids to a dictionary of: title, year, stars (a set of person_ids)
movies = {}

def load_data(directory):
    """
    Load data from CSV files into memory.
    """
    # Load people
    with open(f"{directory}/people.csv", encoding="utf-8") as f:
        reader = csv.DictReader(f)
        for row in reader:
            people[row["id"]] = {
                "name": row["name"],
                "birth": row["birth"],
                "movies": set()
            }
            if row["name"].lower() not in names:
                names[row["name"].lower()] = {row["id"]}
            else:
                names[row["name"].lower()].add(row["id"])

    # Load movies
    with open(f"{directory}/movies.csv", encoding="utf-8") as f:
        reader = csv.DictReader(f)
        for row in reader:
            movies[row["id"]] = {
                "title": row["title"],
                "year": row["year"],
                "stars": set()
            }

    # Load stars
    with open(f"{directory}/stars.csv", encoding="utf-8") as f:
        reader = csv.DictReader(f)
        for row in reader:
            try:
                people[row["person_id"]]["movies"].add(row["movie_id"])
                movies[row["movie_id"]]["stars"].add(row["person_id"])
            except KeyError:
                pass

def main():
    if len(sys.argv) > 2:
        sys.exit("Usage: python degrees.py [directory]")
    directory = sys.argv[1] if len(sys.argv) == 2 else "large"

    # Load data from files into memory
    print("Loading data...")
    load_data(directory)
    print("Data loaded.")

    source = person_id_for_name(input("Name: "))
    if source is None:
        sys.exit("Person not found.")
    target = person_id_for_name(input("Name: "))
    if target is None:
        sys.exit("Person not found.")

    path = shortest_path(source, target)

    if path is None:
        print("Not connected.")
    else:
        degrees = len(path)
        print(f"{degrees} degrees of separation.")
        path = [(None, source)] + path
        for i in range(degrees):
            person1 = people[path[i][1]]["name"]
            person2 = people[path[i + 1][1]]["name"]
            movie = movies[path[i + 1][0]]["title"]
            print(f"{i + 1}: {person1} and {person2} starred in {movie}")

def shortest_path(source, target):
    """
    Returns the shortest list of (movie_id, person_id) pairs
    that connect the source to the target.

    If no possible path, returns None.
    """

    # builds the frontier and adds explored nodes to a list
    explored_list = explore(source, target)

    # returns None if people are not connected
    if explored_list is None:
        return None

    # recreates the shortest path from the explored nodes list
    solution = reconstruct_path(explored_list)

    return solution

# builds a queue frontier and uses it to create a list of explored nodes
def explore(start, target):
    # print("Exploring...")

    f = QueueFrontier()

    f.add(Node(start, None, None))

    explored_nodes = []

    # this loop gets the next node in the frontier, adds all unexplored neighbors to the frontier,
    # and then removes the current node from the frontier
    while True:
        try:
            # pop off the node you're going to explore
            current_node = f.remove()

            """
            # check if the node you're currently exploring is the target, if so, add to list and break
            if current_node.state == target:
                explored_nodes.append(current_node)
                break
            """
            # get neighbors for that node and iterate through them
            for x in neighbors_for_person(current_node.state):
                # add here a test to see if neighbor is target, to optimize search
                if x[1] == target:
                    explored_nodes.append(Node(x[1], current_node, x[0]))
                    # print(f"Explored {len(explored_nodes)} nodes.")
                    return explored_nodes
                # if the node is not in the frontier and is not in the explored list, add it to the frontier
                # IMPORTANT each node needs to have a state (person), parent (previous node), action (movie)
                if not f.contains_state(x[1]) and not (any(x[1] == node.state for node in explored_nodes)):
                    f.add(Node(x[1], current_node, x[0]))

            # when done with adding neighbors, add node to explored list
            explored_nodes.append(current_node)

        # this should run only when it has went through all possible layers of neighbors but didn't find target
        except:
            # print(f"Explored {len(explored_nodes)} nodes.")
            return None

    # print(f"Explored {len(explored_nodes)} nodes.")
    return explored_nodes

# go through the nodes in reverse to find the path solution
def reconstruct_path(node_list):
    # this reverses the list
    node_list.reverse()

    # initialize empty list for storing the reconstructed path
    reconstructed_path = []

    # start from the first node in the reversed list
    current_node = node_list[0]

    # loop through node list and stop when you reach a node with no parent
    while current_node.parent is not None:
        # when reconstructing path, each step is a (movie_id, person_id) tuple
        reconstructed_path.append((current_node.action, current_node.state))
        # then move on to the next
        current_node = current_node.parent

    reconstructed_path.reverse()

    return reconstructed_path

def person_id_for_name(name):
    """
    Returns the IMDB id for a person's name,
    resolving ambiguities as needed.
    """
    person_ids = list(names.get(name.lower(), set()))
    if len(person_ids) == 0:
        return None
    elif len(person_ids) > 1:
        print(f"Which '{name}'?")
        for person_id in person_ids:
            person = people[person_id]
            name = person["name"]
            birth = person["birth"]
            print(f"ID: {person_id}, Name: {name}, Birth: {birth}")
        try:
            person_id = input("Intended Person ID: ")
            if person_id in person_ids:
                return person_id
        except ValueError:
            pass
        return None
    else:
        return person_ids[0]

def neighbors_for_person(person_id):
    """
    Returns (movie_id, person_id) pairs for people
    who starred with a given person.
    """
    movie_ids = people[person_id]["movies"]
    neighbors = set()
    for movie_id in movie_ids:
        for person_id in movies[movie_id]["stars"]:
            neighbors.add((movie_id, person_id))
    return neighbors

if __name__ == "__main__":
    main()


def solution(storey):

    # https://mag1c.tistory.com/166
    # 5일 경우, 다음 자리 수가 5 이상이면 올라가고, 4 이하면 내려감

    answer = 0

    tmp = str(storey)
    arr = [int(i) for i in tmp]
    answer = 0
    for i in range(len(arr)-1, -1, -1):
        if arr[i] > 5:
            answer += 10-arr[i]
            if i==0:
                answer += 1
            else:
                arr[i-1] += 1
        elif arr[i]==5 and i>0 and arr[i-1]>=5:
            arr[i-1] += 1
            answer += 5
        else:
            answer += arr[i]

    return answer

프로그래머스/unrated/148653. 마법의 엘리베이터/마법의 엘리베이터.py

마법의 엘리베이터.py


import csv
from pathlib import Path
from datetime import datetime
from decimal import Decimal

from trades.models import CurrencyValue

DATA_DIR = Path("../data")

def get_csv(file_path, skip_header=True, delimiter=','):
    with open(file_path, 'r', newline='') as file:
        reader = csv.reader(file, delimiter=delimiter)
        if skip_header:
            next(reader)
        return [line for line in reader]

def clear_data():
    """WARNING: CLEARS ALL DATA FROM ALL TABLES"""
    print("WARNING: ABOUT TO CLEAR ALL DATA FROM ALL TRADES TABLES")
    print("Continue? (type yes)")
    if input("> ").lower() != "yes":
        print("No data was altered")
        return False
    CurrencyValue.objects.all().delete()
    print("Cleared data from all tables.")
    return True

def load_all(years_to_load, months_to_load):
    # load currency values:
    # date,currency,valueInUSD
    for yeardir in (DATA_DIR/'currencyValues').iterdir():
        if years_to_load != "all" and yeardir.name not in years_to_load:
            continue
        for monthdir in yeardir.iterdir():
            if months_to_load != "all" and monthdir.name not in months_to_load:
                continue
            for f in monthdir.iterdir():
                CurrencyValue.objects.bulk_create([
                    CurrencyValue(

                        date=datetime.strptime(l[0], "%d/%m/%Y").date(),
                        currency=l[1],
                        value=Decimal(l[2]))
                    for l in get_csv(f)
                ])
            print(monthdir)

def main():
    if not clear_data():
        print("WARNING: You did not clear data previously in the db. (THIS COULD BE PROBLEMATIC)")
        print("Continue? (type yes)")
        if input("> ").lower() != "yes":
            print("EXITING")
            return
    print("Give comma separated list of years to load (type all for all years)")
    print("WARNING: Loading all years will take a WHILE. last warning")
    s = input("> ").strip()
    if s.lower() != "all":
        years = [y.strip() for y in s.split(',')]
    else:
        years = "all"
    print("Give comma separated list of months (of specified years) to load (type all for all months)")
    print("NOTE: Months names are case sensitive")
    s = input("> ").strip()
    if s.lower() != "all":
        months = [m.strip() for m in s.split(',')]
    else:
        months = "all"
    load_all(years, months)
if __name__ == "__main__":
    main()


# Sukurti naują projektą Mokymas
# • Projekto kataloge sukurti katalogą modules
# • Kataloge modules sukurti failą kursas.py
# • Faile kursas.py sukurti objekto klasę Kursas, kuri turėtų savybes pavadinimas, destytojas, trukme, taip pat metodą
# destyti(), kuris spausdintų „Vyksta mokymas!“
# • Kataloge modules sukurti antrą failą python_kursas.py
# • Faile python_kursas.py sukurti objekto klasę PythonKursas, kuri paveldėtų viską iš klasės Kursas, bei perrašytų
# metodą destyti() taip, kad jis spausdintų „Vyksta programavimas!“
# • Pagrindiniame projekto kataloge sukurti failą main.py
# • Faile main.py importuoti PythonKursas modulį (failą)
# • Faile main.py inicijuoti Kursas objektą su norimomis savybėmis
# • Faile main.py inicijuoti PythonKursas objektą su norimomis savybėmis
# • Paleisti abiejų objektų metodą destyti()

from modules.python_kursas import *

mokymas1 = Kursas("UI/UX mokymai", "Juozas Juozaitis", 5)
mokymas2 = PythonKursas("Python programavimas", "Petras Petraitis", 9)

mokymas1.destyti()
mokymas2.destyti()

# print(mokymas1)
# print(mokymas2)


import requests
from face_reco.apps.utils import get_access_token

# 调用百度API完成M:N人脸搜索
# def baidu_face_multi_search(file_path):
def baidu_face_multi_search(base64):
    card_list = []
    request_url = "https://aip.baidubce.com/rest/2.0/face/v3/multi-search"
    params = {
        # "image": picToBase64(file_path),
        "image": base64,
        "image_type": "BASE64",  # 图片类型
        "group_id_list": "people",  # 这是要检索的图片库
        "max_face_num": 3,  # 最多处理人脸的数量
        "match_threshold": 70,  # score低于此阈值用户的信息将不会被返回
    }
    access_token = get_access_token.getAccessToken()
    # if (access_token == ""):
    #     print("获取access_token失败")
    #     data = {
    #         "error_code": 100,
    #         "message": "无效的access_token参数"
    #     }
    #     return data
    # 请求地址
    request_url = request_url + "?access_token=" + access_token
    # 请求头
    headers = {'content-Type': 'application/json'}
    # 响应
    response = requests.post(request_url, data=params, headers=headers)
    json = response.json()
    return json

# if __name__ == '__main__':
#     baidu_face_multi_search(file_path)