import JsonUtils
import ResultEvaluationUtils
from SituationSegmenter import SituationSegmenter
from SensingEvent import SensingEvent
from FrequencyPredictor import FrequencyPredictor
from TreePredictor import TreePredictor
import time
from multiprocessing import Process

def generateSensingEvent(timeIndex, sequenceInstanceJson, inputsForPredictionIndices, inputInfo):
        inputValues = [sequenceInstanceJson[str(inputIndex)][timeIndex] for inputIndex in inputsForPredictionIndices]
        return SensingEvent(inputInfo, inputValues, sequenceInstanceJson['situation_id'][timeIndex])

def generateEmotionIDs(timeIndex, sequenceInstanceJson, aversiveInputIndexs, aversiveThresholdValues):
        inputAversiveValues = [sequenceInstanceJson[str(inputIndex)][timeIndex] for inputIndex in aversiveInputIndexs]
        numAversiveIndexes = len(inputAversiveValues)
        emotionIDs = [inputIndex for inputIndex in range(numAversiveIndexes) if inputAversiveValues[inputIndex] < aversiveThresholdValues[inputIndex]]
        return emotionIDs

def comparePredictions(in_truth, in_prediction):
    if in_truth == -1:
        return 'ig'
    if in_prediction == 1:
        if in_prediction == in_truth:
            return 'tp'
        else:
            return 'fp'
    else:
        if in_prediction == in_truth:
            return 'tn'
        else:
            return 'fn'

def calculateCumulativePredictionTypes(in_numAvailableGroundTruth, in_predictionResults):

    allEmotionIDs = in_predictionResults[0][1].keys()
    truePositives = {k:[] for k in allEmotionIDs}
    falsePositives = {k:[] for k in allEmotionIDs}
    trueNegatives = {k:[] for k in allEmotionIDs}
    falseNegatives = {k:[] for k in allEmotionIDs}
    cumulativeResults = {k:dict({'tp':0,'fp':0,'tn':0,'fn':0,'ig':0}) for k in allEmotionIDs}
    for i in range(in_numAvailableGroundTruth):
        correctPrediction = {k:in_predictionResults[i][0].m_predictiveMap.get(k, 0) for k in allEmotionIDs} # assumes defaulting to 0
        actualPrediction = {k:in_predictionResults[i][1][k] for k in allEmotionIDs}
        comparison = {k: comparePredictions(correctPrediction[k], actualPrediction[k]) for k in allEmotionIDs}
        for k in allEmotionIDs:
            cumulativeResults[k][comparison[k]] += 1
        for k in allEmotionIDs:
            truePositives[k].append(cumulativeResults[k]['tp'])
            falsePositives[k].append(cumulativeResults[k]['fp'])
            trueNegatives[k].append(cumulativeResults[k]['tn'])
            falseNegatives[k].append(cumulativeResults[k]['fn'])
    return {'tp':truePositives, 'fp':falsePositives, 'tn':trueNegatives, 'fn':falseNegatives}

def recreateResultsAtIndexFromCumulativePredictionTypes(in_index, in_cumulativePredictionTypes):
    return {k: {'tp': in_cumulativePredictionTypes['tp'][k][in_index], 'fp': in_cumulativePredictionTypes['fp'][k][in_index], 'tn': in_cumulativePredictionTypes['tn'][k][in_index], 'fn': in_cumulativePredictionTypes['fn'][k][in_index]} for k in in_cumulativePredictionTypes['tp'].keys()}

def calculateCumulativeMeasure(in_measure, in_cumulativePredictionTypes, in_initialIgnoreRatio = 0.0, in_nonEvalValue = 0.0):
    allEmotionIDs = [k for k in in_cumulativePredictionTypes['tp'].keys()]
    totalGroundTruth = len(in_cumulativePredictionTypes['tp'][allEmotionIDs[0]])
    baseIndex = int(in_initialIgnoreRatio*totalGroundTruth)
    baseResult = recreateResultsAtIndexFromCumulativePredictionTypes(baseIndex, in_cumulativePredictionTypes)
    measureResults = {k:[in_nonEvalValue for i in range(baseIndex+1)] for k in allEmotionIDs}
    for k in measureResults:
        for i in range(baseIndex+1,totalGroundTruth):
            currentResult = recreateResultsAtIndexFromCumulativePredictionTypes(i, in_cumulativePredictionTypes)
            funcReturn =  ResultEvaluationUtils.resultFormatCall(in_measure, in_result=currentResult[k], in_baseResult=baseResult[k])
            measureResults[k].append(funcReturn)
    return measureResults

def calculateLastResultMeasure(in_measure, in_cumulativePredictionTypes, in_initialIgnoreRatio = 0.0):
    allEmotionIDs = [k for k in in_cumulativePredictionTypes['tp'].keys()]
    totalGroundTruth = len(in_cumulativePredictionTypes['tp'][allEmotionIDs[0]])
    baseIndex = int(in_initialIgnoreRatio*totalGroundTruth)
    baseResult = recreateResultsAtIndexFromCumulativePredictionTypes(baseIndex, in_cumulativePredictionTypes)
    finalResult = recreateResultsAtIndexFromCumulativePredictionTypes(-1, in_cumulativePredictionTypes)
    measureResults = {}
    for k in allEmotionIDs:
        funcReturn =  ResultEvaluationUtils.resultFormatCall(in_measure, in_result=finalResult[k], in_baseResult=baseResult[k])
        measureResults[k] = funcReturn
    return measureResults

def runSituationSequenceInstanceTest(filename, sitSeg, emotionalPredictors, inputsForPredictionIndices, inputsForPredictionInfo, aversiveInputIndexs, aversiveThresholdValues, extraInfo):
    situationSequenceInstance = JsonUtils.readJsonFromFile( filename)
    sequenceInstanceJson = situationSequenceInstance['sequenceInstance']
    instanceLength = len(sequenceInstanceJson['situation_id'])
    #instanceLength = int(instanceLength/10)
    print(filename + ' ' + JsonUtils.jsonToString(extraInfo, indent=None))
    print('situation sequence lenth is ' + str(instanceLength))
    emotionalPredictorsResults = { predictorName : [] for predictorName in emotionalPredictors}

    totalTrainingTime = { predictorName : 0.0 for predictorName in emotionalPredictors}
    maxTrainingTime = { predictorName : 0.0 for predictorName in emotionalPredictors}
    maxPredictionTime = { predictorName : 0.0 for predictorName in emotionalPredictors}
    fullst = time.time()

    for timeIndex in range(instanceLength):
        sensingEvent = generateSensingEvent(timeIndex, sequenceInstanceJson, inputsForPredictionIndices, inputsForPredictionInfo)
        # keep tract of emotional status from inputs (i.e. simple amigdala threshold tracking)
        emotionIDs = generateEmotionIDs(timeIndex, sequenceInstanceJson, aversiveInputIndexs, aversiveThresholdValues)
        sitSeg.registerActiveEmotions(emotionIDs)
        # add new events to segmenter
        newCompletedSituations, newPredictiveData = sitSeg.addNewEvent(sensingEvent)
        if bool(newPredictiveData):
            #print('training at time ' + str(timeIndex))
            for predictorName, predictor in emotionalPredictors.items():
                st = time.time()
                predictor.replacePredictiveData(sitSeg.m_predictingNeutralSituations)
                predictor.train()
                ft = time.time()
                runningTime = ft-st
                maxTrainingTime[predictorName] = max(runningTime, maxTrainingTime[predictorName])
                totalTrainingTime[predictorName] += runningTime
        if bool(newCompletedSituations):
            #print('predicting at time ' + str(timeIndex))
            for predictorName, predictor in emotionalPredictors.items():
                for situation in newCompletedSituations:
                    st = time.time()
                    prediction = predictor.predict(situation)
                    emotionalPredictorsResults[predictorName].append((situation, prediction))
                    ft = time.time()
                    runningTime = ft-st
                    maxPredictionTime[predictorName] = max(runningTime, maxPredictionTime[predictorName])
    fullft = time.time()
    runningTime = fullft-fullst
    print('total run time for sequence ' + str(runningTime))
    for predictorName in emotionalPredictors:
        print(predictorName + "trained for " + str(totalTrainingTime[predictorName]) + ", max training:" + str(maxTrainingTime[predictorName]) + " predicting:" + str(maxPredictionTime[predictorName]))

    compiledResults = {'results':emotionalPredictorsResults, 'time': {'totalTrain': totalTrainingTime, 'maxTrain': maxTrainingTime, 'maxPredict': maxPredictionTime} }
    return compiledResults

def createResultReport(emotionalPredictors, results, sitSeg):
    resultsReportJson = {}
    emotionalPredictorsResults = results['results']
    resultsReport = {}
    for predictorName in emotionalPredictors:
        predictorResultsReport = {}
        cumulativePredictionTypes = calculateCumulativePredictionTypes(len(sitSeg.m_predictingNeutralSituations), emotionalPredictorsResults[predictorName])
        predictorResultsReport['cumulativePredictionTypes'] = cumulativePredictionTypes
        predictorResultsReport['predictions'] = {k: [situationPredictionTuple[1][k] for situationPredictionTuple in emotionalPredictorsResults[predictorName]] for k in emotionalPredictorsResults[predictorName][0][1]}
        finalMeasures = {}
        finalMeasures['recall'] = calculateLastResultMeasure(ResultEvaluationUtils.recall, cumulativePredictionTypes, in_initialIgnoreRatio=0.2)
        finalMeasures['precision'] = calculateLastResultMeasure(ResultEvaluationUtils.precision, cumulativePredictionTypes, in_initialIgnoreRatio=0.2)
        finalMeasures['f1Score'] = calculateLastResultMeasure(ResultEvaluationUtils.f1Measure, cumulativePredictionTypes, in_initialIgnoreRatio=0.2)
        finalMeasures['f2Score'] = calculateLastResultMeasure(ResultEvaluationUtils.f2Measure, cumulativePredictionTypes, in_initialIgnoreRatio=0.2)
        predictorResultsReport['finalMeasures'] = finalMeasures
        predictorResultsReport['time'] = {'totalTrain': results['time']['totalTrain'][predictorName], 'maxTrain': results['time']['maxTrain'][predictorName], 'maxPredict': results['time']['maxPredict'][predictorName]}
        resultsReport[predictorName] = predictorResultsReport
    resultsReportJson['resultsReport'] = resultsReport
    resultsReportJson['situationSegmenter'] = sitSeg.toJson()
    return resultsReportJson

def runTest(useAversive, useNoOverlapDataset, useNonComplete, useReducedPredictionInterval):
    aversiveInputIndexs = [2]
    aversiveThresholdValues = [0.5]

    pathToSituationSequenceInstances = 'SitSeq_Overlaps/'
    if(useNoOverlapDataset):
        pathToSituationSequenceInstances = 'SitSeq_NoOverlaps/'

    inputsForPredictionIndices = [0,1,2,3] # All inputs
    if(not useAversive):
        inputsForPredictionIndices = [v for v in inputsForPredictionIndices if v not in aversiveInputIndexs]

    predictiveIntervalRatio = 2.0
    if(useReducedPredictionInterval):
        predictiveIntervalRatio =1.1
    #compose output dir nam
    outputDir = 'Out_'
    outputDir += 'Overlaps' if not useNoOverlapDataset else 'NoOverlaps'
    outputDir += '_Aversive' if useAversive else '_NoAversive'
    outputDir += '_NonComplete' if useNonComplete else '_NoNonComplete'
    outputDir += '_ReducedInterval' if useReducedPredictionInterval else '_NoReducedInterval'
    outputDir += '/'

    situationFileJson = JsonUtils.readJsonFromFile(pathToSituationSequenceInstances + "situations.json")
    inputsForPredictionInfo = [situationFileJson['inputs'][indx] for indx in inputsForPredictionIndices]

    for i in range(10):
        sitSeg = SituationSegmenter(predictiveIntervalRatio=predictiveIntervalRatio, predictFromNonCompletedSituations=useNonComplete)
        emotionalPredictors = { 'frequency' : FrequencyPredictor(sitSeg.m_events, in_defaultPrediction={0:0}),
                                'treeOriginal' :  TreePredictor(sitSeg.m_events, in_defaultPrediction={0:0}, in_originalCompression=True),
                                'treeNew' :  TreePredictor(sitSeg.m_events, in_defaultPrediction={0:0}, in_originalCompression=False)
                              }
        sitSeqInstFilename = pathToSituationSequenceInstances+'sitSeq_'+str(i)+'.json'

        extraInfo = {}
        extraInfo['sequenceInstanceIndex'] = i
        extraInfo['useAversive'] = useAversive
        extraInfo['useNoOverlapDataset'] = useNoOverlapDataset
        extraInfo['useNonComplete'] = useNonComplete
        extraInfo['useReducedPredictionInterval'] = useReducedPredictionInterval

        results = runSituationSequenceInstanceTest(sitSeqInstFilename, sitSeg, emotionalPredictors, inputsForPredictionIndices, inputsForPredictionInfo, aversiveInputIndexs, aversiveThresholdValues, extraInfo)

        emotionalPredictors['treeOriginal'].exportPNG(outputDir+'treeOriginal_sitSeq_'+str(i)+'.png',0)
        emotionalPredictors['treeNew'].exportPNG(outputDir+'treeNew_sitSeq_'+str(i)+'.png',0)

        resultsReportJson = createResultReport(emotionalPredictors, results, sitSeg)

        resultsReportJson['extraInfo'] = extraInfo
        JsonUtils.writeJsonToFile(outputDir+'sitSeq_'+str(i)+'.results', resultsReportJson)

# subProcess function code adapted from https://gist.github.com/awesomebytes/0483e65e0884f05fb95e314c4f2b3db8
def subProcess(fn):
    """Can be uses as decorator to make a function call another process.
    Needs import
    from multiprocessing import Process"""
    def wrapper(*args, **kwargs):
        processObj = Process(target=fn, args=args, kwargs=kwargs)
        #thread.start()
        return processObj
    return wrapper

if __name__ == '__main__':

    useAversive = False
    useNoOverlapDataset = True
    useNonComplete = False
    useReducedPredictionInterval = True
    booleanChoices = [False, True]

    testProcesses = []
    for useAversive in booleanChoices:
        for useNoOverlapDataset in booleanChoices:
            for useNonComplete in booleanChoices:
                for useReducedPredictionInterval in booleanChoices:
                    testProcesses.append(subProcess(runTest)(useAversive,useNoOverlapDataset,useNonComplete,useReducedPredictionInterval))

    runningProcesses = []
    maxConcurrent = 3
    for i,proc in enumerate(testProcesses):
        if i % maxConcurrent == 0:
            for runningProcess in runningProcesses:
                runningProcess.join()
            runningProcesses.clear()
        proc.start()
        runningProcesses.append(proc)


import argparse
import os
import requests
import re
from clint.textui import progress
from bs4 import BeautifulSoup
import logging
from pathlib import Path

