from Node import Node

import numpy as np

class RegressionTree:
    def __init__(self, n_features, max_depth):
        self.n_features = n_features
        self.max_depth = max_depth
        self.root = None
        self.leaves = None

    def variance(self, X):
        """
        Calculate the variance of a given split of data.
        """
        return np.sum(np.square(X - (np.sum(X) / X.shape[0]))) / X.shape[0]

    def calculate_variance(self, X_train, X_left, X_right):
        """
        Calculate the total variance between the data and its two split sets.
        """
        X_n = len(X_train)

        return (len(X_left) / X_n * self.variance(X_left)) + (len(X_right) / X_n * self.variance(X_right))

    def find_split(self, X_train):
        """
        Perform variance reduction to find the best split in the data for a select number of features
        """
        best = {'variance': np.inf}
        for i in np.random.choice(range(X_train.shape[1]), self.n_features, replace=False):
            for split in X_train[:, i]:
                if split == np.max(X_train[:, i]) or split == np.min(X_train[:, i]):
                    continue
                left_indices = np.where(X_train[:, i] < split)[0]
                right_indices = np.where(X_train[:, i] > split)[0]
                variance = self.calculate_variance(X_train[:, i], X_train[left_indices, i], X_train[right_indices, i])
                if variance < best['variance']:
                    best = {'feature': i,
                            'split': split,
                            'variance': variance,
                            'left_indices': left_indices,
                            'right_indices': right_indices}

        return best['feature'], best['split'], best['variance'], best['left_indices'], best['right_indices']

    def build(self, X_train, y_train):
        """
        Build the tree by generating a node at each level which is either designated a leaf node with the
        average of the training data as its result or a branch node with a left and a right node taking a split
        in the training data.
        """
        node = Node()
        if self.max_depth == 1 or X_train.shape[0] == 1 or y_train.shape[0] == 1:
            node.leaf = True
            node.result = np.sum(y_train) / y_train.shape[0]
        else:
            self.max_depth -= 1
            node.feature, node.split, node.infogain, left_indices, right_indices = self.find_split(X_train)
            node.left = self.build(X_train[left_indices, :], y_train[left_indices])
            node.right = self.build(X_train[right_indices, :], y_train[right_indices])

        return node

    def train(self,  X_train, y_train):
        """
        Train the model by building a tree from a root node.
        """
        self.root = self.build(X_train, y_train)

    def transverse(self, X_test, node, indices):
        """
        Transverse the tree using the given test data point to find the relevant leaf node and its prediction.
        """
        if node.leaf:
            self.leaves[indices] = node.result
        else:
            move_left = X_test[indices, node.feature] < node.split
            left_indices = indices[move_left]
            right_indices = indices[np.logical_not(move_left)]
            if left_indices.shape[0] > 0:
                self.transverse(X_test, node.left, left_indices)
            if right_indices.shape[0] > 0:
                self.transverse(X_test, node.right, right_indices)

    def predict_one(self, node, X_test):
        """
        Predict the result for a single test data point for the purpose of validation.
        """
        if node.leaf:
            return node.result
        else:
            if X_test[node.feature] < node.split:
                return self.predict_one(node.left, X_test)
            else:
                return self.predict_one(node.right, X_test)

    def predict(self, X_test):
        """
        Predict the results for each test data point.
        """
        self.leaves = np.empty(X_test.shape[0], dtype=float)
        self.leaves.fill(-1)
        indices = np.arange(X_test.shape[0])
        self.transverse(X_test, self.root, indices)

        return self.leaves

    def test(self, X_test, y_test):
        """
        Test the model with test data.
        """
        prediction = self.predict_one(self.root, X_test[0])
        print(f'Prediction | X = {X_test[0]} | y = {y_test[0]} | y prediction = {prediction}')

        self.print_tree(self.root, 2)

        predictions = self.predict(X_test)
        rmse = np.sqrt(np.sum(np.square(np.subtract(predictions, y_test))) / len(predictions))
        print(f'Max Depth = {self.max_depth} | RMSE = {rmse}')

    def print_tree(self, tree, indent=0, level=0):
        """
        Pretty print the regression tree.
        """
        indent_space = indent * level * ' '
        level = level + 1

        if tree.leaf:
            print(f"{indent_space}predict {tree.result}")
        else:
            print('')
            print(f"{indent_space}[x{tree.feature} <={tree.split}]")
            self.print_tree(tree.left, indent, level)

            print('')
            print(f"{indent_space}[x{tree.feature} >{tree.split}]")
            self.print_tree(tree.right, indent, level)


from PyQt6.QtWidgets import QApplication, QWidget, QFileDialog, QVBoxLayout, QPushButton, QLabel
from PyQt6.QtCore import Qt
import sys
import os
import re
import PyPDF2

class PDFRenamer(QWidget):
    def __init__(self):
        super().__init__()

        layout = QVBoxLayout()

        self.label = QLabel("Selecione um arquivo PDF para renomear.")
        layout.addWidget(self.label)

        self.btn = QPushButton("Selecionar Arquivo")
        self.btn.clicked.connect(self.openFileNameDialog)
        layout.addWidget(self.btn)

        self.setLayout(layout)

    def openFileNameDialog(self):
        filePath, _ = QFileDialog.getOpenFileName(
            self, "Selecione um arquivo PDF", "", "PDF Files (*.pdf);;Todos os Arquivos (*)")
        if filePath:
            info = self.extract_info_from_pdf(filePath)
            if all(value != 'Unknown' for value in info.values()):
                new_path = self.rename_file(filePath, info)
                self.label.setText(f"Arquivo renomeado para: {new_path}")
            else:
                self.label.setText("Informações não encontradas no PDF.")

    def extract_info_from_pdf(self, pdf_path):
        info = {'ISBN': 'Unknown', 'Name': 'Unknown', 'Year': 'Unknown', 'Publisher': 'Unknown'}

        with open(pdf_path, 'rb') as f:
            reader = PyPDF2.PdfReader(f)

            # Segunda página (índice 1 em notação zero-based)
            text_page_2 = reader.pages[1].extract_text()
            # Terceira página (índice 2 em notação zero-based)
            text_page_3 = reader.pages[2].extract_text()

            # Procurando informações na segunda página
            name = re.search(r'(.+?)\n', text_page_2)
            info['Name'] = name.group(1) if name else 'Unknown'

            # Procurando informações na terceira página
            isbn = re.search(r'ISBN (\d{3}-\d{1,5}-\d{1,7}-\d{1,7}-\d{1})', text_page_3)
            year = re.search(r'Copyright \u00A9 (\d{4})', text_page_3)
            publisher = re.search(r'Published by (.+?)\n', text_page_3)

            info['ISBN'] = isbn.group(1) if isbn else 'Unknown'
            info['Year'] = year.group(1) if year else 'Unknown'
            info['Publisher'] = publisher.group(1) if publisher else 'Unknown'

        return info

    def rename_file(self, old_path, info):
        new_name = f"{info['ISBN']}_{info['Name']}_{info['Year']}_{info['Publisher']}.pdf"
        new_path = os.path.join(os.path.dirname(old_path), new_name)
        os.rename(old_path, new_path)
        return new_path

if __name__ == '__main__':
    app = QApplication(sys.argv)

    window = PDFRenamer()
    window.setWindowTitle("PDF Renamer")
    window.setGeometry(100, 100, 400, 200)
    window.show()

    sys.exit(app.exec())


#!/tools/opt/python/python2.7.2/bin/python2.7

from __future__ import division
import os
import sys

os.environ['PYTHONPATH'] = '/lib/python:/home/people/simon/lib/misc:/panvol1/simon/lib/python:/panvol1/simon/bin/mlst/'
sys.stderr.write('%s\n' % os.environ['PYTHONPATH'])

from Bio.SeqIO.QualityIO import FastqGeneralIterator
import argparse
import mlst_modules
import random
import string
import cdb
import multiprocessing
import gzip

