from threading import Thread
import time
import pytest
from picmd._communicator import Communicator
from picmd._const import PICMD_NO_ERROR, \
        PICMD_INVALID_PARITY_ERROR, \
        PICMD_COMMAND_FAIL_ERROR
from picmd._data import CommandRequest
from picmd._exception import CommandNotFoundException
from picmd._picmd import PiCmd
from picmd._register import HandlerRegister
from .mock import MockSerial

class DomainException(Exception):
    status_code = 0xff
    description = 'domain error'

class InvalidStatusCodeException(Exception):
    status_code = 0xff + 1

class InvalidDescriptionException(Exception):
    description = b'\x00' * (0xffff + 1)

def test_handler():
    p = PiCmd(Communicator(MockSerial()))

    @p.handler(0x01)
    def h1(data, size):
        pass

    with pytest.raises(ValueError):
        @p.handler(256)
        def h2(data, size):
            pass

def test_execute_command():
    p = PiCmd(Communicator(MockSerial()))

    @p.handler(0x01)
    def h1(data, size):
        return 1

    @p.handler(0x02)
    def h2(data):
        raise Exception

    @p.handler(0x03)
    def h3(size):
        raise DomainException

    @p.handler(0x04)
    def h4():
        return 2

    c1 = CommandRequest(0x01, 1, b'\x01', 0x01)
    r1 = p.execute_command(c1)
    assert r1.status == PICMD_NO_ERROR
    assert r1.data == b'\x01\x00\x00\x00\x00\x00\x00\x00'

    c2 = CommandRequest(0x01, 0, b'', 0x02) # invalid parity
    r2 = p.execute_command(c2)
    assert r2.status == PICMD_INVALID_PARITY_ERROR
    assert r2.data == b''

    c3 = CommandRequest(0x02, 0, b'', 0x02)
    r3 = p.execute_command(c3)
    assert r3.status == PICMD_COMMAND_FAIL_ERROR
    assert r3.data == b''

    c4 = CommandRequest(0x03, 0, b'', 0x03)
    r4 = p.execute_command(c4)
    assert r4.status == 0xff
    assert r4.data == b'domain error'

    c5 = CommandRequest(0x04, 0, b'', 0x04)
    r5 = p.execute_command(c5)
    assert r5.status == PICMD_NO_ERROR
    assert r5.data == b'\x02\x00\x00\x00\x00\x00\x00\x00'

def test_execute_command_when_invalid_result_format():
    p = PiCmd(Communicator(MockSerial()))

    @p.handler(0x01)
    def h1():
        return b'\x00' * (0xffff + 1) # over data size

    @p.handler(0x02)
    def h2(data, size):
        raise InvalidStatusCodeException

    @p.handler(0x03)
    def h3(data, size):
        raise InvalidDescriptionException

    r1 = p.execute_command(CommandRequest(0x01, 0, b'', 0x01))
    assert r1.status == PICMD_COMMAND_FAIL_ERROR
    assert r1.data == b''

    r2 = p.execute_command(CommandRequest(0x02, 0, b'', 0x02))
    assert r2.status == PICMD_COMMAND_FAIL_ERROR
    assert r2.data == b''

    r3 = p.execute_command(CommandRequest(0x03, 0, b'', 0x03))
    assert r3.status == PICMD_COMMAND_FAIL_ERROR
    assert r3.data == b''

def test_get_handler():
    p = PiCmd(Communicator(MockSerial()))

    @p.handler(0x01)
    def h1(data, size):
        return 1

    assert p.get_handler(CommandRequest(0x01, 0, b'', 0x01)) is not None

    with pytest.raises(CommandNotFoundException):
        p.get_handler(CommandRequest(0x02, 0, b'', 0x02))

def test_picmd_runner():
    s = MockSerial([
        b'AT*PIC=\x01\x01\x00\x02\x02\r\n'
        ])
    c = Communicator(s)
    p = PiCmd(c)

    @p.handler(0x01)
    def h1():
        return 1

    Thread(target=p.run, daemon=True).start()
    time.sleep(0.1)
    c.stop()

    assert s.written_data == b'*PIC:\x01\x08\x00\x01\x00\x00\x00\x00\x00\x00\x00\x08\r\nOK\r\n'

def test_provide():
    s = MockSerial([
        b'AT*PIC=\x01\x01\x00\x02\x02\r\n'
        ])
    c = Communicator(s)
    p = PiCmd(c)

    def a(v):
        return v + 1

    p.provide({
        'a': a
    })

    @p.handler(0x01)
    def h1(data, a):
        return a(int.from_bytes(data, 'big'))

    Thread(target=p.run, daemon=True).start()
    time.sleep(0.1)
    c.stop()

    assert s.written_data == b'*PIC:\x01\x08\x00\x03\x00\x00\x00\x00\x00\x00\x00\x0a\r\nOK\r\n'

def test_import_handler_register():
    p = PiCmd(Communicator(MockSerial()))

    @p.handler(0x01)
    def h1():
        return 1

    hr1 = HandlerRegister()
    hr2 = HandlerRegister()

    @hr1.handler(0x02)
    def h2():
        return 2

    @hr2.handler(0x03)
    def h3():
        return 3

    @hr2.handler(0x04)
    def h4():
        return 4

    p.import_handler_register(hr1)
    p.import_handler_register(hr2)

    r1 = p.execute_command(CommandRequest(0x01, 0, b'', 0x01))
    assert r1.data == b'\x01\x00\x00\x00\x00\x00\x00\x00'

    r2 = p.execute_command(CommandRequest(0x02, 0, b'', 0x02))
    assert r2.data == b'\x02\x00\x00\x00\x00\x00\x00\x00'

    r3 = p.execute_command(CommandRequest(0x03, 0, b'', 0x03))
    assert r3.data == b'\x03\x00\x00\x00\x00\x00\x00\x00'

    r4 = p.execute_command(CommandRequest(0x04, 0, b'', 0x04))
    assert r4.data == b'\x04\x00\x00\x00\x00\x00\x00\x00'


import argparse
import sys
import requests
import csv
import tempfile
import re
import os
from time import sleep

cycle = ['|', '/', '-', '\\']
methods = ['cterm', '20s']

def split_file(reader, lines=400):
    from itertools import islice, chain
    tmp = next(reader)
    while tmp!="":
        yield chain([tmp], islice(reader, lines-1))
        try:
            tmp = next(reader)
        except StopIteration:
            return

def main(args_input = sys.argv[1:]):
    parser = argparse.ArgumentParser("pvacseq net_chop")
    parser.add_argument(
        'input_file',
        type=argparse.FileType('r'),
        help="Input filtered file with predicted epitopes"
    )
    parser.add_argument(
        'output_file',
        type=argparse.FileType('w'),
        help="Output TSV filename for putative neoepitopes"
    )
    args = parser.parse_args(args_input)
    jobid_searcher = re.compile(r'<!-- jobid: [0-9a-fA-F]*? status: (queued|active)')
    result_delimiter = re.compile(r'-{20,}')
    fail_searcher = re.compile(r'(Failed run|Problematic input:)')
    allele_searcher = re.compile(r'^(.*?) : Distance to trai?ning data .*? nearest neighbor (.*?)\)$', re.MULTILINE)
    reader = csv.DictReader(args.input_file, delimiter='\t')
    writer = csv.DictWriter(
        args.output_file,
        reader.fieldnames+['Predicted Stability', 'Half Life', 'Stability Rank', 'NetMHCstab allele'],
        delimiter='\t',
        lineterminator='\n'
    )
    writer.writeheader()
    x = 0
    i=1
    print("Waiting for results from NetMHCStabPan... |", end='')
    sys.stdout.flush()
    for chunk in split_file(reader, 100):
        peptide_lengths = set()
        staging_file = tempfile.NamedTemporaryFile(mode='w+')
        current_buffer = {}
        alleles_in_chunk = set()
        for line in chunk:
            sequence_id = ('%010x'%x)[-10:]
            staging_file.write('>'+sequence_id+'\n')
            staging_file.write(line['MT Epitope Seq']+'\n')
            alleles_in_chunk.add(line['HLA Allele'])
            peptide_lengths.add(line['Peptide Length'])
            current_buffer[sequence_id] = {k:line[k] for k in line}
            x+=1
        staging_file.seek(0)
        allele_list = [allele.replace('*', '') for allele in alleles_in_chunk]
        allele_list.sort()
        response = requests.post(
            "http://www.cbs.dtu.dk/cgi-bin/webface2.fcgi",
            files={'SEQSUB':(staging_file.name, staging_file, 'text/plain')},
            data = {
                'configfile':'/usr/opt/www/pub/CBS/services/NetMHCstabpan-1.0/NetMHCstabpan.cf',
                'inp':'0',
                'len': ','.join(peptide_lengths),
                'master':'1',
                'slave0':allele_list[-1],
                'allele':','.join(allele_list),
                'thrs':'0.5',
                'thrw': '2',
                'incaff': '0',
                'sort1':'-1',
                'waff':'0.8',
                'sort2':'-1'
            }
        )
        while jobid_searcher.search(response.content.decode()):
            for _ in range(10):
                sys.stdout.write('\b'+cycle[i%4])
                sys.stdout.flush()
                sleep(1)
                i+=1
            response = requests.get(response.url)
        if fail_searcher.search(response.content.decode()):
            sys.stdout.write('\b\b')
            print('Failed!')
            print("NetMHCStabPan encountered an error during processing")
            sys.exit(1)
        pending = []
        allele_map = {item[0]:item[1] for item in allele_searcher.findall(response.content.decode())}
        results = [item.strip() for item in result_delimiter.split(response.content.decode())]
        for i in range(2, len(results), 4): #examine only the parts we want, skipping all else
            for line in results[i].split('\n'):
                data = [word for word in line.strip().split(' ') if len(word)]
                line = current_buffer[data[3]]
                if data[1] == line['HLA Allele'] and len(data[2]) == int(line['Peptide Length']):
                    line.update({
                        'Predicted Stability':data[4],
                        'Half Life':data[5],
                        'Stability Rank':data[6],
                        'NetMHCstab allele':allele_map[line['HLA Allele'].replace('*', '', 1)]
                    })
                    pending.append([int(data[3], 16), {k:line[k] for k in line}])
        writer.writerows([{k:entry[1][k] for k in entry[1]} for entry in sorted(pending, key=lambda x:x[0])])
    sys.stdout.write('\b\b')
    print("OK")
    args.output_file.close()
    args.input_file.close()

if __name__ == '__main__':
    main()


#!/usr/bin/python3
from pyfiglet import Figlet
import yaml, random
import sys
import os
import datetime
import time
from multiprocessing import Process, Queue

from SpeechDriver.tts.ttsdefault import speak
from Services import weather, jokes_quote
from Core import textAnimation
from Core.profile import *
from Services import greeting

"""
print("                                            ")
print("  ________  .__               .__           ")
print("  \______ \ |__| ______ _____ |__| ______   ")
print("   |    |  \|  |/  ___//     \|  |/  ___/   ")
print("   |    `   \  |\___ \|  Y Y  \  |\___ \    ")
print("  /_______  /__/____  >__|_|  /__/____  >   ")
print("          \/        \/      \/        \/    ")
print("                                            ")   """

""" Ping google.com """ #Current not using in main instead using in brain.
from urllib.request import urlopen
def internetExamine():
    while True:
        try:
            response = urlopen('https://www.google.com/', timeout=10)
            print('on')
            return True
        except:
            print('false')
            return False

