# -*- coding: utf-8 -*-

from os import access
import random
import time
from PQTs.Selenium.Base import BaseAcciones

from PQTs.Utilizar import urlutadeo

from selenium.common import exceptions
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select

class Acciones(BaseAcciones):
    def primerapagina(self, cedula):
        try:
            self.ir(urlutadeo)
            self.sleep(2)

        except:
            self.salir()
            return False

        xpathInputcedula = (By.ID,"documentoIdentidad")
        xpathInputconfirmarcedula=(By.ID,"confirmaDocumentoIdentidad")
        xpathBotonContinuar=(By.XPATH,"/html/body/div[3]/form/div/input")

        visibleInputCedula = self.explicitWaitElementoVisibility(15,xpathInputcedula)
        if visibleInputCedula:
            self.escribir(xpathInputcedula,cedula)
            visibleInputConfirmarCedula = self.explicitWaitElementoVisibility(15,xpathInputconfirmarcedula)
            if visibleInputConfirmarCedula:
                self.escribir(xpathInputconfirmarcedula,cedula)
                time.sleep(1)
                self.click(xpathBotonContinuar)

    def segundapagina(self):
        time.sleep(3)
        xpathconvocatoria = (By.ID, 'convocatoria')
        xpathSIGUIENTE = (By.NAME, 'btnSiguiente')

        time.sleep(3)
        visibleonvocatoria= self.explicitWaitElementoVisibility(15,xpathconvocatoria)
        if visibleonvocatoria:
            select_element=self.findElement(xpathconvocatoria)
            select_object= Select(select_element)
            select_object.select_by_value('2022-1A - 33')

        self.click(xpathSIGUIENTE)

        time.sleep(5)

    def tercerapagina(self,diaExp,mesExp,anioExp,diaNac,mesNac,anionaci,NOMBRE,PRIMERAPELLIDO,SEGUNDOAPELLIDO,sexasp,EMAIL,telefonofijo,telefonomivil):
        time.sleep(4)
        xpathdiaExp= (By.ID, 'diaExp')
        select_element=self.findElement(xpathdiaExp)
        select_object= Select(select_element)
        select_object.select_by_value(diaExp)
        time.sleep(1)

        time.sleep(1)
        xpathmesExp= (By.NAME, 'mesExp')
        select_element=self.findElement(xpathmesExp)
        select_object= Select(select_element)
        select_object.select_by_value(mesExp)
        time.sleep(1)

        time.sleep(1)
        xpathanioExp= (By.ID, 'anioExp')
        self.click(xpathanioExp)
        time.sleep(1)
        self.borrar(xpathanioExp)
        self.escribir(xpathanioExp,anioExp)
        time.sleep(1)

        time.sleep(1)
        xpathnombre= (By.NAME, 'datosBasicos.aspirante.nombre')
        self.escribir(xpathnombre,NOMBRE)
        time.sleep(1)

        time.sleep(1)
        xpathprimerapellido= (By.XPATH, '//*[@id="capaFormulario"]/form/div[1]/div/div[3]/table/tbody/tr[5]/td[2]/input')
        self.escribir(xpathprimerapellido,PRIMERAPELLIDO)
        time.sleep(1)

        time.sleep(1)
        xpathsegundoapellido= (By.XPATH, '//*[@id="capaFormulario"]/form/div[1]/div/div[3]/table/tbody/tr[6]/td[2]/input')
        self.escribir(xpathsegundoapellido,SEGUNDOAPELLIDO)
        time.sleep(1)

        if sexasp=="H":
            xpathHOMBRE= (By.CSS_SELECTOR, "input[type='radio'][value='H']")
            self.click(xpathHOMBRE)
        elif sexasp=="D":
            xpathMUJER= (By.CSS_SELECTOR, "input[type='radio'][value='D']")
            self.click(xpathMUJER)

        time.sleep(1)
        xpathdiaNac= (By.ID, 'diaNac')
        select_element=self.findElement(xpathdiaNac)
        select_object= Select(select_element)
        select_object.select_by_value(diaNac)
        time.sleep(1)

        time.sleep(1)
        xpathmesNac= (By.ID, 'mesNac')
        select_element=self.findElement(xpathmesNac)
        select_object= Select(select_element)
        select_object.select_by_value(mesNac)
        time.sleep(1)

        time.sleep(1)

        xpathanacimi= (By.ID, 'anioNac')
        self.click(xpathanacimi)
        self.borrar(xpathanacimi)
        self.escribir(xpathanacimi,anionaci)
        time.sleep(1)

        time.sleep(3)
        xpathidPaissNac= (By.ID, 'idPaissNac')
        select_element=self.findElement(xpathidPaissNac)
        select_object= Select(select_element)
        select_object.select_by_value("170")
        time.sleep(1)

        time.sleep(3)
        xpathiddepartanacimi= (By.NAME, 'datosBasicos.aspirante.codProvinciaNacimiento')
        select_element=self.findElement(xpathiddepartanacimi)
        select_object= Select(select_element)
        select_object.select_by_value("11")
        time.sleep(3)

        time.sleep(5)
        xpathiddepartanacimi= (By.NAME, 'datosBasicos.aspirante.codMunicipioNacimiento')
        select_element=self.findElement(xpathiddepartanacimi)
        select_object= Select(select_element)
        select_object.select_by_value("1")
        time.sleep(1)

        time.sleep(5)
        xpathidProvinciaNac= (By.NAME, 'datosBasicos.aspirante.domicilioCurso.codProvincia')
        select_element=self.findElement(xpathidProvinciaNac)
        select_object= Select(select_element)
        select_object.select_by_value("11")
        time.sleep(1)

        time.sleep(5)
        xpathidLocalidadCur =(By.NAME, 'datosBasicos.aspirante.domicilioCurso.codLocalidad')
        select_element=self.findElement(xpathidLocalidadCur)
        select_object= Select(select_element)
        select_object.select_by_value("1")
        time.sleep(1)

        time.sleep(1)
        xpathtelefonofijo= (By.NAME, 'datosBasicos.aspirante.domicilioCurso.telefono')
        self.escribir(xpathtelefonofijo,telefonofijo)
        time.sleep(1)

        time.sleep(1)
        xpathtelefonomivil= (By.NAME, 'datosBasicos.aspirante.telefonoMovil')
        self.escribir(xpathtelefonomivil,telefonomivil)
        time.sleep(1)

        time.sleep(1)
        xpathemail= (By.NAME, 'datosBasicos.aspirante.email')
        self.escribir(xpathemail,EMAIL)
        time.sleep(1)

        time.sleep(1)
        xpathConfirmaremail= (By.NAME, 'datosBasicos.aspirante.confirmacionEmail')
        self.escribir(xpathConfirmaremail,EMAIL)
        time.sleep(1)

        colegios= ["COLEGIO ACACIA II", "COLEGIO AGUAS CLARAS", "COLEGIO AGUSTIN FERNANDEZ","COLEGIO AGUSTINIANO TAGASTE", "COLEGIO ALBERTO LLERAS CAMARGO",  "COLEGIO ALDEMAR ROJAS", "COLEGIO ALEJANDRO MAGNO",
         "COLEGIO ALEJANDRO MAGNO", "COLEGIO ALEJANDRO MAGNO", "COLEGIO ALEJANDRO OBREGON","COLEGIO ALEMANIA SOLIDARIA", "COLEGIO ALEMANIA UNIFICADA","COLEGIO ALEXANDER FLEMING","COLEGIO ALFONSO LOPEZ MICHELSEN","COLEGIO ALFONSO LOPEZ PUMAREJO",
         "COLEGIO ALFONSO REYES ECHANDIA","COLEGIO ALFRED MARSHALL","COLEGIO ALFREDO IRIARTE","COLEGIO ALMIRANTE PADILLA","COLEGIO ALQUERIA DE LA FRAGUA","COLEGIO ALTAMIRA SURORIENTAL",
         "COLEGIO ALVARO GOMEZ HURTADO","COLEGIO AMANECER DE LUCES","COLEGIO ANDRES BELLO","COLEGIO ANEXO SAN FRANCISCO DE ASIS","COLEGIO ANIBAL FERNANDEZ DE SOTO","COLEGIO ANTONIO BARAYA","COLEGIO ANTONIO GRANADOS","COLEGIO ANTONIO JOSE DE SUCRE",
         "COLEGIO ANTONIO JOSE URIBE","COLEGIO ANTONIO NARIÑO","COLEGIO ANTONIO VAN UDEN","COLEGIO ANTONIO VILLAVICENCIO","COLEGIO AQUILEO PARRA","COLEGIO ARBORIZADORA ALTA","COLEGIO ARBORIZADORA BAJA",
         "COLEGIO ATAHUALPA","COLEGIO ATANASIO GIRARDOT","COLEGIO ATENAS","COLEGIO AULAS COLOMBIANAS SAN LUIS","COLEGIO AUSTRALIANO CAMPESTRE","COLEGIO AVE MARIA"]
        colegiosrd=random.choice(colegios)
        time.sleep(1)
        xpathColegio= (By.ID, 'idCentroEscolarExt')
        self.escribir(xpathColegio,colegiosrd)
        time.sleep(1)

        time.sleep(1)
        xpathidondesentero=(By.NAME, 'datosBasicos.aspirante.tipoPromocion')
        select_element=self.findElement(xpathidondesentero)
        select_object= Select(select_element)
        select_object.select_by_value("18")
        time.sleep(1)

        time.sleep(1)
        xpathaceptardatos= (By.ID, "idPermiteDivulgarDatos")
        self.click(xpathaceptardatos)
        time.sleep(1)

        programaacedemicos=["P009","P010","P011","P012","P013","P014","P015","P016","P017","P018","P019"]
        programaacad=random.choice(programaacedemicos)

        time.sleep(2)
        xpathprogramaacademico=(By.NAME, 'datosBasicos.aspirante.plan')
        select_element=self.findElement(xpathprogramaacademico)
        select_object= Select(select_element)
        select_object.select_by_value(programaacad)
        time.sleep(5)

        time.sleep(1)
        try:
            xpathcentroplan=(By.ID, 'centroPlan')
            select_element=self.findElement(xpathcentroplan)
            select_object= Select(select_element)
            select_object.select_by_value("10")
            time.sleep(1)
        except:
            time.sleep(2)
            xpathcentroplan=(By.ID, 'centroPlan')
            select_element=self.findElement(xpathcentroplan)
            select_object= Select(select_element)
            select_object.select_by_value("10")

        time.sleep(5)
        try:
            xpathcriterioCentroPlan=(By.NAME, 'datosBasicos.aspirante.criterio')
            select_element=self.findElement(xpathcriterioCentroPlan)
            select_object= Select(select_element)
            select_object.select_by_value("CRU")
            time.sleep(2)
        except:
            time.sleep(2)
            xpathcriterioCentroPlan=(By.NAME, 'datosBasicos.aspirante.criterio')
            select_element=self.findElement(xpathcriterioCentroPlan)
            select_object= Select(select_element)
            select_object.select_by_value("CRU")

        xpathbtnSiguiente=(By.XPATH, '//*[@id="capaFormulario"]/div[4]/input')
        self.click(xpathbtnSiguiente)
        print ("boton siguiente final")
        time.sleep(20)