class FastqTrim:
   '''Trim/Filter paired end fastq:
      trim 3' trailing bases under (q)
      trim sequencing adaptors (Illumina) (a)
      filter reads with less than avg. Q quals (m)
      filter reads with less than L length (l)
      filter reads with Ns (keep_n)
   '''

   def __init__(self, f, o, l=25, q=20, m=20, keep_n=False, M=20,
                a=['GATCGGAAGAGCGGTTCAGCAGGAATGCCGAG', 'ACACTCTTTCCCTACACGACGCTCTTCCGATCT',
                'AATGATACGGCGACCACCGAGATCTACACTCTTTCCCTACACGACGCTCTTCCGATCT',
                'CAAGCAGAAGACGGCATACGAGATCGGTCTCGGCATTCCTGCTGAACCGCTCTTCCGATCT',
                'CGGTCTCGGCATTCCTGCTGAACCGCTCTTCCGATCT',
                'ACACTCTTTCCCTACACGACGCTCTTCCGATCT']):
      self.f = f
      self.o = o
      self.l = l
      self.q = q
      self.m = m
      self.keep_n = keep_n
      self.M = M
      self.a = a
      self.paired = False
      self.interleaved = False

      # set adaptors, readtype, fastq format
      self.adaptors = self.set_adaptors()
      self.format = mlst_modules.set_filetype(self.f[0])
      if self.format == 'fastq':
         self.fqtype = mlst_modules.set_fqtype(self.f[0])
         sys.stderr.write('Header/Quality encoding: %s/%s\n' % (self.fqtype[0], self.fqtype[1]))
      self.set_readtype()

   def __repr__(self):
      msg = 'FastqTrim(%s, %s, %i, %i, %i, %s, %i, %s, %s)' % ("["+", ".join(self.f)+"]", "["+", ".join(self.o)+"]", self.l, self.q, self.m, self.keep_n, self.M, self.paired, self.interleaved)
      return msg

   def set_readtype(self):
      '''Set paired and/or interleaved flags'''

      def check_interleaved(self):
         '''Check if a file is interleaved paired or single'''

         if self.f[0].endswith('.gz'):
            fh = gzip.open(self.f[0], 'rb')
         else:
            fh = open(self.f[0], 'r')

         count = 0
         ends = []
         if self.fqtype[0] == 'Illumina1.4' or self.fqtype[0] == 'nd':
            for (title, sequence, quality) in FastqGeneralIterator(fh):
               ends.append(title[-2:])
               count += 1
               if count > 9: break

            # check that they are interleaved (eg. /1, /2, /1, /2)
            interleaved = True
            for i,e in enumerate(ends[::2]):
               if e != '/1':
                  interleaved = False
                  break

            for i,e in enumerate(ends[1::2]):
               if e != '/2':
                  interleaved = False
                  break
         elif self.fqtype[0] == 'Illumina1.8':
            for (title, sequence, quality) in FastqGeneralIterator(fh):
               ends.append(title)
               count += 1
               if count > 9: break

            interleaved = True
            for i,e in enumerate(ends[::2]):
               fields = e.split(' ')
               if fields[1].startswith('2'):
                  interleaved = False
                  break
            for i,e in enumerate(ends[1::2]):
               fields = e.split(' ')
               if fields[1].startswith('1'):
                  interleaved = False
                  break

         if interleaved:
            self.paired = True
            self.interleaved = True

         return self

      if len(self.f) == 2:
         self.paired = True
         self.interleaved = False
      elif len(self.f) == 1:
         self = check_interleaved(self)

   def set_adaptors(self):
      '''Set adaptors according to adaptor length requirements'''

      adaptors = []
      for a in self.a:
         if self.M == 0:
            adaptor = a
         elif (self.M) > len(a):
            adaptor = a
         else:
            adaptor = a[:self.M]
         adaptors.append(adaptor)
      return adaptors

   def filter_adaptor(self, title, sequence, quality):
      '''Filters adaptor and Ns in read'''

      has_adaptor = False
      has_N = False
      is_short = False

      # search for adaptor in reads
      for adaptor in self.adaptors:
         hit = sequence.find(adaptor)
         if hit > -1:
            sequence = sequence[:hit]
            quality = quality[:hit]
            has_adaptor = True

      # check if read contains Ns
      if sequence.find('N') > -1:
         has_N = True

      # check if too small then do not print out
      if len(sequence) < self.l:
         is_short = True

      # return read
      if has_N or is_short:
         return (None, None, None)
      else:
         return (title, sequence, quality)

   # the actual read trimming function
   def trim_qual(self, title, sequence, quality):
      '''Trims read based on 3' qualities and average quality'''

      # functions for read trimming
      def average(values):
         '''Computes the arithmetic mean of a list of numbers.'''
         return sum(values, 0.0) / len(values)

      def illumina2qual(qual_string):
         '''Convert illumina qualities (offset 64) to values.'''
         qual = []
         for q in qual_string:
            qual.append(ord(q)-64)
         return qual

      def sanger2qual(qual_string):
         '''Convert sanger qualities (offset 33) to values.'''
         qual = []
         for q in qual_string:
            qual.append(ord(q)-33)
         return qual

      def trim_index(qual, m):
         '''Determine position to trim from'''
         qs = qual[::-1]
         index = None
         for i,q in enumerate(qs):
            if q > m:
               index = len(qual)-i
               break
         return index

      # check if read is not valid
      if title == None:
         return (None, None, None)

      if self.fqtype[1] == 'Illumina':
         qual = illumina2qual(quality)
      elif self.fqtype[1] == 'Sanger':
         qual = sanger2qual(quality)
      else:
         raise ValueError('Fastq must be Illumina or Sanger')

      # check trailing qualities, should it be trimmed?
      t = trim_index(qual, self.q)
      if t:
         sequence = sequence[:t]
         quality = quality[:t]
         # do not print out if average quality is less than m or length is less than l
         a = average(qual[:t])
         if a < self.m or len(sequence) < self.l:
            return (None, None, None)
         else:
            return (title, sequence, quality)
      else:
         # do not print out if average quality is less than m or length is less than l
         a = average(qual)
         if a < self.m or len(sequence) < self.l:
            return (None, None, None)
         else:
            return (title, sequence, quality)

   def write_pairs(self, f1, f2):
      '''Parse through two paired files and only write if both pairs are present'''

      def intersect(a, b):
         '''Intesection between lists'''
         return list(set(a) & set(b))

      def rm_files(patterns):
         '''Remove files using glob given as list of patterns'''

         import glob
         import os

         for p in patterns:
            files = glob.glob(p)
            if len(files) == 0:
               pass
            else:
               map(os.remove, files)

      def write_out(db_common, f, o):
         '''Write out reads'''

         if f.endswith('.gz'):
            fh = gzip.open(f, 'rb')
         else:
            fh = open(f, 'r')

         out = open(o, 'w')
         written_count = 0
         total_count = 0
         if self.fqtype[0] == 'Illumina1.4':
            for (title, sequence, quality) in FastqGeneralIterator(fh):
               total_count += 1
               if db_common.has_key(title[:-2]):
                  out.write('@%s\n%s\n+\n%s\n' % (title, sequence, quality))
                  written_count += 1
         elif self.fqtype[0] == 'Illumina1.8':
            for (title, sequence, quality) in FastqGeneralIterator(fh):
               total_count += 1
               if db_common.has_key(title.split(' ')[0]):
                  out.write('@%s\n%s\n+\n%s\n' % (title, sequence, quality))
                  written_count += 1
         elif self.fqtype[0] == 'IlluminaSRA':
             for (title, sequence, quality) in FastqGeneralIterator(fh):
               total_count += 1
               if db_common.has_key(title.split(' ')[1][:-2]):
                  out.write('@%s\n%s\n+\n%s\n' % (title, sequence, quality))
                  written_count += 1

         sys.stderr.write('%s: Total %i, Written %i (%.1f%%)\n' % (f, total_count, written_count, written_count/total_count*100))
         fh.close()
         out.close()

      def create_db(f, db_fname):
         '''Write out db of headers'''

         if f.endswith('.gz'):
            fh = gzip.open(f, 'rb')
         else:
            fh = open(f, 'r')

         if self.fqtype[0] == 'Illumina1.4':
            fh_headers = (x.strip()[1:-2] for i, x in enumerate(fh) if not (i % 4))
         elif self.fqtype[0] == 'Illumina1.8':
            fh_headers = (x.split(' ')[0][1:] for i, x in enumerate(fh) if not (i % 4))
         elif self.fqtype[0] == 'IlluminaSRA':
            fh_headers = (x.split(' ')[1][:-3] for i, x in enumerate(fh) if not (i % 4))
         else:
            sys.stderr.write('Header encoding not determined: %s\n' % self.fqtype[0])

         db = cdb.cdbmake(db_fname, db_fname + '.tmp')
         for h in fh_headers:
            db.add(h, 'T')
         db.finish()
         del(db)

      ## get headers from both trimmed files ##
      # strip the /2 or /1 and grab only the headers
      # write in dbm to minimze memory usage

      # create db's (parallel)
      rand = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(36))
      db1_fname = 'db1_%s' % rand
      db2_fname = 'db2_%s' % rand

      jobs = []
      p = multiprocessing.Process(target=create_db, args=(f1, db1_fname, ))
      p.start()
      jobs.append(p)

      p = multiprocessing.Process(target=create_db, args=(f2, db2_fname, ))
      p.start()
      jobs.append(p)

      # wait for jobs to finish
      for job in jobs:
         job.join()

      ## get headers that are in both trimmed files ##
      db1 = cdb.init(db1_fname)
      db2 = cdb.init(db2_fname)
      common = intersect(db1.keys(), db2.keys())

      dbcommon_fname = 'dbcommon_%s' % rand
      db_common = cdb.cdbmake(dbcommon_fname, dbcommon_fname + '.tmp')
      for h in common:
         db_common.add(h, 'T')
      db_common.finish()
      del(db_common)

      # open common db
      db_common = cdb.init(dbcommon_fname)
      jobs = []
      p = multiprocessing.Process(target=write_out, args=(db_common, f1, self.o[0]))
      p.start()
      jobs.append(p)

      p = multiprocessing.Process(target=write_out, args=(db_common, f2, self.o[1]))
      p.start()
      jobs.append(p)

      # wait for jobs to finish
      for job in jobs:
         job.join()

      rm_files([db1_fname, db2_fname, dbcommon_fname, f1, f2])

   def trim(self, paired=False, interleave=False):
      '''Start trimming of reads'''

      def trim_file(self, f, f_out):
         written = 0
         total = 0
         if f.endswith('.gz'):
            fh_in = gzip.open(f, 'rb')
         else:
            fh_in = open(f, 'r')
         fh_out = open(f_out, 'w')
         for (title, sequence, quality) in FastqGeneralIterator(fh_in):
            total += 1
            (title, sequence, quality) = self.filter_adaptor(title, sequence, quality)
            (title, sequence, quality) = self.trim_qual(title, sequence, quality)
            if title != None:
               if len(sequence) != len(quality):
                  raise ValueError('sequence and quality not of the same length\n%s\n%s\n' % (sequence, quality))
               fh_out.write('@%s\n%s\n+\n%s\n' % (title, sequence, quality))
               written += 1
         fh_out.close()
         fh_in.close()
         sys.stderr.write('%s: written %s of %s (%.1f%%)\n' % (f, written, total, written/total))

      def trim_interleaved_file(self, f, f_out):
         written = 0
         total = 0
         if f.endswith('.gz'):
            fh_in = gzip.open(f, 'rb')
         else:
            fh_in = open(f, 'r')
         fh_out = [open(f_out[0], 'w'), open(f_out[1], 'w')]
         for (title, sequence, quality) in FastqGeneralIterator(fh_in):
            (title, sequence, quality) = self.filter_adaptor(title, sequence, quality)
            (title, sequence, quality) = self.trim_qual(title, sequence, quality)
            if title != None:
               if len(sequence) != len(quality):
                  raise ValueError('sequence and quality not of the same length\n%s\n%s\n' % (sequence, quality))
               fh_out[total%2].write('@%s\n%s\n+\n%s\n' % (title, sequence, quality))
               written += 1
            total += 1
         fh_out[0].close()
         fh_out[1].close()
         fh_in.close()
         sys.stderr.write('%s: written %s of %s (%.1f%%)\n' % (f, written, total, written/total))

      if self.paired:
         # set tmp files
         rand = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(36))
         f_out = ['tmp0.'+rand, 'tmp1.'+rand]

         # check if file is interleaved

         if self.interleaved:
            sys.stderr.write('Trimming paired end interleaved\n')
            trim_interleaved_file(self, self.f[0], f_out)
         else:
            # create and start multiprocess
            sys.stderr.write('Trimming paired end\n')
            jobs = []
            for i in range(2):
               p = multiprocessing.Process(target=trim_file, args=(self, self.f[i], f_out[i], ))
               p.start()
               jobs.append(p)

            # wait for jobs to finish
            for job in jobs:
               job.join()

         # write files
         self.write_pairs(f_out[0], f_out[1])
      else:
         sys.stderr.write('Trimming single end\n')
         trim_file(self, self.f[0], self.o[0])

if __name__ == '__main__':

   parser = argparse.ArgumentParser(formatter_class=lambda prog: argparse.HelpFormatter(prog,max_help_position=50, width=110), description='''
      Trim SE or PE files for low q bases, adaptor sequences, Ns
      ''')

   # add the arguments
   parser.add_argument('--i', help='input single or paired end files', nargs='+', required=True)
   parser.add_argument('--min_length', help='minimum length of a read to keep pairs [25]', type=int, default=25)
   parser.add_argument('--min_baseq', help='chomp bases with quality less than [20]', default=20, type=int)
   parser.add_argument('--min_avgq', help='minimum average quality of read [20]', default=20, type=int)
   parser.add_argument('--adaptors', help='adaptor sequence to clip [Illumina adaptors]', nargs='+', default=['GATCGGAAGAGCGGTTCAGCAGGAATGCCGAG', 'ACACTCTTTCCCTACACGACGCTCTTCCGATCT', 'AATGATACGGCGACCACCGAGATCTACACTCTTTCCCTACACGACGCTCTTCCGATCT', 'CAAGCAGAAGACGGCATACGAGATCGGTCTCGGCATTCCTGCTGAACCGCTCTTCCGATCT', 'CGGTCTCGGCATTCCTGCTGAACCGCTCTTCCGATCT', 'ACACTCTTTCCCTACACGACGCTCTTCCGATCT'])
   parser.add_argument('--keep_n', help='do not remove sequences containing N', default=False, action='store_true')
   parser.add_argument('--min_adaptor_match', help='minimum length of match to adaptor (0=all of adaptor) [20]', default=20, type=int)
   parser.add_argument('--o', help='output files', nargs='+', required=True)
   parser.add_argument('--log', help='log level [INFO]', default='info')

   args = parser.parse_args()
   #args = parser.parse_args(''.split())
   #args = parser.parse_args('--i kleb_test_2.fq --l 25 --q 20 --o kleb_test_2.trim.fq'.split())
   #args = parser.parse_args('--i Kleb-10-213361_2_1_sequence.txt Kleb-10-213361_2_2_sequence.txt --M 15 --o Kleb-10-213361_2_1_sequence.trim.fq Kleb-10-213361_2_2_sequence.trim.fq '.split())
   #args = parser.parse_args('--i /home/panfs/cbs/projects/cge/data/cge_private/unsorted_data_hhas/BGI2012/Lane1/split/ec_PE3.clipped.fq --o trimmed/ec_PE3.clipped.fq.trim'.split())
   #args = parser.parse_args('--i test_1.fastq test_2.fastq --o test_1.trim.fastq test_2.trim.fastq'.split())

   # create instance
   fqtrim = FastqTrim(args.i, args.o, args.min_length, args.min_baseq, args.min_avgq, args.keep_n, args.min_adaptor_match, args.adaptors)

   # start trimming
   if len(fqtrim.f) == 2:
      fqtrim.trim(paired=True)
   elif len(fqtrim.f) == 1:
      fqtrim.trim()
   else:
      raise ValueError('Only 1 (single end) or 2 (paired end) files must be given')


"""# FileBrowser

"""
from pathlib import Path
from typing import Optional, cast