""" Greeting """
def greetMe():
    currentH = int(datetime.datetime.now().hour)
    if currentH >= 0 and currentH < 12:
        speak('Good Morning!')
        print('Good Morning!')
    if currentH >= 12 and currentH < 18:
        speak('Good Afternoon!')
        print('Good Afternoon!')
    if currentH >= 18 and currentH != 0:
        speak('Good Evening!')
        print('Good Evening!')

""" MULTIPROCESSING """
def Aneey_wishMailer(Aneey_wishMailer_path):
    time.sleep(random.randint(1, 3))
    os.system("python3 " + Aneey_wishMailer_path + " &")
def Aneey_birthdayAlert(AneeyC_BirthdayAlert_path):
    time.sleep(random.randint(1, 3))
    os.system("python3 " + AneeyC_BirthdayAlert_path + " &")
def Anum_wishMailer(Anum_wishMailer_path):
    time.sleep(random.randint(1, 3))
    os.system("python3 " + Anum_wishMailer_path + " &")
def AnumBirthdayProtocal(AnumBirthdayAlert_path):
    time.sleep(random.randint(1, 3))
    os.system("python3 " + AnumBirthdayAlert_path + " &")
def Anisha_wishMailer(Anisha_wishMailer_path):
    time.sleep(random.randint(1, 3))
    os.system("python3 " + Anisha_wishMailer_path + " &")
def ask_email(ask_abtEmailreminder):
    time.sleep(random.randint(1, 3))
    os.system("python3 " + ask_abtEmailreminder + " &")
def BestfriendBirthdayProtocal(BestfriendBirthdayProtocal_path):
    time.sleep(random.randint(1, 3))
    os.system("python3 " + BestfriendBirthdayProtocal_path + " &")
def PersonalGmailNotify(PersonalGmailNotify_path):
    time.sleep(random.randint(1, 3))
    os.system("python3 " + PersonalGmailNotify_path + " &")
def flask_credentials(flask_credentials_path):
    time.sleep(random.randint(1, 3))
    os.system("python3 " + flask_credentials_path + "&")
def schedule(schedule_path):
    time.sleep(random.randint(1, 3))
    os.system("python3 " + schedule_path + "&")

""" Desktop Notification """
"""
from gi.repository import Notify
# One time initialization of libnotify
Notify.init("Dismis_slave1")
# Create the notification object
title = "Dismis_slave1!"
body = "Meeting at 3PM!"
notification = Notify.Notification.new(
    title, body)
# Actually show on screen
notification.show() """

""" Booting """
def startup():
    """ Start Up """
    textAnimation.load_animation()
    time.sleep(0.30)
    print(' ')

    """ Dismis Banner """
    custom_fig = Figlet(font='graffiti')
    print(custom_fig.renderText('Dismis'))

    """ Greeting """
    greetMe()
    #time.sleep(0.30)

    """ Weather of Default Location """
    currentH = int(datetime.datetime.now().hour)
    if currentH >= 0 and currentH < 12:
        weather.weather_DefaultCity(default_CityLocation, openweatherAPI, accept_path)
        time.sleep(9)

    """ Jokes """
    currentH = int(datetime.datetime.now().hour)
    if currentH >= 0 and currentH < 12:
        jokes_quote.tell_joke(accept_path)
        time.sleep(3)

    """ Quote of The Day """
    currentH = int(datetime.datetime.now().hour)
    if currentH >= 0 and currentH < 12:
        jokes_quote.quote(accept_path)

    """ Final Animation """
    def delay_print(s):
        import time
        import sys
        for c in s:
            sys.stdout.write(c)
            sys.stdout.flush()
            time.sleep(0.1)
    delay_print("Hi, I'm Dismis. Nice to meet you!\n")
    time.sleep(0.20)

""" Running All Main Functions """
#startup()
""" Running Parallel Processes """
Anneybirthday_wisher = Process(target= Aneey_wishMailer(Aneey_wishMailer_path))
Anneybirthday_wisher.start()

Anneybirthday = Process(target= Aneey_birthdayAlert(AneeyC_BirthdayAlert_path))
Anneybirthday.start()

bhaibirthday_wisher = Process(target= Anum_wishMailer(Anum_wishMailer_path))
bhaibirthday_wisher.start()

bhaibirthday = Process(target = AnumBirthdayProtocal(AnumBirthdayAlert_path))
bhaibirthday.start()

Anishabirthday_wisher = Process(target= Anisha_wishMailer(Anisha_wishMailer_path))
Anishabirthday_wisher.start()

reminder =  Process(target=ask_email(ask_abtEmailreminder))
reminder.start()

bffbirthday = Process(target = BestfriendBirthdayProtocal(BestfriendBirthdayProtocal_path))
bffbirthday.start()

chkMail = Process(target = PersonalGmailNotify(PersonalGmailNotify_path))
chkMail.start()

credentials = Process(target = flask_credentials(flask_credentials_path))
credentials.start()

routine = Process(target = schedule(schedule_path))
routine.start()


"""
Files and Directories
=============================================================================

When you need to save data to a local computer, you have to know how to work
with files and directories.

Example Run
-----------------------------------------------------------------------------
Doing everything in a temp dir so it cleans up automatically ...
Hello, stranger!
Welcome to python-exmaples
...

References
-----------------------------------------------------------------------------
https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files
"""

import os
from pathlib import Path
from tempfile import TemporaryDirectory

def main():
    with TemporaryDirectory() as tmpdir:
        print('Doing everything in a temp dir so it cleans up '
              'automatically after we are done! Temp dir is at', tmpdir)

        # Change to the temp dir
        os.chdir(tmpdir)

        # Let's write a file
        with open('hello.txt', 'w') as fp:
            fp.write('Hello, stranger!\n')
            fp.write('Welcome to python-exmaples')

        # Now, we can read it back.
        with open('hello.txt') as fp:

            # Reads everything
            print(fp.read())

            # Go back to the beginning of the file
            fp.seek(0)

            # Read one line at a time
            for line in fp:
                print(line, end='')  # Line has \n, skip same from print

            # Read a few characters at a time
            fp.seek(0)
            print(fp.read(5))

            # Or just one line
            fp.seek(0)
            print(fp.readline())

        # Using pathlib.Path to create a new dir
        new_dir = Path('.') / 'subdir'
        new_dir.mkdir()

        # Create a new file
        new_file = new_dir / 'world.txt'
        with new_file.open('w') as fp:
            fp.write('Path is pretty cool')

        # Read the file
        with new_file.open() as fp:
            print(fp.read())  # Path is pretty cool

        # Or do it using open works too
        with open(new_file) as fp:
            print(fp.read())

        # List all the files in current dir
        for f in Path.cwd().iterdir():
            print(f)
        """
        /tmp/tmpyjm9e_20/hello.txt
        /tmp/tmpyjm9e_20/subdir
        """

        # Glob for only txt files
        for f in Path.cwd().glob('*.txt'):
            print(f)
        """
        /tmp/tmpyjm9e_20/hello.txt
        """

if __name__ == "__main__":
    main()


import math
import pytest
from metamorphic_test import (
    transformation,
    relation,
    metamorphic,
    system,
    randomized,
)
from metamorphic_test.generators import RandInt
from metamorphic_test.relations import approximately

class MathLibrary():
    __PI = 3.14159265358979323846
    __PRECISION = 15

    @staticmethod
    def sin(x: float) -> float:
        x %= 2 * MathLibrary.__PI

        if x < 0:
            return -MathLibrary.sin(-x)

        if x > MathLibrary.__PI:
            return -MathLibrary.sin(x - MathLibrary.__PI)

        assert x >= 0
        assert x <= MathLibrary.__PI

        for i in range(1, MathLibrary.__PRECISION + 1):
            if i % 2 == 0:
                x += math.pow(x, 2 * i + 1) / MathLibrary.factorial(2 * i + 1)
            else:
                x -= math.pow(x, 2 * i + 1) / MathLibrary.factorial(2 * i + 1)

        return x

    @staticmethod
    def factorial(n: int) -> int:
        fact = 1
        for i in range(1, n + 1):
            fact = fact * i
        return fact

test_two_pi = metamorphic('Plus 2 π', relation=approximately)
test_negate_x = metamorphic('sin(-x)')
test_plus_pi = metamorphic('Plus 1 π')
test_pi_minus_x = metamorphic('sin(π-x)', relation=approximately)

@transformation(test_two_pi)
@randomized('n', RandInt(0, 10))
def two_pi_shift(x: float, n: int) -> float:
    return x + 2 * n * math.pi

@transformation(test_negate_x)
def negate(x: float) -> float:
    return -x

@transformation(test_plus_pi)
def pi_shift(x: float) -> float:
    return x + math.pi

@transformation(test_pi_minus_x)
def pi_shift_minus(x: float) -> float:
    return math.pi - x

@relation(test_negate_x, test_plus_pi)
def approximately_negate(x: float, y: float) -> bool:
    return approximately(-x, y)

@pytest.mark.skip
@pytest.mark.parametrize('x', range(-10, 10))
@system(test_two_pi, test_negate_x, test_plus_pi, test_pi_minus_x)
def test(x: float) -> float:
    return MathLibrary.sin(x)


from fastapi import APIRouter, Depends, HTTPException, Query
from app.db.database import get_db
from sqlalchemy.orm import Session
from datetime import date, timedelta
from app.db.models import Sale, Product
from sqlalchemy import func, and_
from typing import List

router = APIRouter()

@router.get("/revenue/daily/{date}", response_model=dict)
def get_daily_revenue(date: date, db: Session = Depends(get_db)):
    next_day = date + timedelta(days=1)

    # Retrieve daily revenue using SQLAlchemy query
    daily_revenue = (
        db.query(func.sum(Product.price * Sale.quantity))
        .join(Sale, Product.id == Sale.product_id)
        .filter(Sale.date >= date, Sale.date < next_day)
        .scalar() or 0.0
    )

    return {'daily_revenue': daily_revenue}

@router.get("/revenue/weekly/{start_date}", response_model=dict)
def get_weekly_revenue(start_date: date, db: Session = Depends(get_db)):
    end_date = start_date + timedelta(days=7)

    weekly_revenue = (
        db.query(func.sum(Product.price * Sale.quantity))
        .join(Sale, Product.id == Sale.product_id)
        .filter(Sale.date >= start_date, Sale.date < end_date)
        .scalar() or 0.0
    )

    return {'weekly_revenue': weekly_revenue}

@router.get("/revenue/annual/{year}", response_model=dict)
def get_annual_revenue(year: int, db: Session = Depends(get_db)):
    start_date = date(year, 1, 1)
    end_date = date(year, 12, 31) + timedelta(days=1)

    annual_revenue = (
        db.query(func.sum(Product.price * Sale.quantity))
        .join(Sale, Product.id == Sale.product_id)
        .filter(Sale.date >= start_date, Sale.date < end_date)
        .scalar() or 0.0
    )

    return {'annual_revenue': annual_revenue}

@router.get("/revenue/compare", response_model=dict)
def compare_revenue(
    start_date: date,
    end_date: date,
    product_ids: List[int] = Query(None),
    categories: List[str] = Query(None),
    db: Session = Depends(get_db)
):
    filters = [Sale.date >= start_date, Sale.date < end_date]

    if product_ids:
        filters.append(Sale.product_id.in_(product_ids))
    if categories:
        filters.append(Product.category.in_(categories))

    filtered_revenue = (
        db.query(Sale.date, func.sum(Product.price * Sale.quantity))
        .join(Product)
        .filter(and_(*filters))
        .group_by(Sale.date)
        .all()
    )

    result = {str(date): float(revenue) for date, revenue in filtered_revenue}
    return result


