import numpy as np
import scipy
from scipy import stats
import pandas as pd
import sqlite3

# Selection criteria:
# c1 is whether cohort 1 is included, analogous for c2, c3, c4

# lvwt_th and sbp_th divide the space of individuals into four quadrants
# quadrant selects which one is the cases

#         sbp_th
#           |
#      2    |    1
#           |
#   --------+-------- lvwt_th
#           |
#      3    |    4
#           |

### returns population, cases, controls given selection criteria
def get_data(bdc, c1, c2, c3, c4, lvwt_th, sbp_th, quadrant):
    cohort = []
    if c1:
        cohort.append("1")
    if c2:
        cohort.append("2")
    if c3:
        cohort.append("3")
    if c4:
        cohort.append("4")
    population = bdc[bdc["cohort"].isin(cohort)]

    if quadrant == 1:
        case_condition = (population["lvwt"] >= lvwt_th) & \
                         (population["systolic.bp"] >= sbp_th)
    elif quadrant == 2:
        case_condition = (population["lvwt"] <= lvwt_th) & \
                         (population["systolic.bp"] >= sbp_th)
    elif quadrant == 3:
        case_condition = (population["lvwt"] <= lvwt_th) & \
                         (population["systolic.bp"] <= sbp_th)
    else:
        case_condition = (population["lvwt"] >= lvwt_th) & \
                         (population["systolic.bp"] <= sbp_th)

    case = population[case_condition]
    control = population[~case_condition]
    return population, case, control

### computes penetrance given selection criteria
def compute_penetrance(bdc, c1, c2, c3, c4, lvwt_th, sbp_th, quadrant, mode, pathogenic_ids):
    population, case, control = get_data(bdc, c1, c2, c3, c4, lvwt_th, sbp_th, quadrant)

    num_dg = case[pathogenic_ids].any("columns").count()      # how many cases have pathogenic variants
    num_d = case.size                                         # how many cases
    num_g = population[pathogenic_ids].any("columns").count() # how many people have pathogenic variants
    num_all = population.size                                 # how many people total

    gld_rv = scipy.stats.beta(num_dg + 1, num_d - num_dg + 1)      # P(G|D)
    d_rv = scipy.stats.beta(num_d + 1, num_all - num_d + 1)        # P(D)
    g_rv = scipy.stats.beta(num_g + 1, num_all - num_g + 1)        # P(G)

    pen_samples = []
    for i in range(10000):
        gld = gld_rv.rvs()
        d = d_rv.rvs()
        g = g_rv.rvs()
        dlg = gld * d / g
        pen_samples.append(dlg)

    if mode == "map":
        hist, edges = np.histogram(pen_samples, bins=1000)
        mode_bin = np.argmax(hist)
        map_pen = edges[mode_bin]
        return map_pen
    elif mode == "5":
        return np.percentile(pen_samples, 0.025)
    elif mode == "95":
        return np.percentile(pen_samples, 0.975)

def compute_pens(bdc_database, variants_database):

    cnx_bdc_test = sqlite3.connect(bdc_database)
    cnx_variants = sqlite3.connect(variants_database)

    bdc = pd.read_sql_query("SELECT * FROM bdc", cnx_bdc_test)
    variants = pd.read_sql_query("SELECT * FROM variants", cnx_variants)
    clinvar = pd.read_sql_query("SELECT * FROM clinvar", cnx_variants)

    # find the rsID's of the pathogenic variants
    pathogenic_ids = []
    for c in bdc.columns:
        if c[0] == "r":
            chromosome = variants[variants["rsID"] == c]["Chromosome"].iloc[0]
            position = variants[variants["rsID"] == c]["Position"].iloc[0]
            clinvar_variants = clinvar[(clinvar["Chromosome"] == chromosome) &                                    (clinvar["Position"] == position)]
            pathogenic = any(clinvar_variants["Pathogenic"])
            if pathogenic:
                pathogenic_ids.append(c)

    # place to store results
    pens = pd.DataFrame(columns=["mode", "penetrance",
                                 "cohort1", "cohort2", "cohort3", "cohort4",
                                 "LVWT threshold", "SBP threshold",
                                 "Quadrant"])

    choice_set = [(mode, c1, c2, c3, c4, lvwt_th, sbp_th, quad) \
                    for mode in ["map", "5", "95"] \
                    for c1 in [True, False] \
                    for c2 in [True, False] \
                    for c3 in [True, False] \
                    for c4 in [True, False] \
                    for lvwt_th in np.arange(0.8, 1, 0.03) \
                    for sbp_th in np.arange(0.8, 1, 0.03) \
                    for quad in [1]]

    for choice in choice_set:
        mode, c1, c2, c3, c4, lvwt_th, sbp_th, quadrant = choice

        # skip if no cohorts are included
        if not (c1 or c2 or c3 or c4):
            continue

        pen = compute_penetrance(bdc, c1, c2, c3, c4, lvwt_th, sbp_th, quadrant, mode, pathogenic_ids)
        row = pd.DataFrame([[mode, pen,
                             c1, c2, c3, c4,
                             lvwt_th, sbp_th, quadrant]],
                           columns=["mode", "penetrance",
                                    "cohort1", "cohort2", "cohort3", "cohort4",
                                    "LVWT threshold", "SBP threshold",
                                    "Quadrant"])
        pens = pens.append(row, ignore_index=True)

    return pens