args = dict()

def find_meta_from_url(url):
    meta_info = dict()
    html_text = requests.get(url).text
    soup = BeautifulSoup(html_text, 'html.parser')
    input_tag = soup.find('input', {'name': 'mediaId'})
    media_id = input_tag['value']
    meta_tag = soup.find('meta', attrs={'property': 'og:title'})
    content = meta_tag.get('content')
    meta_info['media_id'] = media_id
    meta_info['name'] = content
    return meta_info

def download_file(mediaId, chunk_size=1024 * 8, host="download3.vimm.net", referer="https://vimm.net/",
                  user_agent="User-Agent: Mozilla/5.0"):
        with requests.get(f"https://{host}/download/",
                          stream=True,
                          params={"mediaId": str(mediaId)},
                          headers={"User-Agent": user_agent,
                                   "Host": host,
                                   "Referer": referer}) as r:
            r.raise_for_status()

            d = r.headers['content-disposition']
            local_filename = re.findall("filename=(.+)", d)[0]
            local_filename = local_filename.translate({ord(i): None for i in "\"'"})
            print(local_filename)
            info("Downloading " + str(local_filename))
            full_download_path = args.outfolder
            if not os.path.exists(full_download_path):
                os.makedirs(full_download_path)
            with open(full_download_path + local_filename, 'wb') as f:
                total_length = int(r.headers.get('content-length'))
                for chunk in progress.bar(r.iter_content(chunk_size=chunk_size),
                                          expected_size=(total_length / chunk_size) + 1):
                    f.write(chunk)
        return local_filename

def parse_input(filename):
    with open(filename) as download_queue:
        download_list = download_queue.read()
        queue = list()
        for each in download_list.split():
            if each[0] != '#':
                download_entry = dict()
                download_entry['url'] = each
                meta_info = find_meta_from_url(download_entry['url'])
                download_entry['name'] = meta_info['name']
                download_entry['media_id'] = meta_info['media_id']
                queue.append(download_entry)
                info("Added " + download_entry['url'] + " " + download_entry['name'] + " to queue.")
        return queue

def setup_logging():
    logfile = args.logfile
    level = logging.INFO
    if args.debug:
        level = logging.DEBUG

    logging.basicConfig(filename=logfile, encoding='utf-8', level=level, filemode="a+",
                        format="%(asctime)-15s %(levelname)-8s %(message)s")

def info(*args, **kwargs):
    logging.info(*args, **kwargs)

def get_commandline_arguments():
    parser = argparse.ArgumentParser(
        prog="vimmDownloadManager",
        description="Downloads files from vimm.net"
    )
    parser.add_argument('-u', '--url', help='a single url to download')
    parser.add_argument('-i', '--infile', help='input file consisting of vimm.net urls one in each line',
                        default='list.txt')
    parser.add_argument('-o', '--outfolder', help='where to put downloaded files',
                        default=str(Path.home() / "Downloads") + '\\vdmDownloads\\')
    parser.add_argument('-l', '--logfile', help='where to log actions', default='vdm.log')
    parser.add_argument('-d', '--debug', action='store_true', help='enables DEBUGING lines in logs')
    global args
    args = parser.parse_args()
    return args

if __name__ == '__main__':
    get_commandline_arguments()
    setup_logging()
    if args.url is not None:
        meta_info = find_meta_from_url(args.url)
        download_file(meta_info['media_id'])
        exit()
    input_file = args.infile
    queue = parse_input(input_file)
    for download_entry in queue:
        download_hosts = ["download{}.vimm.net".format(i + 1) for i in range(19)]
        while len(download_hosts) != 0:
            try:
                download_file(download_entry['media_id'], host=download_hosts.pop())
                break
            except:
                pass


# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt

# 牛顿法几何意义

X = np.linspace(-5, 20, 1000)
colors = ['r-.', 'g-.', 'b-.', 'y-.', 'c-.', 'm-.', 'k-.', 'w-.', 'r-.', 'g-.', 'b-.', 'y-.', 'c-.', 'm-.', 'k-.', 'w-.']

def tangent(slope, x1, x):
    return slope * (x - x1)

def derivative(g, epsilon=1e-8):
    dx = epsilon
    return lambda x: (g(x + dx) - g(x)) / dx

def solve(g, initial, epsilon=1e-8):
    guess, i = initial, 0
    while abs(g(guess)) > epsilon:
        print('[ Epoch {0} ] guess = {1}'.format(i, guess))
        slope = derivative(g, epsilon)(guess)
        guess -= (g(guess) / slope)
        plt.plot(X, tangent(slope, guess, X), colors[i])
        plt.scatter(guess, 0)
        i += 1
    return guess

def square(x):
    return x ** 2 - 5

plt.plot(X, square(X), 'k-')
print(solve(square, 10, 1e-8))

plt.grid(True)
plt.show()


from pathlib import Path
import pandas as pd
from tqdm import tqdm

# DIRECTORY = Path('/gpfs/gpfs0/k.fedyanin/space/IJB/IJB-C/protocols/pseudo_archive')
DIRECTORY = Path("/gpfs/gpfs0/k.fedyanin/space/IJB/IJB-C/protocols/test1")

POS_NUM = 5000
NEG_NUM = 100000

def main():
    cleaned = "cleaned_templates.csv"
    template_df = pd.read_csv(DIRECTORY/cleaned)
    matches = pd.read_csv(DIRECTORY / 'match.csv')
    subject_by_template = template_df[["TEMPLATE_ID", "SUBJECT_ID"]].groupby("TEMPLATE_ID").min()

    pos_counter = 0
    neg_counter = 0

    idx = []

    for index, row in tqdm(matches.iterrows(), total=len(matches)):
        try:
            subject_1 = subject_by_template.loc[row['ENROLL_TEMPLATE_ID'], 'SUBJECT_ID']
            subject_2 = subject_by_template.loc[row['VERIF_TEMPLATE_ID'], "SUBJECT_ID"]
        except:
            continue

        if subject_1 == subject_2:
            if pos_counter < POS_NUM:
                pos_counter += 1
                idx.append(row.name)
        else:
            if neg_counter < NEG_NUM:
                neg_counter += 1
                idx.append(row.name)

        if pos_counter == POS_NUM and neg_counter == NEG_NUM:
            break

    print(matches.loc[idx])
    matches.loc[idx].to_csv(DIRECTORY / 'short_matches.csv', index=False, header=False)

if __name__ == '__main__':
    main()


import cv2
import numpy as np

img = cv2.imread("../bike.png", cv2.IMREAD_GRAYSCALE)
cv2.imshow("original",img)
kernel5x5 = np.ones((5,5), np.uint8)
kernel2x2 = np.ones((2,2), np.uint8)
dilate = cv2.dilate(img,kernel5x5,iterations=1)
diff = dilate - img
cv2.imshow("diff",diff)
erode = cv2.erode(diff,kernel2x2,iterations=1)
cv2.imshow("Erode2x2",erode)

cv2.waitKey(0)


import psycopg2
import sys
from pathlib import Path

file = Path(__file__).resolve()
parent = file.parents[0]
sys.path.append(str(parent))

from authentication import verify_access_token

def get_all_pets(
    connection: psycopg2.extensions.connection,
    owner_id: int,
    access_token: str,
):
    """
    Returns all pets in the database

    Arguments:
        connection: postgres connection
        owner_id: id of the pet owner
        access_token: access token of the pet owner
    Returns:
        List of pets
    """
    # Verify access token
    if not verify_access_token(connection, owner_id, access_token):
        return False

    cur = connection.cursor()

    query = """SELECT * FROM pets WHERE owner_id = %s ORDER BY name;"""

    try:
        # Execute query
        cur.execute(query, (owner_id,))
        pets = cur.fetchall()
        print(f"Query executed successfully: {query}")
    except Exception as e:
        print(f"Error while executing query: {e}")
        return []

    cur.close()

    pets = [{
        "id": pet[0],
        "name": pet[1],
        "animal": pet[2],
        "breed": pet[3],
        "description": pet[4],
        "image_url": pet[5],
        "is_missing": pet[6],
        "owner_id": pet[7],
    } for pet in pets]

    return pets

def get_pet(
        connection: psycopg2.extensions.connection,
        pet_id: int,
):
    """
    Returns a pet by the given id

    Arguments:
        connection: postgres connection
        pet_id: id of pet
    Returns:
        A pet
    """

    cur = connection.cursor()

    query = """SELECT * FROM pets WHERE id = %s LIMIT 1;"""

    try:
        # Execute query
        cur.execute(query, (pet_id,))
        pet = cur.fetchall()
        print(f"Query executed successfully: {query}")
    except Exception as e:
        print(f"Error while executing query: {e}")
        return False

    cur.close()

    res = pet[0]
    pet = {
        "id": res[0],
        "name": res[1],
        "animal": res[2],
        "breed": res[3],
        "description": res[4],
        "image_url": res[5],
        "owner_id": res[6]
    }

    return pet

def add_pet(
    connection: psycopg2.extensions.connection,
    name: str,
    animal: str,
    breed: str,
    description: str,
    image_url: str,
    owner_id: int,
    access_token: str,
):
    """
    Adds a pet to the database

    Arguments:
        connection: postgres connection
        name: name of the pet
        animal: type of animal
        breed: breed of the pet
        description: description of the pet
        image_url: url of the image of the pet
        owner_id: id of the pet owner
        access_token: access token of the pet owner
    Returns:
        True if successful, False otherwise
    """
    # Verify access token
    if not verify_access_token(connection, owner_id, access_token):
        return False

    cur = connection.cursor()

    query = """INSERT INTO pets (name, animal, breed, description, image_url, owner_id) VALUES (%s, %s, %s, %s, %s, %s);"""

    try:
        # Execute query
        cur.execute(query, (name, animal, breed, description, image_url, owner_id,))
        print(f"Query executed successfully: {query}")
    except Exception as e:
        print(f"Error while executing query: {e}")
        return False

    cur.close()
    connection.commit()

    return True

def edit_pet(
    connection: psycopg2.extensions.connection,
    id: int,
    name: str,
    animal: str,
    breed: str,
    description: str,
    image_url: str,
    owner_id: int,
    access_token: str,
):
    """
    Edits an existing pet in the database

    Arguments:
        connection: postgres connection
        id: id of the pet
        name: name of the pet
        animal: type of animal
        breed: breed of the pet
        description: description of the pet
        image_url: url of the image of the pet
        owner_id: id of the pet owner
        access_token: access token of the pet owner
    Returns:
        True if successful, False otherwise
    """
    # Verify access token
    if not verify_access_token(connection, owner_id, access_token):
        return False

    cur = connection.cursor()

    query = """UPDATE pets SET name = %s, animal = %s, breed = %s, description = %s, image_url = %s, owner_id = %s WHERE id = %s;"""

    result = False
    try:
        # Execute query
        cur.execute(query, (name, animal, breed, description, image_url, owner_id, id))
        result = True
        print(f"Query executed successfully: {query}")
    except Exception as e:
        print(f"Error while executing query: {e}")

    cur.close()
    connection.commit()

    return result

def update_pet_missing_status(connection: psycopg2.extensions.connection, pet_id: int, new_status: bool) -> bool:

    result = False
    try:
        cur = connection.cursor()

        # Update the missing status in the database
        cur.execute("UPDATE pets SET isMissing = %s WHERE id = %s;", (new_status, pet_id))

        connection.commit()
        cur.close()
        result = True

    except Exception as e:
        print(f"Error updating status: {e}")
        connection.rollback()

    return result

def delete_all_pet_data_from_database(connection: psycopg2.extensions.connection, to_delete_id: int, user_id: int, access_token: str):
    """
    This function deletes the pet with the provided id

    """

    # Verify access token
    if not verify_access_token(connection, user_id, access_token):
        print("Access token verification failed.")
        return False

    if not unlink_pet_sightings_from_user_reports(connection=connection, user_id=user_id, pet_id=to_delete_id):
        print("Failed to unlink sightings from user reports.")
        return False

    # Delete pet's missing reports
    if not delete_pet_reports(connection=connection, user_id=user_id, pet_id=to_delete_id):
        print("Failed to delete pet's missing reports.")
        return False

    # Delete pet
    if not delete_pet(connection=connection, user_id=user_id, pet_id=to_delete_id):
        print("Failed to delete pet.")
        return False

    return True

def unlink_pet_sightings_from_user_reports(connection: psycopg2.extensions.connection, user_id: int, pet_id: int):
    """
    This function unlinks sightings on this user's pet's missing reports.
    """

    cur = connection.cursor()

    query = """
        UPDATE sightings SET missing_report_id = NULL WHERE missing_report_id IN (SELECT id FROM missing_reports WHERE author_id = %s AND pet_id = %s);
    """

    try:
        cur.execute(query, (user_id, pet_id))

        # Commit the change
        connection.commit()
        print(f"Sightings successfully unlinked")
        return True

    except Exception as e:
        print(f"Error with deleting user: {e}")

    cur.close()
    return False

def delete_pet_reports(connection: psycopg2.extensions.connection, user_id: int, pet_id: int):
    """
    This function deletes all missing reports created by the user for a pet.
    """

    cur = connection.cursor()

    query = """
        DELETE FROM missing_reports WHERE author_id = %s AND pet_id = %s;
    """

    try:
        cur.execute(query, (user_id, pet_id))

        # Commit the change
        connection.commit()
        print(f"Missing reports successfully deleted")
        return True

    except Exception as e:
        print(f"Error with deleting user: {e}")

    cur.close()
    return False

def delete_pet(connection, user_id, pet_id):
    """
    This function deletes the pet that is selected.
    """

    cur = connection.cursor()

    query = """
        DELETE FROM pets WHERE owner_id = %s AND id = %s;
    """

    try:
        cur.execute(query, (user_id, pet_id))
        connection.commit()
        print(f"Pet successfully deleted")
        return True

    except Exception as e:
        print(f"Error while deleting pet: {e}")

    cur.close()
    return False


#!/usr/bin/python

import ROOT
from ROOT import std, gROOT, TLorentzVector, TMath, TVector3

def cosThetaDitop(pa, pb):
   paMag = TMath.Sqrt( pa.Px()*pa.Px() + pa.Py()*pa.Py() + pa.Pz()*pa.Pz() )
   pbMag = TMath.Sqrt( pb.Px()*pb.Px() + pb.Py()*pb.Py() + pb.Pz()*pb.Pz() )
   costh = (pa.Px()*pb.Px() + pa.Py()*pb.Py() + pa.Pz()*pb.Pz()) / (paMag*pbMag)
   return costh

def QT(pa, pb):
   pTmp = pa+pb
   return pTmp.Perp()

def ySystem(pa, pb):
   pTmp = pa+pb
   return pTmp.Rapidity()

def magBetaSystem(pa, pb):
   pTmp = pa+pb
   return pTmp.Beta()