from datetime import datetime, timedelta
from .envs import settings
import jwt

def create_jwt_token(data: dict) -> str:
    now = datetime.utcnow()

    return jwt.encode(
        {
            **data,
            **{
                "exp": now + timedelta(minutes=15),
                "iat": now,
            },
        },
        settings.jwt_secret,
        algorithm="HS256",
    )

def decode_jwt_token(token: str) -> dict:
    try:
        data = jwt.decode(
            token,
            settings.jwt_secret,
            algorithms=["HS256"],
        )

    except Exception as e:
        print(e)
        return {}

    return data


import matplotlib.pyplot as plt

xlst, ylst = [],[]

def even(x):
    if (x % 2) == 1:
        return False
    else:
        return True

def f(n):
    if even(n):
        return n // 2
    else:
        return 3*n+1

def g(n,i):
    xlst.append(i)
    ylst.append(n)
    print(str(n)+" ",end="")
    if n == 1:
        return 1
    else:
        return g(f(n),i+1)

g(27,0)
xmax = max(tuple(xlst))
ymax = max(tuple(ylst))
print("\nNumber of recursive calls: {0}\nMaximum number: {1}".format(xmax,ymax))
plt.plot(xlst,ylst,"r--")
plt.axis([0,xmax,0,ymax])
plt.savefig("./Assignment11/g27(27,0).png")
plt.show()


from openpyxl import load_workbook
from collections import defaultdict
from FreeTranslationWithContextExperiment.models import *
import re

import os
from django.conf import settings

DEFAULT_NUMBER_REQUIRED_ANSWERS = 20
SENTENCE = 0
GROUP = 1
NATIVE_LANGUAGE = 2
FOREIGN_LANGUAGE = 3

def processFreeTranslationWithContextHeaders(headers):
    """
    process header
    """

    lang_native = headers[NATIVE_LANGUAGE].split()[-1]
    lang_foreign = headers[FOREIGN_LANGUAGE].split()[-1]
    counts = defaultdict(lambda: 0)
    processed_headers = []
    for i, header in enumerate(headers):
        counts[header] += 1
    for i, header in enumerate(headers):
        if counts[header] > 1:
            processed_headers.append((header, False))
        else:
            processed_headers.append((header, True))

    return lang_native, lang_foreign, processed_headers

#Added by Hasan on 2018-06-10
def processFreeTranslationWithContextHeadersNew(headers):
    print(headers)

    native_header = headers[NATIVE_LANGUAGE].split()[-1]
    foreign_header = headers[FOREIGN_LANGUAGE].split()[-1]

    native_split = native_header.split('_')
    foregin_split = foreign_header.split('_')

    lang_native = native_split[0]
    lang_foreign = foregin_split[0]

    script_native = None
    script_foreign = None

    if len(native_split) > 1:
        script_native = native_split[-1].upper()

    if len(foregin_split) > 1:
        script_foreign = foregin_split[-1].upper()

    counts = defaultdict(lambda:0)
    processed_headers = []
    for i,header in enumerate(headers):
        counts[header] += 1
    for i,header in enumerate(headers):
        if counts[header] > 1:
            processed_headers.append((header, False))
        else:
            processed_headers.append((header, True))

    return lang_native, lang_foreign, script_native, script_foreign, processed_headers

def parseSentence(sentence):
    """
    parse sentence and return correct answer for each gap
    """
    sentence = sentence.replace("{", "[").replace("}", "]")
    sentence_without_gaps = sentence
    gaps = re.findall(r"[^[]*\[([^]]*)\]", sentence)
    gap_answer = ''

    # for g in gaps:
    #     print(g)
    #     gap_ans = re.findall(r"[^[]*\(([^]]*)\)", g)[0]
    #     print(gap_ans)
    #     gap_answer += gap_ans + ','
    #     sentence_without_gaps = sentence_without_gaps.replace('[' + g + ']', "").strip()

    for g in gaps:
        print(g)
        gap_ques, gap_ans = g.split('|')
        sentence_without_gaps = sentence_without_gaps.replace(g, gap_ques).strip()
    gap_answer = gap_ans
    print("exiting")
    sentence_without_gaps = sentence_without_gaps.split()
    print(sentence_without_gaps)
    # return 0
    # removing symbols
    symbols_to_remove = ['.', ',', ';', ':', '-']
    for symbol in symbols_to_remove:
        if symbol in sentence_without_gaps:
            sentence_without_gaps.remove(symbol)

    return gap_answer, sentence_without_gaps
    # return gap_answer.strip(','), sentence_without_gaps

def parseFreeTranslationWithContextFileRow(row):
    """
    parse row
    """
    sentence = row[SENTENCE]
    gap_answers, sentence_without_gaps = parseSentence(sentence)
    entry_group = row[GROUP]
    print(gap_answers, sentence_without_gaps, entry_group)
    return sentence, gap_answers, entry_group, len(sentence_without_gaps)

def processFreeTranslationWithContextUploadedFile(location, filename, experiment_name, priority, medal_filename=None):
    # open the file
    filepath = os.path.join(location, filename)
    f = load_workbook(filepath)

    imported_experiments = []

    # make corresponding experiment
    for ws in f.worksheets:
        data = []
        i = 0
        headers = None
        for c in ws.rows:
            if i == 0:
                if not c[0].value is None:
                    headers = list(map(lambda x: x.value, c))
            else:
                data.append(list(map(lambda x: x.value, c)))
            i += 1

        if not headers is None:

            # Lnative, Lforeign, headers = processFreeTranslationWithContextHeaders(headers)

            Lnative, Lforeign, Snative, Sforeign, headers = processFreeTranslationWithContextHeadersNew(headers)

            # get native language from database
            LNobject = Language.objects.get(language_code=Lnative.lower())
            # get foreign language from database
            LFobject = Language.objects.get(language_code=Lforeign.lower())

            groups = {}

            #Added by Hasan
            # folder_name = os.path.basename(settings.FREE_TRANSLATION_WITH_CONTEXT_UPLOAD_FOLDER)
            folder_name = 'FreeTranslationWithContext'
            # print(data)
            for d in data:
                sentence, gap_answers, group, sentence_words_without_gaps = parseFreeTranslationWithContextFileRow(d)
                if not group in groups:
                    groups[group] = []
                groups[group].append((sentence, gap_answers, sentence_words_without_gaps))

            for group, L in groups.items():
                # make the experiment
                name = experiment_name + "_%s-%s_group-%s" % (Lnative, Lforeign, group)
                experiment_object = FreeTranslationWithContextExperiment()
                experiment_object.user_medal = medal_filename
                experiment_object.save()
                experiment_object.native_language = LNobject
                experiment_object.foreign_language = LFobject
                experiment_object.experiment_name = name
                experiment_object.priority = priority

                #Added by Hasan on 2018-06-10
                experiment_object.native_script = Snative
                experiment_object.foreign_script = Sforeign

                #Added by Hasan on 2018-05-28
                experiment_object.stimuli_file = filename
                experiment_object.folder_name = folder_name
                experiment_object.save()
                # add language requirements
                # user must be native speaker of native language
                native_req, created = NativeLanguagePrerequisite.objects.get_or_create(required_language=LNobject,
                                                                                positive=True)
                if created:
                    native_req.save()
                experiment_object.user_prerequisites.add(native_req)

                for sentence, gap_answers, words_without_gaps in L:
                    # make a question plus comma separated answers for gaps and link it to this experiment_object
                    # make FreeTranslationWithContextQuestion
                    total_gaps = 1 #only one gap
                    total_words = total_gaps + words_without_gaps
                    FQ = FreeTranslationWithContextQuestion(sentence=sentence)
                    # set total time in seconds (3 seconds for each word + 10 seconds for each gap)
                    FQ.question_answer_time = (total_words * 3) + (total_gaps * 10)
                    FQ.save()
                    # make correct answer
                    for gap_answer in gap_answers.split(','):
                                FA = FreeTranslationWithContextCorrectAnswer()
                                FA.gap_answer = gap_answer
                                FA.save()
                                FQ.correct_answers.add(FA)

                    FQ.save()
                    # add question to experiment
                    experiment_object.experiment_questions.add(FQ)

                exp = {}
                exp["experiment_name"] = name
                exp["native_language"] = Lnative
                exp["foreign_language"] = Lforeign
                exp["number_of_questions"] = len(L)
                imported_experiments.append(exp)

    return imported_experiments


import json
from datetime import datetime