# from socket import *

# s = socket()

# sever_addr = ("127.0.0.1",9800)
# s.connect(sever_addr)
# filename="send.jpg"
# with open(filename,"rb") as f:
#     while True:
#         s1 = f.read(1024)
#         if not s1:
#             break
#         s.send(s1)

# # recv = s.recv(1024)
# # print("from server:",recv.decode())
# s.close()

from socket import *
s = socket()
s.connect(("127.0.0.1",8000))
f = open('send.jpg','rb')
while True:
    s1 = f.read(1024)
    if not s1:
        break
    s.send(s1)
    # recv = s.recv(1024)
    # print("from server msg:",recv.decode())

f.close()
s.close()


import json
import time

def record(name, weight):
    date = time.strftime("%d.%m.%Y")

    records = get_records()

    if date in records:
        record = records[date]
    else:
        record = {"meals": []}

    meal = {
        "name": name,
        "calories": calories(name, weight)
    }

    record["meals"].append(meal)

    records[date] = record

    f = open('records.json', 'w')
    f.write(json.dumps(records))
    f.close()

def get_records():
    try:
        f = open('records.json', 'r')
    except:
        return {}

    records = json.loads(f.read())
    f.close()

    return records

def calories(name, weight):
    dishes = get_dishes()

    for dish in dishes:
        if dish['name'] == name:
            return int(dish['calories']) / 100 * weight

    return 0

def get_dishes():
    try:
        f = open('dishes.json', 'r')
    except:
        return []

    dishes = json.loads(f.read())
    f.close()

    return dishes

def present(name, dishes):
    for dish in dishes:
        if dish['name'] == name:
            return True

    return False

def add_dish(name, calories):
    dishes = get_dishes()
    if present(name, dishes):
        return

    dish = {
        'name': name,
        'calories': calories
    }

    dishes.append(dish)

    f = open('dishes.json', 'w')
    f.write(json.dumps(dishes))
    f.close()


from django.shortcuts import render
from rest_framework import viewsets
from .models import WordList
from .serializers import WordListSerializer
from django.views.decorators.csrf import csrf_exempt
import json
from django.http.response import HttpResponse
from django.core import serializers
from store.models import Store
from datetime import datetime
from urllib.parse import urlencode, quote_plus
from urllib.request import Request, urlopen
import urllib
import xmltodict
from numpy import unicode
import chardet

# Create your views here.
class WordListViewSet(viewsets.ModelViewSet):
    queryset = WordList.objects.all()
    serializer_class = WordListSerializer #순차화

@csrf_exempt
def wordListFilter(data):
    data = json.load(data)
    s_keyword = data['keyword']
    year = data['year']
    mon = data['mon']

    query = WordList.objects.filter(keyword=s_keyword, word_year=year, word_mon=mon)

    # query_result = []
    # for que in query:
        # query_result.append({'keyword':que.word_word, 'word_cnt':que.word_cnt})

    query_list = serializers.serialize('json', query)
    return HttpResponse(query_list, content_type="application/json; charset=utf-8")

