from bs4 import BeautifulSoup
import re
import requests

ENROLLMENT_BOUNDS = {
    0: [0, 5000],
    1: [5000, 15000],
    2: [15000, 30000],
    3: [30000, 10000000],
}

def get_college_basic(uni_id_list):
    where_str = ''
    order_by_str = 'ORDER BY (CASE'
    counter = 1
    for id in uni_id_list:
        id_str = f'u.university_id = {id}'
        if len(where_str) > 0:
            where_str = f'{where_str} or {id_str}'
        else:
            where_str = f'{id_str}'

        order_by_str = f'{order_by_str} WHEN {id_str} THEN {counter}'
        counter += 1
    order_by_str = f'{order_by_str} END) ASC'

    columns = "u.university_id, u.name, u.city, u.state, u.website, u.campus_location, u.total_enrollment"
    query = f'SELECT {columns} FROM university u WHERE {where_str} {order_by_str};'
    print(query)
    return query

def get_college(uni_id):
    select_str = "SELECT u.university_id, u.name, u.city, u.state, u.website, u.campus_location, u.total_enrollment, si.control, si.religious, si.accepts_ap_credit, si.study_abroad, si.offers_rotc, si.has_football, si.has_basketball, si.ncaa_member, si.retention_rate, si.graduation_rate, adm.total_applicants, adm.total_admitted, adm.admission_rate, adm.male_applicants, adm.female_applicants, adm.male_admitted, adm.female_admitted, adm.sat_rw_25, adm.sat_rw_75, adm.sat_math_25, adm.sat_math_75, adm.act_25, adm.act_75, fin.in_state_price, fin.out_of_state_price, fin.average_price_after_aid, fin.percent_given_aid, di.percent_american_indian_native_alaskan, di.percent_asian, di.percent_hawaiian_pacific_islander, di.percent_black, di.percent_white, di.percent_hispanic, di.percent_other, di.percent_two_races"
    from_str = "FROM university as u, school_info as si, admission_stats as adm, financial_stats as fin, diversity_stats as di"
    where_str = f"WHERE u.university_id = {uni_id} AND u.university_id = si.university_id AND u.university_id = adm.university_id AND u.university_id = fin.university_id AND u.university_id = di.university_id"

    info_query = f"{select_str}\n{from_str}\n{where_str};"
    majors_query = f"SELECT program_name FROM academic_programs WHERE {uni_id} = university_id;"

    return info_query, majors_query

def generate_query(params):
    state = params.get('state')
    state_location = int(params.get('state_location'))
    campus_location = params.getlist('campus_location')
    size = params.getlist('enrollment')
    majors = params.getlist('study-fields')
    sat_math = int(params.get('sat_math'))
    sat_reading = int(params.get('sat_reading'))
    act = int(params.get('act'))
    tuition = int(params.get('tuition'))
    financial_aid = int(params.get('financial-aid'))
    religious = params.get('religious')
    ap_credit = params.get('ap_credit')
    study_abroad = params.get('study_abroad')
    offers_rotc = params.get('offers_rotc')
    ncaa = params.get('ncaa')

    # Multiple score by this much for each type
    location_mult = 6 - int(params.get('location_rank'))
    academics_mult = 6 - int(params.get('academics_rank'))
    finance_mult = 6 - int(params.get('finance_rank'))
    other_mult = 6 - int(params.get('other_rank'))

    # Initial SQL strings
    where_str = "WHERE u.university_id = si.university_id AND u.university_id = adm.university_id AND u.university_id = fin.university_id AND u.university_id = di.university_id"
    group_str = "GROUP BY u.university_id"

    select_str = "SELECT u.university_id, u.name, u.city, u.state, u.website, u.campus_location, u.total_enrollment"

    majors_query = ""
    if majors:
        majors_string = "(" + ",".join(majors) + ")"
        majors_query = f"""
        , (SELECT uni.university_id, COUNT(a.cip_code) as majors_count
        FROM university as uni, academic_programs as a
        WHERE uni.university_id = a.university_id AND a.cip_code IN {majors_string}
        GROUP BY uni.university_id
        ORDER BY majors_count
        ) as maj
        """
        where_str = f"{where_str} AND u.university_id = maj.university_id"

    from_str = f"FROM university as u, school_info as si, admission_stats as adm, financial_stats as fin, diversity_stats as di {majors_query}"

    # State selection
    location_order = []
    if state_location == 0:
        location_order.append(f"(SUM(u.state = '{state}'))")
    elif state_location == 1:
        location_order.append(f"(SUM(u.state = '{state}') * 3)")
    elif state_location == 2:
        location_order.append(f"SUM(u.state = '{state}')")

    # Campus location and enrollment
    if campus_location:
        location_str = "('" + "', '".join(campus_location) + "')"
        location_order.append(f"SUM(u.campus_location IN {location_str})")
    if size:
        lower_bound = ENROLLMENT_BOUNDS[int(min(size))][0]
        upper_bound = ENROLLMENT_BOUNDS[int(max(size))][1]
        location_order.append(f"SUM(u.total_enrollment >= {lower_bound})")
        location_order.append(f"SUM(u.total_enrollment <= {upper_bound})")
    location_str = "((" + " + ".join(location_order) + \
        f") * {location_mult}) as location_score"

    if location_order:
        select_str = f"{select_str}, {location_str}"
    else:
        select_str = f"{select_str}, 0 as location_score"

    # SAT/ACT Scores
    academics_order = []
    if sat_math > 200:
        academics_order.append(f"SUM(adm.sat_math_25 <= {sat_math})")
    if sat_reading > 200:
        academics_order.append(f"SUM(adm.sat_rw_25 <= {sat_reading})")
    if act > 1:
        academics_order.append(f"SUM(adm.act_25 <= {act})")
    if majors:
        academics_str = "(maj.majors_count + (" + " + ".join(academics_order) + \
            f") * {academics_mult}) as academics_score"
    else:
        academics_str = "((" + " + ".join(academics_order) + \
            f") * {academics_mult}) as academics_score"

    if academics_order:
        select_str = f"{select_str}, {academics_str}"
    else:
        select_str = f"{select_str}, 0 as academics_score"

    # Financial
    finance_order = []
    if tuition:
        if financial_aid:
            finance_order.append(
                f"SUM(fin.percent_given_aid >= 50) + SUM(fin.average_price_after_aid <= {tuition})")
        else:
            price_state = "in_state_price" if state_location == 1 else "out_of_state_price"
            finance_order.append(f"SUM(fin.{price_state} <= {tuition})")
    finance_str = "((" + " + ".join(finance_order) + \
        f") * {finance_mult}) as finance_score"

    if finance_order:
        select_str = f"{select_str}, {finance_str}"
    else:
        select_str = f"{select_str}, 0 as finance_score"

    # Other preferences
    other_order = []
    if religious is not None:
        if int(religious):
            other_order.append("SUM(si.religious = 1)")
        else:
            other_order.append("SUM(si.religious = 0)")
    if ap_credit is not None and int(ap_credit):
        other_order.append("SUM(si.accepts_ap_credit = 1)")
    if study_abroad is not None and int(study_abroad):
        other_order.append("SUM(si.study_abroad = 1)")
    if offers_rotc is not None and int(offers_rotc):
        other_order.append("SUM(si.offers_rotc = 1)")
    if ncaa is not None and int(ncaa):
        other_order.append("SUM(si.ncaa_member = 1)")
    other_str = "((" + " + ".join(other_order) + \
        f") * {other_mult}) as other_score"

    if other_order:
        select_str = f"{select_str}, {other_str}"
    else:
        select_str = f"{select_str}, 0 as other_score"

    # Academic priority
    order_str = "ORDER BY"
    ranks = {
        location_mult: "location_score DESC",
        academics_mult: "academics_score DESC",
        finance_mult: "finance_score DESC",
        other_mult: "other_score DESC",
    }
    order = [ranks[rank] for rank in range(5, 1, -1)]
    order_str = "ORDER BY " + ", ".join(order) + ", u.name ASC"

    limit_str = "LIMIT 21"

    columns = "university_id, name, city, state, website, campus_location, total_enrollment"
    return (f"{select_str}\n{from_str}\n{where_str}\n{group_str}\n{order_str}\n{limit_str};", order)

def find_major(majors_list):
    # second advanced function
    # NOTE: this does not seem too advanced, so maybe we can parse each major / type to describe what it is
    # calculate quiz output
    major_dict = {}
    for l in majors_list:
        for major in l:
            major_dict[major] = major_dict.get(major, 0) + 1
    major_type = max(major_dict, key=major_dict.get)

# query for majors based on type
    query = "SELECT major FROM majors_info WHERE type='" + \
        str(major_type) + "'"
    return major_type, query

def get_major_type_info(major):
    URL = "https://acd.iupui.edu/explore/choose-your-major/connect-majors-to-careers/interests/" + \
        major.lower() + "/index.html"
    html_text = requests.get(URL).text
    soup = BeautifulSoup(html_text, 'html.parser')

    sub_title = str(soup.find('h3'))[4:-5]

    desc = str(soup.find_all('div', class_="text", string=re.compile("These")))
    desc = desc.split('. ', 1)[1]
    desc = desc.split(' If not,')[0]

    return sub_title, desc

def get_major_info(major_name):
    major_path = "https://www.mymajors.com/college-majors/"
    name = re.sub("[^a-zA-z]+", " ", major_name)
    major = "-".join(name.lower().split())
    url = major_path + major

    page = requests.get(url).text

    default_text = "A general program that focuses on law and legal issues from the perspective of the social sciences and humanities."
    soup = BeautifulSoup(page, "html.parser")
    desc = soup.find("p", {"class": "lead"}).get_text()
    desc_text = desc.split('\n')[1].strip()
    if desc_text == default_text:
        return False
    class_list = soup.find("ul", {"class": "cols3"})
    classes = []
    if type(class_list) is None:
        classes = ["No Data Found"]
    else:
        class_list = class_list.get_text().strip().split('\n')
        classes = [cl.strip() for cl in class_list if cl.strip()]

    career_url = "https://www.mymajors.com/careers/" + major + "-major"
    careers_page = requests.get(career_url).text

    soup = BeautifulSoup(careers_page, "html.parser")
    job_list = soup.find("ul", {"class": "cols2"})
    jobs = []
    if job_list is None:
        jobs = ["No Data Found"]
    else:
        job_list = job_list.get_text().strip().split('\n')
        jobs = [job.strip() for job in job_list if job.strip()]

    salary_data = soup.find_all("td")
    salaries = {}
    for i in range(0, len(salary_data), 2):
        if (i + 1) < len(salary_data):
            label = salary_data[i].get_text().strip()
            salary = salary_data[i+1].get_text().strip()
            salaries[label] = salary
    if not len(salaries):
        salaries["Data"] = "Not Found"

    return desc_text, classes, jobs, salaries


def squares(list):
    for i in range(len(list)):
        list[i] = int(list[i]) ** 2
    print(list)
def main():
    input_list = input("Enter values separated by a space: ")
    list = input_list.split()
    print(list)
    squares(list)
    print("the new list is: ", list)

main()


#Osiris Team binary decoding program
#Written originally by Dustin Smith

#input grab
binaryString = input("Input binary string: ")
#checks if the message is encoded in ASCII 7 or binary 8 via modulus
if(len(binaryString)%8==0):
    ASCIISize = 8
elif(len(binaryString)%7==0):
    ASCIISize = 7
#indexes the string based on previously found length, converts to int, then uses
#python's built in chr() operator to convert to unicode/ascii format
charList = []
for i in range(0,len(binaryString),ASCIISize):
    charList.append(chr(int(binaryString[i:i+ASCIISize],2)))
#finally joins these characters together and outputs result
print("Output: "+"".join(charList))


import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import scipy
from scipy.misc import derivative

def fn_plot1d(fn, x_min, x_max, filename):
    num_values = 1000
    x = np.linspace(x_min, x_max, num_values)
    fnv = np.vectorize(fn)
    y = fnv(x)
    Xlabel = "X axis"
    Ylabel = fn.__name__ + "(x)"
    Title = "1D plot of " + Ylabel
    plt.plot(x, y)
    plt.xlabel(Xlabel)
    plt.ylabel(Ylabel)
    plt.title(Title)
    #plt.show()
    plt.savefig(filename)
    plt.clf()