# -*- coding: utf-8 -*-
"""
Author: Tomasz Neska
Date: 06/03/2020
Description: Project 2 - utilising three different methods it evaluates the effects of time step and accuracy on the
behaviour of the simple harmonic oscillator
"""
# initialisation
import string
from math import *
import numpy as np
import matplotlib.pyplot as plt
import random
import time
import cmath
import json
from scipy import optimize

plt.rcParams.update({'font.size': 14})
plt.style.use('default')
figure = plt.figure()
plt.rcParams.update({'errorbar.capsize': 2})

class SHO(object):
    def __init__(self, time_step, max_time, b=0.0, m=0.0, k=0.0, init_x=0.0, init_v=0.0, fileNameSave="data.txt",
                 fileNameLoad="data.txt"):
        self.fileNameSave = fileNameSave
        self.fileNameLoad = fileNameLoad
        self.b = b
        self.m = m
        self.k = k
        self.h = time_step
        self.init_v = init_v
        self.init_x = init_x
        self.no_steps = int(np.rint(max_time / time_step))
        self.natural_angular_frequency = np.sqrt(self.k / self.m)
        if self.b != 0:
            self.gamma = self.b / self.m
            self.quality_factor = self.natural_angular_frequency / self.gamma
        self.analytic_series_pos = []
        self.analytic_series_vel = []
        self.analytic_energy = []
        self.__coefficients = []
        self.solver()
        self.analytic_solution()
        self.data = []
        self.b_critical = 2 * np.sqrt(self.k * self.m)

        self.Euler_data = []
        self.B_Euler_data = []
        self.Verlet_data = []
        self.Euler_Cromer_data = []
        self.analytical_data = []
        self.time = np.array(range(0, self.no_steps, 1)) * self.h
        self.disturbed_Verlet_data = []

    def runSimulation(self):
        self.Euler_integrator()
        self.Better_Euler_integrator()
        self.Verlet_integrator()
        self.Euler_Cromer_integrator()
        print("Simulation has been executed")

    def getCoefficients(self):
        return self.__coefficients

    def Euler_integrator(self):
        position_series = [self.init_x]
        velocity_series = [self.init_v]
        for counter in range(1, self.no_steps, 1):
            v_n = velocity_series[len(velocity_series) - 1]
            x_n = position_series[len(position_series) - 1]
            a_n = (-self.b / self.m) * v_n + (-self.k / self.m) * x_n

            position_series.append(x_n + self.h * v_n)
            velocity_series.append(v_n + self.h * a_n)

        self.Euler_data = [position_series, velocity_series, self.energy_function(position_series, velocity_series)]

    def Better_Euler_integrator(self):
        position_series = [self.init_x]
        velocity_series = [self.init_v]
        for counter in range(1, self.no_steps, 1):
            v_n = velocity_series[len(velocity_series) - 1]
            x_n = position_series[len(position_series) - 1]
            a_0 = (-self.b / self.m) * v_n + (-self.k / self.m) * x_n

            position_series.append(x_n + self.h * v_n + 0.5 * self.h ** 2 * a_0)
            velocity_series.append(v_n + self.h * a_0)

        self.B_Euler_data = [position_series, velocity_series, self.energy_function(position_series, velocity_series)]

    def Euler_Cromer_integrator(self):
        position_series = [self.init_x]
        velocity_series = [self.init_v]
        for counter in range(1, self.no_steps, 1):
            v_n = velocity_series[len(velocity_series) - 1]
            x_n = position_series[len(position_series) - 1]

            temp = v_n - (self.k * self.h / self.m) * x_n  # v_n+1
            velocity_series.append(temp)
            position_series.append(x_n + self.h * temp)

        self.Euler_Cromer_data = [position_series, velocity_series,
                                  self.energy_function(position_series, velocity_series)]
        print(np.array(self.Euler_Cromer_data))

    def Verlet_integrator(self):
        position_series = [self.init_x]
        velocity_series = [self.init_v]

        D = 2 * self.m + self.b * self.h
        B = ((self.b * self.h) - (2 * self.m)) / D
        A = 2 * (2 * self.m - (self.k * self.h ** 2)) / D

        a_0 = (-self.b / self.m) * self.init_v + (-self.k / self.m) * self.init_x
        x_1 = self.init_x + self.init_v * self.h + 0.5 * a_0 * self.h ** 2  # obtained using a Taylor expansion of order 2
        position_series.append(x_1)

        for counter in range(1, self.no_steps, 1):
            position_series.append(A * position_series[counter] + B * position_series[counter - 1])

        # calculating velocities using an approximation of O(h^2)
        # the velocity is estimated using the mean value theorem
        for counter in range(1, self.no_steps, 1):
            velocity_series.append(
                (position_series[counter + 1] - position_series[counter - 1]) / (2 * self.h))  # +O(h^2)
        position_series = position_series[:len(position_series) - 1]

        self.Verlet_data = [position_series, velocity_series, self.energy_function(position_series, velocity_series)]

    def energy_function(self, position, velocity):
        temp_pos = np.array(position)
        temp_vel = np.array(velocity)
        return 0.5 * self.m * temp_vel ** 2 + 0.5 * self.k * temp_pos ** 2

    def convert_array(self, array):
        # operates on 1 dimensional arrays
        temp = []
        for entry in array:
            temp.append(entry)

        return temp

    def analytic_solution(self):
        # creates the analytic solution position series
        t_0 = 0
        for counter in range(0, self.no_steps, 1):
            self.analytic_series_pos.append(self.ana_position(t_0))
            self.analytic_series_vel.append(self.ana_velocity(t_0))
            t_0 += self.h
        print("solution found")
        self.analytic_energy = self.energy_function(self.analytic_series_pos, self.analytic_series_vel)

    def solver(self):
        #
        print((self.k / self.m))
        print((self.b ** 2 / (4 * self.m ** 2)))
        #
        A = 0
        B = 0
        temp = (self.b ** 2 / (4 * self.m ** 2))
        if self.b == 0:
            marker = 1
            print("The analytic solution is a simple harmonic motion")
            omega = np.sqrt(self.k / self.m)
            A = self.init_v / omega
            B = self.init_x

            # x = A*sin(omega*t) + B*cos(omega*t)
            # v = omega A cos(omega t) - omega*B*sin(omega t)

            self.__coefficients = [omega, 0, marker, A, B]
        elif (self.k / self.m) > temp:  # imaginary
            print("The solution is a lightly damped oscillation")
            marker = 3

            p = -1 * self.b / 2 * self.m
            q = np.sqrt((self.k / self.m) - self.b ** 2 / (4 * self.m ** 2))
            # initial conditions
            A = (- self.init_x * p + self.init_v) / q
            B = self.init_x
            self.__coefficients = [p, q, marker, A, B]
        elif (self.k / self.m) == temp:
            print("The solution is a critically damped oscillation")
            marker = 2  # repeated real solutions
            K = -1 * self.b / 2 * self.m
            # initial conditions
            A = self.init_x
            self.__coefficients = [K, 0, marker, A, B]
        elif (self.k / self.m) < temp:  # overdamped oscillation
            marker = 4
            print("The solution is an overdamped oscillation")
            p = -1 * self.b / 2 * self.m + np.sqrt(-(self.k / self.m) + self.b ** 2 / (4 * self.m ** 2))
            q = -1 * self.b / 2 * self.m - np.sqrt(-(self.k / self.m) + self.b ** 2 / (4 * self.m ** 2))

            # initial conditions
            A = (q * self.init_x - self.init_v) / (q - p)
            B = self.init_x - A
            self.__coefficients = [p, q, marker, A, B]
        print(marker)

    def ana_position(self, t):
        k_1 = self.__coefficients[0]
        k_2 = self.__coefficients[1]
        marker = self.__coefficients[2]
        A = self.__coefficients[3]
        B = self.__coefficients[4]
        if marker == 1:  # no damping solution
            return A * np.sin(self.natural_angular_frequency * t) + B * np.cos(self.natural_angular_frequency * t)
        elif marker == 2:  # regular damping (complex)
            return A * np.exp(k_1 * t)
        elif marker == 3:  # repeated root
            return np.exp(k_1 * t) * (A * np.sin(k_2 * t) + B * np.cos(k_2 * t))
        elif marker == 4:  # two real distinct solutions
            return A * np.exp(k_1 * t) + B * np.exp(k_2 * t)

    def ana_velocity(self, t):
        k_1 = self.__coefficients[0]
        k_2 = self.__coefficients[1]
        marker = self.__coefficients[2]
        A = self.__coefficients[3]
        B = self.__coefficients[4]
        if marker == 1:  # no damping solution
            return A * k_1 * np.cos(k_1 * t) - B * k_1 * np.sin(k_1 * t)
        elif marker == 2:  # regular damping (complex)
            return A * k_1 * np.exp(k_1 * t)
        elif marker == 3:  # repeated root
            return k_1 * np.exp(k_1 * t) * (A * np.sin(k_2 * t) + B * np.cos(k_2 * t)) + np.exp(k_1 * t) * (
                    A * k_2 * np.cos(k_2 * t) - B * k_2 * np.sin(k_2 * t))
        elif marker == 4:  # two real distinct solutions
            return A * k_1 * np.exp(k_1 * t) + B * k_2 * np.exp(k_2 * t)

    def plot_data(self):  # plots all on separate graphs
        # analytical solution
        figure3 = plt.figure()
        axes_5 = figure3.add_subplot(121)
        axes_5.plot(self.analytic_series_pos, self.analytic_series_vel, label="Analytical")
        axes_5.set_xlabel("position/ m")  # edit later if the functions don't exist
        axes_5.set_ylabel("velocity/ ms^-1")  # as above
        # energy plotting
        axes_6 = figure3.add_subplot(122)
        axes_6.plot(self.time, self.analytic_energy)
        axes_6.set_xlabel("time/ s")
        axes_6.set_ylabel("energy/ J")
        figure3.legend()

        # Euler method
        # plotting
        figure = plt.figure()
        axes_1 = figure.add_subplot(121)
        axes_1.plot(self.Euler_data[0], self.Euler_data[1], label="Euler")
        axes_1.set_xlabel("position/ m")  # edit later if the functions don't exist
        axes_1.set_ylabel("velocity/ ms^-1")  # as above
        # energy plotting

        axes_2 = figure.add_subplot(122)
        axes_2.plot(self.time, self.Euler_data[2])
        axes_2.set_xlabel("time/ s")
        axes_2.set_ylabel("energy/ J")
        figure.legend()
        # end plotting

        # Better Euler method
        # plotting
        figure2 = plt.figure()
        axes_3 = figure2.add_subplot(121)
        axes_3.plot(self.B_Euler_data[0], self.B_Euler_data[1], label="Better Euler")
        axes_3.set_xlabel("position/ m")  # edit later if the functions don't exist
        axes_3.set_ylabel("velocity/ ms^-1")  # as above
        # energy plotting
        axes_4 = figure2.add_subplot(122)
        axes_4.plot(self.time, self.B_Euler_data[2])
        axes_4.set_xlabel("time/ s")
        axes_4.set_ylabel("energy/ J")
        figure2.legend()
        # end plotting

        # Verlet method
        figure4 = plt.figure()
        axes_7 = figure4.add_subplot(121)
        axes_7.plot(self.Verlet_data[0], self.Verlet_data[1], label="Verlet")
        axes_7.set_xlabel("position/ m")
        axes_7.set_ylabel("velocity/ ms^-1")
        # energy plotting
        axes_8 = figure4.add_subplot(122)
        axes_8.plot(self.time, self.Verlet_data[2])
        axes_8.set_xlabel("time/ s")
        axes_8.set_ylabel("energy/ J")
        figure4.legend()

        # Euler Cromer method
        figure5 = plt.figure()
        axes_9 = figure5.add_subplot(121)
        axes_9.plot(self.Euler_Cromer_data[0], self.Euler_Cromer_data[1], label="Euler Cromer Method")
        axes_9.set_xlabel("position/ m")
        axes_9.set_ylabel("velocity/ ms^-1")
        # energy plotting
        axes_10 = figure5.add_subplot(122)
        axes_10.plot(self.time, self.Euler_Cromer_data[2])
        axes_10.set_xlabel("time/ s")
        axes_10.set_ylabel("energy/ J")
        figure5.legend()

    def plot_single(self):
        figure = plt.figure()
        axes_1 = figure.add_subplot(121)
        axes_1.set_xlabel("position/ m")
        axes_1.set_ylabel("velocity/ ms^-1")
        # energy_function
        energy = []
        axes_2 = figure.add_subplot(122)
        axes_2.set_xlabel("time/ s")
        axes_2.set_ylabel("Energy/ J")

        axes_1.plot(self.Euler_data[0], self.Euler_data[1], label="Euler")
        axes_2.plot(self.time, self.Euler_data[2])

        axes_1.plot(self.B_Euler_data[0], self.B_Euler_data[1], label="Improved Euler")
        axes_2.plot(self.time, self.B_Euler_data[2])

        axes_1.plot(self.Verlet_data[0], self.Verlet_data[1], label="Verlet")
        axes_2.plot(self.time, self.Verlet_data[2])

        axes_1.plot(self.Euler_Cromer_data[0], self.Euler_Cromer_data[1], label="Euler Cromer")
        axes_2.plot(self.time, self.Euler_Cromer_data[2])

        axes_1.plot(self.analytic_series_pos, self.analytic_series_vel, label="Analytic solution")
        axes_2.plot(self.time, self.analytic_energy)
        figure.legend()

    def save_data(self):
        # all files are saved as json dictionaries in the format "name of method": [position, velocity, energy]
        # the header of the file headers named appropriately contains the
        temp = [self.analytic_series_pos, self.analytic_series_vel, self.convert_array(self.analytic_energy)]

        data = {}
        data["Analytic"] = temp
        data["Euler"] = [self.Euler_data[0], self.Euler_data[1], self.convert_array(self.Euler_data[2])]
        data["Better Euler"] = [self.B_Euler_data[0], self.B_Euler_data[1], self.convert_array(self.B_Euler_data[2])]
        data["Verlet"] = [self.Verlet_data[0], self.Verlet_data[1], self.convert_array(self.Verlet_data[2])]
        data["Euler Cromer"] = [self.Euler_Cromer_data[0], self.Euler_Cromer_data[1],
                                self.convert_array(self.Euler_Cromer_data[2])]
        data["coefficients"] = [self.h, self.no_steps, self.b, self.m, self.k, self.init_x,
                                self.init_v]  # h, T, b, m, k, x, v

        with open(self.fileNameSave, 'w') as outfile:
            json.dump(data, outfile)
        outfile.close()

    def load_data(self):
        try:
            with open(self.fileNameLoad) as json_file:
                data = json.load(json_file)
                self.Euler_data = data["Euler"]
                self.B_Euler_data = data["Better Euler"]
                self.Verlet_data = data["Verlet"]
                self.analytic_series_pos = data["Analytic"][0]
                self.analytic_series_vel = data["Analytic"][1]
                self.analytic_energy = data["Analytic"][2]
                self.Euler_Cromer_data = data["Euler Cromer"]
                self.h, self.no_steps, self.b, self.m, self.k, self.init_x, self.init_v = data["coefficients"]
                print(self.h)
                print(self.no_steps)
                print(self.b)
                print(self.m)
                print(self.k)
                print(self.init_x)
                print(self.init_v)

            json_file.close()
            return True
        except:
            print("The file was not found")
            return False

    def find_accuracy(self):
        # finds the accuracy of the simulation by using the analytic energy as a baseline
        # this assigns a number of "fictitious energy" and also graphs the growth of the errors with time
        figure = plt.figure()
        axes_1 = figure.add_subplot(111)
        axes_1.set_ylabel("Energy error/ J")
        axes_1.set_xlabel("time/ s")
        fict_energy = []
        baseline = np.array(self.analytic_energy)

        # Euler's method
        temp = np.abs(np.array(self.Euler_data[2]) - baseline)
        axes_1.plot(self.time, temp, label="Euler")
        fict_energy.append(np.sum(temp))
        # Better Euler
        temp = np.abs(np.array(self.B_Euler_data[2]) - baseline)
        axes_1.plot(self.time, temp, label="Improved Euler")
        fict_energy.append(np.sum(temp))
        # Cromer
        temp = np.abs(np.array(self.Euler_Cromer_data[2]) - baseline)
        axes_1.plot(self.time, temp, label="Euler Cromer")
        fict_energy.append(np.sum(temp))
        # Verlet
        temp = np.abs(np.array(self.Verlet_data[2]) - baseline)
        axes_1.plot(self.time, temp, label="Verlet")
        fict_energy.append(np.sum(temp))
        temp = 0
        print("Euler: " + str(fict_energy[0]) + " J")
        print("Improved Euler: " + str(fict_energy[1]) + "J")
        print("Euler Cromer: " + str(fict_energy[2]) + "J")
        print("Verlet: " + str(fict_energy[3]) + "J")
        figure.legend()
        axes_1.set_title("h = " + str(self.h))

    def const_dist_Verlet_integrator(self, force, min, max):
        position_series = [self.init_x]
        velocity_series = [self.init_v]

        D = 2 * self.m + self.b * self.h
        B = (self.b * self.h - 2 * self.m) / D
        A = 2 * (2 * self.m - self.k * self.h ** 2) / D

        a_0 = (-self.b / self.m) * self.init_v + (-self.k / self.m) * self.init_x
        x_1 = self.init_x + self.init_v * self.h + 0.5 * a_0 * self.h ** 2  # obtained using a Taylor expansion of order 2
        position_series.append(x_1)

        for counter in range(1, self.no_steps, 1):
            if (counter * self.h > min) and (counter * self.h < max):
                position_series.append(
                    A * position_series[counter] + B * position_series[counter - 1] + (force / self.m * self.h ** 2))
            else:
                position_series.append(A * position_series[counter] + B * position_series[counter - 1])

        # calculating velocities using an approximation of O(h^2)
        # the velocity is estimated using the mean value theorem
        # the velocity is independent of the equation of motion. It just utilises the definition of velocity. If h is small
        # enough this approximation holds true
        for counter in range(1, self.no_steps, 1):
            velocity_series.append(
                (position_series[counter + 1] - position_series[counter - 1]) / (2 * self.h))  # +O(h^2)
        position_series = position_series[:len(position_series) - 1]

        self.disturbed_Verlet_data = [position_series, velocity_series,
                                      self.energy_function(position_series, velocity_series)]

    def funct_dist_Verlet_integrator(self, min, max, Amp, freq):
        position_series = [self.init_x]
        velocity_series = [self.init_v]

        D = 2 * self.m + self.b * self.h
        B = (self.b * self.h - 2 * self.m) / D
        A = 2 * (2 * self.m - self.k * self.h ** 2) / D

        a_0 = (-self.b / self.m) * self.init_v + (-self.k / self.m) * self.init_x
        x_1 = self.init_x + self.init_v * self.h + 0.5 * a_0 * self.h ** 2  # obtained using a Taylor expansion of order 2
        position_series.append(x_1)

        for counter in range(1, self.no_steps, 1):
            if (counter * self.h > min) and (counter * self.h < max):
                position_series.append(
                    A * position_series[counter] + B * position_series[counter - 1] + (
                            Amp * np.sin(freq * counter * self.h) / self.m * self.h ** 2))
            else:
                position_series.append(A * position_series[counter] + B * position_series[counter - 1])

        # calculating velocities using an approximation of O(h^2)
        # the velocity is estimated using the mean value theorem
        # the velocity is independent of the equation of motion. It just utilises the definition of velocity. If h is small
        # enough this approximation holds true
        for counter in range(1, self.no_steps, 1):
            velocity_series.append(
                (position_series[counter + 1] - position_series[counter - 1]) / (2 * self.h))  # +O(h^2)
        position_series = position_series[:len(position_series) - 1]

        self.disturbed_Verlet_data = [position_series, velocity_series,
                                      self.energy_function(position_series, velocity_series)]

    def push_testing(self, min, max, force, amp, freq):
        # constant force
        self.const_dist_Verlet_integrator(force, min, max)
        constant_data = self.disturbed_Verlet_data

        # sinusoidal force
        self.funct_dist_Verlet_integrator(min, max, amp, freq)
        function_data = self.disturbed_Verlet_data

        figure = plt.figure()
        axes_1 = figure.add_subplot(111)
        axes_1.plot(self.time, constant_data[0], label="constant force")
        # axes_1.plot(self.time, function_data[0], label="sinusoidal force")
        axes_1.plot(self.time, self.Verlet_data[0], label="undisturbed")
        # axes_1.plot(self.time, self.analytic_series_pos, label="analytical solution")
        figure.legend()

    def search(self, arr, x):
        '''
        variable name               type                    description
        i                           integer                 counter
        arr                         list                    array
        x                           float                   the value being searched
        '''
        # linear search function
        for i in range(len(arr)):
            if arr[i] == x:
                return i
        return -1

    def resonance_Plot(self):
        def test_func(x, a, b):
            return a * np.sin(b * x)

        temp = np.sqrt(self.k / self.m)
        freq_array = []
        for counter in range(0, 40, 1):
            freq_array.append(counter * temp * 0.1)

        amplitude = []
        for freq in freq_array:
            # get the data sets for a specific frequency
            self.funct_dist_Verlet_integrator(0, self.no_steps * self.h, self.init_x, freq)
            temp = self.disturbed_Verlet_data[0]
            # calculate amplitude
            params, params_covariance = optimize.curve_fit(test_func, self.time, temp, p0=[2, 2])
            amplitude.append((params[0]))
            # append to the arrays
        # plot the results
        figure = plt.figure()
        axes_1 = figure.add_subplot(111)
        axes_1.set_xlabel("Frequency/ Hz")
        axes_1.set_ylabel("Amplitude/ m")
        axes_1.plot(freq_array, amplitude, "+b")

    def Critical(self):
        temp = self.b
        b = [0.5 * self.b_critical, self.b_critical, 2 * self.b_critical]
        data = []
        for entry in b:
            self.b = entry
            self.Verlet_integrator()
            data.append(self.Verlet_data)

        # Verlet method
        # phase plots
        figure4 = plt.figure()
        axes_7 = figure4.add_subplot(121)
        axes_7.plot(data[0][0], data[0][1], label="0.5b")
        axes_7.plot(data[1][0], data[1][1], label="b")
        axes_7.plot(data[2][0], data[2][1], label="2b")
        axes_7.set_xlabel("position (m)")
        axes_7.set_ylabel("velocity (ms^-1)")
        # energy plotting
        axes_8 = figure4.add_subplot(122)
        axes_8.plot(self.time, data[0][2])
        axes_8.plot(self.time, data[1][2])
        axes_8.plot(self.time, data[2][2])
        axes_8.set_xlabel("time (s)")
        axes_8.set_ylabel("energy (J)")
        # position plot
        figure = plt.figure()
        axes_1 = figure.add_subplot(111)
        axes_1.plot(self.time, data[0][0], label="0.5b")
        axes_1.plot(self.time, data[1][0], label="b")
        axes_1.plot(self.time, data[2][0], label="2b")
        axes_1.set_ylabel("Position (m)")
        axes_1.set_xlabel("Time (s)")
        figure4.legend()
        figure.legend()

        self.b = temp

    def thing(self):
        plt.plot(self.time, self.Verlet_data[0], label="Verlet")
        plt.plot(self.time, self.analytic_series_pos, label="analytic")
        plt.plot(self.time, self.Euler_Cromer_data[0], label="Eruler Cromer")
        plt.plot(self.time, self.Euler_data[0], label="Euler")
        plt.plot(self.time, self.B_Euler_data[0], label="Better euler")

        plt.legend()