@csrf_exempt
def recommendItem(data):
    jsonData = json.load(data)
    local_id = jsonData['id']

    store = Store.objects.get(store_id=local_id)
    category = store.store_ctg

    month = datetime.today().month

    itemList = WordList.objects.filter(keyword=category, word_mon = month)

    reData = {}

    for item in itemList:
        word = item.word_word
        if reData.get(item.word_word) is not None:
            reData[word] = reData.get(word) + item.word_cnt
        else:
            reData[word] = item.word_cnt

    def sortByVal(x):
        return x[1]

    res = sorted(reData.items(), key=sortByVal, reverse=True)
    highData = res[0]
    highKeyword = highData[0]

    #가장 높은 빈도의 단어로 상품 리스트 추출
    url = 'http://openapi.11st.co.kr/openapi/OpenApiService.tmall?key=1fc323faf14a0ddc1479e3d6f04069f6&apiCode=ProductSearch&keyword='+urllib.parse.quote_plus(category +" "+ highKeyword)+'&sortCd=G'
    request = Request(url)
    request.get_method = lambda: 'GET'
    response_body = urlopen(request).read().decode('euc-kr')

    jsonString = json.dumps(xmltodict.parse(response_body), indent=4, ensure_ascii=False)
    # print(jsonString)

    #jsonStr를 Dict객체로 변환
    jsonDict = json.loads(jsonString.replace("'", "\""))

    dataResponse = jsonDict['ProductSearchResponse']
    dataProducts = dataResponse['Products']
    dataProduct = dataProducts['Product']

    productResult = {}
    getPdtCnt = 10

    for i in range(0, getPdtCnt):
        product = dataProduct[i]
        productResult['pdt'+str(i+1)] = {'title': product['ProductName'], 'image': product['ProductImage'], 'page': product['DetailPageUrl'],'price': product['SalePrice']}

    # jsonResult = serializers.serialize('json', productResult)
    jsonResult = json.dumps(productResult)

    return HttpResponse(jsonResult, content_type="application/json; charset=utf-8")


from torch import nn

class ENCODER(nn.Module):
    def __init__(self, features):
        super(ENCODER, self).__init__()
        self.encoder = nn.Sequential(
            nn.Conv2d(3,features, 3, 1, 1),
            nn.ReLU(True),
            nn.InstanceNorm2d(features),
            # nn.LayerNorm((32, 128, 128)),
            nn.MaxPool2d(2),
            nn.Conv2d(features, 64, 3, 1, 1),
            nn.ReLU(True),
            nn.InstanceNorm2d(64),
            # nn.LayerNorm((64, 64, 64)),
            nn.MaxPool2d(2),
            nn.Dropout2d(0.1),
            nn.Conv2d(64, 128, 3, 1, 1),
            nn.ReLU(True),
            nn.InstanceNorm2d(128),
            # nn.LayerNorm((128, 32, 32)),
            nn.MaxPool2d(2),
            nn.Dropout2d(0.1),
            nn.Conv2d(128, 256, 3, 1, 1),
            nn.ReLU(True),
            nn.InstanceNorm2d(256),
            # nn.LayerNorm((256, 16, 16)),
            nn.MaxPool2d(2),
            nn.Dropout2d(0.2),
            nn.Conv2d(256, 512, 3, 1, 1),
            nn.ReLU(True),
            nn.LayerNorm((512, 8, 8)),
            nn.MaxPool2d(2),
            nn.Dropout2d(0.2),
            # nn.Conv2d(512, 512, 4, 1, 0),
            # nn.ReLU(True),
            # nn.InstanceNorm2d(512),
            # # nn.MaxPool2d(2),
            # nn.Dropout2d(0.1)
        )

    def forward(self, x):
        x = self.encoder(x)
        return x

class DECODER(nn.Module):
    def __init__(self, features):
        super(DECODER, self).__init__()
        self.decoder = nn.Sequential(
            nn.UpsamplingBilinear2d(scale_factor=2),
            nn.Conv2d(512,256, 3, 1, 1),
            nn.ReLU(True),
            nn.UpsamplingBilinear2d(scale_factor=2),
            nn.Conv2d(256, 128, 3, 1, 1),
            nn.ReLU(True),
            nn.UpsamplingBilinear2d(scale_factor=2),
            nn.Conv2d(128, 64, 3, 1, 1),
            nn.ReLU(True),
            nn.UpsamplingBilinear2d(scale_factor=2),
            nn.Conv2d(64, 32, 3, 1, 1),
            nn.ReLU(True),
            nn.UpsamplingBilinear2d(scale_factor=2),
            nn.Conv2d(32, 3, 3, 1, 1),
            nn.Sigmoid()
        )

    def forward(self, x):
        x = self.decoder(x)
        return x