class Notebook:
    def __init__(self):
        self.update()

    # Reload algorithms and records
    def update(self):
        with open('records.json') as f:
            self.records = json.load(f)
        f.close()
        self.id_no = len(self.records)

        with open('algos.json') as f:
            self.algos = json.load(f)
        f.close()

    # Load an algorithm
    # para:
    # name, str. Algorithm name
    # return:
    # res, json. Loading the entry
    def load(self,name):
        return 0

    # Create a new algorithm
    # para:
    # algo_name, json. Json file of algorithm
    # time, python time object. Current time
    # description, str. Description of the algorithm
    # return:
    # bool, successfully added or not
    def create(self, algo_name, time = datetime.now().strftime("%d/%m/%Y %H:%M:%S"), description=""):
        # Create algo json
        if algo_name not in self.records.values():
            x = {str(self.id_no):{
                 'name':algo_name,
                 'last_edited_time':time,
                 'description':description,
                 'example':[],
                 'function':[]
                }
            }
            write_json(x,'algos.json')
            write_json({self.id_no:algo_name},'records.json')
            # Increase id by 1
            self.id_no += 1
            self.update()
            return True
        else:
            return False

    # Edit an algorithm
    # para:
    # algo_name, str. Current algorithm name.
    # attribute, str. The attribute to be changed
    # content, str. Replacing the old content of the attribute
    # return:
    # Bool, successfully changed or not
    def edit(self,algo_name,attribute,content):
        self.update()
        return 0

    # Add example record to an entry
    # para:
    # example_jason, json of the example
    # return:
    # bool, successful added or not
    def add_example(self,example_json):
        return 0

    # Add a function to exsist algorithm
    # para:
    # algo_name, str. Name of the algorithm
    # file_path, str. Directory of the file
    # return:
    # bool, wether the function is added or not
    def add_function(self,alg_name,file_path):
        return 0

    # Delete an algorithm
    # para:
    # algo_name, str. Algorithm name
    # return:
    # Bool, Successfully deleted or not
    def delete(self,algo_name):
        return 0

    # Serach an algorithm
    # para:
    # algo_name
    # return:
    # res,json file
    def search(self,algo_name):
        for key,val in self.records.items():
            if val == algo_name:
                return self.algos[key]
        return None

    # Display info
    # para:
    # algo_name,str
    # return:
    # void
    def display(self,algo_name):
        return 0

# function to add to JSON
def write_json(new_data, filename):
    with open(filename,'r+') as file:
        file_data = json.load(file)
        # Join new_data with file_data inside emp_details
        file_data.update(new_data)
        # Sets file's current position at offset.
        file.seek(0)
        # convert back to json.
        json.dump(file_data, file, indent = 4)
        file.close()

note=Notebook()


import json
import time
import copy

def utc_timestamp():
    return time.strftime("%Y-%m-%dT%H:%M:%S.00Z", time.gmtime())

def response_event(name, header, endpoint):
    event = {
                "header": {
                    "namespace": "Alexa",
                    "name": name,
                    "payloadVersion": "3",
                    "messageId": header["messageId"],
                    "correlationToken": header["correlationToken"]
                },
                "endpoint": {
                    "scope": {
                        "type": "BearerToken",
                        "token": endpoint["scope"]["token"]
                    },
                    "endpointId": endpoint["endpointId"]
                }
            }
    return event

def resolve_response_name(header):
    name = "Response"
    if header["namespace"] == "Alexa" and header["name"] == "ReportState":
        name = "StateReport"
    elif header["namespace"] == "Alexa.Discovery" and header["name"] == "Discover":
        name = "Discover.Response"
    return name

class AlexaEntertainmentCenter:
    def __init__(self, capabilities=[], endpoint_id="Entertainment-Center",
                 manufacturer="Various", friendly_name="Entertainment Center",
                 description="Home Entertainment Center",
                 display_categories=["TV"]):
        self.capabilities = capabilities
        self.endpoint_id = endpoint_id
        self.manufacturer = manufacturer
        self.friendly_name = friendly_name
        self.description = description
        self.display_categories = display_categories

    def discovery(self, header, registered_things):
        endpoint_list = []
        endpoint = {
                "endpointId": self.endpoint_id,
                "manufacturerName": self.manufacturer,
                "friendlyName": self.friendly_name,
                "description": self.description,
                "displayCategories": self.display_categories,
                "capabilities": []
            }
        for capability in self.capabilities:
            endpoint["capabilities"].append(capability.discovery())
        for thing in registered_things:
            endpoint["endpointId"] = thing["thingName"]
            endpoint["friendlyName"] = thing["thingName"]
            endpoint_list.append(copy.deepcopy(endpoint))
        response_header = copy.deepcopy(header)
        response_header["name"] = resolve_response_name(header)
        return_message = {
            "event": {
                "header": response_header,
                "payload": { "endpoints": endpoint_list }
            }
        }
        return return_message

    def discovery_json(self):
        return json.dumps(self.discovery, indent=4, sort_keys=True)

    def response(self, header, endpoint):
        name = resolve_response_name(header)
        response_properties = []
        for capability in self.capabilities:
            response_properties.append(capability.response_properties())
        pass
        response_data = {
            "context": {
                "properties": response_properties
            },
            "event": response_event(name, header, endpoint),
            "payload": {}
        }
        return response_data

class AlexaPowerController:
    def __init__(self, power_state=None):
        self.set_power_state(power_state)

    def set_power_state(self, power_state):
        if str(power_state).upper != 'ON':
            power_state = 'OFF'
        self.power_state = str(power_state).upper()

    def get_power_state(self):
        return self.power_state

    def turn_on(self):
        self.set_power_state('ON')

    def turn_off(self):
        self.set_power_state('OFF')

    def discovery(self):
        capability = {
            "type": "AlexaInterface",
            "interface": "Alexa.PowerController",
            "version": "3",
            "properties": {
                "supported": [
                    {
                        "name": "powerState"
                    }
                ],
                "proactivelyReported": False,
                "retrievable": True
            }
            }
        return capability

    def take_action(self, header, payload):
        if header['name'] == "TurnOn":
            self.turn_on()
        elif header['name'] == "TurnOff":
            self.turn_off()

    def response(self, header, endpoint):
        name = resolve_response_name(header)
        response_data = {
            "context": {
                "properties": self.response_properties()
            },
            "event": response_event(name, header, endpoint),
            "payload": {}
        }
        return response_data

    def response_properties(self):
        if self.power_state is None:
            raise Exception('set power_state before responding')
        properties = [{
                    "namespace": "Alexa.PowerController",
                    "name": "powerState",
                    "value": self.power_state,
                    "timeOfSample": utc_timestamp(),
                    "uncertaintyInMilliseconds": 500
                }]
        return properties

class AlexaSpeaker:
    def __init__(self, muted=None, volume=None):
        self.set_muted(muted)
        self.set_volume(volume)

    def set_muted(self, muted):
        self.muted = muted

    def get_muted(self):
        return self.muted

    def mute_on(self):
        self.set_muted(True)

    def mute_off(self):
        self.set_muted(False)

    def set_volume(self, volume):
        self.volume = volume

    def get_volume(self):
        return self.volume

    def adjust_volume(self, amount):
        if self.volume is None:
            raise Exception('Set the volume before adjusting')
        if amount < 0:
            self.set_volume(self.get_volume() - amount)
        else:
            self.set_volume(self.get_volume() + amount)

    def discovery(self):
        capability = {
            "type": "AlexaInterface",
            "interface": "Alexa.Speaker",
            "version": "3",
            "properties": {
                "supported": [
                    {
                        "name": "muted"
                    },
                    {
                        "name": "volume"
                    }
                ],
                "proactivelyReported": False,
                "retrievable": True
            }
        }
        return capability

    def take_action(self, header, payload):
        if header['name'] == "SetVolume":
            self.set_volume(payload['volume'])
        elif header['name'] == "AdjustVolume":
            self.adjust_volume(payload['volume'])
        elif header['name'] == "SetMute":
            self.set_muted(payload['mute'])

    def response(self, header, endpoint):
        name = resolve_response_name(header)
        response = {
            "context": {
                "properties": self.response_properties()
            },
            "event": response_event(name, header, endpoint)
        }
        return response

    def response_properties(self):
        if self.muted is None:
            raise Exception('Set muted property before responding')
        if self.volume is None:
            raise Exception('set volume property before responding')
        properties = [{
                    "namespace": "Alexa.Speaker",
                    "name": "muted",
                    "value": self.muted,
                    "timeOfSample": utc_timestamp(),
                    "uncertaintyInMilliseconds": 500
                }, {
                    "namespace": "Alexa.Speaker",
                    "name": "volume",
                    "value": self.volume,
                    "timeOfSample": utc_timestamp(),
                    "uncertaintyInMilliseconds": 500
                }]
        return properties


from argparse import ArgumentParser
from couchpotato import web
from couchpotato.api import api
from couchpotato.core.event import fireEventAsync, fireEvent
from couchpotato.core.helpers.variable import getDataDir, tryInt
from logging import handlers
from werkzeug.contrib.cache import FileSystemCache
import atexit
import locale
import logging
import os.path
import sys
import time

def getOptions(base_path, args):

    data_dir = getDataDir()

    # Options
    parser = ArgumentParser(prog = 'CouchPotato.py')
    parser.add_argument('--config_file', default = os.path.join(data_dir, 'settings.conf'),
                        dest = 'config_file', help = 'Absolute or ~/ path of the settings file (default ./_data/settings.conf)')
    parser.add_argument('--debug', action = 'store_true',
                        dest = 'debug', help = 'Debug mode')
    parser.add_argument('--console_log', action = 'store_true',
                        dest = 'console_log', help = "Log to console")
    parser.add_argument('--quiet', action = 'store_true',
                        dest = 'quiet', help = 'No console logging')
    parser.add_argument('--nogit', action = 'store_true',
                        dest = 'nogit', help = 'No git available')
    parser.add_argument('--daemon', action = 'store_true',
                        dest = 'daemon', help = 'Daemonize the app')
    parser.add_argument('--pid_file', default = os.path.join(data_dir, 'couchpotato.pid'),
                        dest = 'pid_file', help = 'Path to pidfile needed for daemon')

    options = parser.parse_args(args)

    options.config_file = os.path.expanduser(options.config_file)

    return options

def cleanup():
    fireEvent('app.crappy_shutdown', single = True)
    time.sleep(1)