def fn_plot2d(fn, x_min, x_max, y_min, y_max, filename):
    num_x = 1000
    num_y = 1000
    x = np.linspace(x_min, x_max, num_x)
    y = np.linspace(y_min, y_max, num_y)
    X,Y = np.meshgrid(x,y)
    fnv = np.vectorize(fn)
    Z = fnv(X,Y)
    fig = plt.figure()
    ax = fig.gca(projection = '3d')
    ax.plot_surface(X,Y,Z)
    Xlabel = "X axis"
    Ylabel = "Y axis"
    Zlabel = fn.__name__ + "(x,y)"
    Title = "2D plot of " + Zlabel
    ax.set_xlabel(Xlabel)
    ax.set_ylabel(Ylabel)
    ax.set_zlabel(Zlabel)
    ax.set_title(Title)
    #plt.show()
    ax.figure.savefig(filename)
    #plt.gca(projection = 'rectilinear')
    plt.clf()

def nth_derivative_plotter(fn, n, x_min, x_max, filename):
    num_values = 1000
    x = np.linspace(x_min, x_max, num_values)
    fnv = np.vectorize(fn)
    y = derivative(fnv,x,dx = 1e-3, n = n)
    strn = str(n)
    Xlabel = "X axis"
    Ylabel = fn.__name__ + fr'$^{{({strn})}}$' + '(x)'
    Title = "nth derivative plotter (n = " + strn + ")"
    plt.plot(x,y)
    plt.xlabel(Xlabel)
    plt.ylabel(Ylabel)
    plt.title(Title)
    plt.savefig(filename)
    plt.clf()

def h(x):
    if x > 0:
        return np.exp(-1/(x*x))
    else:
        return 0

def g(x):
    return (h(2-x)/(h(2-x)+h(x-1)))

def b(x):
    if x < 0:
        x = -x
    return g(x)

def sinc(x,y):
    if (x == 0 and y == 0):
        return 1
    else:
        norm = (x**2 + y**2) ** (0.5)
        return (np.sin(norm)/norm)

if __name__ == '__main__':
    fn_plot1d(b,-2,2,'fn1plot.png')
    fn_plot2d(sinc, -1.5*np.pi, 1.5*np.pi, -1.5*np.pi, 1.5*np.pi, 'fn2plot.png')
    nth_derivative_plotter(b, 1, -2, 2, 'bd_1.png')
    nth_derivative_plotter(b, 2, -2, 2, 'bd_2.png')


from scripts.src.common.config import Color, Keywords, Direct, DataType
from common_and_plotting_functions.functions import check_and_mkdir_of_direct
from scripts.src.common.plotting_functions import multi_row_col_bar_plot

from scripts.data.common_functions import common_data_loader

from scripts.model.model_loader import model_loader, ModelList
from scripts.src.core.model.model_constructor import common_model_constructor

from ...common.result_processing_functions import common_flux_comparison_func

data_wrap_obj, keyword = common_data_loader(DataType.renal_carcinoma, test_mode=False, natural_anti_correction=True)
# user_defined_model = model_loader(ModelList.invivo_infusion_model)
user_defined_model = model_loader(ModelList.base_model_with_glc_tca_buffer)
mfa_model_obj = common_model_constructor(user_defined_model)

name = 'renal_carcinoma_invivo_infusion'
# output_folder = '{}/{}'.format(Direct.output_direct, name)
# raw_data_folder = '{}/{}'.format(output_folder, Direct.raw_flux_analysis_direct)

class SpecificParameter(object):
    test_dynamic_constant_flux_list = []
    test_preset_constant_flux_value_dict = {
        # 'GLC_total_input': 100,
        'GLC_supplement_net': 0,
        'CIT_supplement_net': 0,
        # 'GLN_input': 80,
        'ASP_input': 50,
        # 'SER_input': 8,
        # 'ALA_input': 20,
        # 'OAC_supplement_net': 0,
    }
    specific_flux_range_dict = {
        'Salvage_c': (1, 10),
    }

test_data_param_raw_list = [
    {
        keyword.tissue: keyword.kidney,
        '': [
            {
                keyword.patient: 1,
                '': [
                    {
                        keyword.index: 1,
                    },
                    {
                        keyword.index: 2,
                    },
                ]
            }]
    }
]

complete_data_param_raw_list = [
    {
        keyword.tissue: keyword.kidney,
        '': [
            {
                keyword.patient: 1,
                '': [
                    # {
                    #     keyword.index: 1,
                    # },
                    # {
                    #     keyword.index: 2,
                    # },
                    # {
                    #     keyword.index: 3,
                    # },
                    {
                        keyword.index: Keywords.average,
                    },
                ]
            },
            {
                keyword.patient: 2,
                '': [
                    # {
                    #     keyword.index: 1,
                    # },
                    # {
                    #     keyword.index: 2,
                    # },
                    # {
                    #     keyword.index: 3,
                    # },
                    {
                        keyword.index: Keywords.average,
                    },
                ]
            },
            {
                keyword.patient: 3,
                '': [
                    # {
                    #     keyword.index: 1,
                    # },
                    # {
                    #     keyword.index: 2,
                    # },
                    # {
                    #     keyword.index: 3,
                    # },
                    {
                        keyword.index: Keywords.average,
                    },
                ]
            },
            {
                keyword.patient: 4,
                '': [
                    # {
                    #     keyword.index: 1,
                    # },
                    # {
                    #     keyword.index: 2,
                    # },
                    # {
                    #     keyword.index: 3,
                    # },
                    {
                        keyword.index: Keywords.average,
                    },
                ]
            },
            {
                keyword.patient: 5,
                '': [
                    # {
                    #     keyword.index: 1,
                    # },
                    # {
                    #     keyword.index: 2,
                    # },
                    # {
                    #     keyword.index: 3,
                    # },
                    {
                        keyword.index: Keywords.average,
                    },
                ]
            },
        ]
    },
    {
        keyword.tissue: keyword.carcinoma,
        '': [
            {
                keyword.patient: 1,
                '': [
                    # {
                    #     keyword.index: 1,
                    # },
                    # {
                    #     keyword.index: 2,
                    # },
                    # {
                    #     keyword.index: 3,
                    # },
                    {
                        keyword.index: Keywords.average,
                    },
                ]
            },
            {
                keyword.patient: 2,
                '': [
                    # {
                    #     keyword.index: 1,
                    # },
                    # {
                    #     keyword.index: 2,
                    # },
                    # {
                    #     keyword.index: 3,
                    # },
                    {
                        keyword.index: Keywords.average,
                    },
                ]
            },
            {
                keyword.patient: 3,
                '': [
                    # {
                    #     keyword.index: 1,
                    # },
                    # {
                    #     keyword.index: 2,
                    # },
                    # {
                    #     keyword.index: 3,
                    # },
                    {
                        keyword.index: Keywords.average,
                    },
                ]
            },
            {
                keyword.patient: 4,
                '': [
                    # {
                    #     keyword.index: 1,
                    # },
                    # {
                    #     keyword.index: 2,
                    # },
                    # {
                    #     keyword.index: 3,
                    # },
                    {
                        keyword.index: Keywords.average,
                    },
                ]
            },
            {
                keyword.patient: 5,
                '': [
                    # {
                    #     keyword.index: 1,
                    # },
                    # {
                    #     keyword.index: 2,
                    # },
                    # {
                    #     keyword.index: 3,
                    # },
                    {
                        keyword.index: Keywords.average,
                    },
                ]
            },
        ]
    },
    {
        keyword.tissue: keyword.brain,
        '': [
            {
                keyword.patient: 1,
                '': [
                    # {
                    #     keyword.index: 1,
                    # },
                    # {
                    #     keyword.index: 2,
                    # },
                    # {
                    #     keyword.index: 3,
                    # },
                    {
                        keyword.index: Keywords.average,
                    },
                ]
            },
            {
                keyword.patient: 2,
                '': [
                    # {
                    #     keyword.index: 1,
                    # },
                    # {
                    #     keyword.index: 2,
                    # },
                    # {
                    #     keyword.index: 3,
                    # },
                    {
                        keyword.index: Keywords.average,
                    },
                ]
            },
            {
                keyword.patient: 3,
                '': [
                    # {
                    #     keyword.index: 1,
                    # },
                    # {
                    #     keyword.index: 2,
                    # },
                    # {
                    #     keyword.index: 3,
                    # },
                    {
                        keyword.index: Keywords.average,
                    },
                ]
            },
            {
                keyword.patient: 4,
                '': [
                    # {
                    #     keyword.index: 1,
                    # },
                    # {
                    #     keyword.index: 2,
                    # },
                    # {
                    #     keyword.index: 3,
                    # },
                    {
                        keyword.index: Keywords.average,
                    },
                ]
            },
            {
                keyword.patient: 5,
                '': [
                    # {
                    #     keyword.index: 1,
                    # },
                    # {
                    #     keyword.index: 2,
                    # },
                    # {
                    #     keyword.index: 3,
                    # },
                    {
                        keyword.index: Keywords.average,
                    },
                ]
            },
        ]},
]

important_flux_list = [
    # 'GLC_unlabelled_input',
    ('FBA_c', 'FBA_c__R'),
    'PC_m',
    'G6PDH2R_PGL_GND_c',
    'PDH_m',
    'CS_m',
    'AKGD_m',
    'ICDH_m',
    'PYK_c',
    ('SUCD_m', 'SUCD_m__R'),
    ('FUMH_m', 'FUMH_m__R'),
    ('CIT_trans__R', 'CIT_trans'),
    ('MDH_c', 'MDH_c__R'),
    ('MDH_m', 'MDH_m__R'),
    ('GPT_c', 'GPT_c__R'),
    'PHGDH_PSAT_PSP_c',
    ('LDH_c', 'LDH_c__R'),
    'Salvage_c',
    'ACITL_c',
    'PEPCK_c',
    ('GAPD_c', 'GAPD_c__R'),
    'GLC_input',
    'GLN_input',
    ('SHMT_c', 'SHMT_c__R'),
    ('AKGMAL_m__R', 'AKGMAL_m')
]

mid_name_list = [
    ['3PG_c', 'SER_c', 'PYR_c+PYR_m', 'LAC_c'],
    ['ALA_c', 'CIT_c+CIT_m', 'SUC_m', 'FUM_m'],
    ['MAL_c+MAL_m', 'GLU_c+GLU_m', 'GLN_c+GLN_m', 'ASP_c+ASP_m']
]

def data_param_list_generator(param_raw_list):
    current_param_list = []
    for labeling_param_dict in param_raw_list:
        labeling_key = labeling_param_dict[keyword.tissue]
        labeling_content_list = labeling_param_dict['']
        for type_param_dict in labeling_content_list:
            type_key = type_param_dict[keyword.patient]
            type_content_list = type_param_dict['']
            for index_param_dict in type_content_list:
                index_key = index_param_dict[keyword.index]
                current_param_list.append({
                    keyword.tissue: labeling_key,
                    keyword.patient: type_key,
                    keyword.index: index_key,
                    Keywords.obj_threshold_key: None
                })
    return current_param_list

data_param_raw_list = complete_data_param_raw_list
total_param_list = data_param_list_generator(data_param_raw_list)

def collect_results(final_data_obj):
    final_mapping_dict = {}
    for param_dict in total_param_list:
        tissue_key = param_dict[keyword.tissue]
        patient_key = param_dict[keyword.patient]
        index_key = param_dict[keyword.index]
        project_name = data_wrap_obj.project_name_generator(tissue_key, patient_key, index_key)
        final_mapping_dict[project_name] = (tissue_key, patient_key, index_key)
        final_data_obj.load_current_result_label(project_name)
        if Keywords.obj_threshold_key in final_data_obj.final_information_dict[project_name]:
            del final_data_obj.final_information_dict[project_name][Keywords.obj_threshold_key]
    return final_mapping_dict