def systemBoostVector(pa, pb):
   pTmp = pa+pb
   return pTmp.BoostVector()

def Boost(pboost, p):
   pBoosted = p.Clone("")
   pBoosted.Boost(-1.*pBoost.BoostVector())
   return pBoosted

def Boost(pa, pb, p):
   pTmp = pa+pb
   pBoosted = p.Clone("")
   pBoosted.Boost(-1.*pTmp.BoostVector())
   return pBoosted

def betaiSystem(pa, pb, i):
   pTmp = pa+pb
   E = pTmp.E()
   if(E<=0.):  return -99999999.
   if  (i==1): return pTmp.Px()/E;
   elif(i==2): return pTmp.Py()/E;
   elif(i==3): return pTmp.Pz()/E;
   return -99999999.

def betaTSystem(pa, pb):
   pTmp = pa+pb
   beta = 0
   if(pTmp.E()!=0.): return pTmp.Pt()/pTmp.E()
   return -999.

def magBetaSystem(pa, pb, ea, eb):
   if((ea+eb)>0.): return (pa+pb)/(ea+eb)
   return -999999.

def cosphi(reference1, target1, reference2, target2):
   targettmp1 = target1.Clone("tmp1")
   targettmp2 = target2.Clone("tmp2")
   vboost1 = reference1.BoostVector()
   targettmp1.Boost(-vboost1)
   vboost2 = reference2.BoostVector()
   targettmp2.Boost(-vboost2)
   cosp = targettmp1.Vect()*targettmp2.Vect() # scalar product
   cosp /= (targettmp1.Vect().Mag()*targettmp2.Vect().Mag())
   return cosp

def costheta(reference, target):
   targettmp = target.Clone("tmp")
   vboost = reference.BoostVector()
   targettmp.Boost(-vboost)
   cost = targettmp.Vect()*vboost # scalar product
   cost /= (targettmp.Vect().Mag()*vboost.Mag())
   return cost

def cosThetaTrue(pa, ida, pb, idb, doflip=False):
   #  http://xrootd.slac.stanford.edu/BFROOT/www/doc/workbook_backup_010108/analysis/analysis.html
   #  A useful quantity in many analyses is the helicity angle.
   #  In the reaction Y . X . a + b, the helicity angle of
   #  particle a is the angle measured in the rest frame of the
   #  deidaying parent particle, X, between the direction of the
   #  deiday daughter a and the direction of the grandparent particle Y.
   pTmp = pa+pb;                     # this is the mumu system (Z) 4vector
   ZboostVector = pTmp.BoostVector() # this is the 3vector of the Z
   p = TLorentzVector(0,0,-1,1)      # this is the muon 4vector
   if  (ida>0): p.SetPxPyPzE(pa.Px(),pa.Py(),pa.Pz(),pa.E())
   else:        p.SetPxPyPzE(pb.Px(),pb.Py(),pb.Pz(),pb.E())
   p.Boost(-ZboostVector) # boost p to the Ditop CM (rest) frame
   cosThetaB = p.Vect().Z()/p.Vect().Mag()
   if(ySystem(pa,pb)<0. and doflip): cosThetaB *= -1. # reclassify ???
   return cosThetaB

def cosThetaBoost(pa, ida, pb, idb, doflip=False):
   #  http://xrootd.slac.stanford.edu/BFROOT/www/doc/workbook_backup_010108/analysis/analysis.html
   #  A useful quantity in many analyses is the helicity angle.
   #  In the reaction Y . X . a + b, the helicity angle of
   #  particle a is the angle measured in the rest frame of the
   #  deidaying parent particle, X, between the direction of the
   #  deiday daughter a and the direction of the grandparent particle Y.
   pTmp = pa+pb;                     # this is the mumu system (Z) 4vector
   ZboostVector = pTmp.BoostVector() # this is the 3vector of the Z
   p = TLorentzVector(0,0,-1,1)      # this is the muon 4vector
   if  (ida>0): p.SetPxPyPzE(pa.Px(),pa.Py(),pa.Pz(),pa.E())
   else:        p.SetPxPyPzE(pb.Px(),pb.Py(),pb.Pz(),pb.E())
   p.Boost(-ZboostVector) # boost p to the Ditop CM (rest) frame
   cosThetaB = p.Vect()*pTmp.Vect()/(p.P()*pTmp.P())
   if(ySystem(pa,pb)<0. and doflip): cosThetaB *= -1. # reclassify ???
   return cosThetaB

def cosThetaCollinsSoper(pa, ida, pb, idb, doflip=True):
   # this will work only for leptons e, mu and tau
   # by default it is assumed that pa is the lepton
   # if instead pb is the lepton, then the result is
   # reclassified by a (-) sign - see line 4.
   mass = (pa+pb).M()
   mass2 = (pa+pb).M()*(pa+pb).M()
   QT2 = (pa+pb).Pt()*(pa+pb).Pt() # QT(pa,pb)*QT(pa,pb)
   # cosThetaCS = 2.*( pa.Plus()*pb.Minus() - pa.Minus()*pb.Plus() ) / TMath.Sqrt( mass2 * (mass2 + QT2) )
   cosThetaCS = 2.*( pa.Pz()*pb.E() - pa.E()*pb.Pz() ) / TMath.Sqrt( mass2 * (mass2 + QT2) )
   if(ida<0): cosThetaCS *= -1. # if pb is the lepton
   if(ySystem(pa,pb)<0 and doflip): cosThetaCS *= -1. # reclassify
   return cosThetaCS

def CostCS(p1, charge1, p2):
   #Cosine of the theta decay angle (top (Q=+2/3)) in the Collins-Soper frame
   pTop1CM = TLorentzVector(0,0,-1,1)  # In the CM. frame
   pTop2CM = TLorentzVector(0,0,-1,1)  # In the CM. frame
   pProjCM = TLorentzVector(0,0,-1,1) # In the CM. frame
   pTargCM = TLorentzVector(0,0,-1,1) # In the CM. frame
   pDitopCM = TLorentzVector(0,0,-1,1) # In the CM. frame
   pTop1Ditop = TLorentzVector(0,0,-1,1) # In the Ditop rest frame
   pTop2Ditop = TLorentzVector(0,0,-1,1) # In the Ditop rest frame
   pProjDitop = TLorentzVector(0,0,-1,1) # In the Ditop rest frame
   pTargDitop = TLorentzVector(0,0,-1,1) # In the Ditop rest frame
   beta = TVector3(0,0,0)
   zaxisCS = TVector3(0,0,0)
   mp = 0.93827231
   ep = 6500.

   # Fill the Lorentz vector for projectile and target in the CM frame
   pProjCM.SetPxPyPzE(0.,0.,-ep,TMath.Sqrt(ep*ep+mp*mp))
   pTargCM.SetPxPyPzE(0.,0.,+ep,TMath.Sqrt(ep*ep+mp*mp))

   # Get the Topons parameters in the CM frame
   pTop1CM.SetPxPyPzE(p1.Px(),p1.Py(),p1.Pz(),p1.E())
   pTop2CM.SetPxPyPzE(p2.Px(),p2.Py(),p2.Pz(),p2.E())

   # Obtain the Ditop parameters in the CM frame
   pDitopCM=pTop1CM+pTop2CM

   # Translate the Ditop parameters in the Ditop rest frame
   beta=(-1./pDitopCM.E())*pDitopCM.Vect()
   if(beta.Mag()>=1): return 666.
   pTop1Ditop=pTop1CM
   pTop2Ditop=pTop2CM
   pProjDitop=pProjCM
   pTargDitop=pTargCM
   pTop1Ditop.Boost(beta)
   pTop2Ditop.Boost(beta)
   pProjDitop.Boost(beta)
   pTargDitop.Boost(beta)

   # Determine the z axis for the CS angle
   zaxisCS=(((pProjDitop.Vect()).Unit())-((pTargDitop.Vect()).Unit())).Unit();

   # Determine the CS angle (angle between Top+ and the z axis defined above)
   cost = -999

   if(charge1>0): cost = zaxisCS.Dot((pTop1Ditop.Vect()).Unit())
   else:          cost = zaxisCS.Dot((pTop2Ditop.Vect()).Unit())

   return cost

def CostHE(p1, charge1, p2):
   #Cosine of the theta decay angle (top (Q=+2/3)) in the Helicity frame
   pTop1CM = TLorentzVector(0,0,-1,1)   # In the CM frame
   pTop2CM = TLorentzVector(0,0,-1,1)   # In the CM frame
   pDitopCM = TLorentzVector(0,0,-1,1) # In the CM frame
   pTop1Ditop = TLorentzVector(0,0,-1,1) # In the Ditop rest frame
   pTop2Ditop = TLorentzVector(0,0,-1,1) # In the Ditop rest frame
   beta = TVector3(0,0,0)
   zaxisCS = TVector3(0,0,0)

   # Get the muons parameters in the CM frame
   pTop1CM.SetPxPyPzE(p1.Px(),p1.Py(),p1.Pz(),p1.E())
   pTop2CM.SetPxPyPzE(p2.Px(),p2.Py(),p2.Pz(),p2.E())

   # Obtain the Ditop parameters in the CM frame
   pDitopCM=pTop1CM+pTop2CM

   # Translate the muon parameters in the Ditop rest frame
   beta=(-1./pDitopCM.E())*pDitopCM.Vect()
   if(beta.Mag()>=1): return 666.
   pTop1Ditop=pTop1CM
   pTop2Ditop=pTop2CM
   pTop1Ditop.Boost(beta)
   pTop2Ditop.Boost(beta)

   # Determine the z axis for the calculation of the polarization angle (i.e. the direction of the Ditop in the CM system)
   zaxis=(pDitopCM.Vect()).Unit()

   # Calculation of the polarization angle (angle between mu+ and the z axis defined above)
   cost = -999.
   if(charge1>0): cost = zaxis.Dot((pTop1Ditop.Vect()).Unit())
   else:          cost = zaxis.Dot((pTop2Ditop.Vect()).Unit())

   return cost

def PhiCS(p1, charge1, p2):
   # Phi decay angle (top (Q=+2/3)) in the Collins-Soper frame
   pTop1CM = TLorentzVector(0,0,-1,1)  # In the CM frame
   pTop2CM = TLorentzVector(0,0,-1,1)  # In the CM frame
   pProjCM = TLorentzVector(0,0,-1,1)  # In the CM frame
   pTargCM = TLorentzVector(0,0,-1,1)  # In the CM frame
   pDitopCM = TLorentzVector(0,0,-1,1) # In the CM frame
   pTop1Ditop = TLorentzVector(0,0,-1,1) # In the Ditop rest frame
   pTop2Ditop = TLorentzVector(0,0,-1,1) # In the Ditop rest frame
   pProjDitop = TLorentzVector(0,0,-1,1) # In the Ditop rest frame
   pTargDitop = TLorentzVector(0,0,-1,1) # In the Ditop rest frame
   beta = TVector3(0,0,0)
   yaxisCS = TVector3(0,0,0)
   xaxisCS = TVector3(0,0,0)
   zaxisCS = TVector3(0,0,0)
   mp = 0.93827231
   ep = 6500.

   # Fill the Lorentz vector for projectile and target in the CM frame
   pProjCM.SetPxPyPzE(0.,0.,-ep,TMath.Sqrt(ep*ep+mp*mp))
   pTargCM.SetPxPyPzE(0.,0.,+ep,TMath.Sqrt(ep*ep+mp*mp))

   # Get the muons parameters in the CM frame
   pTop1CM.SetPxPyPzE(p1.Px(),p1.Py(),p1.Pz(),p1.E())
   pTop2CM.SetPxPyPzE(p2.Px(),p2.Py(),p2.Pz(),p2.E())

   # Obtain the Ditop parameters in the CM frame
   pDitopCM=pTop1CM+pTop2CM

   # Translate the Ditop parameters in the Ditop rest frame
   beta=(-1./pDitopCM.E())*pDitopCM.Vect()
   if(beta.Mag()>=1): return 666.
   pTop1Ditop=pTop1CM
   pTop2Ditop=pTop2CM
   pProjDitop=pProjCM
   pTargDitop=pTargCM
   pTop1Ditop.Boost(beta)
   pTop2Ditop.Boost(beta)
   pProjDitop.Boost(beta)
   pTargDitop.Boost(beta)

   # Determine the z axis for the CS angle
   zaxisCS=(((pProjDitop.Vect()).Unit())-((pTargDitop.Vect()).Unit())).Unit()
   yaxisCS=(((pProjDitop.Vect()).Unit()).Cross((pTargDitop.Vect()).Unit())).Unit()
   xaxisCS=(yaxisCS.Cross(zaxisCS)).Unit()

   phi = -999.
   if(charge1>0.): phi = TMath.ATan2((pTop1Ditop.Vect()).Dot(yaxisCS),((pTop1Ditop.Vect()).Dot(xaxisCS)))
   else:           phi = TMath.ATan2((pTop2Ditop.Vect()).Dot(yaxisCS),((pTop2Ditop.Vect()).Dot(xaxisCS)))
   if(phi>TMath.Pi()): phi = phi-TMath.Pi()

   return phi

def PhiHE(p1, charge1, p2):
   # Phi decay angle (top (Q=+2/3)) in the Helicity frame
   pTop1Lab = TLorentzVector(0,0,-1,1)  # In the lab. frame
   pTop2Lab = TLorentzVector(0,0,-1,1)  # In the lab. frame
   pProjLab = TLorentzVector(0,0,-1,1)  # In the lab. frame
   pTargLab = TLorentzVector(0,0,-1,1)  # In the lab. frame
   pDitopLab = TLorentzVector(0,0,-1,1) # In the lab. frame
   pTop1Ditop = TLorentzVector(0,0,-1,1) # In the Ditop rest frame
   pTop2Ditop = TLorentzVector(0,0,-1,1) # In the Ditop rest frame
   pProjDitop = TLorentzVector(0,0,-1,1) # In the Ditop rest frame
   pTargDitop = TLorentzVector(0,0,-1,1) # In the Ditop rest frame
   beta = TVector3(0,0,0)
   xaxis = TVector3(0,0,0)
   yaxis = TVector3(0,0,0)
   zaxis = TVector3(0,0,0)
   mp = 0.93827231
   ep = 6500.

   # Get the muons parameters in the LAB frame
   pTop1Lab.SetPxPyPzE(p1.Px(),p1.Py(),p1.Pz(),p1.E())
   pTop2Lab.SetPxPyPzE(p2.Px(),p2.Py(),p2.Pz(),p2.E())

   # Obtain the Ditop parameters in the LAB frame
   pDitopLab=pTop1Lab+pTop2Lab
   zaxis=(pDitopLab.Vect()).Unit()

   # Translate the muon parameters in the Ditop rest frame
   beta=(-1./pDitopLab.E())*pDitopLab.Vect()
   if(beta.Mag()>=1.): return 666.

   pProjLab.SetPxPyPzE(0.,0.,-ep,TMath.Sqrt(ep*ep+mp*mp))
   pTargLab.SetPxPyPzE(0.,0.,+ep,TMath.Sqrt(ep*ep+mp*mp))

   pProjDitop=pProjLab
   pTargDitop=pTargLab

   pProjDitop.Boost(beta)
   pTargDitop.Boost(beta)

   yaxis=((pProjDitop.Vect()).Cross(pTargDitop.Vect())).Unit()
   xaxis=(yaxis.Cross(zaxis)).Unit()

   pTop1Ditop=pTop1Lab
   pTop2Ditop=pTop2Lab
   pTop1Ditop.Boost(beta)
   pTop2Ditop.Boost(beta)

   phi = -999.
   if(charge1>0.): phi = TMath.ATan2((pTop1Ditop.Vect()).Dot(yaxis),(pTop1Ditop.Vect()).Dot(xaxis))
   else:           phi = TMath.ATan2((pTop2Ditop.Vect()).Dot(yaxis),(pTop2Ditop.Vect()).Dot(xaxis))

   return phi