def runCouchPotato(options, base_path, args, desktop = None):

    # Load settings
    from couchpotato.environment import Env
    settings = Env.get('settings')
    settings.setFile(options.config_file)

    # Create data dir if needed
    data_dir = os.path.expanduser(Env.setting('data_dir'))
    if data_dir == '':
        data_dir = getDataDir()

    if not os.path.isdir(data_dir):
        os.makedirs(data_dir)

    # Create logging dir
    log_dir = os.path.join(data_dir, 'logs');
    if not os.path.isdir(log_dir):
        os.mkdir(log_dir)

    try:
        locale.setlocale(locale.LC_ALL, "")
        encoding = locale.getpreferredencoding()
    except (locale.Error, IOError):
        pass

    # for OSes that are poorly configured I'll just force UTF-8
    if not encoding or encoding in ('ANSI_X3.4-1968', 'US-ASCII', 'ASCII'):
        encoding = 'UTF-8'

    # Register environment settings
    Env.set('encoding', encoding)
    Env.set('uses_git', not options.nogit)
    Env.set('app_dir', base_path)
    Env.set('data_dir', data_dir)
    Env.set('log_path', os.path.join(log_dir, 'CouchPotato.log'))
    Env.set('db_path', 'sqlite:///' + os.path.join(data_dir, 'couchpotato.db'))
    Env.set('cache_dir', os.path.join(data_dir, 'cache'))
    Env.set('cache', FileSystemCache(os.path.join(Env.get('cache_dir'), 'python')))
    Env.set('console_log', options.console_log)
    Env.set('quiet', options.quiet)
    Env.set('desktop', desktop)
    Env.set('args', args)
    Env.set('options', options)

    # Determine debug
    debug = options.debug or Env.setting('debug', default = False, type = 'bool')
    Env.set('debug', debug)

    # Development
    development = Env.setting('development', default = False, type = 'bool')
    Env.set('dev', development)
    if not development:
        atexit.register(cleanup)

    # Use reloader
    reloader = debug is True and development and not Env.get('desktop') and not options.daemon

    # Disable server access log
    logging.getLogger('werkzeug').setLevel(logging.WARNING)

    # Only run once when debugging
    fire_load = False
    if os.environ.get('WERKZEUG_RUN_MAIN') or not reloader:

        # Logger
        logger = logging.getLogger()
        formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s', '%H:%M:%S')
        level = logging.DEBUG if debug else logging.INFO
        logger.setLevel(level)

        # To screen
        if (debug or options.console_log) and not options.quiet and not options.daemon:
            hdlr = logging.StreamHandler(sys.stderr)
            hdlr.setFormatter(formatter)
            logger.addHandler(hdlr)

        # To file
        hdlr2 = handlers.RotatingFileHandler(Env.get('log_path'), 'a', 500000, 10)
        hdlr2.setFormatter(formatter)
        logger.addHandler(hdlr2)

        # Start logging & enable colors
        import color_logs
        from couchpotato.core.logger import CPLog
        log = CPLog(__name__)
        log.debug('Started with options %s' % options)

        # Load configs & plugins
        loader = Env.get('loader')
        loader.preload(root = base_path)
        loader.run()

        # Load migrations
        from migrate.versioning.api import version_control, db_version, version, upgrade
        db = Env.get('db_path')
        repo = os.path.join(base_path, 'couchpotato', 'core', 'migration')
        logging.getLogger('migrate').setLevel(logging.WARNING) # Disable logging for migration

        latest_db_version = version(repo)

        initialize = True
        try:
            current_db_version = db_version(db, repo)
            initialize = False
        except:
            version_control(db, repo, version = latest_db_version)
            current_db_version = db_version(db, repo)

        if current_db_version < latest_db_version and not debug:
            log.info('Doing database upgrade. From %d to %d' % (current_db_version, latest_db_version))
            upgrade(db, repo)

        # Configure Database
        from couchpotato.core.settings.model import setup
        setup()

        if initialize:
            fireEvent('app.initialize', in_order = True)

        fire_load = True

    # Create app
    from couchpotato import app
    api_key = Env.setting('api_key')
    url_base = '/' + Env.setting('url_base').lstrip('/') if Env.setting('url_base') else ''

    # Basic config
    app.secret_key = api_key
    config = {
        'use_reloader': reloader,
        'host': Env.setting('host', default = '0.0.0.0'),
        'port': tryInt(Env.setting('port', default = 5000))
    }

    # Static path
    app.static_folder = os.path.join(base_path, 'couchpotato', 'static')
    web.add_url_rule('%s/static/<path:filename>' % api_key,
                      endpoint = 'static',
                      view_func = app.send_static_file)

    # Register modules
    app.register_blueprint(web, url_prefix = '%s/' % url_base)
    app.register_blueprint(api, url_prefix = '%s/%s/' % (url_base, api_key))

    # Some logging and fire load event
    try: log.info('Starting server on port %(port)s' % config)
    except: pass
    if fire_load: fireEventAsync('app.load')

    # Go go go!
    app.run(**config)


import sqlite3
import argparse
from core import *
from weblogo import *
import pandas as pd

def get_transcript_sequence(transcript, organism_sqlite_cursor):
    '''
    return the nucleotide sequence for a given transcript as a string
    '''
    sequence = organism_sqlite_cursor.execute(
        f"SELECT sequence FROM transcripts WHERE transcript == '{transcript}'"
    ).fetchall()[0]

    return sequence[0]

def main(args):
    cursor = get_sqlite_cursor(args.s)

    openprot = read_openprot_annotations(args.transcripts)

    probs_df = pd.read_csv(args.p)
    init = []
    for row in probs_df.iterrows():
        init.append([f'{row[1]["transcript"]}_orf', row[1]["prob_uORF_init_rpb"], row[1]["prob_uORF_init_raw"]])
        init.append([f'{row[1]["transcript"]}_cds', row[1]["prob_cds_init_rpb"], row[1]["prob_cds_init_raw"]])

    init_df = pd.DataFrame(init, columns=[
                                'transcript',
                                'rpb_prob',
                                'raw_prob',
    ])
    print(init_df.sort_values('raw_prob'))
    unique_transcripts = list(probs_df['transcript'].unique())

    outfile = open(args.o, 'w')
    for row in openprot.iterrows():
        if "None" in list(row[1]):
            continue

        cds_start = int(row[1]['cds_start'])
        orf_start = int(row[1]['orf_start'])
        sequence = get_transcript_sequence(row[1]['transcript'], cursor)
        outfile.write(f">{row[1]['transcript']}_orf\n")
        outfile.write(f"{sequence[orf_start-10:orf_start+10]}\n")
        print(sequence[orf_start-1:orf_start+2])
        outfile.write(f">{row[1]['transcript']}_cds\n")
        outfile.write(f"{sequence[cds_start-10:cds_start+10]}\n")

    outfile.close
    return True

if __name__ == "__main__":
    parser = argparse.ArgumentParser()

    parser.add_argument("--transcripts", help="path to subset of openprot data ")
    parser.add_argument("-s", help="path to organism sqlite ")
    parser.add_argument("-p", help="path to probabilities csv")
    parser.add_argument("-o", help="path to output fasta file of sequences at start site")

    args = parser.parse_args()
    main(args)


import cv2

#设置高低阈值
lowThreshold = 0
max_lowThreshold = 100
ratio = 3
kernel_size = 3

img = cv2.imread('lenna.png')
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

def Canny(lowThreshold,ratio,img_gray):
    detected_edges = cv2.GaussianBlur(img_gray,(3,3),0) #高斯滤波处理
    detected_edges = cv2.Canny(detected_edges,
                               lowThreshold,
                               lowThreshold * ratio,
                               apertureSize=kernel_size)  # 边缘检测
    cv2.imshow('canny demo', detected_edges)
    cv2.waitKey()

Canny(0,ratio,img_gray)


# Даны два файла,
# в каждом из которых находится запись многочлена.
#  Задача - сформировать файл, содержащий сумму многочленов.
#  2*x² + 4*x + 5 3*x² +10*x + 6 Вывод: 5*x² + 14*x + 11

import sympy

with open('C:/GB_1/lecture_Py/file5.1DZ.txt', 'r') as file:
   list1 = file.read()
   print(list1)
with open('C:/GB_1/lecture_Py/file5.2DZ.txt', 'r') as file:
   list2 = file.read()
   print(list2)
sum = sympy.simplify(list1+ '+' + list2)
print(sum)
with open('C:/GB_1/lecture_Py/file5.3DZ.txt', 'w', encoding='utf-8') as file:
   file.write(str(sum))


import pygame
from snakeplayer import *
from scene import *
from Apple import *
import time

def display_info():

    """ Print out information about the"""
    """display driver and video information."""
    print('The display is using the "{}" driver.'.format(pygame.display.get_driver()))
    print('Video Info:')
    print(pygame.display.Info())

def main():

    print('hello world!')
    pygame.init()
    display_info()
    window_size = (800, 800)

    screen = pygame.display.set_mode(window_size)
    title = 'Snake++'
    pygame.display.set_caption(title)
    snake = SnakePlayer(screen)
    apple = Apple(screen, snake)
    scene_list = [TitleScene(screen, title, rgbcolors.green, 72),enterNameScreen(screen, title, rgbcolors.purple, 72), InstructionScene(screen, title,rgbcolors.grey, 72), GameLevel(screen, snake, apple)
    , GameOverScreen(screen,'Game Over',rgbcolors.red, 72), highScores(screen, title, 60)]
    #scene_list = [highScores(screen, title, 60)]

    for scene in scene_list:
        scene.play_music()
        while scene.is_valid():
            for e in pygame.event.get():
                scene.process_event(e)
            scene.update()
            scene.draw()
            pygame.display.update()
        scene.stop_music()
    pygame.quit()


import pytest
import torch
from flash.core.serve.types import Label, Repeated
from flash.core.utilities.imports import _TOPIC_SERVE_AVAILABLE

@pytest.mark.skipif(not _TOPIC_SERVE_AVAILABLE, reason="Not testing serve.")
def test_repeated_deserialize():
    repeated = Repeated(dtype=Label(classes=["classA", "classB"]))
    res = repeated.deserialize(*({"label": "classA"}, {"label": "classA"}, {"label": "classB"}))
    assert res == (torch.tensor(0), torch.tensor(0), torch.tensor(1))

@pytest.mark.skipif(not _TOPIC_SERVE_AVAILABLE, reason="Not testing serve.")
def test_repeated_serialize(session_global_datadir):
    repeated = Repeated(dtype=Label(path=str(session_global_datadir / "imagenet_labels.txt")))
    assert repeated.deserialize(*({"label": "chickadee"}, {"label": "stingray"})) == (
        torch.tensor(19),
        torch.tensor(6),
    )
    assert repeated.serialize((torch.tensor(19), torch.tensor(6))) == ("chickadee", "stingray")
    assert repeated.serialize(torch.tensor([19, 6])) == ("chickadee", "stingray")