def experimental_results_comparison_parameter_generator(target_metabolite_data_dict):
    final_color_dict = {}
    final_data_dict_for_plotting = {}
    for labeling_key, each_labeling_data_dict in target_metabolite_data_dict.items():
        data_dict_for_plotting = {}
        color_dict = {}
        for type_key, each_type_data_dict in each_labeling_data_dict.items():
            for index_key, each_index_data_dict in each_type_data_dict.items():
                current_type_index_name = '{}_{}'.format(type_key, index_key)
                if current_type_index_name not in color_dict:
                    if type_key == 1:
                        current_color = Color.blue
                    elif type_key == 2:
                        current_color = Color.orange
                    else:
                        raise ValueError()
                    color_dict[current_type_index_name] = current_color
                for metabolite_name, each_metabolite_data_obj in each_index_data_dict.items():
                    if metabolite_name not in data_dict_for_plotting:
                        data_dict_for_plotting[metabolite_name] = {}
                    data_dict_for_plotting[metabolite_name][current_type_index_name] = \
                        each_metabolite_data_obj.data_vector
        final_data_dict_for_plotting[labeling_key] = data_dict_for_plotting
        final_color_dict[labeling_key] = color_dict
    return keyword.output_folder, final_data_dict_for_plotting, final_color_dict

def flux_comparison_parameter_generator(final_solution_data_dict, final_flux_name_index_dict):
    from ...common.config import index_calculation_func_dict
    current_index_name_func_dict = index_calculation_func_dict
    final_dict_for_flux_comparison_plotting = {}
    final_key_name_parameter_dict = {}
    final_color_dict = {}
    comparison_name_tissue_dict = {
        'kidney_tumor_vs_brain': [keyword.carcinoma, keyword.brain],
        'tumor_vs_kidney': [keyword.kidney, keyword.carcinoma]}
    current_important_flux_list = list(important_flux_list)
    if current_index_name_func_dict is not None:
        current_important_flux_list.extend(current_index_name_func_dict.items())
    patient_key_set = set()
    for comparison_name, current_tissue_name_list in comparison_name_tissue_dict.items():
        data_dict_for_plotting = {}
        key_name_parameter_dict = {}
        color_dict = {}
        data_dict_order_list = []
        if comparison_name == 'kidney_tumor_vs_brain':
            for tissue_index, tissue_name in enumerate(current_tissue_name_list):
                for patient_key, current_patient_dict in final_solution_data_dict[tissue_name].items():
                    if patient_key not in patient_key_set:
                        patient_key_set.add(patient_key)
                    current_flux_name_index_dict = final_flux_name_index_dict[tissue_name][patient_key]
                    data_dict_order_list.append(
                        (tissue_index, tissue_name, patient_key, current_patient_dict, current_flux_name_index_dict))
        elif comparison_name == 'tumor_vs_kidney':
            for patient_key in patient_key_set:
                for tissue_index, tissue_name in enumerate(current_tissue_name_list):
                    current_patient_dict = final_solution_data_dict[tissue_name][patient_key]
                    current_flux_name_index_dict = final_flux_name_index_dict[tissue_name][patient_key]
                    data_dict_order_list.append(
                        (tissue_index, tissue_name, patient_key, current_patient_dict, current_flux_name_index_dict))
        else:
            raise ValueError()
        for tissue_index, tissue_name, patient_key, current_patient_dict, current_flux_name_index_dict in data_dict_order_list:
            for index_num, current_data_array in current_patient_dict.items():
                key_name = '{}_{}_{}'.format(tissue_name, patient_key, index_num)
                key_name_parameter_dict[key_name] = (tissue_name, patient_key, index_num)
                if tissue_index == 0:
                    color_dict[key_name] = Color.blue
                else:
                    color_dict[key_name] = Color.orange
                common_flux_comparison_func(
                    current_important_flux_list, current_flux_name_index_dict[index_num], current_data_array,
                    data_dict_for_plotting, key_name)
        final_dict_for_flux_comparison_plotting[comparison_name] = data_dict_for_plotting
        final_key_name_parameter_dict[comparison_name] = key_name_parameter_dict
        final_color_dict[comparison_name] = color_dict
    return final_dict_for_flux_comparison_plotting, final_key_name_parameter_dict, final_color_dict

def experimental_data_plotting(
        complete_experimental_mid_data_obj_dict, complete_result_information_dict, output_direct):
    mid_data_dict_for_plotting = {}
    raw_data_dict_for_plotting = {}
    color_dict = {}
    patient_color_dict = {}
    complete_color_list = [Color.blue, Color.orange, Color.purple]
    for result_label, experimental_mid_data_obj_dict in complete_experimental_mid_data_obj_dict.items():
        result_information_dict = complete_result_information_dict[result_label]
        tissue = result_information_dict[keyword.tissue]
        patient = result_information_dict[keyword.patient]
        index = result_information_dict[keyword.index]
        if index == Keywords.average:
            continue
        if tissue not in mid_data_dict_for_plotting:
            mid_data_dict_for_plotting[tissue] = {}
            raw_data_dict_for_plotting[tissue] = {}
        for metabolite_name, mid_data_obj in experimental_mid_data_obj_dict.items():
            current_mid_label_tissue_dict = mid_data_dict_for_plotting[tissue]
            current_raw_label_tissue_dict = raw_data_dict_for_plotting[tissue]
            if metabolite_name not in current_mid_label_tissue_dict:
                current_mid_label_tissue_dict[metabolite_name] = {}
                current_raw_label_tissue_dict[metabolite_name] = {}
            patient_index_str = f'{patient}_{index}'
            current_mid_label_tissue_dict[metabolite_name][patient_index_str] = mid_data_obj.data_vector
            current_raw_label_tissue_dict[metabolite_name][patient_index_str] = mid_data_obj.raw_data_vector
            if patient_index_str not in color_dict:
                if patient not in patient_color_dict:
                    current_color = complete_color_list[len(patient_color_dict) % 3]
                    patient_color_dict[patient] = current_color
                color_dict[patient_index_str] = patient_color_dict[patient]
    target_emu_name_nested_list = [
        ['glucose', '3-phosphoglycerate', 'pyruvate', 'lactate'],
        ['alanine', 'citrate', 'succinate', 'fumarate'],
        ['malate', 'aspartate', 'glutamate', 'glutamine'],
    ]
    target_row_num = len(target_emu_name_nested_list)
    target_col_num = len(target_emu_name_nested_list[0])
    for tissue, each_tissue_mid_data_dict_for_plotting in mid_data_dict_for_plotting.items():
        each_tissue_raw_data_dict_for_plotting = raw_data_dict_for_plotting[tissue]
        for raw_data in (False, True):
            if raw_data:
                parent_direct = 'raw_data'
                complete_data_dict = each_tissue_raw_data_dict_for_plotting
                ylim = (0, None)
            else:
                parent_direct = 'mid_data'
                complete_data_dict = each_tissue_mid_data_dict_for_plotting
                ylim = (0, 1)
            current_title = f'{tissue}'
            current_output_direct = '{}/{}'.format(output_direct, parent_direct)
            check_and_mkdir_of_direct(current_output_direct)
            multi_row_col_bar_plot(
                complete_data_dict, target_emu_name_nested_list, target_row_num, target_col_num,
                error_bar_data_dict=None, color_dict=color_dict, title_dict=None,
                output_direct=current_output_direct, current_title=current_title, ylim=ylim,
                xlabel_list=None, figsize=None, legend=False)

def result_output_dataframe_dict_generator(complete_result_dict):
    pass
    # return {'Sheet1': pd.DataFrame()}

def metabolic_network_parameter_generator():
    experimental_mid_metabolite_set = {
        'PYR_c', 'PYR_m',
        'LAC_c',
        'ALA_c',
        'SUC_m',
        'FUM_m',
        'SER_c',
        'MAL_c', 'MAL_m',
        'ASP_c', 'ASP_m',
        'GLU_c', 'GLU_m',
        'GLN_c', 'GLN_m',
        'CIT_c', 'CIT_m',
        '3PG_c',
    }
    experimental_mixed_mid_metabolite_set = {
        'PYR_c', 'PYR_m',
        'MAL_c', 'MAL_m',
        'ASP_c', 'ASP_m',
        'GLU_c', 'GLU_m',
        'GLN_c', 'GLN_m',
        'CIT_c', 'CIT_m',
    }
    biomass_metabolite_set = {
        'ALA_c', 'RIB5P_c', 'GLY_c', 'SER_c', 'ASP_c',
        'ACCOA_c', 'GLU_c', 'GLN_c',
    }
    input_metabolite_set = {
        'GLC_e', 'GLC_unlabelled_e', 'GLN_e', 'ASP_e', 'SER_e', 'GLY_e', 'ALA_e', 'LAC_e',
    }
    c13_labeling_metabolite_set = {
        'GLC_e',
    }
    boundary_flux_set = {
        'GLC_input', 'GLC_unlabelled_input'
    }
    infusion = False
    return experimental_mid_metabolite_set, experimental_mixed_mid_metabolite_set, biomass_metabolite_set, \
        input_metabolite_set, c13_labeling_metabolite_set, boundary_flux_set, infusion


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2020/7/3 16:46
# @Author  : wenlei

'''
找二叉树节点的后续节点
'''

class Node():
    def __init__(self, x):
        self.value = x
        self.left = None
        self.right = None
        self.parent = None

def getSuccessorNode(node):
    if not node:
        return node
    if node.right:
        return getMostLeft(node.right) # 找到右子树的最左节点
    else:
        parent = node.parent
        while parent and parent.left != node:
            node = parent
            parent = node.parent
    return parent

def getMostLeft(node):
    while node.left:
        node = node.left
    return node

def getProceedNode(node):
    if not node:
        return node
    if node.left:
        return getMostRight(node.left)
    else:
        parent = node.parent
        while parent and parent.right != node:
            node = parent
            parent = node.parent
        return parent

def getMostRight(node):
    while node.right:
        node = node.right
    return node

if __name__ == '__main__':
    head = Node(6)
    head.parent = None
    head.left = Node(3)
    head.left.parent = head
    head.left.left = Node(1)
    head.left.left.parent = head.left
    head.left.left.right = Node(2)
    head.left.left.right.parent = head.left.left
    head.left.right = Node(4)
    head.left.right.parent = head.left
    head.left.right.right = Node(5)
    head.left.right.right.parent = head.left.right
    head.right = Node(9)
    head.right.parent = head
    head.right.left = Node(8)
    head.right.left.parent = head.right
    head.right.left.left = Node(7)
    head.right.left.left.parent = head.right.left
    head.right.right = Node(10)
    head.right.right.parent = head.right

    # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    # 后续节点
    test = head.left.left
    print(test.value, " next: ", getSuccessorNode(test).value)
    test = head.left.left.right
    print(test.value, " next: ", getSuccessorNode(test).value)
    test = head.left
    print(test.value, " next: ", getSuccessorNode(test).value)
    test = head.left.right
    print(test.value, " next: ", getSuccessorNode(test).value)
    test = head.left.right.right
    print(test.value, " next: ", getSuccessorNode(test).value)
    test = head
    print(test.value, " next: ", getSuccessorNode(test).value)
    test = head.right.left.left
    print(test.value, " next: ", getSuccessorNode(test).value)
    test = head.right.left
    print(test.value, " next: ", getSuccessorNode(test).value)
    test = head.right
    print(test.value, " next: ", getSuccessorNode(test).value)
    test = head.right.right #  10's next is None
    print(test.value, " next: ", getSuccessorNode(test))

    # 前驱节点
    test = head.left.left  #  1's last is None
    print(test.value, " last: ", getProceedNode(test))
    test = head.left.left.right
    print(test.value, " last: ", getProceedNode(test).value)
    test = head.left
    print(test.value, " last: ", getProceedNode(test).value)
    test = head.left.right
    print(test.value, " last: ", getProceedNode(test).value)
    test = head.left.right.right
    print(test.value, " last: ", getProceedNode(test).value)
    test = head
    print(test.value, " last: ", getProceedNode(test).value)
    test = head.right.left.left
    print(test.value, " last: ", getProceedNode(test).value)
    test = head.right.left
    print(test.value, " last: ", getProceedNode(test).value)
    test = head.right
    print(test.value, " last: ", getProceedNode(test).value)
    test = head.right.right
    print(test.value, " last: ", getProceedNode(test).value)