import socket
import tempfile
import sys
import os
import threading

from cpc.util.conf.conf_base import Conf

class ConnectionBundle(Conf):
    '''
    this worker conf will be transformed to a connection bundle
    '''
    #__shared_state = {}
    CN_ID = "worker"  #used to distinguish common names in certs

    def __init__(self, userSpecifiedPath=None, create=False,
                 fqdn=socket.getfqdn()):
        # check whether the object is already initialized
        if not create:
            if self.exists():
                return
                # call parent constructor with right file name.
            Conf.__init__(self, name='client.cnx',
                userSpecifiedPath=userSpecifiedPath)
        if create:
            # create an empty conf without any values.
            self.conf = dict()

        self.client_host = fqdn
        self.server_secure_port = Conf.getDefaultServerSecurePort()
        self.client_secure_port = Conf.getDefaultClientSecurePort()
        self.privateKey = ''
        self.publicKey = ''
        self.cert = ''
        self.CAcert = ''
        self.initDefaults()

        # TODO: make it a regular Lock() - for now this might reduce the
        # chances of a deadlock
        self.lock = threading.RLock()

        #worker specific
        dn = os.path.dirname(sys.argv[0])
        self.execBasedir = ''
        if dn != "":
            self.execBasedir = os.path.abspath(dn)

        self._add('exec_base_dir', self.execBasedir,
            'executable base directory', writable=False)

        self.tempfiles = dict()
        #if conffile:
        self._tryRead()
        '''
        the private key, cert and
        ca cert need to be provided as filepaths to the ssl connection object
        So we create tempfiles for them here
        '''
        privKeyTempFile = tempfile.NamedTemporaryFile(delete=False)
        privKeyTempFile.write(self.get('private_key'))
        privKeyTempFile.seek(0)
        self.tempfiles['private_key'] = privKeyTempFile
        privKeyTempFile.close()

        certTempFile = tempfile.NamedTemporaryFile(delete=False)
        certTempFile.write(self.get('cert'))
        certTempFile.seek(0)
        self.tempfiles['cert'] = certTempFile
        certTempFile.close()

        caCertTempFile = tempfile.NamedTemporaryFile(delete=False)
        caCertTempFile.write(self.get('ca_cert'))
        caCertTempFile.seek(0)
        self.tempfiles['ca_cert'] = caCertTempFile
        caCertTempFile.close()

    #overrrides method in ConfBase
    def initDefaults(self):
        self._add('client_host', self.client_host,
                  "Hostname for the client to connect to", True,None)
        self._add('server_secure_port', Conf.getDefaultServerSecurePort(),
                   "Port number the server uses for communication from servers ",
                   True,None,'\d+')

        self._add('client_secure_port', Conf.getDefaultClientSecurePort(),
                  "Port number the server listens on for communication from clients",
                  True,None,'\d+')

        self._add('private_key', '',
            "Port number for the client to connect to https", True, None)
        self._add('public_key', '',
            "Port number for the client to connect to https", True, None)
        self._add('cert', '',
            "Port number for the client to connect to https", True, None)

        self._add('ca_cert', '',
            "Port number for the client to connect to https", True, None)

        self._add('plugin_path', "",
            "Colon-separated list of directories to search for plugins",
            True, writable=False)

        self._add('local_executables_dir', "executables",
            "Directory containing executables for the run client. Part of executables_path",
            False,
            relTo='conf_dir', writable=False)
        self._add('global_executables_dir', "executables",
            "The directory containing executables for the run client. Part of executables_path",
            False,
            relTo='global_dir', writable=False)
        self._add('executables_path', "",
            "Colon-separated directory list to search for executables",
            True, writable=False)

        # the worker's run directory should NEVER be fixed relative to
        # anything else; instead, it should just run in the current directory
        self._add('run_dir', #os.path.join(os.environ["HOME"],
            "cpc-worker-workload",
            "The run directory for the run client",
            True, writable=False)

    def getClientHost(self):
        return self.get('client_host')

    def getServerSecurePort(self):
        return int(self.get('server_secure_port'))

    def getClientSecurePort(self):
        return int(self.get('client_secure_port'))

    def getPrivateKey(self):
        return self.tempfiles['private_key'].name

    def getCaChainFile(self):
        return self.tempfiles['ca_cert'].name

    def getCertFile(self):
        return self.tempfiles['cert'].name

    def getRunDir(self):
        return self.get("run_dir")

    def getHostName(self):
        ''' The fully qualified domain name of the client  '''
        return socket.getfqdn()

    def setServerSecurePort(self, httpsPort):
        self.conf["server_secure_port"].set("%s" % httpsPort)

    def setClientSecurePort(self, httpsPort):
        self.conf["client_secure_port"].set("%s" % httpsPort)

    def setPrivateKey(self, privateKey):
        '''
        @input privateKey String, a pem formatted string
        '''
        self.conf["private_key"].set(privateKey)

    def setPublicKey(self, publicKey):
        '''
        @input publicKey String, a pem formatted string
        '''
        self.conf["public_key"].set(publicKey)

    def setCert(self, cert):
        '''
        @input cert String, a pem formatted string
        '''
        self.conf["cert"].set(cert)

    def setCaCert(self, caCert):
        '''
        @input ca_cert String, a pem formatted string
        '''
        self.conf["ca_cert"].set(caCert)

    def setHostname(self, hostname):
        self.conf["client_host"].set(hostname)


def add(str1, str2):
    str3 = '[' + str1.strip() + ',' + str2.strip() + ']'
    return str3

def reduce(str):
    reduced = False
    while not reduced:
        str, exploded = explode(str)
        if not exploded:
            str, has_split = split(str)
            if not has_split:
                reduced = True

    return str

def explode(str_in):
    brackets = 0
    str_out = ''
    exploded = False
    ante_digit_pos = 0
    post_digit_pos = 0

    # find explosion position
    for i in range(len(str_in)):
        if str_in[i] == '[':
            brackets += 1
        elif str_in[i] == ']':
            brackets -= 1
        if brackets == 5 and not exploded:
            expl_pos = i
            exploded = True

    if exploded:
        # digit before expl
        for i in range(expl_pos):
            if str_in[i] not in ['[', ']', ',']:
                ante_digit_pos = i

        # digit after expl
        for i in range(len(str_in)-1, expl_pos+4, -1):
            if str_in[i] not in ['[', ']', ',']:
                post_digit_pos = i

        if ante_digit_pos != 0:
            str_ante = str_in[0:ante_digit_pos] + str(int(str_in[ante_digit_pos]) + int(
                str_in[expl_pos+1])) + str_in[ante_digit_pos+1:expl_pos]
        else:
            str_ante = str_in[0:expl_pos]

        if post_digit_pos != 0:
            print(str_in[expl_pos:expl_pos+3])
            str_post = str_in[expl_pos+5:post_digit_pos] + str(int(str_in[post_digit_pos]) + int(
                str_in[expl_pos+3])) + str_in[post_digit_pos+1:]
        else:
            str_post = str_in[expl_pos+5:]

        str_out = str_ante + '0' + str_post
    else:
        str_out = str_in
    return str_out, exploded