@pytest.mark.skipif(not _TOPIC_SERVE_AVAILABLE, reason="Not testing serve.")
def test_repeated_max_len():
    repeated = Repeated(dtype=Label(classes=["classA", "classB"]), max_len=2)

    with pytest.raises(ValueError):
        repeated.deserialize(*({"label": "classA"}, {"label": "classA"}, {"label": "classB"}))
    assert repeated.deserialize(*({"label": "classA"}, {"label": "classB"})) == (
        torch.tensor(0),
        torch.tensor(1),
    )
    with pytest.raises(ValueError):
        repeated.serialize((torch.tensor(0), torch.tensor(0), torch.tensor(1)))
    assert repeated.serialize((torch.tensor(1), torch.tensor(0))) == ("classB", "classA")

    # max_len < 1
    with pytest.raises(ValueError):
        Repeated(dtype=Label(classes=["classA", "classB"]), max_len=0)
    assert Repeated(dtype=Label(classes=["classA", "classB"]), max_len=1) is not None

    # type(max_len) is not int
    with pytest.raises(TypeError):
        Repeated(dtype=Label(classes=["classA", "classB"]), max_len=str)

@pytest.mark.skipif(not _TOPIC_SERVE_AVAILABLE, reason="Not testing serve.")
def test_repeated_non_serve_dtype():
    class NonServeDtype:
        pass

    with pytest.raises(TypeError):
        Repeated(NonServeDtype())

@pytest.mark.skipif(not _TOPIC_SERVE_AVAILABLE, reason="Not testing serve.")
def test_not_allow_nested_repeated():
    with pytest.raises(TypeError):
        Repeated(dtype=Repeated())


# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

import uuid

from openstack.load_balancer.v2 import l7_rule
from openstack.tests.unit import base

EXAMPLE = {
    'admin_state_up': True,
    'compare_type': 'REGEX',
    'created_at': '2017-08-17T12:14:57.233772',
    'id': uuid.uuid4(),
    'invert': False,
    'key': 'my_cookie',
    'l7_policy_id': uuid.uuid4(),
    'operating_status': 'ONLINE',
    'project_id': uuid.uuid4(),
    'provisioning_status': 'ACTIVE',
    'type': 'COOKIE',
    'updated_at': '2017-08-17T12:16:57.233772',
    'value': 'chocolate',
}

class TestL7Rule(base.TestCase):
    def test_basic(self):
        test_l7rule = l7_rule.L7Rule()
        self.assertEqual('rule', test_l7rule.resource_key)
        self.assertEqual('rules', test_l7rule.resources_key)
        self.assertEqual(
            '/lbaas/l7policies/%(l7policy_id)s/rules', test_l7rule.base_path
        )
        self.assertTrue(test_l7rule.allow_create)
        self.assertTrue(test_l7rule.allow_fetch)
        self.assertTrue(test_l7rule.allow_commit)
        self.assertTrue(test_l7rule.allow_delete)
        self.assertTrue(test_l7rule.allow_list)

    def test_make_it(self):
        test_l7rule = l7_rule.L7Rule(**EXAMPLE)
        self.assertTrue(test_l7rule.is_admin_state_up)
        self.assertEqual(EXAMPLE['compare_type'], test_l7rule.compare_type)
        self.assertEqual(EXAMPLE['created_at'], test_l7rule.created_at)
        self.assertEqual(EXAMPLE['id'], test_l7rule.id)
        self.assertEqual(EXAMPLE['invert'], test_l7rule.invert)
        self.assertEqual(EXAMPLE['key'], test_l7rule.key)
        self.assertEqual(EXAMPLE['l7_policy_id'], test_l7rule.l7_policy_id)
        self.assertEqual(
            EXAMPLE['operating_status'], test_l7rule.operating_status
        )
        self.assertEqual(EXAMPLE['project_id'], test_l7rule.project_id)
        self.assertEqual(
            EXAMPLE['provisioning_status'], test_l7rule.provisioning_status
        )
        self.assertEqual(EXAMPLE['type'], test_l7rule.type)
        self.assertEqual(EXAMPLE['updated_at'], test_l7rule.updated_at)
        self.assertEqual(EXAMPLE['value'], test_l7rule.rule_value)

        self.assertDictEqual(
            {
                'limit': 'limit',
                'marker': 'marker',
                'created_at': 'created_at',
                'updated_at': 'updated_at',
                'project_id': 'project_id',
                'tags': 'tags',
                'any_tags': 'tags-any',
                'not_tags': 'not-tags',
                'not_any_tags': 'not-tags-any',
                'operating_status': 'operating_status',
                'provisioning_status': 'provisioning_status',
                'is_admin_state_up': 'admin_state_up',
                'compare_type': 'compare_type',
                'invert': 'invert',
                'key': 'key',
                'type': 'type',
                'rule_value': 'rule_value',
                'l7_policy_id': 'l7policy_id',
            },
            test_l7rule._query_mapping._mapping,
        )


import sys
import json
import numpy as np
import matplotlib.pyplot as plt

# ==========================
# *** Reading JSON files ***

# *** Reading for PMTs ***

def getAoPJson(filename, elecver):
    xst = []
    yaopHbpmt = []
    yaopHberrpmt = []
    yaopCapmt = []
    yaopCaerrpmt = []

    ydiffHbCa = []
    npmts = 3

    for pmt in range(0, npmts):
        tmpfile = open(filename+str(pmt+1)+".json", 'r')
        print("opened:", filename+str(pmt+1)+".json")
        tmpdata = json.load(tmpfile)
        tmpaveAoPHb = []
        tmperrAoPHb = []
        tmpaveAoPCa = []
        tmperrAoPCa = []
        for info in tmpdata[elecver]:
            tmpaveAoPHb.append( info['extAveAoPHb'] )
            tmperrAoPHb.append( info['extRmsAoPHb'] )
            tmpaveAoPCa.append( info['extAveAoPCa'] )
            tmperrAoPCa.append( info['extRmsAoPCa'] )

            if ( pmt==npmts-1 ):
                xst.append( info['stationId'] )
        yaopHbpmt.append( tmpaveAoPHb )
        yaopHberrpmt.append( tmperrAoPHb )
        yaopCapmt.append( tmpaveAoPCa )
        yaopCaerrpmt.append( tmperrAoPCa )

    return xst, yaopHbpmt, yaopHberrpmt, yaopCapmt, yaopCaerrpmt

basenameUub = "../fitaopmlt/uubFitaopPMT"
basenameUb = "../../nouub/fitHist/fitaopmlt/ubFitaopPMT"

outnameHbase = "../../plots/aopHbaseUubUbPMTs.png"
outnameCalib = "../../plots/aoCalibUubUbPMTs.png"

aopUub = getAoPJson(basenameUub, "uub")
aopUb = getAoPJson(basenameUb, "ub")
stLabel = []
npmts = 3

ubouub = 8.33/25.
markers = ['o', 's', '^']

# ==============================
# *** For AoP HBase Plotting ***
diffHb = []
tmpaopUub = np.array( aopUub[1] )
tmpaopUb = np.array( aopUb[1] )

for pmt in range(0, npmts):
    tmp = []
    for st in range(len(aopUub[0])):
        if tmpaopUub[pmt][st] > 4 and tmpaopUb[pmt][st] > 2:
            tmp.append( 1 - ( ubouub*tmpaopUub[pmt][st]/tmpaopUb[pmt][st] ) )
        else:
            tmp.append(1)
    diffHb.append(tmp)

yerr = []
for pmt in range(0, npmts):
    tmp = []
    for st in range( len(aopUub[0]) ):
        if aopUb[1][pmt][st] > 0:
            tmp.append( ( aopUub[2][pmt][st]/aopUb[1][pmt][st] )**2 + ( aopUb[2][pmt][st]*aopUub[1][pmt][st]/aopUb[1][pmt][st]**2 )**2 )
        else:
            tmp.append( 0 )
    yerr.append( np.sqrt( tmp ) )

plt.figure(figsize=(16,9))
for i in range(0, npmts):
    plt.errorbar(aopUub[0], diffHb[i], yerr=yerr[i], fmt=markers[i], markersize=12, label=" PMT"+str(i+1))

plt.legend(fontsize=22, loc=1)
plt.xlabel("Station Id.", fontsize=24)
plt.xticks(rotation=60)
plt.ylabel("(1 - (0,33*AoPuub)/AopUb) HBase [au]", fontsize=24)
plt.xticks(fontsize=22)
plt.yticks(fontsize=22)
plt.ylim(0, 0.6)
#plt.grid(axis='y', color='0.75')
#plt.show()
plt.tight_layout()
plt.savefig(outnameHbase, dpi=100)
print("Average AoP Peak-HBase OK")

tmpsum = []
tmpsum.append( [np.average(diffHb[pmt]) for pmt in range(3)] )
print(np.average(np.array(tmpsum)))

# ==============================
# *** For AoP Calib Plotting ***

diffHb = []
tmpaopUub = np.array( aopUub[3] )
tmpaopUb = np.array( aopUb[3] )

for pmt in range(0, npmts):
    tmp = []
    for st in range(len(aopUub[0])):
        if tmpaopUub[pmt][st] > 4 and tmpaopUb[pmt][st] > 2:
            tmp.append( 1 - ( ubouub*tmpaopUub[pmt][st]/tmpaopUb[pmt][st] ) )
        else:
            tmp.append(1)
    diffHb.append(tmp)

yerr = []
for pmt in range(0, npmts):
    tmp = []
    for st in range( len(aopUub[0]) ):
        if aopUb[1][pmt][st] > 0:
            tmp.append( ( aopUub[4][pmt][st]/aopUb[3][pmt][st] )**2 + ( aopUb[4][pmt][st]*aopUub[3][pmt][st]/aopUb[3][pmt][st]**2 )**2 )
        else:
            tmp.append( 0 )
    yerr.append( np.sqrt( tmp ) )

plt.figure(figsize=(16,9))
for i in range(0, npmts):
    plt.errorbar(aopUub[0], diffHb[i], yerr=yerr[i], fmt=markers[i], markersize=12, label=" PMT"+str(i+1))
    #plt.plot(aopUub[0], diffHb[i], markers[i], markersize=12, label=" PMT"+str(i+1))
plt.legend(fontsize=22, loc=1)
plt.xlabel("Station Id.", fontsize=24)
plt.xticks(rotation=60)
plt.ylabel("(1 - (0,33*AoPuub)/AopUb) Calib [au]", fontsize=24)
plt.xticks(fontsize=22)
plt.yticks(fontsize=22)
plt.ylim(0,0.6)
#plt.grid(axis='y', color='0.75')
#plt.show()
plt.tight_layout()
plt.savefig(outnameCalib, dpi=100)
print("Average AoP Peak-Calib OK")