class MLP(nn.Module):
    def __init__(self, in_features, hidden_features, num_classes, dropout):
        super().__init__()
        self.classifier = nn.Sequential(
            nn.Linear(in_features, hidden_features),
            nn.ReLU(True),
            nn.BatchNorm1d(hidden_features),
            nn.Dropout(dropout),
            nn.Linear(hidden_features, hidden_features),
            nn.ReLU(True),
            nn.BatchNorm1d(hidden_features),
            nn.Dropout(dropout),
            nn.Linear(hidden_features, num_classes),
        )

    def forward(self, x):
        x = self.classifier(x)
        return x

class VGG(nn.Module):
    def __init__(self, features, num_classes=2):
        super(VGG, self).__init__()
        self.cnn = ENCODER(features)
        self.avgpool = nn.AdaptiveAvgPool2d((1,1))
        self.classifier = MLP(512, 1024, num_classes, 0.3)

    def forward(self, x):
        # print(x.shape)
        x = self.cnn(x)
        # print(x.shape)
        x = self.avgpool(x)
        # print(x.shape)
        x = x.view(x.size(0), -1)
        # print(x.shape)
        x = self.classifier(x)
        # print(x.shape)
        return x

class VGG_AE(nn.Module):
    def __init__(self, features, num_classes=2):
        super(VGG_AE, self).__init__()
        self.encoder = ENCODER(features)
        self.decoder = DECODER(features)
        self.avgpool = nn.AdaptiveAvgPool2d((1,1))
        self.classifier = MLP(512, 1024, num_classes, 0.3)

    def forward(self, x, m1, m2):
        # print(x.shape)
        x = self.encoder(x)
        if m1:
            a = self.avgpool(x)
            a = a.view(a.size(0), -1)
            a = self.classifier(a)
        else:
            m1 = None
        if m2:
            b = self.decoder(x)
        else:
            m2 = None

        return a, b


#!/usr/bin/python

import dis

def foo(x):
  def funcs(y):
    print(x)
  return funcs

code_obj = compile('sum([1,2,3])',  '', 'single')
dis.dis(code_obj)

print(foo.func_code)
dis.dis(foo.func_code)

bar=foo("x")
print(bar.__closure__)
print(bar.__closure__[0].cell_contents)


"""Output the 12z morning low temperature"""
import datetime

import matplotlib.cm as cm
import numpy as np
from pyiem.plot import MapPlot
from pyiem.tracker import loadqc
from pyiem.util import get_dbconn

def main():
    """Go Main Go"""
    now = datetime.datetime.now()
    qdict = loadqc()
    pgconn = get_dbconn('iem', user='nobody')
    icursor = pgconn.cursor()

    sql = """
      select s.id,
      ST_x(s.geom) as lon, ST_y(s.geom) as lat,
      max_tmpf as high, s.network
      from summary c, stations s
      WHERE c.iemid = s.iemid and day = 'TODAY' and max_tmpf > -40
      and s.network in ('IA_ASOS', 'AWOS', 'IL_ASOS','MO_ASOS','KS_ASOS',
      'NE_ASOS','SD_ASOS','MN_ASOS','WI_ASOS') ORDER by high ASC
    """

    lats = []
    lons = []
    vals = []
    valmask = []
    labels = []
    icursor.execute(sql)
    dsm = None
    for row in icursor:
        if row[0] == 'DSM':
            dsm = row[3]
        if qdict.get(row[0], {}).get('tmpf') is not None:
            continue
        lats.append(row[2])
        lons.append(row[1])
        vals.append(row[3])
        labels.append(row[0])
        valmask.append(row[4] in ['AWOS', 'IA_ASOS'])

    if len(lats) < 4:
        return

    mp = MapPlot(sector='iowa',
                 title=("%s Iowa ASOS/AWOS High Temperature"
                        ) % (now.strftime("%-d %b %Y"),),
                 subtitle='map valid: %s' % (
                     now.strftime("%d %b %Y %-I:%M %p"), ))
    # m.debug = True
    if dsm is None:
        dsm = vals[0]

    bottom = int(dsm) - 15
    top = int(dsm) + 15
    bins = np.linspace(bottom, top, 11)
    cmap = cm.get_cmap('jet')
    mp.contourf(lons, lats, vals, bins, units='F', cmap=cmap)
    mp.plot_values(lons, lats, vals, '%.0f', valmask=valmask, labels=labels,
                   labelbuffer=10)
    mp.drawcounties()

    pqstr = "plot ac %s summary/iowa_asos_high.png iowa_asos_high.png png" % (
            now.strftime("%Y%m%d%H%M"), )

    mp.postprocess(pqstr=pqstr)
    mp.close()

if __name__ == '__main__':
    main()