def getData():  # edit this function

    fileName = float(input("Enter the name of the simulation (don't forget the format)"))
    m = float(input("Enter the value for the mass of the particle: "))
    k = float(input("Enter the value of the spring constant: "))
    b = float(input("Enter the value of the damping constant "))
    T = float(input("Enter the time you want the simulation to run: "))
    h = float(input("Enter the time step in seconds: "))
    init_x = float(input("Enter the initial position"))
    init_v = float(input("Enter the initial velocity"))

    return m, k, b, T, h, init_x, init_v

def main():
    option = 0
    while option != "8":
        option = input("Select an option:")
        print("1. Run simulation")
        print("2. Load old simulation")
        if option == "1" or option == "2":
            if option == "1":
                m, k, b, T, h, init_x, init_v = getData()
                os = SHO(h, T, b, m, k, init_x, init_v)
            elif option == "2":
                print("Enter the name of the file or type 'none' if you want to use default")
                name = input()
                if name == "none":
                    os = SHO(0, 0, 0, 0, 0, 0, 0)
                    os.load_data()
                else:
                    os = SHO(0, 0, 0, 0, 0, 0, 0, name)
                    check = os.load_data()
                    if not check:
                        print("Goodbye!")
                        return 0
            option = input("Select an option:")
            print("3. Run critical damping simulation")
            print("4. Run simulation with the force appplied")
            print("5. Plot all of it")
            print("6. Save the simulation")
            print("7. Plot Resonance Curves")
            print("8. Leave")
            if option == "3":
                os.Critical()
            elif option == "4":
                min = input("Minimum time: ")
                max = input("Maximum time: ")
                force = input("Force magnitude: ")
                Amp = input("Sinusoidal force amplitude: ")
                freq = input("Sinusoidal force frequency: ")
                os.push_testing(min, max, force, Amp, freq)
            elif option == "5":
                os.plot_data()
                os.plot_single()
            elif option == "6":
                os.save_data()
                print("File was saved as data.txt")
            elif option == "7":
                os.resonance_Plot()
        else:
            print("Goodbye!")