__all__ = ['osh_core']

import time
from datetime import datetime
from os.path import join, exists
from typing import Tuple

from selenium.common.exceptions import *
from selenium.webdriver import Chrome, ChromeOptions, ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

from src.BusinessCentralLayer.middleware.flow_io import AliyunOSS
from src.BusinessCentralLayer.setting import *
from src.BusinessLogicLayer.plugins.faker_any import get_useragent

class _OnlineServiceHallSubmit(object):

    def __init__(self, silence=True, anti=True, debug=False, only_get_screenshot=True) -> None:

        self.url = 'https://ehall.hainanu.edu.cn/qljfwapp/sys/lwHainanuStuTempReport/*default/index.do#/stuTempReport'

        self.debug = debug
        self.only_get_screenshot = only_get_screenshot
        self.silence = silence
        self.anti = anti

        self.osh_model_today = join(SERVER_DIR_SCREENSHOT, str(datetime.now(TIME_ZONE_CN)).split(' ')[0])

        self._check_model()

    # ----------------------------------
    # Public API
    # ----------------------------------
    def rush_cookie_pool(self, user, kernel: str = 'admin') -> Tuple[int, str]:
        api_: Chrome = self._set_startup_option()

        try:
            # 模拟登入
            login_status = self._login(api_, user)
            if login_status == 302:
                logger.warning(f'FAILED -- {user["username"]}-- {OSH_STATUS_CODE[login_status]} -- 网络状况较差或OSH接口繁忙')
                return 302, user['username']
            # 获取SUPER_USER_COOKIE
            time.sleep(1)
            WebDriverWait(api_, 10).until(EC.element_located_to_be_selected)
            cookie: dict or None = api_.get_cookie('MOD_AMP_AUTH')
            # 若cookie有效则进行cookie缓存操作
            if cookie and isinstance(cookie, dict):
                user_cookie: str = f'{cookie.get("name")}={cookie.get("value")};'
                logger.info(f'Get Superuser Cookie -- {user_cookie}')
                # 根据不同的接入模式，使用不同的解决方案存储cookie
                if kernel == 'admin':
                    with open(SERVER_PATH_COOKIES, 'w', encoding='utf-8') as f:
                        f.write(user_cookie)
                elif kernel == 'general':
                    cache_path = os.path.join(SERVER_DIR_CACHE_FOR_TIMER, f'{user["username"]}.txt')
                    with open(cache_path, 'w', encoding='utf-8') as f:
                        f.write(user_cookie)
                return 400, user_cookie
            else:
                return 403, user['username']
        finally:
            self._kill(api_)

    def run(self, user) -> Tuple[int, str] or Tuple[int, BaseException, str]:
        """
        服务器部署后，必须使用Silence Login 方案，而此时对于任务提交的调试有暂时无法攻克的技术难题
        故不要在部署后使用此模块进行表单提交，而应使用osh-runner
        :param user:
        :return:
        """

        # # 若今日已签到则无需登入
        # model_status = self._check_model(user, check_way='oss')
        # if model_status == 900:
        #     logger.info(f'<OshCore> IGNORE {user["username"]} || {OSH_STATUS_CODE[model_status]}')
        #     return model_status, user['username']

        # logger.info(f'<OshCore> Run OnlineServiceHallSubmit || {user["username"]}')

        # 共享任务句柄
        api_: Chrome = self._set_startup_option()

        try:
            # 模拟登入
            login_status = self._login(api_, user)
            if login_status == 302:
                logger.warning(
                    f'<OshCore> FAILED || 网络状况较差或OSH接口繁忙 || {user["username"]} {OSH_STATUS_CODE[login_status]}')
                return login_status, user['username']

            # 跳转到最新打卡页面
            stu_status: int = self._goto_sign_up(api_, user)

            # 在执行_goto_sign_up时已自动保存并上传任务页截图
            # 若启动该分支仅需完成此需求，请立即结束后续操作
            if self.only_get_screenshot:
                self.print_debug_msg("<OshCore> OnlyGetScreenshot || quick driver")
                return stu_status, user["username"]

            # 若需使用本分支执行签到操作，则根据“是否已签到”决定是否执行签到任务
            # 可签到 -> submit
            if stu_status == 903:
                self._submit(api_, user)
                return 300, user["username"]
            else:
                return stu_status, user["username"]

        # NoneType: 用户无任何待处理表单，意味着该用户不适用当前签到方案
        except TypeError as e:
            logger.warning(f'{user["username"]} -- {OSH_STATUS_CODE[304]}')
            return 304, e, user["username"]
        # 未知异常
        except WebDriverException as e:
            logger.exception(f'{user["username"]} -- {e}')
            return 301, e, user["username"]
        # 垃圾回收
        finally:
            self._kill(api_)

    # ----------------------------------
    # Private API
    # ----------------------------------

    def _check_model(self, user=None, check_way='init') -> bool or int:
        if check_way == 'init':
            if not exists(self.osh_model_today):
                os.mkdir(self.osh_model_today)
                logger.info(f'今日首次打卡进程启动，已初始化文档树')
                return True

        elif check_way == 'stale':
            if "{}.png".format(user['username']) in os.listdir(self.osh_model_today):
                return 900

        elif check_way == 'oss':
            if AliyunOSS().snp_exist(user['username']):
                return 900
        else:
            return False

    def _set_startup_option(self) -> Chrome:
        """
        ChromeDriver settings
        @return:
        """

        self.print_debug_msg("初始化驱动")

        options = ChromeOptions()

        # 最高权限运行
        options.add_argument('--no-sandbox')

        # 隐身模式
        options.add_argument('-incognito')

        # 无缓存加载
        # options.add_argument('--disk-cache-')

        # 设置中文
        options.add_argument('lang=zh_CN.UTF-8')

        options.add_experimental_option('excludeSwitches', ['enable-automation'])

        # 更换头部
        options.add_argument(f'user-agent={get_useragent()}')

        # 静默启动
        if self.silence is True:
            options.add_argument('--headless')

        if not self.anti:
            chrome_pref = {"profile.default_content_settings": {"Images": 2, 'javascript': 2},
                           "profile.managed_default_content_settings": {"Images": 2},
                           }
            options.experimental_options['prefs'] = chrome_pref

        return Chrome(options=options, executable_path=CHROMEDRIVER_PATH)

    def _login(self, api: Chrome, user, retry_num=0, max_retry=3) -> bool or int:

        # FIXME: 加入用户密码错误鉴别
        # 重试次数达到阈值
        if retry_num >= max_retry:
            return 302

        api.get(self.url)
        try:
            if not self.anti:
                time.sleep(1)
            WebDriverWait(api, 10).until(EC.presence_of_element_located((By.ID, "username"))).send_keys(
                user['username'])
            api.find_element_by_id('password').send_keys(user['password'])
            api.find_element_by_tag_name('button').click()

            self.print_debug_msg("模拟登录成功")
            return True
        except TimeoutException or NoSuchElementException:
            retry_num += 1
            api.refresh()
            self._login(api, user, retry_num)
        except StaleElementReferenceException:
            time.sleep(1.2)
            self._login(api, user, retry_num)

    @staticmethod
    def _check_status(element) -> int:
        """

        :param element: API定位的最新任务元素
        :return:
        """

        # 解压数据
        stu_missions = {}
        i = 1
        stu_info: list = element.text.split('\n')
        while i < element.text.split('\n').__len__() - 1:
            stu_missions.update({stu_info[i]: stu_info[i + 1]})
            i += 2

        # 今日签到任务tag已成功定位，但未抵达任务开放时间，此时默认上报状态为false
        if datetime.fromisoformat(stu_missions.get('上报开始时间')) > datetime.now(TIME_ZONE_CN).now():
            return 901
        else:
            # 今日/昨日 任务已签到
            if stu_missions.get('是否上报') == '是':
                return 902
            # 今日/昨日 任务未签到
            elif stu_missions.get('是否上报') == '否':
                return 903

        # if stu_missions.get('是否上报') == '是':
        #     return 902
        # elif stu_missions.get('是否上报') == '否':
        #     if datetime.fromisoformat(stu_missions.get('上报开始时间')) > datetime.now(TIME_ZONE_CN).now():
        #         return 901
        #     else:
        #         return 903

    def print_debug_msg(self, msg: str):
        if self.debug:
            print(msg)

    def _goto_sign_up(self, api: Chrome, user=None, retry_num=0, max_retry=3) -> int:
        """

        :param api:
        :param user:
        :param retry_num:
        :param max_retry:
        :return:
        """
        # 超时中断
        if retry_num >= max_retry:
            logger.debug(f'FAILED -- {user["username"]}-- 该测试用例异常，可能原因为：账号密码错误或网络异常')
            return False

        try:
            # 获取最新任务tag
            time.sleep(1)
            latest_mission = WebDriverWait(api, 50).until(EC.presence_of_element_located((
                By.XPATH,
                "//div[@class='mint-layout-container cjarv696w']"
            )))

            # 查询任务状态
            task_status = self._check_status(latest_mission)

            # 可签到
            if task_status == 903:
                if self.only_get_screenshot:
                    logger.error(f"<OshCore> {user['username']} || 截图捕获失败，今日签到任务未执行。")
                latest_mission.click()

            # 已签到
            elif task_status == 902:
                # logger.info(f"{user['username']} -- {OSH_STATUS_CODE[task_status]}")
                self._save_log(api, user)
                # logger.success(f"{user['username']} -- 截图上传成功")

            # 未开放
            elif task_status == 901:
                logger.warning(f'{user["username"]} -- {OSH_STATUS_CODE[task_status]}')
            return task_status

        # 元素更新/任务超时/网络通信异常
        except NoSuchElementException or TimeoutException:
            retry_num += 1
            logger.debug(f'{user["username"]} -- 任务超时，重试次数{retry_num}')
            self._goto_sign_up(api, retry_num=retry_num)

    def _submit(self, api: Chrome, user=None):

        def _scroll_the_window():
            actions = ActionChains(api)
            actions.key_down(Keys.END).perform()
            actions.reset_actions()

        def _click_temperature_selection_bar(retry=0, max_retry=10):
            try:
                time.sleep(1)
                _scroll_the_window()
                api.find_element_by_xpath("//div[@class='__em-selectlist']").click()
            except ElementClickInterceptedException:
                if retry <= max_retry:
                    retry += 1
                    _click_temperature_selection_bar(retry=retry)

        def _click_confirm_button_of_the_temperature():
            time.sleep(1)
            api.find_element_by_xpath("//div[@visible-item-count]//div[contains(@class,'confirm')]").click()

        def _click_submit_button_of_the_temperature():
            time.sleep(0.5)
            api.find_element_by_xpath(
                "//button[@class='mint-button flowEditButton mt-btn-primary mint-button--normal']").click()

        def _click_submit_button_of_the_form():
            try:
                self.print_debug_msg("尝试捕获弹窗")
                time.sleep(0.5)
                err_ = api.find_element_by_xpath("//div[contains(@class,'mint-msgbox-message')]")
                # api.find_element_by_class_name("mint-msgbox-content").text
                if err_ is not None:
                    logger.error(f"<OshCore> {user['username']} || {err_.text}")
            except NoSuchElementException:
                print("123123123")
                pass

            time.sleep(0.5)
            api.find_element_by_xpath("//button[@class='mint-msgbox-btn mint-msgbox-confirm mt-btn-primary']").click()

        def _generate_behavior_response():
            response = self._save_log(api, user, status_='goto')
            if response:
                logger.success(f"<OshCore> {user['username']} || 签到成功")
            else:
                logger.warning(f"<OshCore> {user['username']} || 签到异常")

        # 进入[体温签到页面]
        api.find_element_by_id("app").click()
        self.print_debug_msg("进入[体温签到页面]")

        # 点击[体温选择栏]
        _click_temperature_selection_bar()
        self.print_debug_msg("点击[体温选择栏]")

        # [确认]体温
        _click_confirm_button_of_the_temperature()
        self.print_debug_msg("[确认]体温")

        # 点击[提交数据]按钮
        _click_submit_button_of_the_temperature()
        self.print_debug_msg("点击[提交数据]按钮")

        # 点击[确认提交数据]按钮
        _click_submit_button_of_the_form()
        self.print_debug_msg("点击[确认提交数据]按钮")

        # 判断签到状态 并上传截图
        _generate_behavior_response()
        self.print_debug_msg("判断签到状态 并上传截图")

    def _save_log(self, api: Chrome, user, status_='wait') -> bool:
        """

        :param api:
        :param user:
        :param status_: wait:已签到 ，goto：刚签到，返回上一级后截图
        :return:
        """

        if status_ == 'wait':
            api.save_screenshot(join(self.osh_model_today, f"{user['username']}.png"))
            AliyunOSS().upload_base64(api.get_screenshot_as_base64(), user['username'])
            return True
        elif status_ == 'goto':
            api.back()
            time.sleep(0.5)
            if self._check_status(api.find_element_by_xpath("//div[@class='mint-layout-container cjarv696w']")) == 902:
                self._save_log(api, user)
                return True
            else:
                return False
        else:
            return False

    @staticmethod
    def _kill(api: Chrome) -> None:
        api.delete_all_cookies()
        api.quit()