from argparse import ArgumentParser

import tabulate
argparser = ArgumentParser()
argparser.add_argument('--device', type=int, required=True, help='id of device to run training on.')
argparser.add_argument('--seed', type=int, required=True, help='random seed to use for training.')
argparser.add_argument('--dir', type=str, help='directory for all model output, logs, checkpoints, etc.')
argparser.add_argument('--debug', action='store_true',
        help='use debug mode which only uses one example to train and eval.')
argparser.add_argument('--three_d', action='store_true',
        help='train a 3d model. (default: False)')
argparser.add_argument('--freeze_encoder', action='store_true',
        help='train UNet with frozen encoder. (default: False).')
argparser.add_argument('--save_freq', type=int, default=1,
        help='epoch frequency with which to checkpoint. (default = 1)')

args = argparser.parse_args()

import sys
import os
import random

import torch
import torchvision
import torch.optim as optim
import torch.nn as nn
from torch.utils.data import DataLoader, Subset
from torch.utils.tensorboard import SummaryWriter

import numpy as np
from tqdm import tqdm

from dataloader import BraTS20202d, BraTS20203d
from models import UNetGenerator, UNetGenerator3d
from losses import BraTSBCEWithLogitsLoss
from sklearn.model_selection import train_test_split

from utils import *

os.makedirs(args.dir, exist_ok=True)
os.makedirs(args.dir + '/logs/', exist_ok=True)
os.makedirs(args.dir + '/checkpoints/', exist_ok=True)

#   sundry
seed        = args.seed
device      = torch.device(f'cuda:{args.device}')

#   model params
input_nc    = 4
output_nc   = 3
num_downs   = 3
ngf         = 64

#   optim params
lr          = 8e-3
momentum    = 0.9
wd          = 1e-4

#   train params
epochs      = 150

#   fix all randomness for reproducibility
random.seed(seed)
np.random.seed(seed)
torch.manual_seed(seed)
torch.cuda.manual_seed(seed)
torch.backends.cudnn.benchmark = False
torch.backends.cudnn.deterministic = True

tr_data_dir    = 'brats2020/2dunet/train-preprocessed-v2/data/'
te_data_dir    = 'brats2020/2dunet/test-preprocessed-v2/data/'

if args.debug:
    tr_data_dir    = 'brats2020/2dunet/debug/'
    te_data_dir = 'brats2020/2dunet/debug/'
    num_workers =0
    batch_size = 1
elif args.three_d:
    tr_data_dir = 'brats2020/2dunet/train/'
    te_data_dir = 'brats2020/2dunet/test/'
    batch_size = 5
    num_workers = 4
else:
    num_workers = 4
    batch_size = 150

#   data setup
print(f'loading training data from: {tr_data_dir}')
print(f'loading test data from: {te_data_dir}')

if args.three_d:
    train_dataset               = BraTS20203d(tr_data_dir)
    test_dataset                = BraTS20203d(te_data_dir)
else:
    train_dataset               = BraTS20202d(tr_data_dir, only_tumor=True)
    test_dataset                = BraTS20202d(te_data_dir, only_tumor=True)

train_loader                = DataLoader(train_dataset, shuffle=True,
                                    num_workers=num_workers, batch_size=batch_size)
                                        #collate_fn=collate_fn)
# batch_size == 1 required for the image logging to work properly
test_loader                 = DataLoader(test_dataset, shuffle=False,
                                num_workers=num_workers, batch_size=1)

#   model setup
if args.three_d:
    model           = UNetGenerator3d(input_nc, output_nc, num_downs, ngf=ngf,
                                    freeze_encoder=args.freeze_encoder).to(device)
    loss            = BraTSBCEWithLogitsLoss()
    optimizer       = optim.SGD(model.parameters(), lr=lr, momentum=momentum, weight_decay=wd)
else:
    model           = UNetGenerator(input_nc, output_nc, num_downs, ngf=ngf,
                                    freeze_encoder=args.freeze_encoder).to(device)
    loss            = BraTSBCEWithLogitsLoss()
    optimizer       = optim.SGD(model.parameters(), lr=lr, momentum=momentum, weight_decay=wd)

start_epoch = 0
writer          = SummaryWriter(log_dir=f'{args.dir}/logs/{start_epoch}/')
table_out_columns = ['ep', 'train loss', 'train_dice_et', 'train_dice_wt','train_dice_tc',\
                'test loss', 'test_dice_et', 'test_dice_wt','test_dice_tc']

def log_epoch(stuff):
    ''' convenience function for logging everything. keeps the main loop clean.'''
    epoch   = stuff['epoch']
    writer.add_scalar('Loss/train', stuff['train_loss'], epoch)
    writer.add_scalar('Dice/enhancing train', stuff['train_dice'][0], epoch)
    writer.add_scalar('Dice/whole train', stuff['train_dice'][1], epoch)
    writer.add_scalar('Dice/core train', stuff['train_dice'][2], epoch)

    writer.add_scalar('Loss/test', stuff['test_loss'], epoch)
    writer.add_scalar('Dice/enhancing test', stuff['test_dice'][0], epoch)
    writer.add_scalar('Dice/whole test', stuff['test_dice'][1], epoch)
    writer.add_scalar('Dice/core test', stuff['test_dice'][2], epoch)

    for img in stuff['images']:
        grid    = torchvision.utils.make_grid(
                    [s.squeeze() for s in torch.split(img[1].squeeze(), 1)], nrow=1, pad_value=255)
        # need a dummy 'channel' dimension for the tensorboard api
        grid    = grid.unsqueeze(1)
        writer.add_images(f'Images/{img[0]}', grid, global_step=epoch)
    # TODO: Haus, NLL, images
    #writer.add_scalar('Dice/whole', np.random.random(), n_iter)
    #writer.add_scalar('Dice/enhancing', np.random.random(), n_iter)
    #writer.add_scalar('Dice/core', np.random.random(), n_iter)

def dice_coeff(pred, trgt):
    smooth  = 1.
    if not pred.is_contiguous():
        pred = pred.contiguous()
    if not trgt.is_contiguous():
        trgt = trgt.contiguous()
    pflat   = pred.view(-1)
    tflat   = trgt.view(-1)

    intsc   = (pflat*tflat).sum()

    return (2*intsc + smooth)/ (pflat.sum() + tflat.sum() + smooth)

def compute_dice(output, target):
    sigs                            = torch.sigmoid(output)
    preds                           = torch.zeros(sigs.size(), dtype=torch.uint8)
    preds[torch.where(sigs > 0.5)]  = 1
    preds                           = preds.cuda(output.get_device())
    dice = np.zeros(3)
    for i in range(3):
        dice[i] = dice_coeff(preds[:, i].squeeze(), target[:, i].squeeze())
    return dice

examples_to_track   = [random.randint(0, len(test_dataset)) for _ in range(10)]

for epoch in range(epochs):
    model.train()
    stuff   = {'epoch': epoch, 'images': []}
    test_loss = train_loss  = 0

    for i, (src, tgt) in enumerate(tqdm(train_loader)):
        optimizer.zero_grad()
        src, tgt    = src.to(device).float(), tgt.to(device).float()
        output      = model(src)

        print(f'outputsize: {output.size()}, tgtsize {tgt.size()}')
        loss_e      = loss(output, tgt)

        train_loss    = loss_e/(i+1) + (i/(i+1))*train_loss
        loss_e.backward()
        optimizer.step()

    stuff['train_loss'] = train_loss
    with torch.no_grad():
        model.eval()
        train_loss   = 0
        stuff['train_dice'] = np.zeros(3)
        for j, (src, tgt) in enumerate(tqdm(train_loader)):
            src, tgt    = src.to(device).float(), tgt.to(device).float()
            output          = model(src)
            loss_e          = loss(output, tgt)
            # updata average loss
            stuff['train_dice']        = compute_dice(output, tgt)/(j+1) + (j/(j+1))*stuff['train_dice']
            train_loss   = loss_e/(j+1) + (j/(j+1))*train_loss

    stuff['test_loss'] = test_loss
    with torch.no_grad():
        model.eval()
        test_loss   = 0
        stuff['test_dice'] = np.zeros(3)
        for j, (src, tgt) in enumerate(tqdm(test_loader)):
            src, tgt    = src.to(device).float(), tgt.to(device).float()
            output          = model(src)
            loss_e          = loss(output, tgt)
            # updata average loss
            stuff['test_dice']        = compute_dice(output, tgt)/(j+1) + (j/(j+1))*stuff['test_dice']
            test_loss   = loss_e/(j+1) + (j/(j+1))*test_loss
            if j+1 in examples_to_track:
                sigs  = torch.sigmoid(output)
                sigs_npy = sigs.cpu().numpy()
                preds  = torch.zeros(sigs.size(), dtype=torch.uint8)
                preds[torch.where(sigs > 0.5)] = 255
                tgt_scaled                  = tgt*255

                if len(preds[1].shape) == 3:
                    preds = preds[..., 100].squeeze()
                img = torch.cat([preds, tgt_scaled.cpu()], dim=1).to(torch.uint8)
                stuff['images'].append((j+1, img))

    train_stats = [ epoch + 1, stuff['train_loss']]+ stuff['train_dice'].tolist() \
                    + [stuff['test_loss']] + stuff['test_dice'].tolist()

    table_train = tabulate.tabulate([train_stats], table_out_columns, tablefmt="simple", floatfmt="8.4f")
    print(table_train)

    # breaks if batch_size > 1
    stuff['test_loss']  = test_loss
    log_epoch(stuff)

    if epoch % args.save_freq == 0:
        torch.save({
            'epoch': epoch,
            'model_state_dict': model.state_dict(),
            'optimizer_state_dict': optimizer.state_dict(),
            'train_loss': train_loss,
            'test_loss': test_loss,
            'train_dice': stuff['train_dice'],
            'test_dice': stuff['test_dice']
            }, f'{args.dir}/checkpoints/epoch_{epoch:03}.pt'
            )


# app imports
import random

from django.utils.translation import ugettext_lazy as _
from django.conf import settings

from utils.faker_factory import faker

from ..mails import BaseMailView

class InvitationConsultantProjectMailView(BaseMailView):
    template_name = 'mails/invitation_consultant_project.html'
    mandatory_mail_args = [
        'user', 'project_name', 'relation_name',
        'is_coach',
    ]
    optional_mail_args = ['team_name', ]
    subject = _(settings.BRAND_NAME + ' - %(name)s invite')
    section = 'project'

    def get_subject(self, **kwargs):
        is_coach = kwargs.get('is_coach')
        if is_coach:
            return _(settings.BRAND_NAME + ' - Team coach invite')
        else:
            relation_name = kwargs.get('relation_name')
            return self.subject % ({'name': relation_name})

    def get_mock_data(self, optional=True):
        project_name = faker.word()
        team_name = faker.word()
        mock_data = {
            'team_name': team_name,
            'project_name': project_name,
            'relation_name': '[relation_name]',
            'user': faker.first_name(),
            'is_coach': random.randint(0, 1),
            'public_url': '/{}'.format(faker.uri_path()),
        }

        return mock_data


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

"""
@author: lishuang
@description: 利用 LSTM 预测股票价格
"""
import os
from itertools import chain

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from tensorflow.keras.layers import Dense, Dropout, LSTM
from tensorflow.keras.models import load_model, Sequential

TIME_STEPS_IN = 3
TIME_STEPS_OUT = 3
EPOCHS = 300
BATCH_SIZE = 100