def main2():
    m = 5.44
    k = 0.93
    b = 0.1
    T = 400  # max time
    h = 0.001  # time step

    os = SHO(h, T, b, m, k, 10, 0)

    os.runSimulation()
    os.thing()

    # os.push_testing(45.6, 100, 5, 5, 0.062832)
    # os.push_testing(57, 100, 5, 5, 6.2832)

main2()
plt.show()


# 破解ctf比赛中的md5截断认证, 如: substr(md5($str), 0, 6) === "3322cf"
from hashlib import md5
from string import ascii_letters, digits
from itertools import permutations

all_string = ascii_letters + digits + '.,:;-_'

def fuzz_md5(value):
    value = value.lower()     # 转换为小写
    for i in range(10):
        print('.', end = '')
        for item in permutations(all_string, i):
            item = ''.join(item)
            if md5(item.encode()).hexdigest()[0:len(value)] == value:
                print('\nSuccess: ' + value + ' ==> ' + item)
                return

md5_value = '3322cf'
fuzz_md5(md5_value)


int_encode = b'2'
float_encode = b'42.3'
string1 = "Hello!"
string1_encode = string1.encode()
int1 = 5
int1_encode = b'%d' %int1
import serial
ser = serial.Serial('/dev/ttyUSB0', 9600)
ser.write(b'3')
ser.write(b'5')
ser.write(b'7')