osh_core = _OnlineServiceHallSubmit


from __future__ import print_function

import kubernetes
import psycopg2
import subprocess
import os
import datetime
import time
import itertools
import base64

# Parameters:
BUCKET = os.environ['S3_BUCKET']
NAMESPACE = os.environ['S3_NAMESPACE']
ACCESS_KEY = os.environ['AWS_ACCESS_KEY']
SECRET_KEY = os.environ['AWS_SECRET_KEY']
HOST = os.environ.get('S3_HOST', 's3.amazonaws.com')
HOST_BUCKET = os.environ.get('S3_HOST_BUCKET', '%(bucket)s.s3.amazonaws.com')
s3cmd = 's3cmd --access_key="%s" --secret_key="%s" --host="%s" --host-bucket="%s"' % (ACCESS_KEY, SECRET_KEY, HOST, HOST_BUCKET)
bucket_prefix = 's3://%s/db_backups/%s' % (BUCKET, NAMESPACE)

def get_latest_md5(db_name, table):
    cmd = '%s ls %s/%s/%s/' % (s3cmd, bucket_prefix, db_name, table)
    current_files = subprocess.Popen(['/bin/sh', '-c', cmd], stdout=subprocess.PIPE)
    current_files, _ = current_files.communicate()
    current_files = current_files.split('\n')
    current_files = [line.split() for line in current_files if line.strip() != '']
    current_files.sort(key=lambda line: line[0]+' '+line[1])
    if len(current_files) == 0:
        return None
    else:
        return current_files[-1][-1].split('.')[-3]  # the md5 hash