def series_to_supervised(series, n_in=1, n_out=1, drop_nan=True):
    """
    将时间序列数据转换为适用于监督学习的数据
    给定输入序列和输出序列的长度

    :param series: 观察序列
    :param n_in: 观测数据 input(X) 的步长，范围是 [1, len(data)]，默认为1
    :param n_out: 观测数据 output(y) 的步长，范围为 [0, len(data)-1]，默认为1
    :param drop_nan: 是否删除 NaN 行，默认为 True
    :return: 适用于监督学习的数据集
    """
    n_vars = 1 if type(series) is list else series.shape[1]
    df = pd.DataFrame(series)
    cols, names = list(), list()
    # 输入序列 (t-n, ..., t-1)
    for i in range(n_in, 0, -1):
        cols.append(df.shift(i))
        names += [f'var{j + 1}(t-{i})' for j in range(n_vars)]

    # 预测序列 (t, t+1, ..., t+n)
    for i in range(0, n_out):
        cols.append(df.shift(-i))
        if i == 0:
            names += [f'var{j + 1}(t)' for j in range(n_vars)]
        else:
            names += [f'var{j + 1}(t+{i})' for j in range(n_vars)]

    # 拼接到一起
    agg = pd.concat(cols, axis=1)
    agg.columns = names
    if drop_nan:
        agg.dropna(inplace=True)
    return agg

def get_train_set(dataset, time_steps_in=1, time_steps_out=1):
    """
    将数据转换为可用于监督学习的数据

    :param dataset:
    :param time_steps_in:
    :param time_steps_out:
    :return:
    """
    train_dataset = np.array(dataset)
    print(train_dataset)
    reframed_train_dataset = np.array(series_to_supervised(train_dataset, time_steps_in, time_steps_out).values)
    print(reframed_train_dataset)
    train_x, train_y = reframed_train_dataset[:, :-time_steps_out], reframed_train_dataset[:, -time_steps_out:]
    # 将数据集重构为符合 LSTM 要求的数据格式，即：[样本数，时间步，特征]
    train_x = train_x.reshape(train_x.shape[0], time_steps_in, 1)
    return train_x, train_y

def plot_img(source_dataset, train_predict):
    """
    绘制图像

    :param source_dataset:
    :param train_predict:
    :return:
    """
    plt.figure(figsize=(24, 8))
    # 原始数据蓝色
    plt.plot(source_dataset[:, -1], c='b', label='actual')
    # 训练数据绿色
    plt.plot([_ for _ in train_predict], c='g', label='predict')
    plt.legend()
    plt.show()

def lstm_model(source_dataset, train_data, label_data, epochs, batch_size, time_steps_out):
    if os.path.exists('data/model.h5'):
        model = load_model('data/model.h5')
    else:
        model = Sequential()
        # 第一层，隐藏层神经元节点个数为128，返回整个序列
        model.add(
            LSTM(128, return_sequences=True, activation='relu', input_shape=(train_data.shape[1], train_data.shape[2]))
        )
        # 第二层，隐藏层神经元节点个数128，只返回序列最后一个输出
        model.add(LSTM(128, return_sequences=False))
        model.add(Dropout(0.5))
        # 第三层，因为是回归问题所以使用linear
        model.add(Dense(time_steps_out, activation='linear'))
        model.compile(loss='mean_squared_error', optimizer='adam')
        model.save('./data/model.h5', overwrite=True)

    # LSTM 训练
    # verbose=2 为每个epoch输出一行记录；
    # verbose=1 为输出进度条记录；
    # verbose=0 不在标准输出流输出日志信息
    res = model.fit(train_data, label_data, batch_size, epochs, verbose=2, shuffle=False)

    # 模型预测
    train_predict = model.predict(train_data)
    train_predict_list = list(chain(*train_predict))

    plt.plot(res.history['loss'], label='train')
    plt.show()
    print(model.summary())
    plot_img(source_dataset, train_predict)

if __name__ == '__main__':
    data = pd.read_csv('data/shanghai_index_1990_12_19_to_2020_03_12.csv', encoding='GB2312')
    data.rename(columns={'日期': 'Date', '收盘价': 'Price'}, inplace=True)
    data_set = data[['Price']].values.astype('float64')
    print(data_set)
    # 转换为可用于监督学习的数据
    train_X, label_y = get_train_set(data_set, TIME_STEPS_IN, TIME_STEPS_OUT)
    # 使用 LSTM 进行训练、预测
    lstm_model(data_set, train_X, label_y, EPOCHS, BATCH_SIZE, TIME_STEPS_OUT)


#coding=utf-8
from confluent_kafka import Producer
import MySQLdb
import json
import time
import random

p = Producer({"bootstrap.servers": "118.24.53.99:9092"})

db = MySQLdb.connect("localhost", "root", "123456", "test_kafka", charset='utf8' )
cursor = db.cursor()

sql = "SELECT msg_body FROM order_kafka_msg;"

def delivery_report(err, msg):
    """ Called once for each message produced to indicate delivery result.
        Triggered by poll() or flush(). """
    if err is not None:
        print('Message delivery failed: {}'.format(err))
    else:
        print('Message delivered to {} [{}]'.format(msg.topic(), msg.partition()))

data_list=[]

# while (True):
cursor.execute(sql.encode("utf-8"))
results = cursor.fetchall()
for result in results:
        print("------------------")
        setJson = json.dumps(json.loads(result[0]),ensure_ascii=False)
        print(setJson.encode("utf-8"))
        p.produce("test",setJson.encode("utf-8"),callback=delivery_report)

p.flush()
    # time.sleep(60)


# 2021.09.12
# 2484
# 주사위 네개

def reward(ls):
    ls.sort()
    set_ls = set(ls)
    len_set = len(set_ls)
    if len_set == 1:   # 4개가 같을 때
        result.append(50000 + ls[0] * 5000)
        return
    elif len_set == 2:
        if ls[1] != ls[2]:  # 2개, 2개씩 같을 때
            result.append(2000+(ls[1]+ls[2])*500)
            return
        else:  # 3개, 1개씩 같을 때
            result.append(10000 + ls[1]*1000)
            return
    for i in range(3):  # 2개, 1개, 1개
        if ls[i] == ls[i+1]:
            result.append(1000 + ls[i]*100)
            return
    result.append(max(ls) * 100)  # 4개 모두 각각 다를 때
    return

n = int(input())
result = []
for _ in range(n):
    ls = list(map(int, input().split()))
    reward(ls)

print(max(result))


from setuptools import setup, find_packages

with open('readme.md', encoding='utf-8') as f:
    long_description = f.read()

setup(
    packages = find_packages(),
    name = 'pbat',
    version = '0.0.16',
    author = "Stanislav Doronin",
    author_email = "mugisbrows@gmail.com",
    url = 'https://github.com/mugiseyebrows/pbat',
    description = 'Batch file preprocessor',
    long_description = long_description,
    long_description_content_type = 'text/markdown',
    install_requires = ['lark'],
    package_data = {
        'pbat': ['examples/*.pbat', 'examples/*.bat', '*.lark']
    },
    entry_points = {
        'console_scripts': [
            'pbat = pbat.compile:main'
        ]
    }
)


import input_data
import tensorflow as tf
import input_data

# 数据集导入
mnist = input_data.read_data_sets("C:\\USers\\hyq\\PycharmProjects\\DataAnalysis", one_hot=True)
# 实现回归模型
x = tf.placeholder("float", [None, 784])
W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))
# 建立模型
y = tf.nn.softmax(tf.matmul(x,W) + b)
# 计算交叉熵
y_ = tf.placeholder("float", [None,10])
cross_entropy = -tf.reduce_sum(y_*tf.log(y))
# 实现反向传播算法和梯度下降算法
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
# 初始化变量
init = tf.initialize_all_variables()

sess = tf.Session()
sess.run(init)
for i in range(1000):
  batch_xs, batch_ys = mnist.train.next_batch(100)
  sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})

# 评估模型
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
print(sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}))


from __future__ import absolute_import, print_function, division
import os
from string import Template

import numpy as np

import theano
from theano import Apply
from theano.tensor import as_tensor_variable
from theano.tensor.sort import TopKOp

from .basic_ops import (GpuKernelBase, Kernel, infer_context_name,
                        as_gpuarray_variable, gpuarray_helper_inc_dir)
from .opt import register_opt, op_lifter, register_opt2
from .type import GpuArrayType

try:
    import pygpu
    import pygpu.gpuarray as ga
except ImportError as e:
    # To make sure theano is importable
    pass