def split(str_in):
    punctuation = ['[', ']', ',']
    split_found = False
    split_pos = 0
    for i in range(len(str_in)-1):
        if str_in[i] not in punctuation:
            if str_in[i+1] not in punctuation and not split_found:
                split_found = True
                split_pos = i
                split_num = int(str_in[i:i+2])
                if split_num % 2 == 0:
                    split_str = '[' + str(split_num//2) + \
                        ',' + str(split_num//2) + ']'
                else:
                    split_str = '[' + str(split_num//2) + \
                        ',' + str((split_num//2) + 1) + ']'
    if split_found:
        str_out = str_in[:split_pos] + split_str + str_in[split_pos+2:]
    else:
        str_out = str_in
    return str_out, split_found

with open('18/test.txt', 'r') as file:
    lines = file.readlines()

line =  lines[0]
for i in range(1, len(lines)):
    line = add(line, lines[i])
    line = reduce(line)


from flask import *
from flask_restful import *
from flask_restful import reqparse
from flask import jsonify
from database import Database
# from Database import *

class ProductApi(Resource):

    def get(self):
        parser = reqparse.RequestParser()
        parser.add_argument('page_number', type=int)
        parser.add_argument('number_of_records', type=int)
        args = parser.parse_args()
        print("args ="+ str(args))
        products = {"products":[{"name": "iphone X", "year": 2017}, {"name": "iphone 5", "year": 2015}]}
        return jsonify(products)

    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('product_name')
        parser.add_argument('product_year', type=int)
        args = parser.parse_args()
        print("args ="+ str(args))
        # database = Database()
        result, message = Database.get_instance().insert_new_product(args['product_name'], args['product_year'])
        # results = {"results": "ok", "message":"insert new product successfully"}
        return jsonify({"result": result, "message": message})

    def put(self):
        parser = reqparse.RequestParser()
        parser.add_argument('product_name')
        parser.add_argument('product_year')
        parser.add_argument('product_id')
        args = parser.parse_args()
        print("args PUT ="+ str(args))
        result, message = Database.get_instance().update_product(args['product_name'], args['product_year'], args['product_id'])
        # results = {"results": "ok", "message":"update product successfully"}
        return jsonify({"result": result, "message": message})

    def delete(self):
        parser = reqparse.RequestParser()
        parser.add_argument('product_id')
        args = parser.parse_args()
        print("args DELETE ="+ str(args))
        # results = {"results": "ok", "message":"update product successfully"}
        result, message = Database.get_instance().delete_product(args['product_id'])
        # results = {"results": "ok", "message":"delete product successfully"}
        return jsonify({"result": result, "message": message})
        # return jsonify(results)


"""
Задание: ждем нужный текст на странице
"""

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import math

def calc(x):
  return str(math.log(abs(12*math.sin(int(x)))))

try:
    link = "http://suninjuly.github.io/explicit_wait2.html"
    browser = webdriver.Chrome()
    # говорим WebDriver ждать все элементы в течение 5 секунд
    # browser.implicitly_wait(5)
    browser.get(link)

    # говорим Selenium проверять в течение 5 секунд, пока кнопка не станет кликабельной
    button = WebDriverWait(browser, 12).until(
        EC.text_to_be_present_in_element((By.ID, "price"), '$100')
    )

    browser.find_element(By.ID, "book").click()

    x = browser.find_element(By.ID, "input_value").text
    y = calc(x)

    answer = browser.find_element(By.ID, "answer")

    browser.execute_script('return arguments[0].scrollIntoView(true);', answer)
    answer.send_keys(y)

    browser.find_element(By.ID, "solve").click()

    alert = browser.switch_to.alert
    alert_text = alert.text
    print(alert_text)
    # alert.accept()

finally:
    browser.quit()


"""Help command
"""
import imp
import pdb
import os
import importlib
from itertools import chain
from app.mod_cmd.client_instruction import ClientInstruction
from app.mod_cmd.helpers import get_package_module_pairs, get_base_package_module_pairs, get_package

def run(project=None, args=[], **kwargs):
    """Show all available console commands. `help [command]` to show detailed help for a command.
    """
    cmd = None
    message = "Below are the commands available, grouped by their functions.\n\n%s\n\nOther useful commands:\n" \
    "\tCTRL + L: Clear console.\n" \
    "\tALT + +: Maximize console size.\n" \
    "\tALT + -: Hide console.\n" \
    "\tALT + 0: Standard console size."
    if project is None:
        message += "\n\nLet's start by loading a prepared project. Try 'load_project risky'.\n" \
        "Tips: Run 'status' whenever you need to figure out where you're at, and run 'help' "\
        "whenever you need suggestion on what to do next"
    else:
        if project.context == None or 'concepts' not in project.context or len(project.context['concepts']) == 0:
            if project.active_doc == None:
                message += "\n\nProject %s is currently active. " \
                    "In the main screen, you should see all documents in this project with their status.\n" \
                    "Basically, the idea of this app is to keep all important information from documents to database.\n" \
                    "This is done by creating concepts, which is done as you label a couple of few documents then let Arthur\n" \
                    "learns the rest of documents in this project.\n" \
                    "Try loading a project by choosing from listed document." % project.name
            else:
                message += "To create a concept, run command 'create_concept'"
        else:
            message += "Now that concept(s) has been created, you can extract features and targets from documents.\n" \
                       "Run a dry-run extraction (i.e. not actually affecting the database) for an active document with command " \
                       " 'extract' (remember to load_doc to activate a document).\n" \
                       "When all seems good, 'extract --all' or 'extract -n [number]' can be run to extract features and targets for real."
    if len(args) > 0:
        cmd = args[0]
        message = "%s"
    docs = get_docs(cmd)
    instruction = ClientInstruction({
        'message': message % "\n".join(docs)
    })
    return [project, instruction]

def get_docs(cmd = None):
    """Get all the available modules and return their documentations. This method will find scripts
       inside another directory under `app/commands` directory.
    """
    docs = []
    if cmd is None:
        last_package = ''
        for package, module in chain(get_package_module_pairs(), get_base_package_module_pairs()):
            if package != last_package:
                if package == 'commands':
                    docs.append('others:')
                else:
                    docs.append(package+':')
            last_package = package

            if package == 'commands':
                package = ''
            if package != '':
                package += '.'
            mod = importlib.import_module("app.mod_cmd.commands.%s%s" % (package, module))
            docs.append(("\t%s: %s" % (module, mod.run.__doc__.split('\n', 1)[0].strip())))
    else:
        package = get_package(cmd)
        if package != '':
            package += '.'
        mod = importlib.import_module("app.mod_cmd.commands.%s%s" % (package, cmd))
        docs.append(("%s\n%s" % (cmd, mod.run.__doc__)).strip())

    return docs


import numpy
import chainer.functions as F

from chainer.functions.activation import lstm
from chainer.functions.activation.lstm import _extract_gates

class GradClipLSTM(lstm.LSTM):
    """
    Long short-term memory unit with forget gate and gradient clipping before each gates.
    It has two inputs (c, x) and two outputs (c, h), where c indicates the cell
    state. x must have four times channels compared to the number of units.

    Gradient clipping is done during backward process
    and not before applying the gradient to weights.

    See: https://arxiv.org/abs/1308.0850
    """

    def __init__(self, clip_min, clip_max):
        super(GradClipLSTM, self).__init__()
        clip_min = clip_min if clip_min is not None else numpy.finfo(
            numpy.float32).min
        clip_max = clip_max if clip_max is not None else numpy.finfo(
            numpy.float32).max
        self.clip_min = float(clip_min)
        self.clip_max = float(clip_max)

    def backward(self, inputs, grads):
        gc_prev, gx = super(GradClipLSTM, self).backward(inputs, grads)
        return gc_prev, F.clip(gx, self.clip_min, self.clip_max)

def grad_clip_lstm(c_prev, x, clip_min=None, clip_max=None):
    return GradClipLSTM(clip_min, clip_max).apply((c_prev, x))


from flask import Flask, jsonify
import sys

app = Flask(__name__)

@app.route('/')
def heavy():
    if len(sys.argv) < 2:
        return 'Error'
    x = 0

    for i in range(40000):
        for j in range(40000):
            x += i*j

    return 'Hello from ' + sys.argv[1] + ' in Heavy!. Computation result = ' + str(x) + "\n"

if __name__ == '__main__':
    app.run(debug = True, host='0.0.0.0', port=5002)


from tkinter import*
from tkinter.colorchooser import*
from tkinter.simpledialog import*
from PIL import ImageGrab

mycolor = 'black'

def mouseClick(event):
    global x1,y1,x2,y2
    x1=event.x
    y1=event.y

def mouseDrop(event):
    global x1,y1,x2,y2,penWidth,penColor
    x2=event.x
    y2=event.y
    if shape=="line":
        canvas.create_line(x1,y1,x2,y2,width=penWidth,fill=penColor)
    elif shape=="oval":
        canvas.create_oval(x1,y1,x2,y2,width=penWidth,fill=penColor,outline=penColor)
    elif shape=="rectangle":
        canvas.create_rectangle(x1,y1,x2,y2,width=penWidth,fill=penColor,outline=penColor)

def getColor():
    global penColor
    color=askcolor()
    penColor=color[1]

def getWidth():
    global penWidth
    penWidth=askinteger("선 두께","선 두께(1~10)를 입력하세요",minvalue=1,maxvalue=10)

def paint(event):
    x1,y1=(event.x),(event.y)
    x2,y2=(event.x+2),(event.y-2)
    canvas.create_oval(x1,y1,x2,y2, fill=mycolor)

def drawLine():
    global shape
    shape="line"

def drawOval():
    global shape
    shape="oval"

def drawRectangle():
    global shape
    shape="rectangle"

def eraser():
    canvas.delete("all")

def save(event):#화면 캡쳐 해서 파일에 저장
    x = window.winfo_rootx()
    y = window.winfo_rooty()#창의 위치 얻어오기
    w = window.winfo_width() + x
    h = window.winfo_height() + y#창의 크기 얻어오기

    box = (x, y, w, h)
    img=ImageGrab.grab(box)#창의 크기만큼만 이미지저장
    saveas='손예은_.bmp'
    img.save(saveas)

window=None
canvas=None
x1,y1,x2,y2=None,None,None,None #선의 시작점과 끝점
penColor='black' #선의 기본 색-검정
penWidth=5 #선의 기본 굵기-5
fillColor=None
shape="paint"

#if shape=="line":

#if shape=="oval":
#if shape=="rectangle":
if __name__=="__main__":
    window=Tk()
    window.title("그림판")
    canvas=Canvas(window,height=850,width=850)

canvas.bind("<Button-1>",mouseClick)
canvas.bind("<ButtonRelease-1>",mouseDrop)
canvas.bind('<B1-Motion>',paint)
canvas.bind("<Button-2>",eraser)
window.bind("<space>", save) #스페이스를 누루면 캡쳐 후 저장
canvas.pack()

mainMenu=Menu(window)
window.config(menu=mainMenu)

shapeMenu=Menu(mainMenu)
mainMenu.add_cascade(label="모양",menu=shapeMenu)
shapeMenu.add_command(label="선",command=drawLine)
shapeMenu.add_command(label="원",command=drawOval)
shapeMenu.add_command(label="사각형",command=drawRectangle)

fileMenu=Menu(mainMenu)
mainMenu.add_cascade(label="설정",menu=fileMenu)
fileMenu.add_command(label="색상 선택",command=getColor)
fileMenu.add_command(label="선 두께 결정",command=getWidth)
fileMenu.add_command(label="지우기",command=eraser)

window.mainloop()


import matplotlib.pyplot as plt

import numpy as np
import pandas as pd
import cv2
import tensorflow as tf
import os
from darkflow.net.build import TFNet
import random as rd
from sklearn.metrics import f1_score

expansion_rate = 2
path_test_data = "../training/"
#path_test_data = "labels/cup/images/"
path_result_folder = "mlp-training/result/"
path_premlp = "mlp-training/result/premlp/"
path_original = "mlp-training/result/original/"
path_cup = "labels/cup/images/"
path_cellphone = "labels/cellphone/images/"
path_paper = "labels/paper/images/"
path_mlp_training = "mlp-training/"

options = {"model": "cfg/truck-yolo.cfg", "load": -1, "gpu":0.75,"threshold":0.9}
#options = {"model": "cfg/truck-yolo.cfg", "load": -1, "gpu":0.0,"threshold":0.9}
#options = {"model": "cfg/truck-yolo.cfg", "load": 56500, "gpu":0.75}
path_yolo_test = "labels/cellphone/images/"

path_mlp_sample_image = "mlp-training/cellphone-0.jpg"
path_mlp_csv = "mlp-training/csv/truck_driver.csv"
path_mlp_model = "mlp-training/saved_models/model-800.ckpt"
size_mlp_data = (100,100)

def relu(num):
    if num > 0:
        return num
    else:
        return 0

def expansion(o_img,bbox,rate):
    img = o_img.copy()
    width = bbox[1] - bbox[0]
    height = bbox[3] - bbox[2]
    center = [bbox[0]+width/2,bbox[2]+height/2]

    new_bbox = [relu(round(center[0] - (width/2)*rate)), \
                relu(round(center[0] + (width/2)*rate)), \
                relu(round(center[1] - (height/2)*rate)), \
                relu(round(center[1] + (height/2)*rate)) ]
    img = img[new_bbox[2]:new_bbox[3], new_bbox[0]:new_bbox[1]]
    #print(center)
    #print(new_bbox)
    return img

def get_yolo_info(imgcv):
    result = tfnet.return_predict(imgcv)
    if len(result) != 0:
        result = result[0]
        info = {'xmin':result["topleft"]["x"],
                'xmax':result["bottomright"]["x"],
                'ymin':result["topleft"]["y"],
                'ymax':result["bottomright"]["y"],
                'label':result["label"]
               }
        return info
    else:
        return False

def pre_mlp(o_img,info,expansion_rate):
    #img = img[info['ymin']:info['ymax'],info['xmin']:info['xmax']]
    img = expansion(o_img, [info['xmin'],info['xmax'], info['ymin'], info['ymax']], expansion_rate)
    #img = expansion(img, [info['xmin'],info['xmax'], img.shape[0]-info['ymax'], img.shape[0]-info['ymin']], expansion_rate)
    return img

def draw(img,info):
    output = img.copy()
    cv2.rectangle(output, (info['xmin'], info['ymin']), (info['xmax'], info['ymax']), (0,0,255),2)
    text_x, text_y = info['xmax']+10 , info['ymin']+10
    cv2.putText(output, info['label'], (text_x, text_y),cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2, cv2.LINE_AA)
    return output

def detect(imgcv):
    result = tfnet.return_predict(imgcv)
    #print(type(result[0]["topleft"]["x"]))
    if len(result) != 0:
        result = result[0]
        cv2.rectangle(imgcv,
            (result["topleft"]["x"], result["topleft"]["y"]),
            (result["bottomright"]["x"],
            result["bottomright"]["y"]),
            (0, 255, 0), 4)
        text_x, text_y = result["topleft"]["x"] - 10, result["topleft"]["y"] - 10
        cv2.putText(imgcv, result["label"], (text_x, text_y),cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2, cv2.LINE_AA)
        #print(result)
        # cv2.imshow('Test',imgcv)
        # cv2.waitKey(0)
        # cv2.destroyAllWindows()
        return imgcv
    else:
        return np.array([])

img = cv2.imread(path_mlp_sample_image,0)
img2 = cv2.resize(img, size_mlp_data)
img2 = img2.flatten()
#print(img2.shape)

imv_csv = pd.read_csv(path_mlp_csv)
class_y = pd.get_dummies(imv_csv['class'], '').as_matrix()#將label做 one_hot encoding
x_train_list, y_train = imv_csv, class_y #資料切割

tf.reset_default_graph()

#### define placeholder ####
input_data = tf.placeholder(dtype=tf.float32,
                           shape=[None, img2.shape[0]],
                           name='input_data') #用來接 feature 資料進入 tensorflow

y_true = tf.placeholder(dtype=tf.float32,
                        shape=[None, y_train.shape[1]],
                        name='y_true') #用來接 label 資料進入 tensorflow

#### define variables(weight/bias) ####
x1 = tf.layers.dense(input_data, 256, activation=tf.nn.sigmoid, name='hidden1') #第一層hidden layer
x2 = tf.layers.dense(x1, 128, activation=tf.nn.sigmoid, name='hidden2') #第二層hidden layer
x3 = tf.layers.dense(x2, 64, activation=tf.nn.sigmoid, name='hidden3')#第三層hidden layer
out = tf.layers.dense(x3, y_train.shape[1], name='output')# output layer

y_pred = out

#### calculate loss ####
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true, logits=y_pred))

#### optimize variables ####
opt = tf.train.GradientDescentOptimizer(learning_rate=0.001)
update = opt.minimize(loss)

#### init ####
init = tf.global_variables_initializer()
config = tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.4
sess = tf.Session(config=config)
sess.run(init)

#tf.global_variables() ## 檢查 graph 裏的 global variables

'''rerun the graph first:
先回到上面將一開始和graph有關的cell先重新執行一遍，將graph架構先建立起來(這樣讀進來的參數才有對應位置存放)'''

sess = tf.Session()
saver = tf.train.Saver()
saver.restore(sess, path_mlp_model) #到我們剛剛存檔的路徑將檔案叫出來，放入graph中對應的參數位置

tfnet = TFNet(options)

def trucker(d,output_folder):
    # video_path = "../FullVideo/DISK1/"
    # video_list = os.listdir(video_path)
    # print(video_list)
    # print(len(video_list))

    date = d[-8:]

    path_video_result_folder = output_folder+"/"+date+"/"
    path_video_result_folder2 = output_folder+"/"+date+"/"+"original/"

#     if not os.path.isdir(path_video_premlp):
#         os.makedirs(path_video_premlp)
    if not os.path.isdir(path_video_result_folder):
        os.makedirs(path_video_result_folder)
    if not os.path.isdir(path_video_result_folder2):
        os.makedirs(path_video_result_folder2)

    video_list = []
    for video in os.listdir(d):
        if 'avi' in video:
            video_list.append(video)
    print(video_list)

    total = 0
    count = 0
    switch = 1
    move_list = []
    stop_count = []
    move_count = []
    status_list = []
    stop_rate = 0.8
    start_rate = 0.2
    standard = 0
    vnum = 1
    for video in video_list:
        print('Now processing:', video, vnum,"/",len(video_list))
        vnum+=1
        cap = cv2.VideoCapture(d+"/"+video)
        timeF = 100
        c = 0
        # 以迴圈從影片檔案讀取影格，並顯示出來
        while(cap.isOpened()):
            ret, frame = cap.read()
            if frame is None:
                break

            if(c%timeF==0):
                #print(c)
                #判斷車子是否行進間
    #             new_img = frame[100:250,350:500]
                new_img = frame[100:250,360:500]
                if c==0:
                    ret,previous = cv2.threshold(new_img,127,255,cv2.THRESH_BINARY)
                else:
                    ret,current = cv2.threshold(new_img,127,255,cv2.THRESH_BINARY)
                    minus = cv2.subtract(current,previous)
                    previous = current.copy()
                    move = np.sum(minus/255)

    #                 cv2.imshow('mytitle',minus)
    #                 #print(move)
    #                 if cv2.waitKey(1) & 0xFF == ord('q'):
    #                     break
    #                 if c== 3000:
    #                     cap.release()
    #                     cv2.destroyAllWindows()

                    if move < 2000:
                        status_list.append(0)
                    else:
                        status_list.append(1)

                    if len(status_list) == 10:
                        if sum(status_list) < 10*(1-stop_rate):
                            switch = 0
                        if sum(status_list) > 10*start_rate:
                            switch = 1
                        #print(status_list, switch)
                        status_list.pop(0)

                #print(type(frame))
                img = frame[:,5:300]

                if switch == 1:
                    yolo_info = get_yolo_info(img)
                    if yolo_info != False:
                        #print(yolo_info)
                        #yolo = draw(img, yolo_info)
                        #cv2.imwrite(path_video_yolo+str(c)+".jpg", yolo)
                        #cv2.imwrite(path_original+file, draw(img, yolo_info))
                        #expansion process
                        bbox = pre_mlp(img,yolo_info,expansion_rate)
                        #cv2.imwrite(path_video_premlp+video[:video.index('.')]+'_'+str(count)+".jpg", bbox)
                        #print(path_video_premlp+str(count)+".jpg")
                        #preprocess
                        bbox = cv2.resize(bbox,size_mlp_data)
                        bbox = cv2.cvtColor(bbox, cv2.COLOR_BGR2GRAY)
                        #print(bbox.shape)
                        bbox = bbox.flatten()
                        #print(bbox.shape)
                        #tmpx
                        tmpx = np.array([]).reshape((0, img2.shape[0]))
                        tmpx = np.row_stack([tmpx, bbox.flatten()])
                        tmpx /= 255
                        #tmpy
                        tmpy = np.array([]).reshape((0, y_train.shape[1]))
                        tmpy = np.row_stack([tmpy, class_y[0]])
                        tr_pred = sess.run([y_pred], feed_dict={input_data:tmpx})
                        #print('aaaaaa')
                        if tr_pred[0][0][0] > tr_pred[0][0][1]:
                        #if tr_pred[0][0][0] > 0.5:
                            print(tr_pred)
                            img = draw(img, yolo_info)
                            cv2.imwrite(path_video_result_folder+video[:video.index('.')]+'_'+str(count)+".jpg", img)
                            cv2.imwrite(path_video_result_folder2+video[:video.index('.')]+'_'+str(count)+".jpg", frame)
                            print(path_video_result_folder+video[:video.index('.')]+'_'+str(count)+".jpg")
                        count += 1
            c += 1
        print('total count:', count)
        print('----------------------------')
        cap.release()
        cv2.destroyAllWindows()
        #print('Object detected files:',count,'/',total)


# Km to Mil
# mengambil jumlah kilometer
kilometer = float(input("Masukan nilai kilometer: "))

# faktor konversi
# yang artinya perbedaan antara mil dan kilometer itu adalah 0,621371
conv_fac = 0.621371

# menghitung mil
mil = kilometer * conv_fac
print('%0.2f Kilometer sama dengan %0.2f Mil' %(kilometer,mil))

# Mil to Km
# mengambil jumlah mil
mil = float(input("Masukan nilai mil: "))

# faktor konversi
# yang artinya perbedaan antara mil dan kilometer itu adalah 0,621371
conv_fac = 1.621371

# menghitung mil
kilometer = mil * conv_fac
print('%0.2f Mil sama dengan %0.2f Kilometer' %(mil, kilometer))


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

# **Task 07: Querying RDF(s)**

# In[1]:

github_storage = "https://raw.githubusercontent.com/FacultadInformatica-LinkedData/Curso2021-2022/master/Assignment4/course_materials"

# Leemos el fichero RDF de la forma que lo hemos venido haciendo

# In[4]:

from rdflib import Graph, Namespace, Literal
from rdflib.namespace import RDF, RDFS
from rdflib.plugins.sparql import prepareQuery

g = Graph()
g.namespace_manager.bind('ns', Namespace("http://somewhere#"), override=False)
g.namespace_manager.bind('vcard', Namespace("http://www.w3.org/2001/vcard-rdf/3.0#"), override=False)
g.parse(github_storage+"/rdf/example6.rdf", format="xml")

# **TASK 7.1: List all subclasses of "Person" with RDFLib and SPARQL**

# In[202]:

# TO DO
ns = Namespace("http://somewhere#")

q1 = prepareQuery('''
  SELECT ?subcls WHERE {
    ?subcls rdfs:subClassOf+ ns:Person
  }
  ''', initNs = {
      "ns":ns,
      "rdfs":RDFS
  }
)

# Visualize the results
for r in g.query(q1):
    print(r.subcls)

# In[203]:

for s,p,o in g.triples((None, RDFS.subClassOf, ns.Person)):
    print(s,p,o)
    for s1,p1,o1 in g.triples((None, p, s)):
        print(s1,p1,o1)

# **TASK 7.2: List all individuals of "Person" with RDFLib and SPARQL (remember the subClasses)**
#

# In[204]:

for s,p1,o in g.triples((None, RDF.type, ns.Person)):
        print(s,p,o)

for s, p, o in g.triples((None, RDFS.subClassOf, ns.Person)):
    for s1,p1,o1 in g.triples((None, RDF.type, s)):
        print(s1,p1,o1)

# Visualize the results

# In[205]:

q2 = prepareQuery('''
  SELECT  ?names WHERE {
    ?class rdfs:subClassOf* ns:Person .
    ?names a ?class .
  }
  ''', initNs = {
      "ns":ns,
      "rdfs":RDFS,
  }
)

# Visualize the results
for r in g.query(q2):
    print(r.names)

# **TASK 7.3: List all individuals of "Person" and all their properties including their class with RDFLib and SPARQL**
#

# In[206]:

q3 = prepareQuery('''
  SELECT ?names ?prop ?val WHERE {
    ?cls rdfs:subClassOf* ns:Person .
    ?names a ?cls .
    ?names ?prop ?val

  }
  ''', initNs = {
      "ns":ns,
      "rdfs":RDFS,
  }
)

# Visualize the results
for r in g.query(q3):
  print(r.names, r.prop, r.val)
# Visualize the results

# In[207]:

def individuals_and_prop(sub, prop, cls):
    for s1, p1, o1 in g.triples((sub, prop, cls)):
        for s2, p2, o2 in g.triples((s1, None, None)):
            print(s2,p2,o2)

individuals_and_prop(None, RDF.type, ns.Person)
for s, p, o in g.triples((None, RDFS.subClassOf, ns.Person)):
    individuals_and_prop(None, RDF.type, s)

# In[ ]:


from collections import deque

"""
    Use DFS to determine whether an undirected graph has a cycle, if so find such a cycle
"""
class Cycle:
    def __init__(self, G):
        if self.has_parallel_edges(G): return

        self.marked = [False] * G.V
        self.edge_to = [0] * G.V
        self.cycle = None
        for v in range(G.V):
            if not self.marked[v]:
                self._dfs(G, v)

    def _dfs(self, G, v):
        self.marked[v] = True
        for w in G.adj[v]:
            if self.cycle: return

            elif not self.marked[w]:
                self.edge_to[w] = v
                self._dfs(G, w)
            elif w != self.edge_to[v]:    # ignore reverse edge leading to v
                self.cycle = deque()
                self.cycle.appendleft(w)
                x = v
                while x != w:
                    self.cycle.appendleft(x)
                    x = self.edge_to[x]
                self.cycle.appendleft(w)
                return

    def has_parallel_edges(self, G):
        self.marked = [False] * G.V
        for v in range(G.V):
            for w in G.adj[v]:
                if self.marked[w]:
                    self.cycle = deque()
                    self.cycle.append(v)
                    self.cycle.append(w)
                    self.cycle.append(v)
                    return True
                self.marked[w] = True
            for w in G.adj[v]:
                self.marked[w] = False
        return False

    def hascycle(self):
        return self.cycle != None

    def getcycle(self):
        return self.cycle

if __name__ == '__main__':
    import sys
    from graph import Graph
    G = Graph.create(sys.stdin)
    c = Cycle(G)
    if c.hascycle():
        print(f"Graph has cycle:")
        print('-'.join(str(v) for v in c.getcycle()))
    else:
        print(f"Graph is acyclic")


"""empty message

Revision ID: 3b52ec217d5c
Revises: 477cd18a5fa8
Create Date: 2019-05-29 03:05:03.622388

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '3b52ec217d5c'
down_revision = '477cd18a5fa8'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('projectslog', sa.Column('group_id', sa.String(), nullable=False))
    op.add_column('projectslog', sa.Column('supervisor_id', sa.String(), nullable=False))
    op.create_foreign_key(None, 'projectslog', 'groups', ['group_id'], ['id'])
    op.create_foreign_key(None, 'projectslog', 'supervisors', ['supervisor_id'], ['id'])
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_constraint(None, 'projectslog', type_='foreignkey')
    op.drop_constraint(None, 'projectslog', type_='foreignkey')
    op.drop_column('projectslog', 'supervisor_id')
    op.drop_column('projectslog', 'group_id')
    # ### end Alembic commands ###


import numpy

class newtongauss:

  # f   is the vectorised function
  # fs  is scalar version of function
  # p   adjustable parameters of function
  # pf  fixed parameters of function
  # x array
  # y array

  @staticmethod
  def fit(f, p, pf, x, y, fs = None):
    if(fs == None):
      fs = f

    p_best = p
    rss_best = newtongauss.rss(f, p, pf, x, y)

    loop = True
    cycle = 0
    while(loop):

      R = newtongauss.residual(f, p, pf, x, y)        # R
      J = newtongauss.jacobian(f, fs, p, pf, x, y)        # J

      JT = numpy.transpose(J)
      JTJ = numpy.matmul(JT, J)
      JTR = numpy.matmul(JT, R)

      dp = numpy.linalg.solve(JTJ, -JTR)
      p = p + dp
      if(newtongauss.rss(f, p, pf, x, y) < rss_best):
        rss_best = newtongauss.rss(f, p, pf, x, y)
        p_best = numpy.copy(p)
      else:
        loop = False
      cycle = cycle + 1
      if(cycle > 10):
        loop = False
    return p_best

  @staticmethod
  def residual(f, p, pf, x, y):
    # Calculate residual
    return f(x[:], p, pf) - y[:]

  @staticmethod
  def jacobian(f, fs, p, pf, x, y):
    dl = len(x)
    pl = len(p)
    J = numpy.zeros((dl, pl), dtype=numpy.float64)
    h = 0.000001

    for i in range(0, dl):
      for j in range(0, pl):
        # Reset parameters
        p_b = numpy.copy(p)
        p_f = numpy.copy(p)
        # Vary jth parameter
        p_b[j] = p_b[j] - 0.5 * h
        p_f[j] = p_f[j] + 0.5 * h
        # Calc J matrix

        J[i,j] = (fs(x[i], p_f, pf) - fs(x[i], p_b, pf)) / h

    return J

  @staticmethod
  def rss(f, p, pf, x, y):
    return sum((f(x[:], p, pf) - y[:])**2)


from typing import List

class Solution:
    def arrayStringsAreEqual(self, word1: List[str], word2: List[str]) -> bool:
        w1 = ""
        w2 = ""
        for w in word1:
            w1 += w
        for w in word2:
            w2 += w
        return w1 == w2

word1 = ["ab", "c"]
word2 = ["a", "bc"]

word1 = ["a", "cb"]
word2 = ["ab", "c"]
print(Solution.arrayStringsAreEqual(Solution, word1, word2))

1662 Check If Two String Arrays are Equivalent.py


from cmath import log, sqrt, log10
from numpy import pi, cos, exp, sin, isnan
from .BlasiusCorrelation import *

def F_Void_8(G, x, Dl, Dv, ST):
    # print(x)
    g = 9.81
    # Void Fraction (Rouhani-Axelsson drift flux model)
    #e=(x/Dv)*((1+0.12*(1-x))*((x/Dv)+((1-x)/Dl))+((1.18*(1-x)*(g*ST*(Dl-Dv))**(1/4))/(G*Dl**(1/2))))**(-1)

    # Homogeneous Void Fraction
    # print(x, Dv, Dl)
    if x <= 0:
        return 0
    elif x >= 1:
        return 1

    eH=1/(1+((1-x)/x)*(Dv/Dl));

    #Rouhani Void Fraction
    er=(x/Dv)*((1+0.12*(1-x))*((x/Dv)+((1-x)/Dl))+((1.18*(1-x)*(g*ST*(Dl-Dv))**(1/4))/(G*Dl**(1/2))))**(-1)

    #Logarithmic Mean Void Fraction
    # e = (eH-er)/log(eH/er)
    # e = er
    return er

def F_xia_18(Dl, Dv, Vl, Vv):
    #Intermittent to Annular Flow Transition Boundary
    xia=(1.8**(1/0.875)*(Dv/Dl)**(-1/1.75)*(Vl/Vv)**(-1/7)+1)**(-1);
    return xia

def F_xia_18con(Dl, Dv, Vl, Vv):
    xia=(0.2914*(Dv/Dl)**(-1/1.75)*(Vl/Vv)**(-1/7)+1)**(-1) #0.2914 replaced 1.8**(1/0.875)
    return xia

def F_Ald_9(d, A, e):
    Ald = A*(1-e)/d**2
    return Ald

def F_Avd_10(d, A, e):
    Avd = A*e/d**2
    return Avd

def F_Gstrat_17con(d, A, x, e, Dl, Dv, Vl):
    g = 9.81

    #Dimensionless Cross Sectional Area Occupied by Vapor Phase
    Avd=F_Avd_10( d,A,e );
    #Dimensionless Cross Sectional Area Occupied by Liquid Phase
    Ald=F_Ald_9( d,A,e );

    #Transition Boundary - Stratified to Stratified-Wavy (S-SW)
    # if x<xia;
    # Gstrat=((226.3**2*Ald_xia*Avd_xia**2*Dv*(Dl-Dv)*Vl*g)/(xia**2*(1-xia)*pi**3))**(1/3);
    # else
    Gstrat=((226.3**2*Ald*Avd**2*Dv*(Dl-Dv)*Vl*g)/(x**2*(1-x)*pi**3))**(1/3)+20*x;   #20*x is new
    return Gstrat

def F_StratAngle_13(e):
    Ang_strat=2*pi-2*(pi*(1-e)+((3*pi)/2)**(1/3)*(1-2*(1-e)+(1-e)**(1/3)-e**(1/3))-(1/200)*(1-e)*e*(1-2*(1-e))*(1+4*((1-e)**2+e**2)))
    return Ang_strat

def F_hld_11(e):
    StratAngle=F_StratAngle_13(e)
    hld=0.5*(1-cos((2*pi-StratAngle)/2))
    return hld

def F_Gwavy_16con(G, d, A, x, e, Dl, Dv, ST):
    #Kattan-Thome-Favrat criterion
    g = 9.81
    #G=1; # G as fake input to weber and Froude, will be divided away.

    #Dimensionless Cross Sectional Area Occupied by Vapor Phase
    Avd=F_Avd_10( d,A,e );

    #Dimensionless Vertical Height of the Liquid
    hld = F_hld_11(e);

    #Liquid Froude Number
    #Frl=F_FroudeLiquid_15( G,d,Dl );

    #Liquid Weber Number for Flow Pattern
    #Wel=F_Weber_16_21( G,d,Dl,ST);

    Wel_Frl=g*d**2*Dl/ST #(We/Fr)l
    Gwavy=(((16*Avd**3*g*d*Dl*Dv)/(x**2*pi**2*(1-(2*hld-1)**2)**(1/2)))*((pi**2/(25*hld**2))*(Wel_Frl)**(-1.023)+1))**(1/2)+50-75*exp(-(x**2-0.97)**2/x/(1-x))
    Gwavy_org = Gwavy

    #Find lowest point on curve
    xn=x
    dx=0.01
    dG=-1
    Gwavy2=Gwavy;
    while dG<0:
        xn=xn-dx
        if xn<0:
            xn=0
        en=F_Void_8(G,xn,Dl,Dv,ST);
        hldn=F_hld_11( en );
        Avdn=F_Avd_10( d,A,en );
        if xn != 0:
            Gwavy2=(((16*Avdn**3*g*d*Dl*Dv)/(xn**2*pi**2*(1-(2*hldn-1)**2)**(1/2)))*((pi**2/(25*hldn**2))*(Wel_Frl)**(-1.023)+1))**(1/2)+50-75*exp(-(xn**2-0.97)**2/xn/(1-xn));
        else:
            Gwavy2 = float("inf")
        dG=Gwavy2-Gwavy
        if Gwavy2<Gwavy and x>0.3:
            Gwavy=Gwavy2
    return Gwavy

def F_Gbub_26(d, A, x, e, Dl, Dv, Vl):
    g = 9.81
    #Perimeter of Interface
    Pid=F_PiD_12(e);

    #Dimensionless Cross Sectional Area Occupied by Vapor Phase
    Avd=F_Avd_10( d,A,e );

    #Dimensionless Cross Sectional Area Occupied by Liquid Phase
    Ald=F_Ald_9( d,A,e );

    #Transition Boundary - Intermittent to Bubbly Flow (I-B)
    Gbub=((256*Avd*Ald**2*d**(1.25)*Dl*(Dl-Dv)*g)/(0.3164*(1-x)**(1.75)*pi**2*Pid*Vl**(0.25)))**(1/1.75);
    return Gbub

def F_Gbub_22con(d, A, x, e, Dl, Dv, Vl):
    g = 9.81

    #Perimeter of Interface
    # Pid=F_PiD_12(e)

    #Dimensionless Cross Sectional Area Occupied by Vapor Phase
    # Avd=F_Avd_10( d,A,e )

    #Dimensionless Cross Sectional Area Occupied by Liquid Phase
    # Ald=F_Ald_9( d,A,e )

    #Transition Boundary - Intermittent to Bubbly Flow (I-B)
    #Gbub=((256*Avd*Ald**2*d**(1.25)*Dl*(Dl-Dv)*g)/(0.3164*(1-x)**(1.75)*pi**2*Pid*Vl**(0.25)))**(1/1.75);
    Gbub=F_Gbub_26(d,A,x,e,Dl,Dv,Vl);
    return Gbub

def F_Gmist_19con(G, d, A, x, e, Dl, Dv, ST):
    # G = 300
    g = 9.81
    # G=1; # G as fake input to weber and Froude, will be divided away.
    #Dimensionless Cross Sectional Area Occupied by Liquid Phase
    Ald=F_Ald_9( d,A,e );
    Avd=F_Avd_10( d,A,e );

    #Liquid Froude Number
    #Frl=F_FroudeLiquid_15( G,d,Dl );

    #Liquid Weber Number for Flow Pattern
    #Wel=F_Weber_16_21( G,d,Dl,ST);

    Wel_Frl=g*d**2*Dl/ST
    Fac=(1.138+2*log10(pi/1.5/Ald))**(-2)
    Gmist = (7680*(Avd**2)*g*d*Dl*Dv*(Wel_Frl)**(-1)/(x**2*(pi**2)*Fac))**0.5

    Gmist_org=Gmist

    # Find lowest point on curve
    xn=x
    dx=0.01
    dG=-1
    while dG.real<0:
        xn=xn-dx
        if xn<0:
            xn=0
        en=F_Void_8(G,xn,Dl,Dv,ST);
        Aldn=F_Ald_9( d,A,en );
        Avdn=F_Avd_10( d,A,en );
        Facn=(1.138+2*log10(pi/1.5/Aldn))**(-2);

        Gmist2 = (7680*(Avdn**2)*g*d*Dl*Dv*(Wel_Frl)**(-1)/(xn**2*(pi**2)*Facn))**0.5;
        dG=Gmist2-Gmist
        if Gmist2.real<Gmist.real and x>0.3:
            Gmist=Gmist2;

    #Gmist=Gmist_org;
    #--------evaporation----
    # qcrit=F_CHF_23(Dl,Dv,Hl,Hv,ST);
    # Gdry=F_Gdry_19(q,d,x,Dl,Dv,Hl,Hv,ST);
    # #Transition Boundary - Dryout to Mist Flow (D-M) (Thome et al.)
    # Gmist=((1/0.502)*(log(0.61/x)+0.57)*(d/(Dv*ST))**(-0.16)*(1/(g*d*Dv*(Dl-Dv)))**(-0.15)*(Dv/Dl)**(0.09)*(q/qcrit)**(-0.72))**(1.613);
    # if Gmist<=Gdry
    #     Gmist=Gdry;
    return Gmist

def F_PiD_12(e):
    StratAngle = F_StratAngle_13(e)
    PiD=sin((2*pi-StratAngle)/2)
    return PiD

def F_FilmAngle_8130con(G, d, A, x, e, Dl, Dv, Vl, ST):
    Gstrat=F_Gstrat_17con(d,A,x,e,Dl,Dv,Vl)
    Gwavy=F_Gwavy_16con(G,d,A,x,e,Dl,Dv,ST)
    AngleStrat=F_StratAngle_13(e)

    FilmAngle=sqrt(AngleStrat*((Gwavy-G)/(Gwavy-Gstrat))).real;
    return FilmAngle

def F_RElo_38(G, d, Vl):
    RElo=G*d/Vl
    return RElo

def F_flo_37(G, d, Vl):
    RElo=F_RElo_38(G,d,Vl);
    flo=BlasiusCorrelation(RElo)[0]/4;
    return flo

def F_DPlo_36(G, d, Dl, Vl):
    flo=F_flo_37(G,d,Vl)
    DPlo=(4*flo/d)*(G**2/(2*Dl))
    return DPlo

def F_DPbub_56(G, d, x, e, Dl, Dv, Vl, Vv, ST):
    DPa=F_DPannu_29(G,d,x,e,Dl,Dv,Vv,ST);
    xia=F_xia_18(Dl,Dv,Vl,Vv);
    eia=F_Void_8(G,xia,Dl,Dv,ST);
    DPlo=F_DPlo_36(G,d,Dl,Vl);
    DPb=DPlo*(1-e/eia)+DPa*(e/eia);
    return DPb

def F_DPannu_29(G, d, x, e, Dl, Dv, Vv, ST):
    #Mean Vapor Phase Velocity
    uv=F_uv_31(G,x,e,Dv);
    #2-Phase Friction Factor for Annular Flow
    fa= F_fa_30( G,d,x,e,Dl,Vv,ST )
    #Frictional Pressure Drop for Annular Flow
    DPa=(4*fa/d)*((Dv*uv**2)/2)
    return DPa

def F_uv_31(G, x, e, Dv):
    # print(G, x, e, Dv)
    if e == 0:
        return 1e6
    uv=G*x/(Dv*e)
    return uv

def F_Rev_32(G, d, x, e, Vv):
    Rev=G*x*d/(Vv*e)
    return Rev

def F_ul_34(G, x, e, Dl):
    ul=G*(1-x)/(Dl*(1-e))
    return ul

def F_WeberLiquid_33(G, d, x, e, Dl, ST):
    ul = F_ul_34(G, x, e, Dl);
    Wel = Dl*ul**2*d/ST;
    return Wel

def F_fa_30(G, d, x, e, Dl, Vv, ST):
    Rev=F_Rev_32(G,d,x,e,Vv);
    Wel=F_WeberLiquid_33(G,d,x,e,Dl,ST);
    fa=3.128*Rev**(-0.454)*Wel**(-0.0308);
    return fa

def F_DPmist_45(G, d, x, Dl, Dv, Vl, Vv):
    #Homogeneous Dynamic Viscosity (Ciccitti)
    VH=Vl*(1-x)+Vv*x;
    #Mist Flow Reynolds Number
    Rem=(G*d)/VH;
    #Mist Flow Friction Factor
    fm=91.2/Rem**(0.832);
    #Homogeneous Void Fraction
    eH=(1+((1-x)/x)*(Dv/Dl))**(-1);
    #Homogeneous Density
    DH=Dl*(1-eH)+Dv*eH;
    #Frictional Pressure Drop for Mist Flow
    DPm=(4*fm/d)*(G**2/(2*DH));
    return DPm

def F_fv_43(G, d, x, e, Vv):
    REv=F_Rev_32(G,d,x,e,Vv)
    fv=BlasiusCorrelation(REv)[0]/4
    return fv

def F_fs_53(G, d, x, e, Dl, Vv, ST):
    StratAngle = F_StratAngle_13(e)/(2*pi)
    fa=F_fa_30(G, d, x, e, Dl, Vv, ST)
    fv=F_fv_43(G,d,x,e,Vv)
    fs=StratAngle*fv+(1-StratAngle)*fa
    return fs

def F_DPstrat_52(G, d, x, e, Dl, Dv, Vl, Vv, ST):
    uv=F_uv_31(G, x, e, Dv);
    fs=F_fs_53(G, d, x, e, Dl, Vv, ST);
    DPs=4*fs*Dv*uv**2/(2*d);
    xia=F_xia_18(Dl,Dv,Vl,Vv);
    eia=F_Void_8(G,xia,Dl,Dv,ST);
    if x < xia:
        DPlo=F_DPlo_36(G,d,Dl,Vl);
        DPs=DPlo*(1-e/eia)+DPs*(e/eia);
    return DPs

def F_DPsw_39(G, d, A, x, e, Dl, Dv, Vl, Vv, ST):
    #Mean Vapor Phase Velocity
    uv=F_uv_31(G,x,e,Dv);

    fsw=F_fsw_40( G,d,A,x,e,Dl,Dv,Vl,Vv,ST );

    #Frictional Pressure Drop for Stratified-Wavy Flow
    #DPsw=4*fsw*((l*Dv*Vv**2)/(2*d)); bug in Joao's code
    DPsw=4*fsw*((Dv*uv**2)/(2*d));
    return DPsw

def F_DryAngle_42( G,d,A,x,e,Dl,Dv,Vl,Vv,ST ):
    StratAngle=F_StratAngle_13(e);
    Gwavy=F_Gwavy_14(G,d,A,x,e,Dl,Dv,ST);
    Gstrat= F_Gstrat_17(G,d,A,x,e,Dl,Dv,Vl,Vv,ST) ;
    DryAngle=StratAngle*((Gwavy-G)/(Gwavy-Gstrat))**0.61;
    return DryAngle

def F_fsw_40(G, d, A, x, e, Dl, Dv, Vl, Vv, ST):
    DryAngle=F_DryAngle_42( G,d,A,x,e,Dl,Dv,Vl,Vv,ST )/(2*pi);
    fa=F_fa_30(G,d,x,e,Dl,Vv,ST);
    fv=F_fv_43(G,d,x,e,Vv);
    fsw=DryAngle**0.02*fv+(1-DryAngle)**0.02*fa;
    return fsw

def F_DPslug_int_35(G, d, x, e, Dl, Dv, Vl, Vv, ST):
    #Delta P for slug and intermittent flow
    DPlo=F_DPlo_36(G,d,Dl,Vl);
    DPa=F_DPannu_29(G,d,x,e,Dl,Dv,Vv,ST);
    xia=F_xia_18(Dl,Dv,Vl,Vv);
    eia=F_Void_8(G,xia,Dl,Dv,ST);

    DPsi=DPlo*(1-(e/eia))+DPa*(e/eia);
    return DPsi

def F_DPmomentum_28(G, q, A, Ph, x, e, Dl, Dv, Hl, Hv, ST):
    l=0.01;
    Q=q*Ph*l;
    MF=G*A;
    xin=x;
    ein=e;
    xout=Q/(MF*(Hv-Hl))+xin;
    eout=F_Void_8(G,xout,Dl,Dv,ST);
    dPm=G**2*((((1-xin)**2/Dl*(1-ein))+(xin**2/Dv*ein))-(((1-xout)**2/Dl*(1-eout))+(xout**2/Dv*eout)))/l;
    return dPm

def F_HTC_8123con(G, q, d, A, x, e, FilmAngle, Dl, Dv, CPl, Kl, Hl, Hv, Vl, ST):
    #Fluid,P,H,G,q,d,A,Ph,Ep,Angle,x,e,Angle_dry,Dl,Dv,Cpl,Kl,Kv,Hl,Hv,Vl,Vv,ST
    #htc
    htcAxial=F_htcAxial_8132con(G,d,A,x,e,Dl,Dv,CPl,Kl,Vl,ST);
    #htf
    htcFilm=F_htcFilm_8143con(q,d,Dl,Dv,Kl,Vl,Hl,Hv);
    #htp
    htc=(htcFilm*FilmAngle+(2*pi-FilmAngle)*htcAxial)/(2*pi);

    return htc

def F_htcFilm_8143con(q, d, Dl, Dv, Kl, Vl, Hl, Hv):
    #Fluid,P,H,G,q,d,A,Ph,Ep,Angle,x,e,Angle_dry,Dl,Dv,Kl,Kv,Hl,Hv,Vl,Vv,ST
    g=9.81;
    htf=0.655*(Dl*(Dl-Dv)*g*(Hv-Hl)*Kl**3/(Vl*d*q))**(1/3);
    return htf

def F_htcAxial_8132con(G, d, A, x, e, Dl, Dv, CPl, Kl, Vl, ST):
    c=0.003
    n=0.74
    m=0.5
    dfilm=F_dfilm_8135con(G,d,A,x,e,Dl,Dv,Vl,ST);
    # print(G, d, A, x, e, Dl, Dv, Vl, ST);

    #numpy.float64 returns a nan when negative number is raised to fractional power, so we must explicity cast to float64
    #https://stackoverflow.com/questions/52708265/why-do-negative-numpy-float64-yield-nan-when-expontiated-with-a-fractional-numbe
    Rel=float(F_ReL_8133con(G,x,e,Vl,dfilm));

    Pr=F_Prandtx( CPl,Kl,Vl) ;
    Gstrat=F_Gstrat_17con(d,A,x,e,Dl,Dv,Vl);
    fi=F_fi_8140con(G,d,A,x,e,Dl,Dv,Vl,ST);
    # print(dfilm, Rel, Pr, Gstrat, fi)
    if G<Gstrat:
        fi=fi*G/Gstrat
    htc=c*Rel**n*Pr**m*Kl/dfilm*fi;
    return htc

def F_fi_8140con(G, d, A, x, e, Dl, Dv, Vl, ST):
    g=9.81;
    dfilm=F_dfilm_8135con(G,d,A,x,e,Dl,Dv,Vl,ST);
    uv=G*x/(Dv*e);
    ul=G*(1-x)/(Dl*(1-e));
    fi=1+(uv/ul)**0.5*((Dl-Dv)*g*dfilm**2/ST)**0.25;
    return fi

def F_dfilm_8135con(G, d, A, x, e, Dl, Dv, Vl, ST):
    Al=A*(1-e)
    FilmAngle=F_FilmAngle_8130con(G,d,A,x,e,Dl,Dv,Vl,ST);
    dfilm=(d-(d**2-Al*8/(2*pi-FilmAngle))**0.5)/2;
    # print(FilmAngle, dfilm);
    # dAl=1;
    # dfilm=0;
    # while dAl>1e-20;
    # Al_guess=((2*pi-FilmAngle)/8)*(d**2-(d-2*dfilm)**2);
    # dAl=Al-Al_guess;
    # dfilm=dfilm+1e-8;

    dfilm=(d/2)-sqrt((d/2)**2-(2*Al)/(2*pi-FilmAngle));
    if dfilm.real>d/2:
        dfilm=d/2
    return dfilm.real

def F_ReL_8133con(G, x, e, Vl, df):
    Rel=4*G*(1-x)*df/(1-e)/Vl
    return Rel

def F_Prandtx(CPx, Kx, Vx):
    #Liquid or vapor Prandtl number
    PR=(CPx*Vx)/Kx;
    return PR

def F_Gwavy_14(G, d, A, x, e, Dl, Dv, ST):
    #Kattan�Thome�Favrat criterion
    g=9.81;

    #Dimensionless Cross Sectional Area Occupied by Vapor Phase
    Avd=F_Avd_10( d,A,e );

    #Dimensionless Vertical Height of the Liquid
    hld=F_hld_11( e );

    #Liquid Froude Number
    #Frl=F_FroudeLiquid_15( G,d,Dl );

    #Liquid Weber Number for Flow Pattern

    #Wel=F_Weber_16_21( G,d,Dl,ST);

    Wel_Frl=g*d**2*Dl/ST; # (We/Fr)l

    #Transition Boundary - Stratified-Wavy to Intermittent and Annular (SW-I/A)
    Gwavy=(((16*Avd**3*g*d*Dl*Dv)/(x**2*pi**2*(1-(2*hld-1)**2)**(1/2)))*(((pi**2)/(25*hld**2))*(Wel_Frl)**-1+1))**(1/2)+50;
    return Gwavy

def F_Gstrat_17(G, d, A, x, e, Dl, Dv, Vl, Vv, ST):
    #Fluid,P,H,G,q,d,A,Ph,Ep,Angle,x,e,Angle_dry,Dl,Dv,Hl,Hv,Vl,Vv
    g=9.81;
    xia=F_xia_18(Dl,Dv,Vl,Vv);
    eia=F_Void_8(G,xia,Dl,Dv,ST);
    #Dimensionless Cross Sectional Area Occupied by Vapor Phase
    Avd=F_Avd_10( d,A,e );
    Avd_xia=F_Avd_10( d,A,eia );
    #Dimensionless Cross Sectional Area Occupied by Liquid Phase
    Ald=F_Ald_9( d,A,e );
    Ald_xia=F_Ald_9( d,A,eia );

    #Transition Boundary - Stratified to Stratified-Wavy (S-SW)
    if x<xia:
        Gstrat=((226.3**2*Ald_xia*Avd_xia**2*Dv*(Dl-Dv)*Vl*g)/(xia**2*(1-xia)*pi**3))**(1/3);
    else:
        Gstrat=((226.3**2*Ald*Avd**2*Dv*(Dl-Dv)*Vl*g)/(x**2*(1-x)*pi**3))**(1/3);
    return Gstrat

def F_Gmist_24(q,d,x,Dl,Dv,Hl,Hv,ST):
    g=9.81
    qcrit=F_CHF_23(Dl,Dv,Hl,Hv,ST);
    Gdry=F_Gdry_19(q,d,x,Dl,Dv,Hl,Hv,ST);
    #Transition Boundary - Dryout to Mist Flow (D-M) (Thome et al.)
    if q == 0 or x == 0:
        return float('inf')
    Gmist=((1/0.502)*(log(0.61/x)+0.57)*(d/(Dv*ST))**(-0.16)*(1/(g*d*Dv*(Dl-Dv)))**(-0.15)*(Dv/Dl)**(0.09)*(q/qcrit)**(-0.72))**(1.613);
    if Gmist.real<=Gdry.real:
        Gmist=Gdry
    return Gmist.real

def F_FroudeVapor_22( G,d,Dl,Dv ):
    # Froude vapor by Mori et al.
    g=9.81;
    Frv=G**2/(Dv*(Dl-Dv)*g*d);
    return Frv

def F_FroudeLiquid_15( G,d,Dl ):
    g=9.81;
    Frl=G**2/(Dl**2*g*d);
    return Frl

def F_CHF_23(Dl, Dv, Hl, Hv, ST):
    g=9.81
    #Critical Heat Flux (By Kutateladze)
    qcrit=0.131*Dv**(0.5)*(Hv-Hl)*(g*ST*(Dl-Dv))**(0.25);
    return qcrit

def F_Gdry_19(q, d, x, Dl, Dv, Hl, Hv, ST):
    g=9.81;
    qcrit=F_CHF_23(Dl,Dv,Hl,Hv,ST)
    # print(q, d, x, Dl, Dv, Hl, Hv, ST)
    if q == 0 or x == 0:
        return float('inf')
    Gdry=((1/0.236)*(log(0.58/x)+0.52)*(d/(Dv*ST))**(-0.17)*(1/(g*d*Dv*(Dl-Dv)))**(-0.17)*(Dv/Dl)**(-0.25)*(q/qcrit)**(-0.27))**(1.471);
    return Gdry

def F_Weber_16_21(G, d, Dx, ST):
    #Weber nummer. Dx is either the liquid or the vapor density
    We=(G**2*d)/(Dx*ST);
    return We

def F_xde_25(G, q, d, Dl, Dv, Hl, Hv, ST):
    #Dry out completion vapor quality
    #Fluid,P,H,G,q,d,A,Ph,Ep,Angle,x,e,Angle_dry,Dl,Dv,Hl,Hv,Vl,Vv,ST
    qcrit=F_CHF_23(Dl,Dv,Hl,Hv,ST);
    Wev=F_Weber_16_21( G,d,Dv,ST );
    Frv=F_FroudeVapor_22( G,d,Dl,Dv );
    xde=0.61*exp(0.57-0.502*Wev**(0.16)*Frv**(0.15)*(Dv/Dl)**(-0.09)*(q/qcrit)**(0.72));
    return xde

def F_xdi_20(G, q, d, Dl, Dv, Hl, Hv, ST):
    #Dry out inception vapor quality
    qcrit = F_CHF_23(Dl, Dv, Hl, Hv, ST)
    Wev = F_Weber_16_21(G, d, Dv, ST )
    Frv = F_FroudeVapor_22(G, d, Dl, Dv)
    xdi=0.58*exp(0.52-0.236*Wev**(0.17)*Frv**(0.17)**(Dv/Dl)**(0.25)*(q/qcrit)**(0.27))
    return xdi

def F_DPslug_sw_44(G,d,A,x,e,Dl,Dv,Vl,Vv,ST):
    # Delta P for slug and stritified wavy flow
    DPlo=F_DPlo_36(G,d,Dl,Vl);
    DPsw=F_DPsw_39(G,d,A,x,e,Dl,Dv,Vl,Vv,ST);
    xia=F_xia_18(Dl,Dv,Vl,Vv);
    eia=F_Void_8(G,xia,Dl,Dv,ST);

    DPssw=DPlo*(1-(e/eia))+DPsw*(e/eia);
    return DPssw

def F_DPdry_51(G, q, d, A, x, Dl, Dv, Hl, Hv, Vl, Vv, ST):
    xia = F_xia_18(Dl,Dv,Vl,Vv);
    xdi = F_xdi_20( G,q,d,Dl,Dv,Hl,Hv,ST);
    xde = F_xde_25( G,q,d,Dl,Dv,Hl,Hv,ST);
    edi = F_Void_8(G,xdi,Dl,Dv,ST);
    Gwavy = F_Gwavy_14(G,d,A,xdi,edi,Dl,Dv,ST);
    DPm = F_DPmist_45(G,d,xde,Dl,Dv,Vl,Vv);
    if G >= Gwavy and xdi < xia:
        DP=F_DPbub_56(G,d,xdi,edi,Dl,Dv,Vl,Vv,ST ) ;
    elif G >= Gwavy and xdi >= xia:
        DP=F_DPannu_29(G,d,xdi,edi,Dl,Dv,Vv,ST);
    else:
        DP=F_DPsw_39(G,d,A,xdi,edi,Dl,Dv,Vl,Vv,ST);
    DPd=DP-(((x-xdi)/(xde-xdi))*(DP-DPm));
    return DPd

def F_PiD_12(e):
    StratAngle=F_StratAngle_13(e);
    PiD=sin((2*pi-StratAngle)/2);
    return PiD

def F_HTCannu_int_bub_slug(p, G, q, d, A, x, e, CPl, CPv, Dl, Dv, Kl, Kv, Vl, Vv, ST):
    DryAngle=0;
    htp=F_HTCtp_1( p,G,q,d,A,x,e,CPl,CPv,Dl,Dv,Kl,Kv,Vl,Vv,ST,DryAngle);
    return htp

def F_HTCstrat( p,G,q,d,A,x,e,CPl,CPv,Dl,Dv,Kl,Kv,Vl,Vv,ST):
    DryAngle=F_StratAngle_13(e);
    htp=F_HTCtp_1( p,G,q,d,A,x,e,CPl,CPv,Dl,Dv,Kl,Kv,Vl,Vv,ST,DryAngle);
    return htp

def F_HTCtp_1045evap( fluid,G,q,d,A,x,e,CPl,Cpv,Kl,Kv,Vl,Vv,DryAngle):
    # hvap=F_hvap_1049evap(G,d,x,e,Cpv,Kv,Vv);
    # hwet=F_hwet_1046evap( fluid,G,q,d,A,x,e,CPl,Kl,Vl,DryAngle);
    hvap = hwet = 0.2
    htp=(DryAngle*hvap+(2*pi-DryAngle)*hwet)/(2*pi);
    return htp

def F_HTCsw( p,G,q,d,A,x,e,CPl,CPv,Dl,Dv,Kl,Kv,Vl,Vv,ST):
    DryAngle=F_DryAngle_42( G,d,A,x,e,Dl,Dv,Vl,Vv,ST );

    htp=F_HTCtp_1( p,G,q,d,A,x,e,CPl,CPv,Dl,Dv,Kl,Kv,Vl,Vv,ST,DryAngle);
    return htp

def F_HTCslug_sw( p,G,q,d,A,x,e,CPl,CPv,Dl,Dv,Kl,Kv,Vl,Vv,ST):
    xia=F_xia_18(Dl,Dv,Vl,Vv);
    DryAngle=F_DryAngle_42( G,d,A,x,e,Dl,Dv,Vl,Vv,ST )*x/xia;
    htp=F_HTCtp_1( p,G,q,d,A,x,e,CPl,CPv,Dl,Dv,Kl,Kv,Vl,Vv,ST,DryAngle);
    return htp

def F_HTCmist_14( G,d,x,CPv,Dl,Dv,Kv,Vv ):
    if x>1:
        x=1
    elif x<0:
        x=0
    Reh=(G*d/Vv)*(x+(Dv/Dl)*(1-x));   #equation 15
    Y=1-0.1*(((Dl/Dv)-1)*(1-x))**0.4;  #equation 16
    PRv=F_Prandtl( CPv,Kv,Vv);
    HTCmist=2e-8*Reh**1.97*PRv**(1.06)*Y**(-1.83)*Kv/d;
#    if isnan(HTCmist):
#        print("RCLSA3", Reh,PRv,Y,Kv,d)
    return HTCmist

def F_HTCdry_17( p,G,q,d,A,x,CPl,CPv,Dl,Dv,Hl,Hv,Kl,Kv,Vl,Vv,ST):
    xde=F_xde_25( G,q,d,Dl,Dv,Hl,Hv,ST);
    xdi=F_xdi_20( G,q,d,Dl,Dv,Hl,Hv,ST);
    edi=F_Void_8(G,xdi,Dl,Dv,ST);
    HTCxde=F_HTCmist_14( G,d,xde,CPv,Dl,Dv,Kv,Vv );
    Gwavy=F_Gwavy_14(G,d,A,xdi,edi,Dl,Dv,ST);
    if G>=Gwavy:
        DryAngle=0;
    else:
        DryAngle=F_DryAngle_42( G,d,A,xdi,edi,Dl,Dv,Vl,Vv,ST );

    HTCxdi=F_HTCtp_1( p,G,q,d,A,xdi,edi,CPl,CPv,Dl,Dv,Kl,Kv,Vl,Vv,ST,DryAngle);
    HTCdry=HTCxdi-((x-xdi)/(xde-xdi))*(HTCxdi-HTCxde);
#    if isnan(HTCdry):
#        print("RCLSA2", HTCxdi,x,xdi,xde,HTCxde)
    return HTCdry

def F_Prandtl(CPx, Kx, Vx):
    #Liquid or vapor Prandtl number
    PRx=(CPx*Vx)/Kx;
    return PRx

def F_hnb_8( p,q):
    #CO2 Critical Pressure
    pcrit=73.773;
    #CO2 Molar Mass
    M=44.0098;
    #Reduced Pressure
    pr=p/pcrit;
    #Nucleate Boiling HTC
    hnb=131*pr**(-0.0063)*(-log10(pr))**(-0.55)*M**(-0.5)*q**(0.58);
    return hnb

def F_delta_11(d,A,e,DryAngle):
    delta=(d/2)-((d/2)**2-((2*A*(1-e))/(2*pi-DryAngle)))**0.5;
    if delta.real>d/2:
        delta=d/2;
    return delta

def F_REd_13(G,d,A,x,e,Vl,DryAngle ):
    delta= F_delta_11(d,A,e,DryAngle);
    Red=4*G*(1-x)*delta/(Vl*(1-e));
    return Red

def F_hcb_12(G, d, A, x, e, CPl, Kl, Vl, DryAngle):
    Red=F_REd_13(G,d,A,x,e,Vl,DryAngle );
    PRl=F_Prandtl( CPl,Kl,Vl);
    delta=F_delta_11(d,A,e,DryAngle);
    hcb=0.0133*Red**0.69*PRl**0.4*Kl/delta;
    return hcb

def F_hv_5(G, d, x, e, CPv, Kv, Vv):
    Rev=F_Rev_32(G,d,x,e,Vv);
    Prv=F_Prandtl(CPv,Kv,Vv);
    hv=0.023*Rev**0.8*Prv**0.4*Kv/d;
    return hv

def F_Supp_9_10( G,d,A,x,e,Dl,Dv,Vl,Vv,ST,DryAngle):
    #Boiling Suppression Factor
    xia=F_xia_18(Dl,Dv,Vl,Vv);
    eia=F_Void_8(G,xia,Dl,Dv,ST);
    delta=F_delta_11(d,A,e,DryAngle);
    delta_ia=F_delta_11(d,A,eia,DryAngle);
    if x<xia:
        S=1;
    else:
        S=1-1.14*(min(d, 0.00753)/0.00753)**2*(1-(delta/delta_ia))**2.2;
    return S

def F_hwet_7(p, G, q, d, A, x, e, CPl, Dl, Dv, Kl, Vl, Vv, ST, DryAngle):
    S=F_Supp_9_10( G,d,A,x,e,Dl,Dv,Vl,Vv,ST,DryAngle );
    hnb=F_hnb_8( p,q);
    hcb=F_hcb_12( G,d,A,x,e,CPl,Kl,Vl,DryAngle );
    hwet=((S*hnb)**3+hcb**3)**(1/3);
    return hwet

def F_HTCtp_1(p, G, q, d, A, x, e, CPl, CPv, Dl, Dv, Kl, Kv, Vl, Vv, ST, DryAngle):
    hv=F_hv_5( G,d,x,e,CPv,Kv,Vv );
    hwet=F_hwet_7( p,G,q,d,A,x,e,CPl,Dl,Dv,Kl,Vl,Vv,ST,DryAngle  );
    htp=(DryAngle*hv+(2*pi-DryAngle)*hwet)/(2*pi);
    return htp