def handle_table(db_url, table):
    start = time.time()
    db_name = db_url.split('/')[-1]
    # print('\tGot table "%s/%s"' % (db_name, table))
    latest_hash = get_latest_md5(db_name, table)
    # print('\tExisting hash "%s"' % latest_hash)
    cmd = 'pg_dump -t "%s" "%s" | gzip | md5sum' % (table, db_url)
    # print('#',cmd)
    proc = subprocess.Popen(['/bin/sh', '-c', cmd], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    current_hash, _ = proc.communicate()
    current_hash = current_hash.split()[0][:6]
    # print('\tCurrent hash "%s"' % (current_hash, ))
    if latest_hash is None:
        status = 'NEW'
    elif current_hash != latest_hash:
        status = 'MODIFIED'
    else:
        status = 'SAME'
    if status != 'SAME':
        filename = '%s/%s/%s/%s.%s.%s.%s.pg_dump.gz' % \
                   (bucket_prefix, db_name, table, db_name, table, datetime.datetime.now().date().isoformat(), current_hash)
        cmd = '%s put --no-progress --no-encrypt - %s' % (s3cmd, filename)
        cmd = 'pg_dump -t "%s" "%s" | gzip | %s ' % \
              (table, db_url, cmd)
        # print('#',cmd)
        proc = subprocess.Popen(['/bin/sh', '-c', cmd], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        out, err = proc.communicate()
        print(out, err)
        # print('-->', proc.returncode)
    print('\tTable %s: %s, %d secs' % (table, status, int(time.time() - start)))

def handle_db(db_url):
    start = time.time()
    print('Encountered DB URL %s' % db_url)
    conn = psycopg2.connect(db_url)
    cursor = conn.cursor()
    cursor.execute("""SELECT table_name FROM information_schema.tables
                      WHERE table_schema = 'public'""")
    count = 0
    for table in cursor.fetchall():
        table = table[0]
        handle_table(db_url, table)
        count += 1
    print('\tDB %s: %d tables, %d secs' % (db_url, count, int(time.time() - start)))

def get_services():
    all_urls = set()
    try:
        kubernetes.config.incluster_config.load_incluster_config()
    except Exception as e:
        print(e)
        print('attempting local kube config')
        kubernetes.config.load_kube_config()
    kubev1 = kubernetes.client.CoreV1Api()
    containers = itertools.chain(*[pod.spec.containers for pod
                                   in kubev1.list_pod_for_all_namespaces(watch=False).items])
    envvars = itertools.chain(*[container.env for container in containers if container.env])
    secrets = {s.metadata.name: s.data for s in kubev1.list_secret_for_all_namespaces(watch=False).items}
    for envvar in envvars:
        if envvar.name == 'DATABASE_URL' and envvar.value_from and envvar.value_from.secret_key_ref:
            secret = secrets.get(envvar.value_from.secret_key_ref.name)
            if secret:
                db_url = secret.get(envvar.value_from.secret_key_ref.key)
                if db_url:
                    db_url = base64.b64decode(db_url).decode()
                    if db_url not in all_urls:
                        handle_db(db_url)
                        all_urls.add(db_url)

if __name__ == "__main__":
    get_services()


"""

@author: su
"""
import pygame
import random #隨機模組
import os

HEIGHT = 600
WIDTH = 500

BLUE = (61, 89, 171)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
YELLOW = (255, 255, 0)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)

FPS = 60

#遊戲初始化 and 創建視窗
pygame.init()
#音效初始化
pygame.mixer.init()
screen = pygame.display.set_mode((WIDTH,HEIGHT))
pygame.display.set_caption("飛行船遊戲")
clock = pygame.time.Clock()
running = True

#載入圖片
#匯入img資料夾中的background
background_img = pygame.image.load(os.path.join("img", "background.png")).convert()
player_img = pygame.image.load(os.path.join("img", "player.png")).convert()
player_mini_img = pygame.transform.scale(player_img, (25, 19))
player_mini_img.set_colorkey(BLACK)
pygame.display.set_icon(player_mini_img)
bullet_img = pygame.image.load(os.path.join("img", "bullet.png")).convert()
rock_imgs = []
#載入七種不同的石頭
rock_imgs = []
for i in range(7):
    rock_imgs.append(pygame.image.load(os.path.join("img", f"rock{i}.png")).convert())
    #字串前加f就可以在字串中使用變數
expl_anim = {}
expl_anim['lg'] = []
expl_anim['sm'] = []
expl_anim['player'] = []
for i in range(9):
    expl_img = pygame.image.load(os.path.join("img", f"expl{i}.png")).convert()
    expl_img.set_colorkey(BLACK)
    expl_anim['lg'].append(pygame.transform.scale(expl_img, (75, 75)))
    expl_anim['sm'].append(pygame.transform.scale(expl_img, (30, 30)))
    player_expl_img = pygame.image.load(os.path.join("img", f"player_expl{i}.png")).convert()
    player_expl_img.set_colorkey(BLACK)
    expl_anim['player'].append(player_expl_img)
power_imgs = {}
power_imgs['shield'] = pygame.image.load(os.path.join("img", "shield.png")).convert()
power_imgs['gun'] = pygame.image.load(os.path.join("img", "gun.png")).convert()

#載入音樂
shoot_sound = pygame.mixer.Sound(os.path.join("sound", "shoot.wav"))
gun_sound = pygame.mixer.Sound(os.path.join("sound", "pow1.wav"))
shield_sound = pygame.mixer.Sound(os.path.join("sound", "pow0.wav"))
die_sound = pygame.mixer.Sound(os.path.join("sound", "rumble.ogg"))
expl_sounds = [
    pygame.mixer.Sound(os.path.join("sound", "expl0.wav")),
    pygame.mixer.Sound(os.path.join("sound", "expl1.wav"))
]
pygame.mixer.music.load(os.path.join("sound", "background.ogg"))
pygame.mixer.music.set_volume(0.4)

#顯示分數
font_name = os.path.join("font.ttf") #載入字體
def draw_text(surf, text, size, x, y): #字要寫在哪個平面、寫甚麼、字的大小跟位置
    font =  pygame.font.Font(font_name, size)
    text_surface = font.render(text, True, WHITE)
    text_rect = text_surface.get_rect()
    text_rect.centerx = x
    text_rect.top = y
    surf.blit  (text_surface, text_rect)

def new_rock():
    rock = Rock()
    all_sprites.add(rock)
    rocks.add(rock) #須加回石頭群組才能繼續做碰撞判斷

def draw_health(surf, hp, x, y):
    if hp < 0:
        hp = 0
    BAR_LENGTH = 100
    BAR_HEIGHT = 10
    fill = (hp/100)*BAR_LENGTH
    outline_rect = pygame.Rect(x, y, BAR_LENGTH, BAR_HEIGHT) #外框
    fill_rect = pygame.Rect(x, y, fill, BAR_HEIGHT) #血條
    #畫出外框及血條
    pygame.draw.rect(surf, GREEN, fill_rect)
    pygame.draw.rect(surf,  WHITE, outline_rect, 2)

def draw_lives(surf, lives, img, x, y):
    for i in range(lives):
        img_rect = img.get_rect()
        img_rect.x = x + 32*i
        img_rect.y = y
        surf.blit(img, img_rect)

def draw_init():
    screen.blit(background_img, (0,0))
    draw_text(screen, '太空生存戰!', 64, WIDTH/2, HEIGHT/4)
    draw_text(screen, '← →移動飛船 空白鍵發射子彈~', 22, WIDTH/2, HEIGHT/2)
    draw_text(screen, '按任意鍵開始遊戲!', 18, WIDTH/2, HEIGHT*3/4)
    pygame.display.update()
    waiting = True
    while waiting:
        clock.tick(FPS)
        # 取得輸入
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                return True
            elif event.type == pygame.KEYDOWN:
                waiting = False
                return False

class Player(pygame.sprite.Sprite):

    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.transform.scale(player_img, (50, 38)) #替換飛船圖片並將其大小轉為(50, 38)
        self.image.set_colorkey(BLACK) #把黑色變透明
        self.rect = self.image.get_rect()
        self.radius = 20 #給予飛船判斷圓形碰撞的半徑
        # 控制方塊初始位置
        self.rect.centerx = WIDTH / 2
        self.rect.bottom = HEIGHT - 10
        #控制方塊移動速度
        self.speedx = 8
        self.speedy = 8
        self.health = 100 #飛船生命值
        self.lives = 3
        self.hidden = False
        self.hide_time = 0
        self.gun = 1
        self.gun_time = 0

    def update(self):
        now = pygame.time.get_ticks()
        if self.gun > 1 and now - self.gun_time > 5000:
            self.gun -= 1
            self.gun_time = now

        if self.hidden and now - self.hide_time > 1000:
            self.hidden = False
            self.rect.centerx = WIDTH / 2
            self.rect.bottom = HEIGHT - 10

        key_pressed = pygame.key.get_pressed() #判斷鍵盤按鍵是否被按下
        #控制方塊左右移動
        if key_pressed[pygame.K_RIGHT]:
            self.rect.x += self.speedx
        if key_pressed[pygame.K_LEFT]:
            self.rect.x -= self.speedx
        #控制方塊上下移動
        if key_pressed[pygame.K_UP]:
            self.rect.y -= self.speedy
        if key_pressed[pygame.K_DOWN]:
            self.rect.y += self.speedy
        #控制方塊移動邊界
        if self.rect.right > WIDTH:
            self.rect.right = WIDTH
        if self.rect.left < 0:
            self.rect.left = 0
        if self.rect.top < HEIGHT/2:
            self.rect.top = HEIGHT/2
        if self.rect.bottom > HEIGHT:
            self.rect.bottom = HEIGHT

    def shoot(self):
        if not(self.hidden):
            if self.gun == 1:
                bullet = Bullet(self.rect.centerx, self.rect.top)
                all_sprites.add(bullet)
                bullets.add(bullet)
                shoot_sound.play()
            elif self.gun >=2:
                bullet1 = Bullet(self.rect.left, self.rect.centery)
                bullet2 = Bullet(self.rect.right, self.rect.centery)
                all_sprites.add(bullet1)
                all_sprites.add(bullet2)
                bullets.add(bullet1)
                bullets.add(bullet2)
                shoot_sound.play()

    def hide(self):
        self.hidden = True
        self.hide_time = pygame.time.get_ticks()
        self.rect.center = (WIDTH/2, HEIGHT+500)

    def gunup(self):
        self.gun += 1
        self.gun_time = pygame.time.get_ticks()

class Rock(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image_original = random.choice(rock_imgs) #從列表中隨機挑選一張石頭圖片
        self.image_original.set_colorkey(BLACK) #把黑色變透明
        self.image = self.image_original.copy()

        self.rect = self.image.get_rect()
        self.radius = int(self.rect.width * 0.85 / 2)
        # 控制石頭初始位置
        self.rect.x = random.randrange(0, WIDTH - self.rect.width)
        self.rect.y = random.randrange(-150, -100)  #從視窗外隨機生成掉落
        #控制石頭掉落速度
        self.speedy = random.randrange(2, 8)
        #控制石頭水平移動速度
        self.speedx =random.randrange(-3, 3)
        #石頭轉動角度
        self.total_degree = 0
        self.rotate_degree = random.randrange(-3, 3)
    #石頭動畫
    def rotate(self):
        self.total_degree += self.rotate_degree
        self.total_degree = self.total_degree % 360
        self.image = pygame.transform.rotate(self.image_original, self.total_degree)
        center = self.rect.center#原先圖片的中心點
        self.rect = self.image.get_rect()
        self.rect.center = center
    def update(self):
        #石頭旋轉
        self.rotate()
        #更新石頭的速度
        self.rect.y += self.speedy
        self.rect.x += self.speedx
        #若石頭超出視窗則重置
        if self.rect.top > HEIGHT or self.rect.right < 0 or self.rect.left > WIDTH:
            self.rect.x = random.randrange(0, WIDTH - self.rect.width)
            self.rect.y = random.randrange(-100, -40)
            self.speedy = random.randrange(2, 8)
            self.speedx =random.randrange(-3, 3)

class Bullet(pygame.sprite.Sprite):
    def __init__(self, x, y): #子彈由飛船位置決定，所以需傳入飛船的x,y
        pygame.sprite.Sprite.__init__(self)
        self.image = bullet_img
        self.image.set_colorkey(BLACK) #把黑色變透明

        self.rect = self.image.get_rect()
        # 控制子彈初始位置
        self.rect.centerx = x
        self.rect.bottom = y
        #控制子彈速度
        self.speedy = -10

    def update(self):
        #更新子彈速度
        self.rect.y += self.speedy
        #判斷子彈超出視窗則刪除
        if self.rect.bottom < 0:
            self.kill()

class Explosion(pygame.sprite.Sprite):
    def __init__(self, center, size):
        pygame.sprite.Sprite.__init__(self)
        self.size = size
        self.image = expl_anim[self.size][0]
        self.rect = self.image.get_rect()
        self.rect.center = center
        self.frame = 0
        self.last_update = pygame.time.get_ticks()
        self.frame_rate = 50

    def update(self):
        now = pygame.time.get_ticks()
        if now - self.last_update > self.frame_rate:
            self.last_update = now
            self.frame += 1
            if self.frame == len(expl_anim[self.size]):
                self.kill()
            else:
                self.image = expl_anim[self.size][self.frame]
                center = self.rect.center
                self.rect = self.image.get_rect()
                self.rect.center = center

class Power(pygame.sprite.Sprite):
    def __init__(self, center):
        pygame.sprite.Sprite.__init__(self)
        self.type = random.choice(['shield', 'gun'])
        self.image = power_imgs[self.type]
        self.image.set_colorkey(BLACK)
        self.rect = self.image.get_rect()
        self.rect.center = center
        self.speedy = 3

    def update(self):
        self.rect.y += self.speedy
        if self.rect.top > HEIGHT:
            self.kill()

pygame.mixer.music.play(-1)

# 遊戲迴圈
show_init = True
running = True
while running:
    if show_init:
        close = draw_init()
        if close:
            break
        show_init = False
        all_sprites = pygame.sprite.Group()
        rocks = pygame.sprite.Group()
        bullets = pygame.sprite.Group()
        powers = pygame.sprite.Group()
        player = Player()
        all_sprites.add(player)
        for i in range(8):
            new_rock()
        score = 0

    clock.tick(FPS)
    # 取得輸入
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                player.shoot()

    # 更新遊戲
    all_sprites.update()
    # 判斷石頭 子彈相撞
    hits = pygame.sprite.groupcollide(rocks, bullets, True, True)
    for hit in hits:
        random.choice(expl_sounds).play()
        score += hit.radius
        expl = Explosion(hit.rect.center, 'lg')
        all_sprites.add(expl)
        if random.random() > 0.9:
            pow = Power(hit.rect.center)
            all_sprites.add(pow)
            powers.add(pow)
        new_rock()

    # 判斷石頭 飛船相撞
    hits = pygame.sprite.spritecollide(player, rocks, True, pygame.sprite.collide_circle)
    for hit in hits:
        new_rock()
        player.health -= hit.radius * 2
        expl = Explosion(hit.rect.center, 'sm')
        all_sprites.add(expl)
        if player.health <= 0:
            death_expl = Explosion(player.rect.center, 'player')
            all_sprites.add(death_expl)
            die_sound.play()
            player.lives -= 1
            player.health = 100
            player.hide()

    # 判斷寶物 飛船相撞
    hits = pygame.sprite.spritecollide(player, powers, True)
    for hit in hits:
        if hit.type == 'shield':
            player.health += 20
            if player.health > 100:
                player.health = 100
            shield_sound.play()
        elif hit.type == 'gun':
            player.gunup()
            gun_sound.play()

    if player.lives == 0 and not(death_expl.alive()):
        show_init = True

    # 畫面顯示
    screen.fill(BLACK)
    screen.blit(background_img, (0,0))
    all_sprites.draw(screen)
    draw_text(screen, str(score), 18, WIDTH/2, 10)
    draw_health(screen, player.health, 5, 15)
    draw_lives(screen, player.lives, player_mini_img, WIDTH - 100, 15)
    pygame.display.update()

pygame.quit()