# TODO GPU sort / argsort
class GpuTopKOp(GpuKernelBase, TopKOp):
    '''Implements TopKOp on gpu

    Currently the output seem sorted, but we do not test it. So as on
    the CPU, we only support sorted=False for now.

    '''
    __props__ = TopKOp.__props__
    _f16_ok = True

    def __init__(
        self, axis=-1,
        sorted=True,
        idx_dtype='int64',
        return_values=True,
        return_indices=True
    ):
        if sorted:
            raise NotImplementedError(
                "GpuTopK currently is not sure to give sorted output even if they look sorted..")
        GpuKernelBase.__init__(self)
        TopKOp.__init__(
            self, axis=axis,
            sorted=sorted,
            idx_dtype=idx_dtype,
            return_values=return_values,
            return_indices=return_indices)

    def perform(self, node, inputs, output_storage, params):
        raise NotImplementedError()

    def c_headers(self):
        return ['gpuarray_api.h', 'gpuarray_helper.h', 'numpy_compat.h']

    def c_header_dirs(self):
        return [
            os.path.dirname(__file__),
            gpuarray_helper_inc_dir(),
            pygpu.get_include()]

    def c_code_cache_version(self):
        return (4,)

    def gpu_kernels(self, node, nodename):
        # load kernel source
        device_type = node.inputs[0].type.context.kind
        kernel_ext = {b'cuda': '.cu', b'opencl': '.cl'}[device_type]
        common_ext = {b'cuda': '.cuh', b'opencl': '.h'}[device_type]

        # prepare "$" macros
        if device_type == b'cuda':
            ndim = node.inputs[0].ndim
            dstv_strides_code = ''.join('ssize_t dstv_strides_%d, ' % i for i in range(ndim))
            dsti_strides_code = ''.join('ssize_t dsti_strides_%d, ' % i for i in range(ndim))
            src_strides_code = ''.join('ssize_t src_strides_%d, ' % i for i in range(ndim))
            set_slice_code = '''
        gidx = gid %% dims_%(i)d;
        gid /= dims_%(i)d;
        {dstv};
        {dsti};
        src = ptr_add(src, gidx*src_strides_%(i)d);\n'''.format(
                dstv='dstv = ptr_add(dstv, gidx*dstv_strides_%(i)d)' if self.return_values else '',
                dsti='dsti = ptr_add(dsti, gidx*dsti_strides_%(i)d)' if self.return_indices else '')
            set_slice_code = ''.join(
                set_slice_code % dict(i=j) for j in range(1, ndim))
            if self.return_values:
                set_slice_code += """
                dstv = ptr_add(dstv, dstv_offset);
                """
            if self.return_indices:
                set_slice_code += """
                dsti = ptr_add(dsti, dsti_offset);
                """
            set_slice_code += """
                src = ptr_add(src, src_offset);
            """
            flags = Kernel.get_flags(node.inputs[0].dtype)
            subs = dict(
                inp_t=ga.dtype_to_ctype(node.inputs[0].dtype),
                out_t=ga.dtype_to_ctype(self.idx_dtype),
                dims=''.join('size_t dims_%d, ' % i for i in range(1, ndim)),
                dstv='INPUT_TYPE *dstv,' if self.return_values else '',
                dstv_offset='size_t dstv_offset,' if self.return_values else '',
                dsti='INDEX_TYPE *dsti,' if self.return_indices else '',
                dsti_offset='size_t dsti_offset,' if self.return_indices else '',
                dstv_strides=dstv_strides_code if self.return_values else '',
                dsti_strides=dsti_strides_code if self.return_indices else '',
                src_strides=src_strides_code,
                set_slice=set_slice_code,
                write_value=int(self.return_values),
                write_index=int(self.return_indices),
                ndim=str(ndim)
                )
        elif device_type == b'opencl':
            raise NotImplementedError()

        # setup parameters
        param_types = [ga.SIZE] * (ndim - 1)  # dims
        for _ in range(self.return_values + self.return_indices):
            param_types.append(ga.GpuArray)  # dst*
            param_types.append(ga.SIZE)  # offset
            param_types.extend([ga.SSIZE] * ndim)  # dst*_strides
        param_types.append(ga.SIZE)  # k
        param_types.append(ga.GpuArray)  # src
        param_types.append(ga.SIZE)  # offset
        param_types.extend([ga.SSIZE] * ndim)  # src_strides
        param_types.append(ga.SIZE)  # size

        # load and compile kernels
        with open(os.path.join(
            os.path.dirname(__file__), 'c_code', 'topk_common' + common_ext
        )) as f:
            common_src = f.read()

        kernels = []

        def build_kernel(fname, kname, subs):
            with open(os.path.join(
                os.path.dirname(__file__), 'c_code', fname)
            ) as f:
                kernel_src = f.read()
            ker = Kernel(
                code=("#include <cluda.h>\n" +
                      Template(common_src + kernel_src).substitute(**subs)),
                name=kname,
                params=param_types,
                flags=flags,
                objvar=kname + nodename)
            return ker

        subs['count_t'] = 'int'
        kernels.append(
            build_kernel('topk_dense' + kernel_ext, 'k_topk_dense', subs))
        subs['kname'] = 'k_topk_dense_large'
        kernels.append(
            build_kernel('topk_dense_large' + kernel_ext, 'k_topk_dense_large', subs))
        subs['count_t'] = 'long long'
        subs['kname'] = 'k_topk_dense_xlarge'
        kernels.append(
            build_kernel('topk_dense_large' + kernel_ext, 'k_topk_dense_xlarge', subs))
        return kernels

    def c_code(self, node, nodename, inps, outs, sub):
        context = node.inputs[0].type.context
        if context.kind != b'cuda':
            raise NotImplementedError(
                '%s: We only have CUDA '
                'implementation so far.' % self.__class__.__name__)
        x, k = inps
        inp_dtc = ga.dtype_to_typecode(node.inputs[0].dtype)
        if not self.return_indices:
            yv, = outs
        elif self.return_values:
            yv, yi = outs
        else:
            yi, = outs
        out_dtype_s = self.idx_dtype
        out_dtc = ga.dtype_to_typecode(out_dtype_s)
        fail = sub['fail']
        ctx = sub['params']
        k_dtype = node.inputs[1].type.dtype_specs()[1]
        # max threads per block
        MAX_TPB = context.maxlsize0
        # max blocks per grid
        MAX_BPG = context.maxgsize0
        WARP_SIZE = 32

        ndim = node.inputs[0].ndim
        reordered_axes = list(range(ndim))
        axis = self.axis % ndim
        del(reordered_axes[axis])
        reordered_axes = [axis] + reordered_axes
        dims = ''.join('dims[%d], ' % i for i in reordered_axes[1:])
        prep_output = ''
        if self.return_values:
            def_dvstrides = 'const ssize_t *dvstrides = PyGpuArray_STRIDES(%s)' % yv
            params_dv = '%s->ga.data, %s->ga.offset,\n' % (yv, yv)
            params_dv += ''.join('dvstrides[%d], ' % i for i in reordered_axes)
            prep_output += '''
    if (0 != theano_prep_output(
        &%(yv)s, %(ndim)d, odims,
        %(inp_dtc)s, GA_C_ORDER, %(ctx)s)) {
        %(fail)s;
    }\n''' % locals()
        else:
            def_dvstrides = params_dv = ''

        if self.return_indices:
            def_distrides = 'const ssize_t *distrides = PyGpuArray_STRIDES(%s)' % yi
            params_di = '%s->ga.data, %s->ga.offset,\n' % (yi, yi)
            params_di += ''.join('distrides[%d], ' % i for i in reordered_axes)
            prep_output += '''
    if (0 != theano_prep_output(
        &%(yi)s, %(ndim)d, odims,
        %(out_dtc)s, GA_C_ORDER, %(ctx)s)) {
        %(fail)s;
    }\n''' % locals()
        else:
            def_distrides = params_di = ''
        sstrides = ', '.join('sstrides[%d]' % i for i in reordered_axes)
        code = '''
{
    const ssize_t k_ = ((%(k_dtype)s*)(PyArray_DATA(%(k)s)))[0];
    const size_t *dims = PyGpuArray_DIMS(%(x)s);
    size_t odims[%(ndim)d];
    for (int i=0; i<%(ndim)d; i++)
        odims[i] = dims[i];

    odims[%(axis)d] = k_>=0 ? k_ : -k_;

    if (0 == odims[%(axis)d]) {
        PyErr_SetString(
            PyExc_ValueError,
            "topk: kth must not be zero");
        %(fail)s;
    } else if (dims[%(axis)d] < odims[%(axis)d]) {
        PyErr_SetString(
            PyExc_ValueError,
            "topk: kth cannot be larger than the size of specified axis %(axis)d");
        %(fail)s;
    }
    %(prep_output)s

    size_t grid_size=1, block_size=1;
    for (int i=0; i<%(ndim)d; ++i) {
        if (i!=%(axis)d)
            grid_size *= dims[i];
        else
            block_size = dims[i];
    }
    // round up to multiples of warp size
    block_size = ((block_size + %(WARP_SIZE)d - 1) / %(WARP_SIZE)d) * %(WARP_SIZE)d;

    if (grid_size > %(MAX_BPG)d) {
        PyErr_SetString(
            PyExc_ValueError,
            "topk: too many slices to work with, expected <= %(MAX_BPG)d");
        %(fail)s;
    }

    %(def_dvstrides)s;
    %(def_distrides)s;
    const ssize_t *sstrides = PyGpuArray_STRIDES(%(x)s);

    int err;
    if (dims[%(axis)d] > (1u << 31)) {
        block_size = %(MAX_TPB)d;
        err = k_topk_dense_xlarge_call(
                1, &grid_size, &block_size, 0,
                %(dims)s
                %(params_dv)s
                %(params_di)s
                k_,
                %(x)s->ga.data,
                %(x)s->ga.offset,
                %(sstrides)s,
                dims[%(axis)d]
        );
    } else if (block_size > %(MAX_TPB)d) {
        block_size = %(MAX_TPB)d;
        err = k_topk_dense_large_call(
                1, &grid_size, &block_size, 0,
                %(dims)s
                %(params_dv)s
                %(params_di)s
                k_,
                %(x)s->ga.data,
                %(x)s->ga.offset,
                %(sstrides)s,
                dims[%(axis)d]
        );
    } else {
        err = k_topk_dense_call(
                1, &grid_size, &block_size, 0,
                %(dims)s
                %(params_dv)s
                %(params_di)s
                k_,
                %(x)s->ga.data,
                %(x)s->ga.offset,
                %(sstrides)s,
                dims[%(axis)d]
        );
    }
    if (err != GA_NO_ERROR) {
        PyErr_SetString(
            PyExc_RuntimeError,
            "topk: gpu kernel failed to execute");
        %(fail)s;
    }
}
        '''
        return code % locals()

    def make_node(self, inp, kth):
        ctx_name = infer_context_name(inp)
        inp = as_gpuarray_variable(inp, ctx_name)
        kth = as_tensor_variable(kth)
        bcast = inp.type.broadcastable
        outs = []
        if self.return_values:
            outs.append(inp.type())
        if self.return_indices:
            outs.append(GpuArrayType(
                dtype=self.idx_dtype,
                broadcastable=bcast,
                context_name=ctx_name)())
        return Apply(self, [inp, kth], outs)

    def get_params(self, node):
        return node.inputs[0].type.context

class ValuesEqApproxNoOrder():
    """
    We ignore the order of elements on a given axis during the comparison.
    """

    def __init__(self, axis):
        self.axis = axis

    def __call__(self, val1, val2):
        v1 = np.sort(val1, axis=self.axis)
        v2 = np.sort(val2, axis=self.axis)
        ret = theano.tensor.type.values_eq_approx(v1, v2)
        return ret

@register_opt('fast_compile')
@op_lifter([TopKOp], cuda_only=True)
@register_opt2([TopKOp], 'fast_compile')
def local_gpua_topkop(op, ctx_name, inputs, outputs):
    axis = op.axis
    rv = op.return_values
    ri = op.return_indices
    x, k = inputs
    x = as_gpuarray_variable(x, ctx_name)
    if op.sorted:
        return
    gpu_op = GpuTopKOp(
        axis=axis,
        sorted=op.sorted,
        idx_dtype=op.idx_dtype,
        return_values=rv,
        return_indices=ri)
    rets = gpu_op(x, k, return_list=True)
    c = ValuesEqApproxNoOrder(axis)
    for r in rets:
        r.tag.values_eq_approx = c
    return rets


import argparse
from dataclasses import dataclass
from decimal import *
import re
import sys
from typing import Dict, List

int_re = re.compile('[-+]?[0-9]+')

float_re = re.compile('[-+]?[0-9]+(\.[0-9]+)?')

def extract_int(l: str) -> (int, str):
    m = int_re.match(l)
    assert m
    s = m.group()
    return int(s), l[len(s):]

def extract_dec(l: str) -> (Decimal, str):
    m = float_re.match(l)
    assert m
    s = m.group()
    return Decimal(s), l[len(s):]

@dataclass
class Tool:
    num: int
    dia: Decimal

@dataclass
class Coordinate:
    x: Decimal
    y: Decimal

@dataclass
class Excellon:
    tools: Dict[int, Tool]
    holes: Dict[int, List[Coordinate]]

    def comment(self, l):
        pass

    def cmd_m30(self, l):
        assert self.started
        self.started = False

    def cmd_m48(self, l):
        self.started = True

    def cmd_m71(self, l):
        assert self.started
        self.inch = False

    def cmd_m72(self, l):
        assert self.started
        self.inch = True

    dispatch_m = {
        30: cmd_m30,
        48: cmd_m48,
        71: cmd_m71,
        72: cmd_m72
    }

    def cmd_m(self, l):
        cmd_num, l = extract_int(l)
        assert not l
        self.dispatch_m[cmd_num](self, l)

    def cmd_t(self, l):
        assert self.started
        tool_num, l = extract_int(l)
        assert 1 <= tool_num <= 99
        if not l:
            assert tool_num in self.tools
            self.current_tool_num = tool_num
            return
        assert l[0] == 'C'
        l = l[1:]
        tool_dia, l = extract_dec(l)
        assert not l
        assert tool_num not in self.tools
        self.tools[tool_num] = Tool(tool_num, tool_dia)
        self.holes[tool_num] = []

    def cmd_x(self, l):
        assert self.started
        x, l = extract_dec(l)
        assert l[0] == 'Y'
        y, l = extract_dec(l[1:])
        assert not l
        coord = Coordinate(x / self.digits_scaling, y / self.digits_scaling)
        self.holes[self.current_tool_num].append(coord)
        #print(f'tool {self.current_tool_num} hole {coord}')

    dispatch = { '%': comment,
                 'M': cmd_m,
                 'T': cmd_t,
                 'X': cmd_x
    }

    def parse(self, file):
        self.started = False
        while True:
            l = file.readline()
            if not l:
                break
            l = l.strip()
            self.dispatch[l[0]](self, l[1:])

    def __init__(self, digits = 5, file = None):
        self.digits = digits
        self.digits_scaling = Decimal(10) ** self.digits
        self.tools = { }
        self.holes = { }

        if file is not None:
            self.parse(file)

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('excellon',
                        nargs = '?',
                        type = argparse.FileType('r'),
                        default = sys.stdin)

    # currently only suppress leading zeros is suppored
    parser.add_argument('-d', '--digits',
                        type = int,
                        default = 5,
                        help = 'number of decimal places in coordinates')

    parser.add_argument('-g', '--grid',
                        type = str,
                        default = '0.1',
                        help = 'grid size')

    parser.add_argument('-e', '--exclude-diameter',
                        type = str,
                        default = '0.012',
                        help = 'hole diameter excluded from checking, typically used for vias')

    args = parser.parse_args()

    excellon = Excellon(digits = args.digits, file = args.excellon)

    exclude_dia = Decimal(args.exclude_diameter)
    grid = Decimal(args.grid)

    for tool_num, tool in excellon.tools.items():
        # skip vias
        if tool.dia == exclude_dia:
            continue
        for coord in excellon.holes[tool_num]:
            x = coord.x
            y = coord.y
            if x % grid != 0 or y % grid != 0:
                print(f'dia {tool.dia}: ({x}, {y})')