"""video_clip table

Revision ID: b249d75760e9
Revises: 2d1f40a09897
Create Date: 2023-08-17 11:47:59.172458

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = 'b249d75760e9'
down_revision = '2d1f40a09897'
branch_labels = None
depends_on = None

def upgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('video_clips',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('name', sa.String(length=50), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_video_clips_name'), 'video_clips', ['name'], unique=False)
    op.add_column('render_hosts', sa.Column('record_date', sa.DateTime(), nullable=False))
    # ### end Alembic commands ###

def downgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_column('render_hosts', 'record_date')
    op.drop_index(op.f('ix_video_clips_name'), table_name='video_clips')
    op.drop_table('video_clips')
    # ### end Alembic commands ###


import collections

with open('input') as f:
    _input = list(map(lambda x: list(x), f.read().splitlines()))

N, S, W, E = (-1, 0), (1, 0), (0, -1), (0, 1)
action_order = [N, W, E, S]
wall, clear = "#", "."

class Unit:
    Race = str
    Atk = int
    HP = int
    X = int
    Y = int

    def __init__(self, race, x, y):
        self.Atk = 3
        self.HP = 200
        self.Race = race
        self.X = x
        self.Y = y

    def is_enemy_near(self):
        result = False
        for direction in action_order:
            x, y = direction
            if area[self.X + x][self.Y + y] == self.get_opposite_race():
                result = True
        return result

    def attack(self):
        x, y = self.X, self.Y
        enemy_around = list()
        for x2, y2 in ((x - 1, y), (x, y - 1), (x, y + 1), (x + 1, y)):
            if area[x2][y2] == self.get_opposite_race():
                for enemy in filter(lambda x: x.X == x2 and x.Y == y2  , units):
                    enemy_around.append(enemy)

        if len(enemy_around) > 0:
            min_hp = min(enemy_around, key=lambda x: x.HP).HP
            for x2, y2 in ((x - 1, y), (x, y - 1), (x, y + 1), (x + 1, y)):
                enemy = list(filter(lambda x: x.X == x2 and x.Y == y2 and x.HP == min_hp, units))
                if len(enemy) > 0:
                    enemy[0].HP -= 3
                    if enemy[0].HP <= 0:
                        area[enemy[0].X][enemy[0].Y] = clear
                    break

    def move(self):
        squares = list()
        for enemy in filter(lambda x: x.Race == self.get_opposite_race(), units):
            for x, y in ((enemy.X - 1, enemy.Y), (enemy.X, enemy.Y - 1), (enemy.X, enemy.Y + 1), (enemy.X + 1, enemy.Y)):
                if area[x][y] == clear:
                    squares.append([x, y])

        path = self.get_path_to_nearest_enemy(squares)

        if path is not None and len(path) > 0:
            self.X, self.Y = path[1]

    def get_path_to_nearest_enemy(self, goal):
        start = (self.X, self.Y)
        queue = collections.deque([[start]])
        seen = {start}
        while queue:
            path = queue.popleft()
            x, y = path[-1]
            if [x, y] in goal:
                return path

            for x2, y2 in ((x - 1, y), (x, y - 1), (x, y + 1), (x + 1, y)):
                if area[x2][y2] != wall and area[x2][y2] == clear and (x2, y2) not in seen:
                    queue.append(path + [(x2, y2)])
                    seen.add((x2, y2))

    def get_opposite_race(self):
        if self.Race == "G":
            return "E"
        else:
            return "G"

def update_area():
    for i in range(len(area)):
        for j in range(len(area)):
            if area[i][j] == "E" or area[i][j] == "G":
                area[i][j] = clear
    for unit in units:
        if unit.HP <= 0:
            continue
        area[unit.X][unit.Y] = unit.Race

units = list()
area = _input

for i in range(len(area)):
    for j in range(len(area)):
        if area[i][j] == "E" or area[i][j] == "G":
            units.append(Unit(area[i][j], i, j))

for i in range(0, 100):
    units.sort(key=lambda unit: (unit.X, unit.Y))
    for unit in units:
        if unit.HP <= 0:
            units.remove(unit)

    for unit in units:
        if unit.HP <= 0:
            continue

        if unit.is_enemy_near():
            unit.attack()
        else:
            unit.move()
            if unit.is_enemy_near():
                unit.attack()
        update_area()

    print(i)
    for line in area:
        print("".join(line))

    goblis = list(filter(lambda x: x.Race == "G" and x.HP > 0, units))
    elfs = list(filter(lambda x: x.Race == "E" and x.HP > 0, units))

    if len(goblis) == 0 or len(elfs) == 0:
        result = 0
        for u in filter(lambda x: x.HP > 0, units):
            print(u.HP)
            result += u.HP
        print(i, result, result * i)
        break


from scipy.sparse import csr_matrix
import numpy as np

from xclimf import compute_mrr

def test_compute_mrr():
  row = np.array([0,   0,   1,   1])
  col = np.array([0,   1,   0,   1])
  val = np.array([1.0, 2.0, 2.0, 1.0])
  data = csr_matrix((val, (row, col)), shape=(2, 2))

  U = np.array([
    [1.0, 2.0],
    [2.0, 1.0]
  ])
  V = np.array([
    [2.0, 1.0],
    [1.0, 2.0]
  ])

  mrr = compute_mrr(data, U, V)

  assert mrr == 1

def test_compute_mrr_when_dont_predicted_for_user():
  row = np.array([0,   0,   1])
  col = np.array([0,   1,   2])
  val = np.array([1.0, 2.0, 2.0])
  data = csr_matrix((val, (row, col)), shape=(2, 3))

  U = np.array([
    [1.0, 2.0],
    [2.0, 1.0]
  ])
  V = np.array([
    [2.0, 1.0],
    [1.0, 2.0],
    [0.0, 0.0],
  ])

  mrr = compute_mrr(data, U, V)

  assert mrr == (1.0 + 1.0/3.0)/2.0


##deredden SDSS flux measurements for ECO
##Sep 23, 2016

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

import pyfits
from astropy.io import fits
from scipy import ndimage
from scipy.io.idl import readsav
from scipy.optimize import curve_fit
import numpy as np
from time import clock
import glob
import pandas as pd

from matplotlib import rcParams
rcParams.update({'figure.autolayout': True})

from numpy import pi
from numpy.ma import median
from matplotlib import pyplot as plt
import os.path
import sys
import pdb
import pylab
pylab.ion()

###########################################################
#import and concatenate all the batches --ignore this
#set one
#t1 = fits.open('coords/eco_HeII_one.fits')
#t2 = fits.open('coords/eco_HeII_two.fits')

#nrows1 = t1[1].data.shape[0]
#nrows2 = t2[1].data.shape[0]
#nrows = nrows1 + nrows2

#hdu = fits.new_table(fits.ColDefs(t1[1].columns), nrows=nrows)
#for name in t1[1].columns.names:
#    hdu.data.field(name)[nrows1:]=t2[1].data.field(name)
#hdu.writeto('coords/batchALL1.fits', clobber= True)

##set two
#t3 = fits.open('coords/eco_HeII_three.fits')
#t4 = fits.open('coords/eco_HeII_four.fits')

#nrows3 = t3[1].data.shape[0]
#nrows4 = t4[1].data.shape[0]
#nrows_s2 = nrows3 + nrows4

#hdu2 = fits.new_table(fits.ColDefs(t3[1].columns), nrows=nrows_s2)
#for name in t3[1].columns.names:
#    hdu2.data.field(name)[nrows3:]=t4[1].data.field(name)
#hdu2.writeto('coords/batchALL2.fits', clobber= True)

##set three
#t5 = fits.open('coords/eco_HeII_five.fits')
#t6 = fits.open('coords/eco_HeII_six.fits')

#nrows5 = t5[1].data.shape[0]
#nrows6 = t6[1].data.shape[0]
#nrows_s3 = nrows5 + nrows6

#hdu3 = fits.new_table(fits.ColDefs(t5[1].columns), nrows=nrows_s3)
#for name in t5[1].columns.names:
#    hdu3.data.field(name)[nrows5:]=t6[1].data.field(name)
#hdu3.writeto('coords/batchALL3.fits', clobber= True)

#set four
#7 = fits.open('coords/eco_HeII_seven.fits')
#8 = fits.open('coords/eco_HeII_eight.fits')

#rows7 = t7[1].data.shape[0]
#rows8 = t8[1].data.shape[0]
#rows_s4 = nrows7 + nrows8

#du4 = fits.new_table(fits.ColDefs(t7[1].columns), nrows=nrows_s4)
#or name in t7[1].columns.names:
#   hdu4.data.field(name)[nrows7:]=t8[1].data.field(name)
#du4.writeto('coords/batchALL4.fits', clobber= True)

##set five
#t9 = fits.open('coords/eco_HeII_nine.fits')
#t10 = fits.open('coords/eco_HeII_ten.fits')

#nrows9 = t9[1].data.shape[0]
#nrows10 = t10[1].data.shape[0]
#nrows_s5 = nrows9 + nrows10

#hdu5 = fits.new_table(fits.ColDefs(t9[1].columns), nrows=nrows_s5)
#for name in t9[1].columns.names:
#    hdu5.data.field(name)[nrows9:]=t10[1].data.field(name)
#hdu5.writeto('coords/batchALL5.fits', clobber= True)

##set six
#t11 = fits.open('coords/eco_HeII_eleven.fits')
#t12 = fits.open('coords/eco_HeII_twelve.fits')

#nrows11 = t11[1].data.shape[0]
#nrows12 = t12[1].data.shape[0]
#nrows_s6 = nrows11 + nrows12

#hdu6 = fits.new_table(fits.ColDefs(t11[1].columns), nrows=nrows_s6)
#for name in t11[1].columns.names:
#    hdu6.data.field(name)[nrows11:]=t12[1].data.field(name)
#hdu6.writeto('coords/batchALL6.fits', clobber= True)

##concat the sets

##set seven
#t13 = fits.open('coords/eco_HeII_thirteen.fits')
#ts6 = fits.open('coords/batchALL6.fits')

#nrows13 = t13[1].data.shape[0]
#nrowss6 = ts6[1].data.shape[0]
#nrows_s7 = nrows13 + nrowss6

#hdu7 = fits.new_table(fits.ColDefs(t13[1].columns), nrows=nrows_s7)
#for name in t13[1].columns.names:
#    hdu7.data.field(name)[nrows13:]=ts6[1].data.field(name)
#hdu7.writeto('coords/batchALL7.fits', clobber= True)

#concat 7 and 5
#ts5 = fits.open('coords/batchALL5.fits')
#ts7 = fits.open('coords/batchALL7.fits')

#nrowss5 = ts5[1].data.shape[0]
#nrowss7 = ts7[1].data.shape[0]
#nrows_s8 = nrowss5 + nrowss7

#hdu8 = fits.new_table(fits.ColDefs(ts5[1].columns), nrows=nrows_s8)
#for name in ts5[1].columns.names:
#    hdu8.data.field(name)[nrowss5:]=ts7[1].data.field(name)
#hdu8.writeto('coords/batchALL8.fits', clobber= True)

#concat 8 and 4
#ts8 = fits.open('coords/batchALL8.fits')
#ts4 = fits.open('coords/batchALL4.fits')

#nrowss8 = ts8[1].data.shape[0]
#nrowss4 = ts4[1].data.shape[0]
#nrows_s9 = nrowss8 + nrowss4

#hdu9 = fits.new_table(fits.ColDefs(ts8[1].columns), nrows=nrows_s9)
#for name in ts8[1].columns.names:
#    hdu9.data.field(name)[nrowss8:]=ts4[1].data.field(name)
#hdu9.writeto('coords/batchALL9.fits', clobber= True)

#cont 9 and 3
#ts9 = fits.open('coords/batchALL9.fits')
#ts3 = fits.open('coords/batchALL3.fits')

#nrowss9 = ts9[1].data.shape[0]
#nrowss3 = ts3[1].data.shape[0]
#nrows_s10 = nrowss9 + nrowss3

#hdu10 = fits.new_table(fits.ColDefs(ts9[1].columns), nrows=nrows_s10)
#for name in ts9[1].columns.names:
#    hdu10.data.field(name)[nrowss9:]=ts3[1].data.field(name)
#hdu10.writeto('coords/batchALL10.fits', clobber= True)

##cont 10 and 2
#ts10 = fits.open('coords/batchALL10.fits')
#ts2 = fits.open('coords/batchALL2.fits')

#nrowss10 = ts10[1].data.shape[0]
#nrowss2 = ts2[1].data.shape[0]
#nrows_s11 = nrowss10 + nrowss2

#hdu11 = fits.new_table(fits.ColDefs(ts10[1].columns), nrows=nrows_s11)
#for name in ts10[1].columns.names:
#    hdu11.data.field(name)[nrowss10:]=ts2[1].data.field(name)
#hdu11.writeto('coords/batchALL11.fits', clobber= True)

##concat 11 and 1
#ts11 = fits.open('coords/batchALL11.fits')
#ts1 = fits.open('coords/batchALL1.fits')

#nrowss11 = ts11[1].data.shape[0]
#nrowss1 = ts1[1].data.shape[0]
#nrows_s12 = nrowss11 + nrowss1

#hdu12 = fits.new_table(fits.ColDefs(ts11[1].columns), nrows=nrows_s12)
#for name in ts11[1].columns.names:
#    hdu12.data.field(name)[nrowss11:]=ts1[1].data.field(name)
#hdu12.writeto('ECO_SDSS_raw.fits', clobber= True)
##############################################################3

#BEGIN ANALYSIS
#open the file
hdulist = fits.open('ECO_SDSS_raw.fits')
#extract the data
hdu_data = hdulist[1].data
#extract the header
hdu_headers = hdulist[1].header
#separate the data columns
galname = hdu_data.field(0)
oii_3726_flux = hdu_data.field(1)
oii_3726_flux_err = hdu_data.field(2)
oii_3729_flux = hdu_data.field(3)
oii_3729_flux_err = hdu_data.field(4)
neiii_3869_flux = hdu_data.field(5)
neiii_3869_flux_err = hdu_data.field(6)
h_delta_flux = hdu_data.field(7)
h_delta_flux_err = hdu_data.field(8)
h_gamma_flux = hdu_data.field(9)
h_gamma_flux_err = hdu_data.field(10)
oiii_4363_flux = hdu_data.field(11)
oiii_4363_flux_err = hdu_data.field(12)
h_beta_flux = hdu_data.field(13)
h_beta_flux_err = hdu_data.field(14)
oiii_4959_flux = hdu_data.field(15)
oiii_4959_flux_err = hdu_data.field(16)
oiii_5007_flux = hdu_data.field(17)
oiii_5007_flux_err = hdu_data.field(18)
hei_5876_flux = hdu_data.field(19)
hei_5876_flux_err = hdu_data.field(20)
oi_6300_flux = hdu_data.field(21)
oi_6300_flux_err = hdu_data.field(22)
nii_6548_flux = hdu_data.field(23)
nii_6548_flux_err = hdu_data.field(24)
h_alpha_flux = hdu_data.field(25)
h_alpha_flux_err = hdu_data.field(26)
nii_6584_flux = hdu_data.field(27)
nii_6584_flux_err = hdu_data.field(28)
sii_6717_flux = hdu_data.field(29)
sii_6717_flux_err = hdu_data.field(30)
sii_6731_flux = hdu_data.field(31)
sii_6731_flux_err = hdu_data.field(32)
ariii_7135_flux = hdu_data.field(33)
ariii_7135_flux_err = hdu_data.field(34)
heii_4685_flux = hdu_data.field(39)
heii_4685_flux_err = hdu_data.field(40)
oii_3726_flux_port = hdu_data.field(41)
oii_3726_flux_port_err = hdu_data.field(42)

########reddening correct###############
#intrinsic balmer decrement
balm_dec_exp = 2.86

#observed balmer decrement
balm_dec_obs = h_alpha_flux/h_beta_flux

#relation from balmer decrement to color excess
cee = 3.1*(np.log10(balm_dec_obs) - np.log10(balm_dec_exp))

#color excess for each galaxy
EBV_excess = cee*0.77

#speed of light
c_kms = 3.0*10**5.0

#extinction curve points
odonnell_dat = np.loadtxt('odonnell94mwextcurve.txt', dtype = "float")
#milky way lambda
mw_lam = odonnell_dat[:,0]
#factor to relate each mw lam and color excess
mw_A_overEBV = odonnell_dat[:,2]

###################REST FRAME###################
oii_3726_flux_ext = np.zeros(len(EBV_excess))
oii_3729_flux_ext = np.zeros(len(EBV_excess))
neiii_3869_flux_ext = np.zeros(len(EBV_excess))
h_delta_flux_ext = np.zeros(len(EBV_excess))
h_gamma_flux_ext = np.zeros(len(EBV_excess))
oiii_4363_flux_ext = np.zeros(len(EBV_excess))
h_beta_flux_ext = np.zeros(len(EBV_excess))
oiii_4959_flux_ext = np.zeros(len(EBV_excess))
oiii_5007_flux_ext = np.zeros(len(EBV_excess))
hei_5876_flux_ext = np.zeros(len(EBV_excess))
oi_6300_flux_ext = np.zeros(len(EBV_excess))
nii_6548_flux_ext = np.zeros(len(EBV_excess))
h_alpha_flux_ext  = np.zeros(len(EBV_excess))
nii_6584_flux_ext = np.zeros(len(EBV_excess))
sii_6717_flux_ext = np.zeros(len(EBV_excess))
sii_6731_flux_ext = np.zeros(len(EBV_excess))
ariii_7135_flux_ext = np.zeros(len(EBV_excess))
heii_4685_flux_ext = np.zeros(len(EBV_excess))
oii_3726_flux_port_ext = np.zeros(len(EBV_excess))

#find conversion array for each galaxy at each wavelength
mw_A_atmwlam  = np.zeros(len(EBV_excess))

for i in np.arange(len(galname)):
    mw_A_atmwlam = mw_A_overEBV*EBV_excess[i]
    #there is a mw_A_atmwlam for each galaxy, this index is the same for all
    mw_A_oii_3726_rest = mw_A_atmwlam[242]
    mw_A_oii_3729_rest = mw_A_atmwlam[243]
    mw_A_neiii_3869_rest = mw_A_atmwlam[290]
    mw_A_h_delta_rest = mw_A_atmwlam[367]
    mw_A_h_gamma_rest = mw_A_atmwlam[447]
    mw_A_oiii_4363_rest = mw_A_atmwlam[454]
    mw_A_h_beta_rest = mw_A_atmwlam[620]
    mw_A_oiii_4959_rest = mw_A_atmwlam[653]
    mw_A_oiii_5007_rest = mw_A_atmwlam[669]
    mw_A_hei_5876_rest = mw_A_atmwlam[959]
    mw_A_oi_6300_rest = mw_A_atmwlam[1100]
    mw_A_nii_6548_rest = mw_A_atmwlam[1183]
    mw_A_h_alpha_rest = mw_A_atmwlam[1187]
    mw_A_nii_6584_rest = mw_A_atmwlam[1195]
    mw_A_sii_6717_rest = mw_A_atmwlam[1239]
    mw_A_sii_6731_rest = mw_A_atmwlam[1244]
    mw_A_ariii_7135_rest = mw_A_atmwlam[1378]
    mw_A_heii_4685_rest = mw_A_atmwlam[562]
    mw_A_oii_3726_port_rest = mw_A_atmwlam[242]
    #find deextinction for obs lambda for each galaxy
    oii_3726_deext_rest = 10.0**(mw_A_oii_3726_rest/2.5)
    oii_3729_deext_rest = 10.0**(mw_A_oii_3729_rest/2.5)
    neiii_3869_deext_rest = 10.0**(mw_A_neiii_3869_rest/2.5)
    h_delta_deext_rest = 10.0**(mw_A_h_delta_rest/2.5)
    h_gamma_deext_rest = 10.0**(mw_A_h_gamma_rest/2.5)
    oiii_4363_deext_rest = 10.0**(mw_A_oiii_4363_rest/2.5)
    h_beta_deext_rest = 10.0**(mw_A_h_beta_rest/2.5)
    oiii_4959_deext_rest = 10.0**(mw_A_oiii_4959_rest/2.5)
    oiii_5007_deext_rest = 10.0**(mw_A_oiii_5007_rest/2.5)
    hei_5876_deext_rest = 10.0**(mw_A_hei_5876_rest/2.5)
    oi_6300_deext_rest = 10.0**(mw_A_oi_6300_rest/2.5)
    nii_6548_deext_rest = 10.0**(mw_A_nii_6548_rest/2.5)
    h_alpha_deext_rest = 10.0**(mw_A_h_alpha_rest/2.5)
    nii_6584_deext_rest = 10.0**(mw_A_nii_6584_rest/2.5)
    sii_6717_deext_rest = 10.0**(mw_A_sii_6717_rest/2.5)
    sii_6731_deext_rest = 10.0**(mw_A_sii_6731_rest/2.5)
    ariii_7135_deext_rest = 10.0**(mw_A_ariii_7135_rest/2.5)
    heii_4685_deext_rest= 10.0**(mw_A_heii_4685_rest/2.5)
    oii_3726_port_deext_rest = 10.0**(mw_A_oii_3726_port_rest/2.5)
    #output is dextincted avg flux for each line in each galaxy
    oii_3726_flux_ext[i] = oii_3726_flux[i]*oii_3726_deext_rest
    oii_3729_flux_ext[i] = oii_3729_flux[i]*oii_3729_deext_rest
    neiii_3869_flux_ext[i] = neiii_3869_flux[i]*neiii_3869_deext_rest
    h_delta_flux_ext[i] = h_delta_flux[i]*h_delta_deext_rest
    h_gamma_flux_ext[i] = h_gamma_flux[i]*h_gamma_deext_rest
    oiii_4363_flux_ext[i] = oiii_4363_flux[i]*oiii_4363_deext_rest
    h_beta_flux_ext[i] = h_beta_flux[i]*h_beta_deext_rest
    oiii_4959_flux_ext[i] = oiii_4959_flux[i]*oiii_4959_deext_rest
    oiii_5007_flux_ext[i] = oiii_5007_flux[i]*oiii_5007_deext_rest
    hei_5876_flux_ext[i] = hei_5876_flux[i]*hei_5876_deext_rest
    oi_6300_flux_ext[i] = oi_6300_flux[i]*oi_6300_deext_rest
    nii_6548_flux_ext[i] = nii_6548_flux[i]*nii_6548_deext_rest
    h_alpha_flux_ext[i]  = h_alpha_flux[i]*h_alpha_deext_rest
    nii_6584_flux_ext[i] = nii_6584_flux[i]*nii_6584_deext_rest
    sii_6717_flux_ext[i] = sii_6717_flux[i]*sii_6717_deext_rest
    sii_6731_flux_ext[i] = sii_6731_flux[i]*sii_6731_deext_rest
    ariii_7135_flux_ext[i] = ariii_7135_flux[i]*ariii_7135_deext_rest
    heii_4685_flux_ext[i] = heii_4685_flux[i]*heii_4685_deext_rest
    oii_3726_flux_port_ext[i] = oii_3726_flux_port[i]*oii_3726_port_deext_rest

#export to fits file
col1 = fits.Column(name = 'NAME', format = '20A', array=np.array(galname))
col2 = fits.Column(name = 'oii_3726_flux_ext', format = 'E', array=oii_3726_flux_ext)
col3 = fits.Column(name = 'oii_3726_flux_ext_err', format = 'E', array=oii_3726_flux_err)
col4 = fits.Column(name = 'oii_3729_flux_ext', format = 'E', array=oii_3729_flux_ext)
col5 = fits.Column(name = 'oii_3729_flux_ext_err', format = 'E', array=oii_3729_flux_err)
col6 = fits.Column(name = 'neiii_3869_flux_ext', format = 'E', array=neiii_3869_flux_ext)
col7 = fits.Column(name = 'neiii_3869_flux_ext_err', format = 'E', array=neiii_3869_flux_err)
col8 = fits.Column(name = 'h_delta_flux_ext', format = 'E', array=h_delta_flux_ext)
col9 = fits.Column(name = 'h_delta_flux_ext_err', format = 'E', array=h_delta_flux_err)
col10 = fits.Column(name = 'h_gamma_flux_ext', format = 'E', array=h_gamma_flux_ext)
col11 = fits.Column(name = 'h_gamma_flux_ext_err', format = 'E', array=h_gamma_flux_err)
col12 = fits.Column(name = 'oiii_4363_flux_ext', format = 'E', array=oiii_4363_flux_ext)
col13 = fits.Column(name = 'oiii_4363_flux_ext_err', format = 'E', array=oiii_4363_flux_err)
col14 = fits.Column(name = 'h_beta_flux_ext', format = 'E', array=h_beta_flux_ext)
col15 = fits.Column(name = 'h_beta_flux_ext_err', format = 'E', array=h_beta_flux_err)
col16 = fits.Column(name = 'oiii_4959_flux_ext', format = 'E', array=oiii_4959_flux_ext)
col17 = fits.Column(name = 'oiii_4959_flux_ext_err', format = 'E', array=oiii_4959_flux_err)
col18 = fits.Column(name = 'oiii_5007_flux_ext', format = 'E', array=oiii_5007_flux_ext)
col19 = fits.Column(name = 'oiii_5007_flux_ext_err', format = 'E', array=oiii_5007_flux_err)
col20 = fits.Column(name = 'hei_5876_flux_ext', format = 'E', array=hei_5876_flux_ext)
col21 = fits.Column(name = 'hei_5876_flux_ext_err', format = 'E', array=hei_5876_flux_err)
col22 = fits.Column(name = 'oi_6300_flux_ext', format = 'E', array=oi_6300_flux_ext)
col23 = fits.Column(name = 'oi_6300_flux_ext_err', format = 'E', array=oi_6300_flux_err)
col24 = fits.Column(name = 'nii_6548_flux_ext', format = 'E', array=nii_6548_flux_ext)
col25 = fits.Column(name = 'nii_6548_flux_ext_err', format = 'E', array=nii_6548_flux_err)
col26 = fits.Column(name = 'h_alpha_flux_ext', format = 'E', array=h_alpha_flux_ext)
col27 = fits.Column(name = 'h_alpha_flux_ext_err', format = 'E', array=h_alpha_flux_err)
col28 = fits.Column(name = 'nii_6584_flux_ext', format = 'E', array=nii_6584_flux_ext)
col29 = fits.Column(name = 'nii_6584_flux_ext_err', format = 'E', array=nii_6584_flux_err)
col30 = fits.Column(name = 'sii_6717_flux_ext', format = 'E', array=sii_6717_flux_ext)
col31 = fits.Column(name = 'sii_6717_flux_ext_err', format = 'E', array=sii_6717_flux_err)
col32 = fits.Column(name = 'sii_6731_flux_ext', format = 'E', array=sii_6731_flux_ext)
col33 = fits.Column(name = 'sii_6731_flux_ext_err', format = 'E', array=sii_6731_flux_err)
col34 = fits.Column(name = 'ariii_7135_flux_ext', format = 'E', array=ariii_7135_flux_ext)
col35 = fits.Column(name = 'ariii_7135_flux_ext_err', format = 'E', array=ariii_7135_flux_err)
col36 = fits.Column(name = 'Flux_HeII_4685_ext', format = 'E', array=heii_4685_flux_ext)
col37 = fits.Column(name = 'Flux_HeII_4685_ext_Err', format = 'E', array =heii_4685_flux_err )
col38 = fits.Column(name = 'Flux_OII_3726_ext', format = 'E', array=oii_3726_flux_port_ext)
col39 = fits.Column(name = 'Flux_OII_3726_ext_Err', format = 'E', array=oii_3726_flux_port_err)
col40 = fits.Column(name = 'balmer_decrement', format = 'E', array=balm_dec_obs)
col41 = fits.Column(name = 'balmer_decrement_ext', format = 'E', array=(h_alpha_flux_ext/h_beta_flux_ext))

#condense colummns, construct new table, write out results to binary fits
cols = fits.ColDefs([col1, col2,col3, col4, col5, col6, col7, col8, col9, col10, col11, col12, col13, col14, col15, col16, col17, col18, col19, col20, col21,col22,col23,col24,col25,col26,col27,col28,col29,col30,col31,col32,col33,col34,col35, col36, col37, col38, col39, col40, col41])
tbhdu = fits.new_table(cols)
#tbhdu.writeto('ECO_SDSS_dext.fits', clobber=True)

#plot check BPT
#define demarcation function, log_NII_HA vs. log_OIII_HB
def log_OIII_HB_NII(log_NII_HA):
    return 1.3 + (0.61 / (log_NII_HA - 0.05))

def comp_OIII_HB_NII(log_NII_HA):
    return 1.19 + 0.61 / (log_NII_HA - 0.47)

# create line ratios [NII]/Halpha and [OIII]/Hbeta

nii_sum = nii_6548_flux_ext + nii_6584_flux_ext

x = np.log10(nii_sum/h_alpha_flux_ext)
y = np.log10(oiii_5007_flux_ext/h_beta_flux_ext)

#create starforming vs. AGN line
Measured_Predicted_OIII_HB = log_OIII_HB_NII(x)
Measured_Predicted_comp_OIII_HB = comp_OIII_HB_NII(x)

#generate list of points in x direction to plot demarcation line over entire range of plot
Predicted_NII_HA = np.linspace(-3.0, 0.35)
#evaluate function at those points
Predicted_log_OIII_HB_NII = log_OIII_HB_NII(Predicted_NII_HA)
Predicted_comp_log_OIII_HB_NII = comp_OIII_HB_NII(Predicted_NII_HA)

### sample regions above and below line to plot the points above and below separately, ie in different colors
#galaxies above line (AGN)
Above_Predicted_AGN = y > Measured_Predicted_OIII_HB
Above_Predicted_comp = y > Measured_Predicted_comp_OIII_HB

#select range to avoid ugly log function behavior at origin of plot
sel = Predicted_NII_HA < 0

#plot
fig = plt.figure(1)
plt.clf
ax = fig.add_subplot(111)
demarc, = ax.plot(Predicted_NII_HA[sel], Predicted_log_OIII_HB_NII[sel], color = "black",linestyle = '--')
composite, = ax.plot(Predicted_NII_HA, Predicted_comp_log_OIII_HB_NII, color = "black", linewidth = 1.5)
full, = ax.plot(x, y, 'k.', markersize =4)
ax.set_xlim(-3,2)
ax.set_ylim(-3,4)
ax.set_xlabel(r"$\rm \log([NII]/H\alpha)$", fontsize = 22)
ax.set_ylabel(r"$\rm \log([OIII]/H\beta)$", fontsize = 22)
ax.set_title("SDSS ECO BPT Diagnostic Plot", fontsize = 20)
#plt.savefig("SDSS_ECO_BPT.pdf")

###################################################################
#plot HeII

#define AGN demarcation lines
def log_HEII_HB(log_NII_HA):
    return  -1.22 + 1.0 / ((8.92*log_NII_HA) + 1.32)

heii_sel = np.where(heii_4685_flux_ext > heii_4685_flux_err*3.)
galname_heii = galname[heii_sel]

#define axis
x_heii = np.log10(nii_sum[heii_sel]/h_alpha_flux_ext[heii_sel])
y_heii = np.log10(heii_4685_flux_ext[heii_sel]/h_beta_flux_ext[heii_sel])

#create starforming vs. AGN line
Measured_Predicted_HEII_HB = log_HEII_HB(x_heii)

#generate list of points in x direction to plot demarcation line over entire range of plot
#evaluate function at those points
#generate list of points in x direction to plot demarcation line over entire range of plot
Predicted_NII_HA = np.linspace(-3.0, 0.35)
Predicted_log_HEII_HB = log_HEII_HB(Predicted_NII_HA)

#select range to avoid ugly log function behavior at origin of plot
sel = Predicted_NII_HA < -0.15

### sample regions above and below line to plot the points above and below separately, ie in different colors
#galaxies above line (AGN)
Above_Predicted_AGN_heii = y_heii > Measured_Predicted_HEII_HB

#plot
fig = plt.figure(2)
plt.clf
ax_heii = fig.add_subplot(111)
demarc, = ax_heii.plot(Predicted_NII_HA[sel], Predicted_log_HEII_HB[sel], color = "black",linewidth = 1.5)
full, = ax_heii.plot(x_heii, y_heii, 'k.', markersize =4)
ax_heii.set_xlim(-3.0,1.0)
ax_heii.set_ylim(-3.0,1.0)
ax_heii.set_xlabel(r"$\rm \log([NII]/H\alpha)$", fontsize = 22)
ax_heii.set_ylabel(r"$\rm \log([HeII]/H\beta)$", fontsize = 22)
ax_heii.set_title("SDSS RESOLVE HeII Diagnostic Plot", fontsize = 20)
#plt.savefig("SDSS_RESOLVE_HeII.eps")

#demarc, = ax[1].plot(Predicted_NII_HA[sel], Predicted_log_HEII_HB[sel], color = "black",linewidth = 1.5)
#full, = ax[1].plot(x_heii, y_heii, 'k.', markersize =4)
#es0s, = ax[1].plot(x_sel_heii[no_zero_heii],y_sel_heii[no_zero_heii],'bo', markersize = 8)
#active, = ax[1].plot(activex_heii[no_zero_active_heii],activey_heii[no_zero_active_heii],"ro", markersize = 8)
#ax[1].set_xlim(-3.0,1.0)
#ax[1].set_ylim(-3.0,1.0)
#ax[1].set_xlabel(r"$\rm \log([NII]/H\alpha)$", fontsize = 22)
#ax[1].set_ylabel(r"$\rm \log([HeII]/H\beta)$", fontsize = 22)
#ax[1].set_title("SDSS RESOLVE HeII", fontsize = 20)
#ax[1].set(aspect = 'equal')
#plt.tight_layout()
#plt.savefig("SDSS_RESOLVE_HeII.eps")


from Tkinter import *
import pygame.mixer
from time import sleep

mixer = pygame.mixer
mixer.init()

sound_file = "50459_M_RED_Nephlimizer.wav"
track = mixer.Sound(sound_file)

def track_stop():
    track.stop()

def track_start():
    track.play(loops = -1)
    sleep(2)
    track.set_volume(0.9)
    sleep(2)
    track.set_volume(0.1)
    sleep(2)
    track.stop()

app = Tk()
app.title("Head First Mix")

stop_botton = Button(app, command = track_stop, text = "Stop")
stop_botton.pack(side = RIGHT)

start_button = Button(app, command = track_start, text = "Start")
start_button.pack(side = LEFT)

app.geometry('255x100+200+100')
app.mainloop()


import datetime
import uuid

from eventsourcing.domain import Aggregate, event

from goods_model import Goods

class PaymentProcessed(Aggregate.Event):
    is_paid: bool

class OrderDispatched(Aggregate.Event):
    is_dispatched: bool

class OrderDelivered(Aggregate.Event):
    is_delivered: bool

class OrderPlaced(Aggregate.Event):
    order_id: int
    buyer_id: int
    goods_id: int
    is_active: bool

class OrderCancelled(Aggregate.Event):
    order_id: int

class Order(Aggregate):
    def __init__(self):
        self.order_id = None
        self.buyer_id = None
        self.goods_id = None
        self.is_active = False
        self.is_paid = False
        self.is_dispatched = False
        self.is_delivered = False
        self.message = ''

    def get_order(self, order_id):
        if self.order_id == order_id:
            return self
        raise ValueError('not found')

    @event(OrderPlaced)
    def place_order(self, buyer_id, goods_id):
        item = Goods().find_one_item(goods_id)
        item.change_is_ordered(True)
        self.order_id = str(uuid.uuid4())
        self.buyer_id = buyer_id
        self.goods_id = goods_id
        self.is_active = True
        self.is_paid = False
        self.is_dispatched = False
        self.is_delivered = False

    @event(OrderCancelled)
    def cancel_order(self, order_id):
        if not self.is_active:
            raise ValueError("Order is not active and cannot be cancelled.")
        if self.order_id != order_id:
            raise ValueError("Order ID does not match.")
        self.is_active = False

    @event(PaymentProcessed)
    def payment_process(self):
        self.is_paid = True

    @event(OrderDelivered)
    def order_delivered(self):
        self.is_delivered = True

    @event(OrderDispatched)
    def dispatch_order(self):
        if not self.is_paid:
            raise ValueError("Cannot dispatch an order that hasn't been paid for.")
        self.is_dispatched = True


def prob_at_least_N(k: int, N: int):
    # All AaBb-XXXX matings always has a 25% probability of AaBb offspring (Punnett square).
    # This is a binomial experiment;
    # We are looking for the probability of at least N 'successes' (AaBb) with 2^k trials and success rate of 25%.
    # p(N ≥ AaBb)
    # This is equal to 1 minus the probability of less than N AaBb with 2^k and success rate of 25%
    # p(N ≥ AaBb) = 1 - p(N < AaBb)
    # p(N ≥ AaBb) = 1 - p(N - 1 ≤ AaBb)   [Note that N is a natural number]
    # The right hand side can be nicely expressed by the binomial cumulative distribution function (bcdf)
    # p(N ≥ AaBb) = 1 - bcdf(N - 1, 2^k, p)

    p_AaBb = 0.25

    from scipy.stats import binom
    return 1 - binom.cdf(N - 1, 2**k, p_AaBb)

sample_input = '5 9'
if __name__=='__main__':
    k, N = (int(i) for i in sample_input.split(' '))
    print(prob_at_least_N(k, N))


import datetime
from textwrap import dedent

from vdirsyncer.storage.base import Item
from khal.controllers import get_agenda, import_ics

from .aux import _get_text
from . import aux

today = datetime.date.today()
yesterday = today - datetime.timedelta(days=1)
tomorrow = today + datetime.timedelta(days=1)

event_allday_template = u"""BEGIN:VEVENT
SEQUENCE:0
UID:uid3@host1.com
DTSTART;VALUE=DATE:{}
DTEND;VALUE=DATE:{}
SUMMARY:a meeting
DESCRIPTION:short description
LOCATION:LDB Lobby
END:VEVENT"""

event_today = event_allday_template.format(today.strftime('%Y%m%d'),
                                           tomorrow.strftime('%Y%m%d'))
item_today = Item(event_today)

class TestGetAgenda(object):
    def test_new_event(self, coll_vdirs):
        coll, vdirs = coll_vdirs
        event = coll.new_event(event_today, aux.cal1)
        coll.new(event)
        assert ['\x1b[1mToday:\x1b[0m', '\x1b[34ma meeting\x1b[0m'] == get_agenda(coll, aux.locale)

    def test_empty_recurrence(self, coll_vdirs):
        coll, vidrs = coll_vdirs
        coll.new(coll.new_event(dedent(
            'BEGIN:VEVENT\r\n'
            'UID:no_recurrences\r\n'
            'SUMMARY:No recurrences\r\n'
            'RRULE:FREQ=DAILY;COUNT=2;INTERVAL=1\r\n'
            'EXDATE:20110908T130000\r\n'
            'EXDATE:20110909T130000\r\n'
            'DTSTART:20110908T130000\r\n'
            'DTEND:20110908T170000\r\n'
            'END:VEVENT\r\n'
        ), aux.cal1))
        assert 'no events' in '\n'.join(get_agenda(
            coll, aux.locale,
            dates=[datetime.date(2011, 9, 8),
                   datetime.date(2011, 9, 9)]
        )).lower()

class TestImport(object):
    def test_import(self, coll_vdirs):
        coll, vdirs = coll_vdirs
        import_ics(coll, {'locale': aux.locale}, _get_text('event_rrule_recuid'),
                   batch=True)
        start_date = aux.BERLIN.localize(datetime.datetime(2014, 4, 30))
        end_date = aux.BERLIN.localize(datetime.datetime(2014, 9, 26))
        events = list(coll.get_localized(start_date, end_date))
        assert len(events) == 6
        events = sorted(events)
        assert events[1].start_local == aux.BERLIN.localize(datetime.datetime(2014, 7, 7, 9, 0))
        assert aux.BERLIN.localize(datetime.datetime(2014, 7, 14, 7, 0)) in \
            [ev.start for ev in events]

        import_ics(coll, {'locale': aux.locale}, _get_text('event_rrule_recuid_update'),
                   batch=True)
        events = list(coll.get_localized(start_date, end_date))
        for ev in events:
            print(ev.start)
        assert len(events) == 5
        assert aux.BERLIN.localize(datetime.datetime(2014, 7, 14, 7, 0)) not in \
            [ev.start_local for ev in events]

    def test_mix_datetime_types(self, coll_vdirs):
        """
        Test importing events with mixed tz-aware and tz-naive datetimes.
        """
        coll, vdirs = coll_vdirs
        import_ics(
            coll,
            {'locale': aux.locale},
            _get_text('event_dt_mixed_awareness'),
            batch=True
        )
        start_date = aux.BERLIN.localize(datetime.datetime(2015, 5, 29))
        end_date = aux.BERLIN.localize(datetime.datetime(2015, 6, 3))
        events = list(coll.get_localized(start_date, end_date))
        assert len(events) == 2
        events = sorted(events)
        assert events[0].start_local == \
            aux.BERLIN.localize(datetime.datetime(2015, 5, 30, 12, 0))
        assert events[0].end_local == \
            aux.BERLIN.localize(datetime.datetime(2015, 5, 30, 16, 0))
        assert events[1].start_local == \
            aux.BERLIN.localize(datetime.datetime(2015, 6, 2, 12, 0))
        assert events[1].end_local == \
            aux.BERLIN.localize(datetime.datetime(2015, 6, 2, 16, 0))