import solara
from solara.website.utils import apidoc

@solara.component
def Page():
    file, set_file = solara.use_state(cast(Optional[Path], None))
    path, set_path = solara.use_state(cast(Optional[Path], None))
    directory, set_directory = solara.use_state(Path("~").expanduser())

    with solara.VBox() as main:
        can_select = solara.ui_checkbox("Enable select")

        def reset_path():
            set_path(None)
            set_file(None)

        # reset path and file when can_select changes
        solara.use_memo(reset_path, [can_select])
        solara.FileBrowser(directory, on_directory_change=set_directory, on_path_select=set_path, on_file_open=set_file, can_select=can_select)
        solara.Info(f"You are in directory: {directory}")
        solara.Info(f"You selected path: {path}")
        solara.Info(f"You opened file: {file}")
    return main

__doc__ += apidoc(solara.FileBrowser.f)  # type: ignore


class Solution:
    def __init__(self):
        self.res = []
        # 记录回溯的路径
        self.track = []
        # 记录 track 中的元素之和
        self.trackSum = 0

    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
        if not candidates:
            return []
        # 先排序，让相同的元素靠在一起
        candidates.sort()
        self.backtrack(candidates, 0, target)
        return self.res

    # 回溯算法主函数
    def backtrack(self, nums: List[int], start: int, target: int):
        # base case，达到目标和，找到符合条件的组合
        if self.trackSum == target:
            self.res.append(self.track[:])
            return
        # base case，超过目标和，直接结束
        if self.trackSum > target:
            return

        # 回溯算法标准框架
        for i in range(start, len(nums)):
            # 剪枝逻辑，值相同的树枝，只遍历第一条
            if i > start and nums[i] == nums[i - 1]:
                continue
            # 做选择
            self.track.append(nums[i])
            self.trackSum += nums[i]
            # 递归遍历下一层回溯树
            self.backtrack(nums, i + 1, target)
            # 撤销选择
            self.track.pop()
            self.trackSum -= nums[i]

backtracking/permutation-combination-subset/40. Combination Sum II.py


# WASTC 2016 Programming Concepts Python
# Sable Cantus
#
# Exercise 7.6 - Game of War v. 3.0
# Would you like to play again?
# must add a variable for each card so it can only be picked once

import random
computerScore = 0
humanScore = 0
play = 'y'

print ("Let's play a game!", "\n")

while play.lower() == 'y':

    #generate cards and suite's
    computerCard = random.randint(2,14)
    computerSuite = random.randint(0,3)
    computerCardFace = computerCard

    humanCard = random.randint(2,14)
    humanSuite = random.randint(0,3)
    humanCardFace = humanCard

    # head-bash approach to naming
    if computerSuite == 0:
        computerSuite = "Spades"
    elif computerSuite == 1:
        computerSuite = "Hearts"
    elif computerSuite == 2:
        computerSuite = "Spades"
    elif computerSuite == 3:
        computerSuite = "Diamonds"

    if computerCard > 10:
        if computerCard == 11:
            computerCardFace = "Jack"
        elif computerCard == 12:
            computerCardFace = "Queen"
        elif computerCard == 13:
            computerCardFace = "King"
        elif computerCard == 14:
            computerCardFace = "Ace"

    if humanSuite == 0:
        humanSuite = "Spades"
    elif humanSuite == 1:
        humanSuite = "Hearts"
    elif humanSuite == 2:
        humanSuite = "Spades"
    elif humanSuite == 3:
        humanSuite = "Diamonds"

    if humanCard > 10:
        if humanCard == 11:
            humanCardFace = "Jack"
        elif humanCard == 12:
            humanCardFace = "Queen"
        elif humanCard == 13:
            humanCardFace = "King"
        elif humanCard == 14:
            humanCardFace = "Ace"

    #pretty output
    print ()
    print ("Computer's card is a", computerCardFace, "of", computerSuite)
    print ("Your card is a", humanCardFace, "of", humanSuite)
    print ()

    # determine the winner
    if computerCard == humanCard:
        print (">>>>> It's a tie! This means WAR <<<<<")
    elif computerCard > humanCard:
        print (">>>>> Computer wins :<()")
        computerScore =+ 1
    else:
        print (">>>>> You win! <<<<<")
        humanScore += 1

    print ()
    print("Computer:", computerScore)
    print("Human: ", humanScore)

    if humanScore == 52:
        print ("You win the game!")
        break
    elif computerScore == 52:
        print ("You lose, computer wins. Better luck next time.")

    print ()
    print ("Would you like to play again? ", end="")
    play = input()[0]


import multiprocessing

import numpy
import pandas
from addict import Dict

import CADETMatch.score as score
import CADETMatch.util as util

name = "fractionationCombine"
settings = Dict()
settings.adaptive = True
settings.badScore = 0
settings.meta_mask = True
settings.count = None

def run(sim_data, feature):
    "similarity, value, start stop"
    simulation = sim_data["simulation"]
    funcs = feature["funcs"]
    components = feature["components"]
    numComponents = len(components)
    samplesPerComponent = feature["samplesPerComponent"]
    multiplier = 1.0 / samplesPerComponent
    start = feature["start"]
    stop = feature["stop"]

    time_centers = (start + stop) / 2.0

    times = simulation.root.output.solution.solution_times

    scores = {}
    for comp in components:
        scores[comp] = 0.0

    sim_values = []
    exp_values = []

    graph_sim = {}
    graph_exp = {}
    for (start, stop, component, exp_value, func) in funcs:
        selected = (times >= start) & (times <= stop)

        local_times = times[selected]
        local_values = simulation.root.output.solution[feature["unit"]][
            "solution_outlet_comp_%03d" % component
        ][selected]

        sim_value = numpy.trapz(local_values, local_times)

        exp_values.append(exp_value)
        sim_values.append(sim_value)

        scores[component] += func(sim_value) * multiplier

        if component not in graph_sim:
            graph_sim[component] = []
            graph_exp[component] = []

        time_center = (start + stop) / 2.0
        graph_sim[component].append((time_center, sim_value))
        graph_exp[component].append((time_center, exp_value))

    # sort lists
    for key, value in graph_sim.items():
        value.sort()
    for key, value in graph_exp.items():
        value.sort()

    sim_data["graph_exp"] = graph_exp
    sim_data["graph_sim"] = graph_sim

    temp = [scores[comp] for comp in components]

    return (
        temp,
        util.sse(numpy.array(sim_values), numpy.array(exp_values)),
        len(sim_values),
        time_centers,
        numpy.array(sim_values),
        numpy.array(exp_values),
        [1.0 - i for i in temp],
    )

def setup(sim, feature, selectedTimes, selectedValues, CV_time, abstol):
    temp = {}
    data = pandas.read_csv(feature["fraction_csv"])
    rows, cols = data.shape

    start = numpy.array(data.iloc[:, 0])
    stop = numpy.array(data.iloc[:, 1])

    temp["start"] = start
    temp["stop"] = stop

    headers = data.columns.values.tolist()

    smallestTime = min(data["Stop"] - data["Start"])
    abstolFraction = abstol * smallestTime

    multiprocessing.get_logger().debug("abstolFraction %s", abstolFraction)

    funcs = []

    for sample in range(rows):
        for component in headers[2:]:
            start = data["Start"][sample]
            stop = data["Stop"][sample]
            value = data[component][sample]
            func = score.value_function(value, abstolFraction)

            funcs.append((start, stop, int(component), value, func))

    settings.count = len(headers[2:])
    temp["funcs"] = funcs
    temp["components"] = [int(i) for i in headers[2:]]
    temp["samplesPerComponent"] = rows
    temp["unit"] = feature["unit_name"]
    return temp

def headers(experimentName, feature):
    data = pandas.read_csv(feature["fraction_csv"])
    rows, cols = data.shape
    # remove first two columns since those are the start and stop times
    cols = cols - 2

    total = rows * cols
    data_headers = data.columns.values.tolist()

    temp = []
    for component in data_headers[2:]:
        temp.append("%s_%s_Component_%s" % (experimentName, feature["name"], component))
    return temp


import os, time, csv

def readfile():
    with open('FinalResults.csv') as csv_file:
        csv_reader = csv.reader(csv_file, delimiter=',')
        line_count = 0
        result = ""
        for row in csv_reader:
            if line_count == 0:
                result += f'{row[0]},{row[1]},{row[2]},{row[3]}\n'
                line_count += 1
            else:
                result += f'{row[0]},{row[1]},{row[2]},{row[3]}\n'
                line_count += 1
        print(f'Processed {line_count} lines.')
        print(result)
        return result

def watch():
    path_to_watch = "."
    before = dict([(f, None) for f in os.listdir(path_to_watch)])
    go = True
    while go:
        time.sleep(1)

        after = dict ([(f, None) for f in os.listdir (path_to_watch)])
        added = [f for f in after if not f in before]
        removed = [f for f in before if not f in after]

        if "".join(added) == "FinalResults.csv":
            print("".join(added))
            go = False
            return readfile()

        if removed:
            print("Removed: ", "".join(removed))

        before = after


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

import os
import sys

try:
    from setuptools import setup
except ImportError:
    from distutils.core import setup

if sys.argv[-1] == 'publish':
    os.system('python setup.py sdist upload')
    sys.exit()

readme = open('README.rst').read()
history = open('HISTORY.rst').read().replace('.. :changelog:', '')

setup(
    name='pahodemo',
    version='0.1.0',
    description='Paho library that connects several raspberry pi\'s through MQTT',
    long_description=readme + '\n\n' + history,
    author='Marco Plaisier',
    author_email='m.plaisier@gmail.com',
    url='https://github.com/marcofinalist/pahodemo',
    packages=[
        'pahodemo',
    ],
    package_dir={'pahodemo': 'pahodemo'},
    include_package_data=True,
    install_requires=[
    ],
    license="BSD",
    zip_safe=False,
    keywords='pahodemo',
    classifiers=[
        'Development Status :: 2 - Pre-Alpha',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: BSD License',
        'Natural Language :: English',
        "Programming Language :: Python :: 2",
        'Programming Language :: Python :: 2.6',
        'Programming Language :: Python :: 2.7',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.3',
    ],
    test_suite='tests',
)


from django.urls import path
from . import views
from rest_framework import permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapi

schema_view = get_schema_view(
    openapi.Info(
        title="Your API",
        default_version='v1',
        description="Your API description",
        terms_of_service="https://www.example.com/terms/",
        contact=openapi.Contact(email="contact@example.com"),
        license=openapi.License(name="Your License"),
    ),
    public=True,
    permission_classes=(permissions.AllowAny,),
)