if __name__ == '__main__':
    main()


# #############################################################################
# 本題參數設定，請勿更改
seed = 0   # 亂數種子數
# #############################################################################
import warnings
warnings.filterwarnings('ignore')

import numpy as np
import pandas as pd

evaluation = pd.DataFrame({'Model': [],
                           'Details':[],
                           'RMSE (test)':[],
                           'R2 (train)':[],
                           'adj. R2 (train)':[],
                           'R2 (test)':[],
                           'adj. R2 (test)':[]}
                            )

# 讀取台北市房價資料集
df = pd.read_csv('Taipei_house.csv')

# 對"行政區"進行 one-hot encoding
df = pd.get_dummies(df, columns=['行政區'])
# 處理"車位類別"
df['車位類別'] = [0 if x=='無' else 1 for x in df['車位類別']]

# 計算 Adjusted R-squared
def adj_R2(r2, n, k):
    """ 函式描述：計算 Adjusted R-squared
    參數：
        r2:R-squared 數值
        n: 樣本數
        k: 特徵數

    回傳：
        Adjusted R-squared
    """
    return r2-(k-1)/(n-k)*(1-r2)

from sklearn.metrics import mean_squared_error
def measurement(model, X_train, X_test):
    y_pred = model.predict(X_test)

    rmse = round(np.sqrt(mean_squared_error(y_test, y_pred)), 0)
    r2_train = round(model.score(X_train, y_train), 4)
    adj_r2_train = round(adj_R2(model.score(X_train, y_train),
                                X_train.shape[0], X_train.shape[1]), 4)
    r2_test = round(model.score(X_test, y_test), 4)
    adj_r2_test = round(adj_R2(model.score(X_test, y_test),
                               X_test.shape[0], X_test.shape[1]), 4)
    return [rmse, r2_train, adj_r2_train, r2_test, adj_r2_test]

# 切分訓練集(80%)、測試集(20%)
features= ['土地面積', '建物總面積', '屋齡', '樓層', '總樓層', '用途',
           '房數', '廳數', '衛數', '電梯', '車位類別',
           '行政區_信義區', '行政區_大安區', '行政區_文山區','行政區_松山區']
target = '總價'
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(df[features],
                                                    df[target],
                                                    test_size=0.2,
                                                    random_state=seed)

lst_model, lst_info = [], []
# 複迴歸(參數皆為預設值)
# #########################################################################
# '行政區_信義區', '行政區_大安區', '行政區_文山區','行政區_松山區' 四個特徵是經過
# one-hot encoding 後產生，若欄位名稱不同可自行修改之。
# #########################################################################
from sklearn import linear_model
lst_model.append(linear_model.LinearRegression())
lst_info.append(['複迴歸','15 features'])

# 脊迴歸(Ridge regression)，除以下參數設定外，其餘為預設值
# #########################################################################
# alpha=10
# #########################################################################
lst_model.append(linear_model.Ridge(alpha=10))
lst_info.append(['Ridge','15 features'])

# 多項式迴歸，除以下參數設定外，其餘為預設值
# #########################################################################
# degree=2
# #########################################################################
from sklearn.preprocessing import PolynomialFeatures
poly_fea = PolynomialFeatures(degree=2)
X_train_poly = poly_fea.fit_transform(X_train)
X_test_poly = poly_fea.fit_transform(X_test)

lst_model.append(linear_model.LinearRegression())
lst_info.append(['多項式迴歸','deg=2'])

# 多項式迴歸 + Lasso迴歸，除以下參數設定外，其餘為預設值
# #########################################################################
# alpha=10
# #########################################################################
lst_model.append(linear_model.Lasso(alpha=10))
lst_info.append(['多項式迴歸+Lasso','deg=2'])

idx = evaluation.shape[0]
for i in range(len(lst_model)):
    if '多項式' in lst_info[i][0]:
        X_train, X_test = X_train_poly, X_test_poly

    model = lst_model[i].fit(X_train, y_train)
    row = lst_info[i] + measurement(model, X_train, X_test)
    evaluation.loc[idx+i] = row

print('對訓練集的最大 Adjusted R-squared: %.4f' % max(evaluation['adj. R2 (train)']))
print('對測試集的最小 RMSE:%d' % min(evaluation['RMSE (test)']))
print('兩個模型對測試集的最大 Adjusted R-squared: %.4f' %
      max(evaluation.loc[:1, 'adj. R2 (test)']))

''' 預測 '''
# 利用所有資料重新擬合模型，並進行預測
X = df[features]
y = df[target]
X_poly = poly_fea.fit_transform(X)

#features= ['土地面積', '建物總面積', '屋齡', '樓層', '總樓層', '用途',
#           '房數', '廳數', '衛數', '電梯', '車位類別',
#           '行政區_信義區', '行政區_大安區', '行政區_文山區','行政區_松山區']
new = np.array([36, 99, 32, 4, 4, 0, 3, 2, 1, 0, 0, 0, 0, 0, 1]).reshape(1, -1)
df_new = pd.DataFrame(new, columns=features)
df_poly_fea = poly_fea.fit_transform(df_new)

lst = evaluation['adj. R2 (test)'].tolist()
idx = lst.index(max(lst))
if idx <=1:
    model = lst_model[idx].fit(X, y)
    print('房價預測結果：%d' % model.predict(df_new))
else:
    model = lst_model[idx].fit(X_poly, y)
    print('房價預測結果：%d' % model.predict(df_poly_fea))


from PyQt5.QtWidgets import QLabel, QApplication, QDialog, QGridLayout, QHBoxLayout, QPushButton, QFormLayout, \
    QWidget, \
    QLineEdit
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon

class calculator_frame(QDialog):
    def __init__(self):
        super().__init__()
        self.shower = QLineEdit()
        self.label = QLabel()
        self.init()
        self.tmp_string_num = ""
        self.tmp_num = 0
        self.sum_num = ""
        self.num = 0

    def init(self):
        self.setWindowTitle("个人计算器")
        self.setWindowIcon(QIcon('calculator.ico'))
        self.label.setStyleSheet('font-size:20px;color:rgb(180,180,180,255);')
        self.shower.setStyleSheet('font-size:20px;color:rgb(180,180,180,255);')
        self.shower.setEnabled(False)
        hbox = QHBoxLayout()
        form_widget = QWidget()
        grid_widget = QWidget()
        form_layout = QFormLayout()
        form_layout.addRow("memory:", self.shower)
        form_layout.addRow("result=", self.label)
        form_widget.setLayout(form_layout)
        # self.setFixedSize(300,200)

        grid_layout = QGridLayout()
        one = QPushButton("1")
        two = QPushButton("2")
        three = QPushButton("3")
        four = QPushButton("4")
        five = QPushButton("5")
        six = QPushButton("6")
        seven = QPushButton("7")
        eight = QPushButton("8")
        nine = QPushButton("9")
        zero = QPushButton("0")
        point = QPushButton(".")
        equal = QPushButton("=")
        add = QPushButton("+")
        sub = QPushButton("-")
        mult = QPushButton("*")
        div = QPushButton("/")

        one.clicked.connect(self.clicker)
        two.clicked.connect(self.clicker)
        three.clicked.connect(self.clicker)
        four.clicked.connect(self.clicker)
        five.clicked.connect(self.clicker)
        six.clicked.connect(self.clicker)
        seven.clicked.connect(self.clicker)
        eight.clicked.connect(self.clicker)
        nine.clicked.connect(self.clicker)
        zero.clicked.connect(self.clicker)
        add.clicked.connect(self.clicker)
        sub.clicked.connect(self.clicker)
        mult.clicked.connect(self.clicker)
        div.clicked.connect(self.clicker)
        equal.clicked.connect(self.clicker)
        point.clicked.connect(self.clicker)
        one.setStyleSheet('font-size:32px;color:rgb(0,0,0,255);')
        two.setStyleSheet('font-size:32px;color:rgb(0,0,0,255);')
        three.setStyleSheet('font-size:32px;color:rgb(0,0,0,255);')
        four.setStyleSheet('font-size:32px;color:rgb(0,0,0,255);')
        five.setStyleSheet('font-size:32px;color:rgb(0,0,0,255);')
        six.setStyleSheet('font-size:32px;color:rgb(0,0,0,255);')
        seven.setStyleSheet('font-size:32px;color:rgb(0,0,0,255);')
        eight.setStyleSheet('font-size:32px;color:rgb(0,0,0,255);')
        nine.setStyleSheet('font-size:32px;color:rgb(0,0,0,255);')
        zero.setStyleSheet('font-size:32px;color:rgb(0,0,0,255);')
        point.setStyleSheet('font-size:32px;color:rgb(0,0,0,255);')
        equal.setStyleSheet('font-size:32px;color:rgb(0,0,0,255);')
        add.setStyleSheet('font-size:28px;color:rgb(0,0,0,255);')
        sub.setStyleSheet('font-size:28px;color:rgb(0,0,0,255);')
        mult.setStyleSheet('font-size:28px;color:rgb(0,0,0,255);')
        div.setStyleSheet('font-size:28px;color:rgb(0,0,0,255);')

        grid_layout.addWidget(add, 2, 4)
        grid_layout.addWidget(div, 1, 4)
        grid_layout.addWidget(mult, 0, 4)
        grid_layout.addWidget(sub, 3, 4)
        grid_layout.addWidget(zero, 3, 2)
        grid_layout.addWidget(point, 3, 1)
        grid_layout.addWidget(equal, 3, 3)
        grid_layout.addWidget(one, 2, 1)
        grid_layout.addWidget(two, 2, 2)
        grid_layout.addWidget(three, 2, 3)
        grid_layout.addWidget(four, 1, 1)
        grid_layout.addWidget(five, 1, 2)
        grid_layout.addWidget(six, 1, 3)
        grid_layout.addWidget(seven, 0, 1)
        grid_layout.addWidget(eight, 0, 2)
        grid_layout.addWidget(nine, 0, 3)
        grid_widget.setLayout(grid_layout)
        hbox.addWidget(form_widget, 0, Qt.AlignLeft)
        hbox.addWidget(grid_widget, 0, Qt.AlignRight)
        self.setLayout(hbox)

    def clicker(self):
        num_or_opt = self.sender().text()
        if num_or_opt.isdigit():
            self.tmp_string_num += str(num_or_opt)
            self.tmp_num = int(self.tmp_string_num)
            self.shower.setText(self.tmp_string_num)
            self.sum_num += self.tmp_string_num
            print(self.sum_num)
            self.label.setText(self.sum_num)
            self.tmp_string_num=""
            self.tmp_num = 0
        else:
            if not num_or_opt == "=":
                self.tmp_string_num += num_or_opt
                self.sum_num += num_or_opt
                self.shower.setText(self.tmp_string_num)
                self.tmp_string_num = ""
                self.tmp_num = 0
            else:
                self.label.setText(str(eval(self.sum_num)))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainFrame = calculator_frame()
    mainFrame.show()
    sys.exit(app.exec_())


import speech_recognition as sr
import pyttsx3

def SpeakText(command):
    engine = pyttsx3.init()
    engine.say(command)
    engine.runAndWait()

def CollectText(x, gram):
    recognizer = sr.Recognizer()
    microphone = sr.Microphone()
    with microphone as source:
        recognizer.adjust_for_ambient_noise(source, duration=0.3)
        audio = recognizer.listen(source)
        x = recognizer.recognize_sphinx(audio, grammar=gram)
        x = x.lower()
        return x


from django.shortcuts import render, redirect
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.contrib.auth import login as auth_login, logout as auth_logout
from django.views.decorators.http import require_http_methods
from .forms import CustomUserCreationForm

@require_http_methods(['GET', 'POST'])
def login(request):
    if request.method == 'POST':
        # 다른 form과 인자 구성이 다름
        form = AuthenticationForm(request, request.POST)
        if form.is_valid():
            user = form.get_user()
            auth_login(request, user)
            next = request.GET.get('next')
            return redirect(next or 'board:board_index')
    else:
        form = AuthenticationForm()
    context = {
        'form' : form,
    }
    return render(request, 'accounts/login.html', context)

def logout(request):
    auth_logout(request)
    return redirect('board:board_index')

@require_http_methods(['GET', 'POST'])
def signup(request):
    if request.method == 'POST':
        form = CustomUserCreationForm(request.POST)
        if form.is_valid():
            user = form.save()
            auth_login(request, user)
            return redirect('board:board_index')
    else:
        form = CustomUserCreationForm()

    context = {'form' : form}
    return render(request, 'accounts/signup.html', context)


from django.http import HttpResponse
from django.template import RequestContext
from taikoexplorer_db.models import Video, Composer, Song, Group, SongStyle, ComposerSong, VideoSong, VideoGroup
from django.core import serializers
from django.forms.models import model_to_dict
from django.db.models import Count

import youtube, json, sys

#serves the /add-video-data async requests
def editVideoData(request):
  print("edit video data")
  if request.method == 'POST':
    vid = request.POST.get("vid")
    vtitle = request.POST.get("vtitle", None)
    vdesc = request.POST.get("vdesc", None)
    dthumb = request.POST.get("dthumb", None)
    mthumb = request.POST.get("mthumb", None)
    cid = request.POST.get("cid", None)
    ctitle = request.POST.get("ctitle", None)
    groupName = request.POST.get("group_name", None)
    songData = request.POST.get("song_title", None)
    composerName = request.POST.get("composer_name", None)
    songStyle = request.POST.get("song_style", None)
    forceCreateSong = json.loads(
      request.POST.get("force_create_song", False)
    )

    video = None
    # add new video is it's not already in the db
    video, created = Video.objects.get_or_create(
      vid=vid,
      title=vtitle,
      description=vdesc,
      channelTitle=ctitle,
      channelID=cid,
      default_thumb_url=dthumb,
      medium_thumb_url=mthumb)
    if created:
      print("new video")
      video.save()

    if groupName is None and songData is None and composerName is None:
      raise Exception("No data was provided")

    # add group
    if groupName is not None:
      groupName = json.loads(groupName)
      groupArr = []
      for g in groupName :
        group = None
        if type(g['id']) is not int:
          print("new group")
          group = Group(name=g['id'])
          group.save()
        else:
          group = Group.objects.get(pk=g['id'])
        videoGroup, vg_created = VideoGroup.objects.get_or_create(
          video=video,
          group=group
        )
        if vg_created:
          print("new video group association")
          videoGroup.save()

        groupArr.append(model_to_dict(group))
      return HttpResponse(
          json.dumps(groupArr), content_type='application/json')

    # add song and composer
    # must have a song title and a song style
    if songData is not None and songStyle is not None:
      songData = json.loads(songData)
      composerName = json.loads(composerName)
      songStyle = json.loads(songStyle)

      song = None
      if type(songData['id']) is not int or forceCreateSong is True:
        # force create is disgusting and expensive as fuck
        # since we query for all the songs first, we should probably store that
        # info somewhere and check it again before assuming the user is a jerk
        if forceCreateSong is True:
          print("force create")
          composerIDs = []
          for c in composerName:
            composerIDs.append(c['id'])
          styles = SongStyle.objects.filter(name__in=songStyle)
          composers = Composer.objects.filter(id__in=composerIDs)
          # Good lord this query looks like shit...necessary though
          # http://stackoverflow.com/questions/8618068/django-filter-queryset-in-for-every-item-in-list
          # If the user forces a create, we need to check if the song they
          # eventually enter is actually a real song.  Only triggered if
          # the user is actually kind of a jackass.

          # still stupid that we have to do this...it'll work for now
          songs = Song.objects.filter(
            title=songData['text']
          ).filter(
            styles__in=styles
          ).annotate(
            num_styles=Count('styles')
          ).filter(
            num_styles=len(styles)
          ).filter(
            composers__in=composers
          ).annotate(
            num_composers=Count('composers')
          ).filter(
            num_composers=len(composers)
          )
          # there should only be one.  this assumes that there would never be
          # more than two songs titled the same thing with the same styles
          # and the same composers
          # if there's not...well we're fucked :P
          if len(songs) > 0:
            song = list(songs[:1])[0]
          else:
            song = Song(title=songData['text'])
            print("new song")
            song.save()
        else:
          song = Song(title=songData['id'])
          print("new song")
          song.save()
      else:
        song = Song.objects.get(pk=songData['id'])

      songDict = model_to_dict(song)
      # adding styles
      for idx, ss in enumerate(songStyle):
        style = SongStyle.objects.get(name=ss)
        song.styles.add(style)
        if idx == 0:
          songDict["styles"] = []
        songDict["styles"].append({
          "fields": model_to_dict(style)
        })

      # adding the composers
      for idx, c in enumerate(composerName) :
        composer = None
        if type(c['id']) is not int:
          print("new composer")
          composer = Composer(full_name=c['id'])
          composer.save()
        else:
          composer = Composer.objects.get(pk=c['id'])

        cs, cs_created = ComposerSong.objects.get_or_create(
          composer=composer,
          song=song
        )
        if cs_created:
          print("new composer song association")
          cs.save()
        if idx == 0:
          songDict["composers"] = []
        songDict["composers"].append({
          "fields": model_to_dict(composer)
        })
      videoSong, vs_created = VideoSong.objects.get_or_create(
        video=video,
        song=song
      )
      if vs_created:
        print("new video song association")
        videoSong.save()

      sys.stdout.flush()
      return HttpResponse(
          json.dumps(songDict), content_type='application/json')

  # not a post
  return HttpResponse(json.dumps("failure"), content_type='application/json')

#serves the /delete-video-data async request
def deleteVideoData(request):
  if request.method == 'POST':
    vid = request.POST.get("vid")
    eid = request.POST.get("eid")
    type = request.POST.get("type")
    if type == "song":
      song = Song.objects.get(pk=eid)
      video = Video.objects.get(vid=vid)
      VideoSong.objects.get(video=video, song=song).delete()
    elif type == "group":
      group = Group.objects.get(pk=eid)
      Video.objects.get(vid=vid).groups.remove(group)
    return HttpResponse(json.dumps("success"), content_type='application/json')
  # not a post
  return HttpResponse(json.dumps("failure"), content_type='application/json')

# takes a video db object and formats it to match the yt search result json
def formattedVideoData(video):
  return {
    "id": {
      "videoId": video.vid
    },
    "snippet": {
      "title": video.title,
      "description": video.description,
      "channelId": video.channelID,
      "channelTitle": video.channelTitle,
      "thumbnails": {
        "default": {
          "url": video.default_thumb_url
        },
        "medium": {
          "url": video.medium_thumb_url
        }
      }
    }
  }

def dbSearchResults(query):
  songs = Video.objects.filter(
    songs__title__icontains=query
  )
  groups = Video.objects.filter(
    groups__name__icontains=query
  )
  composers = Composer.objects.filter(
    full_name__icontains=query
  ).prefetch_related('songs__videos')
  songStyles = SongStyle.objects.filter(
    name__icontains=query
  ).prefetch_related('songs__videos')
  composerVideos = []
  for c in composers:
    composerVideos.extend(c.videos)
  songStyleVideos = []
  for ss in songStyles:
    songStyleVideos.extend(ss.videos)
  # this ensures that we don't get duplicate videos
  videos = list(
    set(songs) | set(groups) | set(composerVideos) | set(songStyleVideos)
  )
  formattedVideos = []
  for video in videos :
    formattedVideos.append(formattedVideoData(video))
  return [{"items" : formattedVideos}, videos]

def youtubeSearchResults(getrequest, results = 10):
  if results <= 0:
    return None
  options = dict({
    "q" : getrequest.get("query", None),
    "maxResults" : getrequest.get("maxResults", results),
    "pageToken" : getrequest.get("pageToken", "")
  })
  searchResults = youtube.youtube_search(options)
  videos = Video.objects.filter(
    vid__in=searchResults.get("vids", None)
  ).prefetch_related(
    'songs__composers', 'groups'
  )
  results = [searchResults, videos]
  return results

# iterate through tags and create a map with the vid as the key
def rekeyAndFormatVideoData(videos):
  dataDict = {}
  for video in videos :
    songArr = json.loads(
      serializers.serialize(
        "json",
        video.songs.all()
      )
    )
    for idx, song in enumerate(songArr):
      song["fields"]["composers"] = json.loads(
        serializers.serialize(
          "json",
          video.songs.all()[idx].composers.all()
        )
      )
      song["fields"]["styles"] = json.loads(
        serializers.serialize(
          "json",
          video.songs.all()[idx].styles.all()
        )
      )

    dataDict[video.vid] = {
      "videoData" : model_to_dict(video),
      "groups" : json.loads(
        serializers.serialize("json", video.groups.all())
      ),
      "songs" : songArr,
    }
  return dataDict

#serves the /confirm-video-data async request
def confirmVideoData(request):
  if request.method == 'POST':
    entityID = request.POST.get("entityid")
    video = Video.objects.get(pk=entityID)
    video.is_confirmed = True;
    video.save()
    return HttpResponse(json.dumps("success"), content_type='application/json')

  return HttpResponse(json.dumps("failure"), content_type='application/json')

# serves the /yts api
def youtubeSearch(request):
  query = request.GET.get("q", None)
  query_type = request.GET.get("type", None)
  vid = request.GET.get("vid", None)
  type_dict = {
    'composer': Composer,
    'group': Group,
    'song': Song
  }
  data = []
  returnData = []
  if query is not None and query_type is not None:
    model = type_dict[query_type]
    if query_type == 'composer':
      try:
        d = model.objects.all().filter(full_name__icontains=query)
        data = d
      except Composer.DoesNotExist:
        data = []
    elif query_type == 'group':
      try:
        d = model.objects.all().filter(name__icontains=query)
        data = d
      except Group.DoesNotExist:
        data = []
    elif query_type == 'song':
      try:
        d = model.objects.all().filter(title__icontains=query)
        data = d
      except Song.DoesNotExist:
        data = []
    if data:
      # format the data
      for entry in data:
        entity = entry
        entry = model_to_dict(entry)
        if query_type == 'composer':
          entry["text"] = entry["full_name"]
        elif query_type == 'group':
          entry["text"] = entry["name"]
        elif query_type == 'song':
          entry["text"] = entry["title"]
          entry["videos"] = json.loads(
            serializers.serialize(
              "json",
              Video.objects.filter(
                songs__id=entry["id"]
              ).all()
            )
          )
          entry["already_tagged"] = False

          if vid is not None:
            # whether or not the song is already tagged in the specified video
            for video in entry["videos"]:
              if video["fields"]["vid"] == vid:
                entry["already_tagged"] = True

          composerDict = json.loads(
            serializers.serialize(
              "json",
              entity.composers.all()
            )
          )
          composerInfo = []
          for composer in composerDict:
            composerInfo.append({
              "text": composer["fields"]["full_name"],
              "id":composer["pk"]
            })
          entry["composers"] = composerInfo

          styleDict = json.loads(
            serializers.serialize(
              "json",
              entity.styles.all()
            )
          )
          styleNames = []
          # We just need the name to set this
          for style in styleDict:
            styleNames.append(style["fields"]["name"])
          entry["styles"]  = styleNames

        returnData.append(entry)

  return HttpResponse(
      json.dumps(returnData), content_type='application/json')


log_file_name = 'log.txt'

warnings_count = 0
info_count = 0
error_count = 0

try:
    with open(log_file_name,'r') as log_file:
        for line in log_file:
            print(line)
            if(line.find('INFO:') > -1):
                info_count+= 1
            elif(line.find('ERROR:') > -1):
                error_count+= 1
            elif(line.find('WARNING:') > -1):
                warnings_count += 1

except FileNotFoundError:
    print(log_file_name,'File not found')
except Exception as ex:
    print(ex)

print("WARNINGS:",warnings_count)
print("ERRORS:",error_count)
print("INFO:",info_count)