urlpatterns = [
    path('getFood/', views.getFood, name='getFood'),
    path('postFood/', views.postFood, name='postFood'),

    path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
    path('redoc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),

]


import gzip
import json
import sys

import networkx as nx
import numpy as np
import osmnx as ox
import pandas as pd
import requests
import scipy as sp

import geomadi.geo_enrich as g_e
import geomadi.geo_octree as g_o

gO = g_o.h3tree()

def simplifyGraph(G, connection="strong"):
    """simplify a graph"""
    # G = ox.load_graphml(filename=fName)
    print("G nodes: " + str(len(G.nodes())))
    print("G edges: " + str(len(G.edges())))
    G_simp = ox.simplify_graph(G)
    print('simp_G:')
    print("G simp nodes: " + str(len(G_simp.nodes())))
    print("G simp edges: " + str(len(G_simp.edges())))
    if connection == "strong":
        G_connect = max(nx.weakly_connected_component_subgraphs(G_simp), key=len)
    elif connection == "weak":
        G_connect = max(nx.strongly_connected_component_subgraphs(G_simp), key=len)
    elif connection == "undirect":
        G_connect = max(nx.connected_component_subgraphs(G_simp.to_undirected()), key=len)
    else:
        G_connect = G_simp
    print('connected_G:')
    print("G connected nodes: " + str(len(G_connect.nodes())))
    print("G connected edges: " + str(len(G_connect.edges())))
    G_proj = ox.project_graph(G_connect, to_crs={'init': 'epsg:4326'})
    print('proj done')
    return G_proj

def removeType(G, move_type="driver"):
    """remove fclass types"""
    print("set move type %s" % (move_type))
    l = list(G.edges(data=True))
    tL, n = np.unique([x[2]['highway'] for x in l], return_counts=True)
    tL = ['cycleway', 'footway', 'living_street', 'motorway', 'motorway_link', 'path', 'pedestrian', 'primary',
          'residential', 'secondary', 'secondary_link', 'service', 'steps', 'tertiary', 'track', 'track_grade1',
          'track_grade3', 'trunk', 'trunk_link', 'unclassified']
    if move_type == "pedestrian":
        tL = ['cycleway', 'footway', 'living_street', 'path', 'pedestrian', 'residential', 'primary', 'secondary',
              'secondary_link', 'tertiary', 'trunk', 'trunk_link']
    if move_type == "driver":
        tL = ['living_street', 'motorway', 'motorway_link', 'primary', 'residential', 'secondary', 'secondary_link',
              'tertiary', 'trunk', 'trunk_link']
    G1 = G.copy()
    G1.graph['crs'] = {'init': 'epsg:4326'}
    G1.graph['name'] = move_type + " network"
    for i, j, x in G.edges(data=True):
        if x['highway'] in tL: continue
        G1.remove_edge(i, j)
    idL = []
    for i, j in G1.edges():
        idL.append(i)
        idL.append(j)
    idL = np.unique(idL)
    for i in G.nodes():
        if not i in idL:
            G1.remove_node(i)
    return G1

def composeGraph(graphL):
    """compose a list of graphs into a single one"""
    composed_G = nx.compose_all(graphL)
    return composed_G

def composeFiles(fileL):
    """compose a list of graphs from files"""
    graphL = []
    for f in fileL:
        graph1 = ox.load_graphml(filename=f)
    composed_G = nx.compose_all(graphL)
    simp_G = ox.simplify_graph(composed_G)
    return composed_G

def segment2graph(geo, isPlot=False):
    """create a graph from a collection of lines"""
    print("building the graph")
    gO = g_o.h3tree()
    G = nx.MultiDiGraph()
    # G = nx.Graph()
    G.graph['crs'] = {'init': 'epsg:4326'}
    G.graph['name'] = "local network"
    for i, g in geo.iterrows():
        seg = list(g['geometry'].coords)
        for start, end, j in zip(seg[:-1], seg[1:], range(len(seg))):
            # line = sh.geometry.LineString([start,end])
            dist = g_e.haversine(start[0], start[1], end[0], end[1])
            # j1, j2 = g['osm_id']+"_"+str(j), g['osm_id']+"_"+str(j+1)
            j1, j2 = gO.encode(start[0], start[1], precision=13), gO.encode(end[0], end[1], precision=13)
            G.add_edge(j1, j2, key=0, src=j1, trg=j2, speed=g['maxspeed'], highway=g['fclass'], name=g['name'],
                       length=dist)  # ,geometry=line,osm_id=g['osm_id'])
            G.add_node(j1, pos=start, x=start[0], y=start[1], key=0)  # ,osmid=j1)
            G.add_node(j2, pos=end, x=end[0], y=end[1], key=0)  # ,osmid=j2)
    if isPlot:
        ox.plot_graph(G)
    return G

def line2graph(geo, isPlot=False):
    """create a graph from a collection of lines"""
    gO = g_o.h3tree()
    G = nx.MultiDiGraph()
    # G = nx.Graph()
    G.graph['crs'] = {'init': 'epsg:4326'}
    G.graph['name'] = "local network"
    for i, g in geo.iterrows():
        seg = list(g['geometry'].coords)
        start, end = seg[0], seg[-1]
        dist = g_e.haversine(start[0], start[1], end[0], end[1])
        j1, j2 = gO.encode(start[0], start[1], precision=13), gO.encode(end[0], end[1], precision=13)
        G.add_edge(j1, j2, key=0, speed=g['maxspeed'], highway=g['fclass'], name=g['name'], length=dist)
        G.add_node(j1, pos=start, x=start[0], y=start[1], key=0)
        G.add_node(j2, pos=end, x=end[0], y=end[1], key=0)
    if isPlot:
        ox.plot_graph(G)
    print("built the graph size %d" % (G.size()))
    return G

def downloadGraph(city="Salò, Italy"):
    """download graph from city"""
    G = ox.graph_from_place(city)
    G = ox.project_graph(G)
    ox.plot_graph(G)
    return G

def lineLenght(l):
    """length of a line in kilometers"""
    l1 = [[x, y] for x, y in zip(l.xy[0], l.xy[1])]
    length = sum([g_e.haversine(x[0], x[1], y[0], y[1]) for x, y in zip(l1[:-1], l1[1:])])
    return length

def getNearestNode(G, coord_x, coord_y):
    """get nearest node, if actual node is not in the graph"""
    coords = (coord_x, coord_y)
    node = ox.get_nearest_node(G, coords, method='euclidean')
    return node

def getNeighbors(G, posL):
    """get nearest node, if actual node is not in the graph"""
    pos = [(x['x'], x['y']) for i, x in G.nodes(data=True)]
    tree = sp.spatial.KDTree(pos)
    nearest_dist, nearest_ind = tree.query(posL)
    posI = {}
    for i, j in enumerate(G.nodes()): posI[i] = j
    posI = [posI[x] for x in nearest_ind]
    neiL = [G.node[x] for x in posI]
    return posI

def weightGraph(graph):
    keys = {}
    for edge in (graph.edges(data=True)):
        attrs = {}
        if edge[2]['highway'] == 'motorway':
            attrs['weight'] = edge[2]['length'] * 1
        elif edge[2]['highway'] == 'primary':
            attrs['weight'] = edge[2]['length'] * 1.5
        elif edge[2]['highway'] == 'secondary':
            attrs['weight'] = edge[2]['length'] * 1.8
        else:
            attrs['weight'] = edge[2]['length'] * 3
        keyy = (edge[0], edge[1], 0)
        keys[keyy] = attrs
    nx.set_edge_attributes(graph, keys)
    return graph

def weightSpeed(G):
    """weight the graph according to street speed"""
    wL = {'motorway': 3, 'motorway_link': 3, 'primary': 2, 'residential': 0.5, 'secondary': 2, 'secondary_link': 2,
          'tertiary': 1.5, 'trunk': 2, 'trunk_link': 2}
    keys = {}
    for u, v, k, edge in (G.edges(keys=True, data=True)):
        s = edge['speed']
        l = edge['length']
        t = edge['highway']
        if isinstance(s, list): s = s[0]
        if isinstance(l, list): l = l[0]
        if isinstance(t, list): t = t[0]
        t = wL[t]
        s = max(s, 30)  # kmh
        l = max(l, 0.1)  # km
        w = s / l * 0.01 * t
        G[u][v][k].update(weight=w)
    return G

def calcPair(G, route):
    """pair distance between points"""
    if len(route) < 2: return False, [0, 0, 0, 0]
    length, weight, duration = 0, 0, 0
    for i, j in zip(route[:-1], route[1:]):
        edgeData = G.get_edge_data(i, j)[0]
        length = length + edgeData['length']
        weight = weight + edgeData['weight']
        if isinstance(edgeData['speed'], list):
            time = edgeData['length'] / max(min(edgeData['speed']), 1)  # *(1.-edgeData['weight']))
        else:
            time = edgeData['length'] / max(edgeData['speed'], 1)  # *(1.-edgeData['weight']))
        duration = duration + time
    weight = weight / (len(route) - 1)
    # if length > 3: return False, [0,0,0,0] #long distances are useless
    return True, [route[0], route[-1], length, weight, duration]

def calcRoute(G, start, destL, colL):
    node = start['node']
    try:  # calculate the route from the OSM node to all nodes in the network
        route_dij = nx.single_source_dijkstra_path(G=G, source=node, weight='weight')
    except:
        print("Start node " + str(node) + " not found")
        nearest_node = getNearestNode(node, start['y'], start['x'])
        print("Using nearest node instead, nodeid: " + str(nearest_node))
        route_dij = nx.single_source_dijkstra_path(G=G, source=nearest_node, weight='weight')

    routeL = [x for i, x in route_dij.items() if i in destL]
    pairL = []
    for route in routeL:
        status, link = calcPair(G, route)
        if status: pairL.append(link)

    pairL = pd.DataFrame(pairL, columns=colL)
    return pairL, len(routeL) / len(destL)

def routeOsrm(start, end):
    """routing-with-local-osrm"""
    # 'docker run -t -i -p 5000:5000 -v "${PWD}:/data" osrm/osrm-backend osrm-routed --algorithm mld /data/berlin-latest.osrm')
    x1, y1 = gO.decode(start)
    x2, y2 = gO.decode(end)
    fromP = "%f,%f" % (x1, y1)
    toP = "%f,%f" % (x2, y2)
    resq = requests.get("http://127.0.0.1:5000/route/v1/driving/" + fromP + ";" + toP + "?steps=true")
    route = resq.json()
    route = route['routes'][0]
    return [start, end, route['distance'], route['weight'], route['duration']]

def progress(count, total, status='', delta_time=0, completion=1.):
    """progressbar"""
    bar_len = 60
    filled_len = int(round(bar_len * count / float(total)))
    percents = round(100.0 * count / float(total), 1)
    bar = '=' * filled_len + '-' * (bar_len - filled_len)
    sys.stdout.write('[%s] %s%% %s %.2fh comp %.2f\r' % (bar, percents, status, delta_time, completion))
    sys.stdout.flush()

def save(G, fName):
    """suggest different file formats"""
    nx.write_gml(G, fName + ".gml")
    # G = nx.read_gml(fName+".gml")
    if False:
        ox.save_graphml(G, filename=fName, folder=baseDir + "gis/graph/")
        ox.save_gdf_shapefile(graph, filename=fName + ".gdf", folder=baseDir + "gis/graph/")
        ox.save_graphml(G, filename=gName, folder=baseDir + "gis/graph/")
        G = ox.load_graphml(filename=gName, folder=baseDir + "gis/graph/")
        ox.save_gdf_shapefile(G, filename=fName + ".gdf", folder=baseDir + "gis/graph/")
        G = ox.load_graphml(filename=fName + ".gdf", folder=baseDir + "gis/graph/")
        nx.readwrite.write_shp(G, baseDir + "gis/graph/berlin_street")
        nx.write_graphml_lxml(G, baseDir + "fName" + ".graphml")

def saveJson(G, fName, indent=0):
    """save a simple json"""
    l = [(u, v, k, x) for u, v, k, x in G.edges(keys=True, data="geometry") if x != None]
    print("geometry elements %d" % len(l))
    for i in l:
        del G[i[0]][i[1]][i[2]]['geometry']
    data = dict(nodes=list(G.nodes(data=True)), edges=list(G.edges(data=True)))
    json_str = json.dumps(data, indent=indent) + "\n"
    json_bytes = json_str.encode('utf-8')
    with gzip.GzipFile(fName, 'w') as fout:
        fout.write(json_bytes)

def loadJson(fName):
    """load a graph from a json"""
    G = nx.MultiGraph()
    G.graph['crs'] = {'init': 'epsg:4326'}
    G.graph['name'] = "local network"
    with gzip.GzipFile(fName, 'r') as fin:
        json_bytes = fin.read()
    json_str = json_bytes.decode('utf-8')
    data = json.loads(json_str)
    G.add_nodes_from(data['nodes'])
    G.add_edges_from(data['edges'])
    return G


"""
Reinforcement learning maze example.
Red rectangle:          explorer.
Black rectangles:       hells       [reward = -1].
Yellow bin circle:      paradise    [reward = +1].
All other states:       ground      [reward = 0].
This script is the main part which controls the update method of this example.
The RL is in RL_brain.py.

"""

from maze_env import Maze
from RL_brain import QLearningTable

def update():
    for episode in range(20):
        # initial observation
        observation = env.reset()
        done=False
        env.render()
        cnt=0
        while not done:
            cnt+=1
            # RL choose action based on observation
            action = RL.choose_action(observation)
            # RL take action and get next observation and reward
            observation_, reward, done = env.step(action)
            # RL learn from this transition
            RL.learn(observation, action, reward, observation_)
            # swap observation
            observation = observation_

            # fresh env
            env.render()
        print('\r\ntotal steps:%s'% cnt)
        print(RL.q_table)
    # end of game
    print('game over')
    env.destroy()

if __name__ == "__main__":
    env = Maze()
    RL = QLearningTable(actions=list(range(env.n_actions)))
    env.after(100, update)
    env.mainloop()


import requests

import pandas as pd
from bs4 import BeautifulSoup
from fake_useragent import UserAgent

AWOIAF_URL = "https://awoiaf.westeros.org"
HOUSES_LIST_URL = "https://awoiaf.westeros.org/index.php/List_of_Houses"
HOUSES_FILE = "houses.csv"

if __name__ == '__main__':
    df = pd.DataFrame(columns=["Name", "Region"])
    df.index.name = "URL"

    response = requests.get(HOUSES_LIST_URL, headers={"User-Agent": UserAgent().chrome}, timeout=10)
    soup = BeautifulSoup(response.content, "html.parser")

    tables = soup.find_all("table", {"class": "wikitable sortable plainrowheaders"})
    tables += soup.find_all("table", {"class": "wikitable sortable"})
    assert len(tables) == 6

    for table in tables[:-2]:
        for row in table.tbody.find_all("tr"):
            house = row.find_all("td")
            if len(house) < 2:
                continue

            url = house[1].find('a')
            url = f"{AWOIAF_URL}{url['href']}"
            name = house[1].text.strip()
            region = house[0].text.strip()
            df.loc[url] = name, region

    for row in tables[-2].tbody.find_all("tr"):
        house = row.find_all("td")
        if len(house) < 1:
            continue

        url = house[0].find('a')
        url = f"{AWOIAF_URL}{url['href']}"
        name = house[0].text.strip()
        region = "Yi Ti"
        df.loc[url] = name, region

    df = df.sort_values(by="Region")
    df.to_csv(HOUSES_FILE)


import sys
from PythonGEUtils import *
from PythonGEUtils.engine import *
import time
import random

sprites = [pygame.image.load("flappy.png"),pygame.image.load("background.png")]
sprites.append(pygame.image.load("ground.png"))
sprites.append(pygame.image.load("pipe.png"))
sprites.append(pygame.image.load("panel.png"))
sprites.append(pygame.image.load("bomb.png"))

scenes = []
mainScene = Scene("Main Scene",[])

#COMPONENTS
class PlayerController(BaseComponent):
	def __init__(self,s):
		self.parent = s
		self.name = "PLAYERCONTROLLER"
		self.requiresStart = True
	def CreateNew(self,s):
		return PlayerController(s)
	def Start(self):
		global objects
	def Update(self):
		pass
class Block(BaseComponent):
	def __init__(self,s):
		self.parent = s
		self.name = "BLOCK"
		self.requiresStart = True
	def CreateNew(self,s):
		return Block(s)
	def Start(self):
		global objects
	def Update(self):
		pass
	def CheckBombCount(self):
		near = self.parent.DirectComponent("COLLIDER").CollisionBox([150,150],[-75,-75])
		bombCount = 0
		for x in near:
			if(x.type == "BOMB"):
				bombCount += 1
		return str(bombCount)

componentMaster.append(PlayerController(None))
componentMaster.append(Block(None))
#END OF COMPONENTS

game = GameObject("Game")
game.AddComponent("PLAYERCONTROLLER")
mainScene.AddObject(CloneGameObject(game))

block = GameObject("Button")
#block.AddComponent("RENDERER")
block.AddComponent("COLLIDER")
block.AddComponent("UIBUTTON")
block.AddComponent("BLOCK")
block.AddComponent("UITEXT")
block.DirectComponent("UITEXT").text = ""
block.DirectComponent("UITEXT").size = 18
block.DirectComponent("UIBUTTON").sprite = 4
block.scale = [5,5]

blockPrefab = Prefab("Block",block)

#SCENE SETUP
for x in range(12):
	for y in range(12):
		new = blockPrefab.CreateInstance([x*50+25,y*50+25],0,[5,5])
		r = random.randint(0,20)
		if(r <= 4):
			new.type = "BOMB"
			new.DirectComponent("UIBUTTON").functions.append("self.parent.DirectComponent(\"UIBUTTON\").sprite = 5")
		else:
			new.type = "SPOT"
			new.DirectComponent("UIBUTTON").functions.append("self.parent.DirectComponent(\"UITEXT\").text = self.parent.DirectComponent(\"BLOCK\").CheckBombCount()")
			new.DirectComponent("UITEXT").offset = [-85,-95]
		mainScene.AddObject(new)

scenes.append(mainScene)
game = GameInfo("Game Test 1", {"RESOLUTION":(600,600),"GRAVITY":-0.028,"KEYREPEAT":(0,0)},componentMaster,scenes,0,sprites)

LaunchGame(game)


import imp
import spacy
from spacy.matcher import Matcher

nlp = spacy.load("en_core_web_trf")

matcher = Matcher(nlp.vocab)
pattern = [{"LIKE_EMAIL": True}]
matcher.add("EMAIL_ADDRESS", [pattern])

doc = nlp("This is an email address: kurian.bkk@gmail.com")
matches = matcher(doc)

print(matches)

with open("wiki_us.txt", "r") as f:
    text = f.read()

matcher = Matcher(nlp.vocab)
pattern = [{"POS": "PROPN"}]
matcher.add("PROPER_NOUNS", [pattern])

# doc = nlp(text)
# matches = matcher(doc)
# print(len(matches))
# for match in matches[:10000]:
#     print(match, doc[match[1] : match[2]])

matcher = Matcher(nlp.vocab)
pattern = [{"POS": "PROPN", "OP": "+"}]
matcher.add("PROPER_NOUNS", [pattern], greedy="LONGEST")
doc = nlp(text)
matches = matcher(doc)
print(len(matches))
for match in matches[:10]:
    print(match, doc[match[1] : match[2]])


from ... import keys
from ...api.parameters import Boolean, ClipPeriod, Cursor, Language
from ...queries import V5Query as Qry
from ...queries import query

# required scope: None
@query
def by_slug(slug):
    q = Qry('clips/{slug}', use_token=False)
    q.add_urlkw(keys.SLUG, slug)
    return q

# required scope: None
@query
def get_top(channels=None, games=None, period=ClipPeriod.WEEK, trending=Boolean.FALSE,
            language=Language.ALL, cursor='MA==', limit=10):
    q = Qry('clips/top', use_token=False)
    q.add_param(keys.CHANNEL, channels, None)
    q.add_param(keys.GAME, games, None)
    q.add_param(keys.PERIOD, ClipPeriod.validate(period), ClipPeriod.WEEK)
    q.add_param(keys.TRENDING, Boolean.validate(trending), Boolean.FALSE)
    q.add_param(keys.LANGUAGE, Language.validate(language), Language.ALL)
    q.add_param(keys.LIMIT, limit, 10)
    q.add_param(keys.CURSOR, Cursor.validate(cursor), 'MA==')
    return q

# required scope: user_read
@query
def get_followed(trending=Boolean.FALSE, language=Language.ALL, cursor='MA==', limit=10):
    q = Qry('clips/followed')
    q.add_param(keys.TRENDING, Boolean.validate(trending), Boolean.FALSE)
    q.add_param(keys.LANGUAGE, Language.validate(language), Language.ALL)
    q.add_param(keys.LIMIT, limit, 10)
    q.add_param(keys.CURSOR, Cursor.validate(cursor), 'MA==')
    return q


from api import models
from publicFunc import Response
from publicFunc import account
from django.http import JsonResponse
from publicFunc.condition_com import conditionCom
from publicFunc.play_watermark import watermark # 图片打水印
from api.forms.posters import AddForm, UpdateForm, SelectForm, posterInfoForm
from publicFunc.base64_encryption import b64decode
import json, os, requests

# token验证 海报展示模块
@account.is_token(models.Userprofile)
def posters(request):
    response = Response.ResponseObj()
    # user_id = request.GET.get('user_id')
    if request.method == "GET":
        forms_obj = SelectForm(request.GET)
        if forms_obj.is_valid():
            current_page = forms_obj.cleaned_data['current_page']
            length = forms_obj.cleaned_data['length']
            user_id = request.GET.get('user_id')

            order = request.GET.get('order', '-create_datetime')
            field_dict = {
                'id': '',
                'posters_url': '__contains',
                'posters_status': '',
                'create_datetime': '',
                'create_user_id': '',
                'create_user__name': '__contains',
            }
            q = conditionCom(request, field_dict)
            print('q -->', q)
            objs = models.Posters.objects.filter(q).order_by(order)
            count = objs.count()

            if length != 0:
                start_line = (current_page - 1) * length
                stop_line = start_line + length
                objs = objs[start_line: stop_line]

            # 返回的数据
            ret_data = []

            user_obj = models.Userprofile.objects.get(id=user_id)

            for obj in objs:
                #  将查询出来的数据 加入列表
                ret_data.append({
                    'id': obj.id,
                    'posters_url': obj.posters_url,
                    'posters_status_id': obj.posters_status,
                    'posters_status': obj.get_posters_status_display(),
                    'create_user_id': obj.create_user_id,
                    'create_user__name': obj.create_user.name,
                    'create_datetime': obj.create_datetime.strftime('%Y-%m-%d %H:%M:%S'),
                })

            posters_choices = []
            for i in models.Posters.posters_choices:
                posters_choices.append({
                    'id': i[0],
                    'name': i[1]
                })
            #  查询成功 返回200 状态码
            response.code = 200
            response.msg = '查询成功'
            response.data = {
                'ret_data': ret_data,
                'data_count': count,
                'posters_choices': posters_choices,
            }

            response.note = {
                'id': "海报ID",
                'posters_url': "海报链接",
                'posters_status_id': "海报类型ID",
                'posters_status': "海报类型名称",
                'create_datetime': "创建时间",
                'create_user_id': "创建人ID",
                'create_user__name': "创建人名字",
            }

        else:
            response.code = 402
            response.msg = "请求异常"
            response.data = json.loads(forms_obj.errors.as_json())
    return JsonResponse(response.__dict__)

# 海报增删改
# token验证
@account.is_token(models.Userprofile)
def posters_oper(request, oper_type, o_id):
    response = Response.ResponseObj()
    user_id = request.GET.get('user_id')

    if request.method == "POST":
        form_data = {
            'o_id': o_id,
            'create_user_id': user_id,
            'posters_url': request.POST.get('posters_url'),
            'posters_status': request.POST.get('posters_status', 1),
        }

        # 添加海报
        if oper_type == "add":
            forms_obj = AddForm(form_data)
            if forms_obj.is_valid():
                print("验证通过")
                obj = models.Posters.objects.create(**forms_obj.cleaned_data)
                response.code = 200
                response.msg = "添加成功"
                response.data = {'id': obj.id}
            else:
                print("验证不通过")
                response.code = 301
                response.msg = json.loads(forms_obj.errors.as_json())

        # 修改海报
        elif oper_type == "update":
            forms_obj = UpdateForm(form_data)
            if forms_obj.is_valid():
                print("验证通过")
                o_id, objs = forms_obj.cleaned_data['o_id']
                posters_url = forms_obj.cleaned_data['posters_url']
                posters_status = forms_obj.cleaned_data['posters_status']

                objs.update(posters_url=posters_url, posters_status=posters_status)
                response.code = 200
                response.msg = "修改成功"

            else:
                print("验证不通过")
                response.code = 301
                response.msg = json.loads(forms_obj.errors.as_json())

        # 删除海报
        elif oper_type == "delete":
            # 删除 ID
            objs = models.Posters.objects.filter(id=o_id)
            if objs:
                objs.delete()
                response.code = 200
                response.msg = "删除成功"
            else:
                response.code = 302
                response.msg = '删除ID不存在'

        # 修改海报信息
        # elif oper_type == 'update_poster_info':
        #     form_data = {
        #         'title': request.POST.get('title'),  # 正标题
        #         'subtitle': request.POST.get('subtitle'),  # 副标题
        #         'name': request.POST.get('name'),  # 姓名
        #         'phone': request.POST.get('phone'),  # 电话
        #         'time': request.POST.get('time'),  # 时间
        #         'place': request.POST.get('place'),  # 地点
        #     }
        #
        #     PosterObj = UpdatePosterInfoForm(form_data)
        #     if PosterObj.is_valid():
        #         objs = models.Userprofile.objects.filter(id=user_id)
        #         objs.update(posters_info=PosterObj.data)
        #         response.code = 200
        #         response.msg = '修改成功'
        #     else:
        #         response.code = 301
        #         response.msg = json.loads(PosterObj.errors.as_json())

    else:

        # 海报打水印
        if oper_type == 'play_watermark':
            posters_status = request.GET.get('posters_status')  # 水印类型
            posters_objs = models.Posters.objects.filter(id=o_id)
            if posters_objs:
                img_path = posters_objs[0].posters_url              # 海报地址

                posters_status = int(posters_status)
                if posters_status == 1:
                    obj = models.Userprofile.objects.get(id=user_id)
                    data = {
                        'img_path': img_path,
                        'heading':obj.set_avator + '?imageView2/2/w/300',
                        'name':b64decode(obj.name),
                        'phone':obj.phone_number,
                        'posters_status':posters_status,
                    }
                    watermark_objs = watermark(data)  # 实例化
                    path = watermark_objs.posters_play_watermark()
                    response.code = 200
                    response.data = {'path': path}

                else:
                    place = request.GET.get('place')                # 地址
                    time = request.GET.get('time')                  # 时间
                    fu_title = request.GET.get('subtitle')          # 副标题
                    zhu_title = request.GET.get('title')            # 主标题
                    name = request.GET.get('name')                  # 姓名
                    phone = request.GET.get('phone')                # 电话

                    data = {
                        'posters_status': posters_status,
                        'img_path': img_path,
                        'name': name,
                        'phone': phone,
                        'zhu_title': zhu_title,
                        'fu_title': fu_title,
                        'time': time,
                        'place': place,
                    }
                    form = posterInfoForm(data)
                    if form.is_valid():
                        watermark_objs = watermark(data) # 实例化
                        path = watermark_objs.posters_play_watermark()
                        response.code = 200
                        response.msg = '生成成功'
                        response.data = {'path':path}
                    else:
                        response.code = 301
                        response.msg = json.loads(form.errors.as_json())

            else:
                response.code = 301
                response.msg = '海报被删除'

        else:
            response.code = 402
            response.msg = "请求异常"

    return JsonResponse(response.__dict__)


import argparse
import pickle
import sys
import subprocess
import os
import colorama
from colorama import init,Fore, Back, Style

parser = argparse.ArgumentParser(description='Parse test description')
parser.add_argument('-avh', nargs='?',type = str, default="C:/Keil_v5/ARM/VHT", help="AVH folder")
parser.add_argument('-d', action='store_true', help="Debug log")
parser.add_argument('-n', action='store_true', help="No force rebuild")
parser.add_argument('-r', action='store_true', help="Raw results only")
parser.add_argument('-c', action='store_true', help="Display cycles (so passing test are displayed)")

args = parser.parse_args()

DEBUG=False
if args.d:
    DEBUG=True

init()

sys.path.append("..")

from TestScripts.Parser import TreeElem

ERROR_OCCURED = False

def printTitle(s):
    print("\n" + Fore.GREEN + Style.BRIGHT +  s + Style.RESET_ALL)

def printSubTitle(s):
    print("\n" + Fore.YELLOW + Style.BRIGHT + s + Style.RESET_ALL)

def printError(s):
    print("\n" + Fore.RED + Style.BRIGHT +  s + Style.RESET_ALL)

# Load Output.pickle files for the test description
def loadRoot(f):
    root = None
    with open(f,"rb") as inf:
         root=pickle.load(inf)
    return(root)

# Get test suites from the test descriptions
def getSuites(node,filterList,currentList=[]):
    if node.kind==TreeElem.SUITE:
        currentList.append(node.data["class"])
    if node.kind==TreeElem.GROUP:
       if not node.data["class"] in filterList:
          for c in node.children:
             getSuites(c,filterList,currentList)

class Result:
    def __init__(self,msg,error=False):
        self._error = error
        self._msg = msg

    @property
    def error(self):
        return self._error

    @property
    def msg(self):
        return self._msg

# Run a command and get error or result
# For the test report we don't need the stderr
# in case of error since the test report is giving
# all the details. So, there is an option to
# disable the dump of stderr
def run(*args,mustPrint=False,dumpStdErr=True):
    global ERROR_OCCURED
    global DEBUG
    try:
        if DEBUG:
            print(" ".join(args))
        result=subprocess.run(args,text=True,capture_output=True,timeout=600)
        if result.returncode !=0 :
             ERROR_OCCURED = True
             if dumpStdErr:
                return(Result(result.stderr + "\n\nSTDOUT:\n\n" + result.stdout,error=True))
             else:
                return(Result(result.stdout,error=True))

        if mustPrint:
            print(result.stdout)
        return(Result(result.stdout))
    except Exception as e:
        printError("Exception occured")
        ERROR_OCCURED = True
        return(Result(str(e),error=True))

# Configuration file for AVH core
configFiles={
    "CS310":"ARM_VHT_Corstone_310_config.txt",
    "CS300":"ARM_VHT_Corstone_300_config.txt",
    "M55":"ARM_VHT_MPS2_M55_config.txt",
    "M33_DSP_FP":"ARM_VHT_MPS2_M33_DSP_FP_config.txt",
    "M7DP":"ARM_VHT_MPS2_M7DP_config.txt",
    "M4FP":"ARM_VHT_MPS2_M4FP_config.txt",
    "M3":"ARM_VHT_MPS2_M3_config.txt",
    "M23":"ARM_VHT_MPS2_M23_config.txt",
    "M0plus":"ARM_VHT_MPS2_M0plus_config.txt",
}

# Windows executable
# (At some point this script will also support
# unix)
avhExe={
    "CS310":"VHT_Corstone_SSE-310.exe",
    "CS300":"VHT_Corstone_SSE-300_Ethos-U55.exe",
    "M55":"VHT_MPS2_Cortex-M55.exe",
    "M33_DSP_FP":"VHT_MPS2_Cortex-M33.exe",
    "M7DP":"VHT_MPS2_Cortex-M7.exe",
    "M4FP":"VHT_MPS2_Cortex-M4.exe",
    "M3":"VHT_MPS2_Cortex-M3.exe",
    "M23":"VHT_MPS2_Cortex-M23.exe",
    "M0plus":"VHT_MPS2_Cortex-M0plus.exe",
}

AVHROOT = args.avh

# Run AVH
def runAVH(build,core):
    axf="out/test/%s/Release/test.axf" % (build,)
    elf="out/test/%s/Release/test.elf" % (build,)
    app = axf
    if os.path.exists(axf):
        app = axf
    if os.path.exists(elf):
        app = elf
    config = os.path.join("configs",configFiles[core])
    avh = os.path.join(AVHROOT,avhExe[core])
    res=run(avh,"-f",config,app)
    return(res)

####################

# Test descriptions to use
tests=["../Output.pickle","../Output_f16.pickle"]
# Test group to avoid
filterList=["NNTests","ExampleTests"]
allSuites=[]

# Load all the test suite to run
for t in tests:
    root=loadRoot(t)
    suites=[]
    getSuites(root,filterList,suites)
    allSuites += [(x,t) for x in suites ]

# Test suite and output pickle needed to decode the result
#print(allSuites)

#allSuites=[
#("MFCCQ15","../Output.pickle"),
#("MFCCQ31","../Output.pickle"),
#("SupportTestsF16","../Output_f16.pickle"),
#]

#allSuites=[("ComplexTestsF32","../Output.pickle"),
#("DistanceTestsF32","../Output.pickle"),
#("UnaryTestsF32","../Output.pickle"),
#("QuaternionTestsF32","../Output.pickle"),
#("StatsTestsF32","../Output.pickle")
#]

#allSuites=[
#("TransformCF64","../Output.pickle"),
#("TransformCF32","../Output.pickle"),
#("TransformCQ31","../Output.pickle"),
#("TransformCQ15","../Output.pickle"),
#
#("TransformRF64","../Output.pickle"),
#("TransformRF32","../Output.pickle"),
#("TransformRQ31","../Output.pickle"),
#("TransformRQ15","../Output.pickle"),
#
#("MFCCF32","../Output.pickle"),
#("MFCCQ31","../Output.pickle"),
#("MFCCQ15","../Output.pickle"),
#
#("MFCCF16","../Output_f16.pickle"),
#("TransformCF16","../Output_f16.pickle"),
#("TransformRF16","../Output_f16.pickle")
#]

#allSuites=[("StatsTestsQ7","../Output.pickle")]

allSuites=[
("MISCF32","../Output.pickle"),
#("MISCQ15","../Output.pickle"),
#("MISCQ7","../Output.pickle"),
#("FIRF16","../Output_f16.pickle")
]

# Solution and build file for all
# the tests
# It is a pair : csolution target type and AVH identification
# AVH identification is used to find the executable
# and the configuration file
solutions={
    'test_ac6.csolution.yml':[
    #  ("VHT-Corstone-310","CS310"),
      ("VHT-Corstone-300","CS300"),
      ("VHT_M33","M33_DSP_FP"),
      ("VHT_M7","M7DP"),
      ("VHT_M7_UNROLLED","M7DP"),
      ("VHT_M4","M4FP"),
    #  #("VHT_M3","M3"),
    #  #("VHT_M23","M23"),
      ("VHT_M0P","M0plus")
    ],
    'test_gcc.csolution.yml':[
      #("VHT-Corstone-310","CS310"),
      #("VHT_M55","M55"),
      ##("VHT_M33","M33_DSP_FP"),
      ("VHT_M7","M7DP"),
      ("VHT_M7_UNROLLED","M7DP"),
      ("VHT_M4","M4FP"),
      ##("VHT_M3","M3"),
      ##("VHT_M23","M23"),
      ("VHT_M0P","M0plus")
    ]
}

# Override previous solutions for more restricted testing.
solutions={
    'test_ac6.csolution.yml':[
      ("VHT-Corstone-300","CS300"),
    ]
}

HTMLHEADER="""

<title>CMSIS-DSP Test summary</title>

"""

HTMLFOOTER="""

"""

# Run the tests and log the result
# in a summary.html file
with open("summary.html","w") as f:
    print(HTMLHEADER,file=f)
    for s in solutions:
        printTitle("Process solution %s" % s)
        res=run("csolution","convert","-s",s)
        if res.error:
            printError("Error csolution")
            print("
Error converting csolution %s

" % s,file=f)
            print(res.msg,file=f)
            print("
",file=f)
            continue
        print("
Solution %s
" % s,file=f)
        maxNbBuilds=len(solutions[s])
        buildNb=0
        for build,core in solutions[s]:
            buildNb = buildNb + 1
            print("
Core %s
" % build,file=f)
            printTitle("Process core %s (%d/%d)" % (build,buildNb,maxNbBuilds))
            buildFile="test.Release+%s.cprj" % build
            nb = 0
            maxNb = len(allSuites)
            for s,pickle in allSuites:
                nb = nb + 1
                printSubTitle("Process suite %s (%d/%d)" % (s,nb,maxNb))
                res=run(sys.executable,"../processTests.py","-gen","..","-p","../Patterns","-d","../Parameters","-f",pickle,"-e",s,mustPrint=True)
                if res.error:
                    printError("Error processTests")
                    print("
Error generating %s

" % s,file=f)
                    print(res.msg,file=f)
                    print("
",file=f)
                    continue
                if nb==1:
                   # -r is needed for first
                   # build when we switch
                   # between different solutions
                   # (Like one using AC6 and the other
                   # using gcc)
                   if args.n:
                      res=run("cbuild",buildFile)
                   else:
                      res=run("cbuild","-r",buildFile)
                else:
                   res=run("cbuild",buildFile)
                if res.error:
                    printError("Error cbuild")
                    print("
Error building %s

" % s,file=f)
                    print(res.msg,file=f)
                    print("
",file=f)
                    continue
                printSubTitle("Run AVH")
                res=runAVH(build,core)
                if res.error:
                    printError("Error running AVH")
                    print("
Error running %s

" % s,file=f)
                    print(res.msg,file=f)
                    print("
",file=f)
                    continue
                else:
                    with open("results.txt","w") as o:
                        print(res.msg,file=o)
                    # Dump raw result
                    if args.r:
                        print(res.msg)
                # If raw result, no post processing
                if not args.r:
                    res=run(sys.executable,"../processResult.py","-f",pickle,"-e","-ahtml","-r","results.txt",dumpStdErr=False)
                    if res.error:
                        printError("Error processResult")
                        print("
Error processing %s result

" % s,file=f)
                        print(res.msg,file=f)
                        print("
",file=f)
                        continue
                    else:
                        # When no error the section is
                        # included in final file on when
                        # cycles are requested
                        if args.c:
                           print(res.msg,file=f)
    print(HTMLFOOTER,file=f)

if ERROR_OCCURED:
    sys.exit("Error occurred")
else:
    sys.exit(0)


#!/usr/bin/env python
# coding: utf-8

import sys

def main():
    id_to_title = {}
    links_dict = {}
    # Input
    for line in sys.stdin:
        try:
            page_id, which, title = line.strip().split('\t')
            if which == 'p':
                id_to_title[page_id] = title
            elif which == 'l':
                if not page_id in links_dict:
                    links_dict[page_id] = []
                links_dict[page_id].append(title)
        except Exception:
            continue

    # Output
    for page_id, title in id_to_title.items():
        try:
            if not page_id in links_dict:
                print("{0}\t1.0".format(title))
                continue
            print("{0}\t1.0\t{1}".format(title, "\t".join(links_dict[page_id])))
        except Exception:
            continue

if __name__ == '__main__':
    main()


# --------------------------
# MySprite Class
import pygame

class MySprite(pygame.sprite.Sprite):
    "Sprites for the game"
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.position = (0, 0)
        self.speed = (0, 0)
        self.scroll = (0, 0)

    def setPosition(self, position):
        self.position = position
        self.rect.left = self.position[0] - self.scroll[0]
        self.rect.bottom = self.position[1] + self.scroll[1]

    def setScreenPosition(self, sceneryScroll):
        self.scroll = sceneryScroll
        (scrollx, scrolly) = self.scroll
        (posx, posy) = self.position
        self.rect.left = posx - scrollx
        self.rect.bottom = posy + scrolly

    def increasePosition(self, increment):
        (posx, posy) = self.position
        (incrementx, incrementy) = increment
        self.setPosition((posx + incrementx, posy + incrementy))

    def update(self, time):
        incrementx = self.speed[0] * time
        incrementy = self.speed[1] * time
        self.increasePosition((incrementx, incrementy))


import sys
from io import StringIO
import unittest

class TestClass(unittest.TestCase):
    def assertIO(self, input, output):
        stdout, stdin = sys.stdout, sys.stdin
        sys.stdout, sys.stdin = StringIO(), StringIO(input)
        resolve()
        sys.stdout.seek(0)
        out = sys.stdout.read()[:-1]
        sys.stdout, sys.stdin = stdout, stdin
        self.assertEqual(out, output)

#     def test_Sample_Input_1(self):
#         input = """3
# <><
# 3 8 6 10"""
#         output = """2
# 1 5 4 7
# 2 3 2 3"""
#         self.assertIO(input, output)

    def test_Sample_Input_1(self):
        input = """3
<><
3 8 6 10"""
        output = """2
2 4 3 5
1 4 3 5"""
        self.assertIO(input, output)

    def test_Sample_Input_2(self):
        input = """1
<
3 4"""
        output = """1
3 4"""
        self.assertIO(input, output)

    def test_Sample_Input_3(self):
        input = """1
<
3 6"""
        output = """3
1 2
1 2
1 2"""
        self.assertIO(input, output)

def resolve():
  inf = 10**18+1
  # 差が分割数より大きいと良い非不整数列にならない。
  # 差の絶対値の最小値 K で Ai を分割して、余りを 1 ずつできるだけ割り振っていく。
  # 差の分布次第で破綻しそうな気がするけど、差の最小値を使って分割しているので、矛盾が発生しない (はず)
  inf = 10**18+1
  N = int(input())
  S = list(input())
  A = [int(x) for x in input().split(" ")]

  K = inf
  for i in range(N):
    K = min(K, abs(A[i+1]-A[i]))

  B = [[0]*(N+1) for _ in range(K)]
  for i in range(N+1):
    for k in range(K):
      B[k][i] = A[i]//K
      if A[i]%K > k: B[k][i]+=1

  print(K)
  for b in B:
    print(*b, sep=" ")

import sys
if sys.argv[-1] == './Main.py':
  resolve()

if __name__ == "__main__":
    unittest.main()


from handlers import WebRequestHandler
from webapp2_extras import i18n
import os

__author__ = 'Jakub'

class UserSettingsHandler(WebRequestHandler):

    def __init__(self, *args, **kwargs):
        super(UserSettingsHandler, self).__init__(*args, **kwargs)
        self.login_required = True

    def get(self, *args, **kwargs):
        user_key = self.user_key.get()
        locales = [name for name in os.listdir('./locale') if os.path.isdir(os.path.join('./locale', name))]
        self.draw_page('user_settings', locales=locales, locale=user_key.localization)

    def post(self, *args, **kwargs):
        user_key = self.user_key.get()
        user_key.localization = self.request.POST['selectLanguage']
        user_key.put()
        locales = [name for name in os.listdir('./locale') if os.path.isdir(os.path.join('./locale', name))]
        self.draw_page('user_settings', locales=locales, locale=user_key.localization)


# -*- coding: utf-8 -*-
import upemtk as tk
import doctest
from dessiner import *
from deplacement import *
from file import *
from fonctions import *

def affichage(largeurFenetre, hauteurFenetre, largeurInventaire, inventaire, carte):
    """ affichage de la fenêtre, la fonction affiche tout les éléments possibles """
    tk.efface_tout()

    #On met à jour la fenêtre et on affiche chaque élément
    largeurCase = largeurDeCase(largeurFenetre, hauteurFenetre, carte)
    #On parcourt la liste 2D (des sous listes dans une liste)
    dessinerQuadrillage(largeurFenetre, hauteurFenetre,largeurCase, carte) # on peut retirer cette ligne pour que ça soit plus jolie
    for i in range(len(carte)): #i les lignes
        for j in range(len(carte[i])): #j les colonnes
            if carte[i][j] == ".":#Case vide
                pass
            elif carte[i][j] == "W":#Wall
                dessinerMur(j * largeurCase, i * largeurCase, largeurCase)
            elif carte[i][j] == "T":#Target
                dessinerCible(j * largeurCase, i * largeurCase, largeurCase)
            elif carte[i][j] == "S":#Start
                dessinerJoueur(j * largeurCase, i * largeurCase, largeurCase)
            elif carte[i][j] == "D":#Door
                dessinerPorte(j * largeurCase, i * largeurCase, largeurCase)
            elif carte[i][j] == "K":#Key
                dessinerClef(j * largeurCase, i * largeurCase, largeurCase)
            elif carte[i][j] == "B":#Box
                dessinerBoite(j * largeurCase, i * largeurCase, largeurCase)
            elif carte[i][j] == "TB":#Box On a target
                dessinerCible(j * largeurCase, i * largeurCase, largeurCase)
                dessinerBoite(j * largeurCase, i * largeurCase, largeurCase)
            elif carte[i][j] == "TJ":#Joueur On a target
                dessinerCible(j * largeurCase, i * largeurCase, largeurCase)
                dessinerJoueur(j * largeurCase, i * largeurCase, largeurCase)
            elif carte[i][j] == "J":#Joueur
                dessinerJoueur(j * largeurCase, i * largeurCase, largeurCase)
            elif carte[i][j] == "KB":#Box On a key
                dessinerBoite(j * largeurCase, i * largeurCase, largeurCase, "green")

    n = largeurFenetre - largeurInventaire
    dessinerInventaire(n, 0, largeurInventaire, hauteurFenetre)
    dessinerClef(n, 0, largeurCase * 2)

    #largeurCase/1.5 ou largeurCase/15 est là pour centrer le texte
    tk.texte(n + largeurCase / 1.5, largeurCase * 2, inventaire["nbClefs"], "white")
    tk.texte(n + largeurCase / 1.5, largeurCase * 4, inventaire["nbCoups"], "white")

    n = largeurFenetre - largeurInventaire + largeurCase / 15
    tk.texte(n, largeurCase * 6.5,"Echap: Quitter", "white", "nw","Purisa", 9)#bouton quitter
    tk.texte(n, largeurCase * 7,"E: Tirer", "white", "nw","Purisa", 9)#bouton pour tirer
    tk.texte(n, largeurCase * 7.5,"R: Recharger", "white", "nw","Purisa", 9)#bouton reset
    tk.texte(n, largeurCase * 8,"S: Sauvegarde", "white", "nw","Purisa", 9)#bouton save
    tk.texte(n, largeurCase * 8.5,"B: Recommencer", "white", "nw","Purisa", 9)#bouton save
    tk.mise_a_jour()

def main():
    """ Fonction principale du programme """

    #---------- Initialisation ----------
    numeroDeMap = "Edited" # le numéro de la map à lire (changeable)
    carte, inventaire = initialisationMap(numeroDeMap)
    carte_debut = [list(l) for l in carte]
    largeurFenetre, hauteurFenetre, largeurInventaire = generationFenetre(carte)
    infoMap = [largeurFenetre, hauteurFenetre, largeurInventaire] #Stockage des infos dans une liste pour limiter le nombre de paramètres envoyés aux fonctions
    tk.cree_fenetre(largeurFenetre, hauteurFenetre)
    #-------- Fin initialisation --------

    # -- boucle de jeu
    while True:
        affichage(largeurFenetre, hauteurFenetre, largeurInventaire,inventaire, carte)

        # conditions de sortie
        if partieGagnee(carte):
            dessinerVictoire(largeurFenetre,hauteurFenetre)
            tk.attente_clic()
            break

        #Gestion des touches
        typeEvent = attenteMouvement(carte, infoMap)
        if typeEvent == "r":#commande pour revenir à la précédante sauvegarde
            carte, inventaire = recharger()
            continue
        elif typeEvent == "s":#commande de sauvegarde
            ecritureFichierSauvegarde(carte, inventaire)
            continue
        elif typeEvent == "b":#commande de reset
            carte = [list(l) for l in carte_debut]
            inventaire["nbClefs"], inventaire["nbCoups"] = 0, 0
            continue
        #Touches pour quitter le jeu
        elif typeEvent == "Quitte" or typeEvent =="Escape":
            break
        carte = typeMouvement(typeEvent, carte, infoMap, inventaire) #Modifications de la carte par rapport à la touche

    tk.ferme_fenetre()

if __name__ == '__main__':
    """Ce programme est le jeu principale """
    main()
    #print(doctest.testmod())


import pandas as pd
import numpy as np

#The league averages in 2018 for [AVG, OBP, SLG, BB%, K%]
league_average = [0.248, 0.318, 0.409, 0.085, 0.223]

#The odds ratio method
def odds_ratio(batter_stat, pitcher_stat, league_average):
	odds_b = batter_stat/(1-batter_stat)
	odds_p = pitcher_stat/(1-pitcher_stat)
	odds_l = league_average/(1-league_average)
	odds = (odds_b*odds_p)/odds_l
	return odds/(odds+1)

#The bater pitcher matchup regression
def batter_pitcher_matchup(input_data):

	#The pitcher stats are stored in Lineups/Pitcher.csv
	pitcher_stats = np.genfromtxt('Lineups/Pitcher.csv', delimiter=",")

	output_data = pd.DataFrame()

	output_data['Name'] = input_data['Name']

	output_data['AVG'] = odds_ratio(input_data['AVG'], pitcher_stats[1], league_average[0]) \
	 + (pitcher_stats[2]*0.164 + input_data['OBP']*0.08 + pitcher_stats[4]*0.188 \
	 	+ input_data['BB%']*0.159 + ((pitcher_stats[4]-input_data['BB%'])**2)*-0.4 - 0.076)

	output_data['OBP'] = odds_ratio(input_data['OBP'], pitcher_stats[2], league_average[1]) \
	 + (input_data['BB%']*0.126 + pitcher_stats[5]*0.109 + pitcher_stats[2]*0.092 + pitcher_stats[3]*0.058 \
	 	+ pitcher_stats[1]*-0.103 - 0.085)

	output_data['SLG'] = odds_ratio(input_data['SLG'], pitcher_stats[3], league_average[2]) \
	 + (pitcher_stats[4]*-0.509 + input_data['BB%']*-0.521 + pitcher_stats[3]*0.162 + input_data['SLG']*0.066 \
	 	+ pitcher_stats[5]*0.122 - 0.113)

	"""
	output_data['BB%'] = odds_ratio(input_data['BB%'], pitcher_stats[4], league_average[3]) \
	 + (input_data['BB%']*0.107 + pitcher_stats[4]*-0.521 + ((pitcher_stats[1]-input_data['AVG'])**2)*0.338 + ((pitcher_stats[2]-input_data['OBP'])**2)*-0.2 \
	 	+ input_data['SLG']*0.018 - 0.018)
	"""

	output_data['BB%'] = output_data['OBP'] - output_data['AVG']

	#There is no adjustment for K% besides the odds ratio method
	output_data['K%'] = odds_ratio(input_data['K%'], pitcher_stats[5], league_average[4])

	#Players with an abnormally low BB% (pitchers, especially) can end up with a negative
	#value when facing good pitchers. This sets all negative values to 0
	output_data['BB%'] = output_data['BB%'].clip(lower=0.00)

	return output_data

#Alters the batting tiers for the given pitcher using odds ratio method
def batting_tiers_pitchers_matchup(averages, stat):

	pitcher_stats = np.genfromtxt('Lineups/Pitcher.csv', delimiter=",")

	if stat == 'AVG':
		pos = 0
	if stat == 'OBP':
		pos = 1
	if stat == 'SLG':
		pos = 2
	if stat == 'BB%':
		pos = 3
	if stat == 'K%':
		pos = 4

	for i in range(0, len(averages)):
		averages[i] = odds_ratio(averages[i], pitcher_stats[pos+1], league_average[pos])

	return averages


# This file is part of django-ca (https://github.com/mathiasertl/django-ca).
#
# django-ca is free software: you can redistribute it and/or modify it under the terms of the GNU General
# Public License as published by the Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# django-ca 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 General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License along with django-ca. If not, see
# <http://www.gnu.org/licenses/>.

"""validation module to validate license headers."""

import difflib
import os
import textwrap
from pathlib import Path
from typing import Union

from devscripts.commands import CommandError

try:
    import tomllib
except ImportError:  # pragma: py<3.11
    import tomli as tomllib  # type: ignore[no-redef]

LICENSE_HEADER = """This file is part of django-ca (https://github.com/mathiasertl/django-ca).

django-ca is free software: you can redistribute it and/or modify it under the terms of the GNU General
Public License as published by the Free Software Foundation, either version 3 of the License, or (at your
option) any later version.

django-ca 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 General Public License
for more details.

You should have received a copy of the GNU General Public License along with django-ca. If not, see
<http://www.gnu.org/licenses/>."""

PYTHON_BIN_HEADER = """#!/usr/bin/env python3
#
"""

PYTHON_LICENSE_HEADER = textwrap.indent(LICENSE_HEADER, "# ").replace("\n\n", "\n#\n")
PYTHON_READ_LENGTH = len(PYTHON_BIN_HEADER) + len(LICENSE_HEADER) + 64

def handle_python_file(path: Union[str, "os.PathLike[str]"], script: bool) -> int:
    """Check the license header for a Python file."""
    expected_header = PYTHON_LICENSE_HEADER
    if script is True:
        expected_header = PYTHON_BIN_HEADER + PYTHON_LICENSE_HEADER

    with open(path, encoding="utf-8") as stream:
        actual_header = stream.read(PYTHON_READ_LENGTH)

        # skip empty files
        if not actual_header:
            return 0

        if not actual_header.startswith(expected_header):
            actual_lines = actual_header.splitlines()
            expected_lines = expected_header.splitlines()

            diff = difflib.unified_diff(
                actual_lines, expected_lines, fromfile=str(path) + ".orig", tofile=str(path), lineterm=""
            )
            print("\n".join(diff))
            return 1
    return 0

def validate() -> None:
    """Main validation function."""
    errors = 0
    with open("pyproject.toml", "rb") as stream:
        config = tomllib.load(stream)

    standalone_scripts = config["django-ca"]["validation"]["standalone-scripts"]
    excludes = config["django-ca"]["validation"]["excludes"]

    for directory in ["ca", "docs/source", "devscripts"]:
        for path in sorted(Path(directory).glob("**/*.py")):
            if not any(path.match(exclude) for exclude in excludes):
                errors += handle_python_file(path, script=str(path) in standalone_scripts)

    if errors != 0:
        raise CommandError(f"{errors} inconsistent license headers found.")


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

# Написать декоратор log, который будет выводить на экран все аргументы,
# которые передаются вызываемой функции.
def print_received_argument(func):
    def wrapper(*args, **kwargs):
        if args:
            print(*args)

        if kwargs:
            print(**kwargs)

        return func(*args, **kwargs)

    return wrapper

# Написать функцию, которая будет принимать на вход
# натуральное число n, # и возращать сумму его цифр.
# Реализовать используя рекурсию (без циклов, без строк,
# без контейнерных типов данных).
@print_received_argument
def get_natural_sum(number):
    result = 0
    if isinstance(number, int) and number > 0:
        result = (
            number % 10 + get_natural_sum(number // 10) if number > 10 else number
        )
    else:
        print('Give me natural number')

    return result

if __name__ == '__main__':
    assert get_natural_sum(123) == 6
    assert get_natural_sum(123456789) == 45
    assert get_natural_sum(-5) == 0
    assert get_natural_sum('sdf') == 0
    assert get_natural_sum(123.4) == 0
    assert get_natural_sum([1, 2, 3, 4, 5]) == 0


# @Author  : Zhirong Tang
# @Time    : 2022/08/25 21:30

# Definition for singly-linked list.
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        # method-1: 递归法
        # 头部较小的节点与剩下的元素merge合并
        if l1 is None:
            return l2
        elif l2 is None:
            return l1
        elif l1.val < l2.val:
            l1.next = self.mergeTwoLists(l1.next, l2)
            return l1
        else:
            l2.next = self.mergeTwoLists(l1, l2.next)
            return l2

        # method-2: 迭代
        # l1和l2非空时，判断两者哪一更小，则将较小的添加到结果，对应链表的节点后移一位
        # 哨兵节点
        dummy = ListNode(-1)
        prev = dummy
        while l1 and l2:
            if l1.val < l2.val:
                prev.next = l1
                l1 = l1.next
            else:
                prev.next = l2
                l2 = l2.next
            prev = prev.next
        # 合并后l1和l2两者最多只有一个没有合并完，只需要将链表的末尾指向其即可
        prev.next = l1 if l1 else l2
        return dummy.next

LC/linked-list/21-Merge Two Sorted Lists.py


import datetime
import os
import pytz

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
uri = os.environ.get("DATABASE_URL")
app.config["SQLALCHEMY_DATABASE_URI"] = uri
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False

db = SQLAlchemy(app)

class Appointment(db.Model):
    __tablename__ = "appointments"
    id = db.Column(db.BigInteger, primary_key=True, nullable=False, autoincrement=True)
    time = db.Column(db.DateTime())
    location = db.Column(db.String(length=256), nullable=True)
    name = db.Column(db.String(length=256), nullable=True)
    position = db.Column(db.String(length=256), nullable=True)
    email = db.Column(db.String(length=256), nullable=True)
    category = db.Column(db.String(length=256), nullable=True)
    phone = db.Column(db.String(length=256), nullable=True)
    filled = db.Column(db.Boolean, default=False)
    visible = db.Column(db.Boolean, default=True)

    def add_slot(month, day, hour, minute, location=None):
        time = datetime.datetime(
            month=month, day=day, year=2018, hour=hour, minute=minute,
        )
        appt = Appointment(time=time, name=None, position=None, filled=False, location=location)
        db.session.add(appt)
        db.session.commit()

    def remove_slots(month, day):
        for appt in Appointment.query.all():
            if appt.time.month == month and appt.time.day == day:
                appt.visible = False
        db.session.commit()


import yaml

def is_yaml_file_corrupted(file_path):
    try:
        with open(file_path, 'r') as yaml_file:
            yaml.safe_load(yaml_file)
        return False  # Parsing successful, file is not corrupted
    except yaml.YAMLError as e:
        print(f"YAML parsing error: {str(e)}")
        return True  # Parsing failed, file is corrupted

# Replace 'path/to/your/file.yaml' with the actual file path you want to check
file_path = 'personinfo.yaml'

if is_yaml_file_corrupted(file_path):
    print(f"The YAML file at {file_path} is corrupted.")
else:
    print(f"The YAML file at {file_path} is not corrupted.")


class Solution:
    def getSkyline(self, buildings: List[List[int]]) -> List[List[int]]:
        events = []
        for L, R, H in buildings:
            events.append((L, -H, R))
            events.append((R, 0, 0))

        events.sort()

        res = [[0, 0]]
        hp = [(0, float("inf"))]

        for pos, negH, R in events:
            # pop out building which is end
            while hp[0][1] <= pos:
                heapq.heappop(hp)

            if negH != 0:
                heapq.heappush(hp, (negH, R))

            if res[-1][1] != -hp[0][0]:
                res.append([pos, -hp[0][0]])

        return res[1:]


# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: percent
#       format_version: '1.3'
#       jupytext_version: 1.11.5
#   kernelspec:
#     display_name: nicobako.github.io
#     language: python
#     name: nicobako.github.io
# ---

# %% [markdown]
# # Problem 3

# %%
from typing import Iterable

from project_euler import get_problem_description

get_problem_description(3)

# %% [markdown]
# First, we need to write some logic for determining whether
# a number is a *prime number* or not.

# %%
def is_prime_number(number: int) -> bool:
    if number == 1:
        return False
    if number == 2:
        return True
    # first, check if number is even
    if number % 2 == 0:
        return False
    low_num = 2
    high_num = number
    while low_num < high_num:
        high_num = number // low_num
        remainder = number % low_num
        if remainder == 0 and low_num != high_num:
            return False
        low_num += 1
    return True

# %% [markdown]
# Let's see this function in action

# %%
list(filter(is_prime_number, range(50)))

# %% [markdown]
# Looks good to me...

# %% [markdown]
# Now, we need a function for getting the factors of a number

# %%
def get_factors(number: int) -> Iterable[int]:
    factors = set([1, number])
    low_num = 2
    high_num = number
    while low_num <= high_num:
        remainder = number % low_num
        if remainder == 0:
            factors.add(low_num)
            high_num = number // low_num
            factors.add(high_num)
        low_num += 1
    return sorted(factors)

# %% [markdown]
# Let's see this function in action.

# %%
assert [1, 2, 4] == list(get_factors(4))

# %%
assert [1, 2, 4, 5, 10, 20, 25, 50, 100] == list(get_factors(100))

# %% [markdown]
# Looks good, I think.

# %% [markdown]
# Let's see if we can recreate the list mentioned above,
# the prime factors of `13195`.

# %%
assert [5, 7, 13, 29] == list(filter(is_prime_number, get_factors(13195)))

# %% [markdown]
# Looks good!

# %% [markdown]
# Okay, now the real test...

# %%
max(filter(is_prime_number, get_factors(600851475143)))

# %% [markdown]
# Yay! Solution is correct!