#!/usr/bin/env python3
"""A stack again, this time using the built-in "list" type.

A stack is just a list with a "push" method, since the list
already has a "pop".  When it is-a "list" it inherits all
the builtin facilities of the list.
"""

class Stack(list):

    def push(self, thing):
        # list.append(self, thing) works here.
        # Also, the following  works this time because
        # this class does not have an "append" already.
        self.append(thing)

if __name__ == "__main__":
    stack = Stack()
    stack.push("Gone With The Wind")
    stack.push("Maltese Falcon")
    stack.push("Fifth Element")
    print("The stack has a rather nice __str__ already:")
    print(stack)
    print('The stack has all the list facilities, plus the "push":')
    print(dir(stack))
    print("Sorting then popping:")
    stack.sort()
    print(stack.pop())


from urllib.request import urlopen
import urllib
from selenium import webdriver
from bs4 import BeautifulSoup
import http.client
from openpyxl import Workbook
from openpyxl import load_workbook
from openpyxl.writer.excel import ExcelWriter
from openpyxl.cell.cell import ILLEGAL_CHARACTERS_RE
import json
import re
import copy
import string
import time

http.client._MAXHEADERS = 1000

def urllib_download(IMAGE_URL, pName):
	try:
		opener = urllib.request.build_opener()
		opener.addheaders = [('User-agent', 'Mozilla/5.0')]
		urllib.request.install_opener(opener)
		urllib.request.urlretrieve(IMAGE_URL, pName.replace("/","").replace("\\","")+'.jpg')
	except:
		print('no')

def getNodeText(node):
	if(node == None):
		return ""
	else:
		return node.get_text().strip()

retryCount = 0
def getHtmlFromUrl(url, type="get", para={}):
	global retryCount
	try:
		url = urllib.parse.quote(url, safe=string.printable).replace(' ','%20')
		request_obj=urllib.request.Request(url=url)
		response_obj=urllib.request.urlopen(request_obj)
		html_code=response_obj.read()
		if str(html_code).find("403 ERROR")>-1:
			time.sleep(360)
			return getHtmlFromUrl(url)
		else:
			return html_code
	except:
		retryCount += 1
		if retryCount < 5:
			print("retry index"+str(retryCount)+url)
			time.sleep(360)
			return getHtmlFromUrl(url)
		else:
			retryCount = 0
			return ""
def getRenderdHtmlFromUrl(url, isTry):
	global retryCount
	try:
		chrome_options = webdriver.ChromeOptions()
		chrome_options.add_argument('--headless')
		chrome_options.add_argument('--disable-gpu')
		chrome_options.add_argument("window-size=1024,768")

		chrome_options.add_argument("--no-sandbox")
		browser = webdriver.Chrome(chrome_options=chrome_options)
		browser.get(url)
		if str(browser.page_source).find("403 ERROR")>-1:
			time.sleep(360)
			return getRenderdHtmlFromUrl(url, True)
		else:
			return browser.page_source
	except:
		retryCount += 1
		if retryCount < 5:
			print("retry index"+str(retryCount)+url)
			time.sleep(360)
			return getRenderdHtmlFromUrl(url, True)
		else:
			retryCount = 0
			return ""

def writeExcel(workSheet, headers, rowIndex, info):
	cellIndex=1
	for head in headers:
		try:
			if head in info:
				content = ILLEGAL_CHARACTERS_RE.sub(r'', info[head])
				workSheet.cell(rowIndex, cellIndex).value = content.strip()
			else:
				workSheet.cell(rowIndex, cellIndex).value = ""
			cellIndex=cellIndex+1
		except:
			print(rowIndex)

def getProductInfo(url, type1, type2, products):
	print(str(len(products)) + url)
	productListHtml = getRenderdHtmlFromUrl(url, False)
	sope = BeautifulSoup(productListHtml, "html.parser",from_encoding="utf-8")
	pInfo = {
		"link": url,
		"type1": type1,
		"type2": type2
	}
	try:
		syncDom=sope.find_all("p", attrs={"class":"product__synonyms show-more-content"})
		print(syncDom)
		titleArea = sope.find("div", attrs={"class": "product__title-wrapper"})
		navArea = sope.find("ul", attrs={"class": "breadcrumb outline"})
		if titleArea != None:
			pInfo["Product Name"] = getNodeText(titleArea.find("h1"))
			pInfo["Synonyms"] = getNodeText(titleArea.find("p"))
			pInfo["nav"] = getNodeText(navArea)

			specAreas = sope.find_all("div",attrs={"class":"product__item"})
			for specArea in specAreas:
				title = getNodeText(specArea.find("h2"))
				val = getNodeText(specArea.find("p"))
				if title == "API Family":
					val = getNodeText(specArea.parent)
				if len(title) > 0:
					pInfo[title]=val

			img = sope.find("img", attrs={"itemprop":"image"})
			if img != None:
				if "CAS Number" in pInfo and len(pInfo["CAS Number"])>0:
					urllib_download(img["src"], pInfo["CAS Number"])
				else:
					urllib_download(img["src"], pInfo["Product Name"])
			products.append(pInfo.copy())
	except:
		pInfo={
			"nav":"出错了"
		}
		products.append(pInfo.copy())

def getProductList(url, type1, type2, products):
	productListHtml = getHtmlFromUrl(url)
	try:
		data = json.loads(productListHtml)
		hits = data["products"]
		for hit in hits:
			link = hit["url"]
			getProductInfo("https://www.lgcstandards.com/US/en"+link, type1, type2, products)
	except:
		pInfo = {
			"link":url,
			"type1":"读取出错"
		}
		products.append(pInfo)

excelFileName="lgcstandards.xlsx"
wb = Workbook()
workSheet = wb.active
products = []

getProductInfo("https://www.lgcstandards.com/US/en/Dexamethasone-Sodium-Phosphate/p/MM0210.00", "111", "222", products)
# getProductList("https://www.lgcstandards.com/US/en/lgcwebservices/lgcstandards/categories/322963/products?currentPage=1&q=&sort=relevance-code&pageSize=10&country=US&lang=en&fields=FULL&defaultB2BUnit=",'Pharmaceutical',"COVID-19 research and reference materials", products)

# for page in range(0,13):
# 	getProductList("https://www.lgcstandards.com/US/en/lgcwebservices/lgcstandards/categories/322963/products?currentPage="+str(page)+"&q=&sort=relevance-code&pageSize=100&country=US&lang=en&fields=FULL&defaultB2BUnit=",'Pharmaceutical',"COVID-19 research and reference materials", products)
# for page in range(0,16):
# 	getProductList("https://www.lgcstandards.com/US/en/lgcwebservices/lgcstandards/categories/323809/products?currentPage="+str(page)+"&q=&sort=relevance-code&pageSize=100&country=US&lang=en&fields=FULL&defaultB2BUnit=",'Pharmaceutical','API standards', products)
# for page in range(0,72):
# 	getProductList("https://www.lgcstandards.com/US/en/lgcwebservices/lgcstandards/categories/323810/products?currentPage="+str(page)+"&q=&sort=relevance-code&pageSize=100&country=US&lang=en&fields=FULL&defaultB2BUnit",'Pharmaceutical','Impurity standards', products)
# for page in range(0,42):
# 	getProductList("https://www.lgcstandards.com/US/en/lgcwebservices/lgcstandards/categories/324176/products?currentPage="+str(page)+"&q=&sort=relevance-code&pageSize=100&country=US&lang=en&fields=FULL&defaultB2BUnit=",'Pharmaceutical','Pharmacopoeial standards', products)
# for page in range(0,31):
# 	getProductList("https://www.lgcstandards.com/US/en/lgcwebservices/lgcstandards/categories/279516/products?currentPage="+str(page)+"&q=&sort=relevance-code&pageSize=100&country=US&lang=en&fields=FULL&defaultB2BUnit=",'Pharmaceutical','European Pharmacopoeia (Ph. Eur.)', products)
# for page in range(0,19):
# 	getProductList("https://www.lgcstandards.com/US/en/lgcwebservices/lgcstandards/categories/279513/products?currentPage="+str(page)+"&q=&sort=relevance-code&pageSize=100&country=US&lang=en&fields=FULL&defaultB2BUnit=",'Pharmaceutical','British Pharmacopoeia', products)
# for page in range(0,4):
# 	getProductList("https://www.lgcstandards.com/US/en/lgcwebservices/lgcstandards/categories/279517/products?currentPage="+str(page)+"&q=&sort=relevance-code&pageSize=100&country=US&lang=en&fields=FULL&defaultB2BUnit=",'Pharmaceutical','Reagents according to pharmacopoeias', products)
# for page in range(0,2):
# 	getProductList("https://www.lgcstandards.com/US/en/lgcwebservices/lgcstandards/categories/279526/products?currentPage="+str(page)+"&q=&sort=relevance-code&pageSize=20&country=US&lang=en&fields=FULL&defaultB2BUnit=",'Pharmaceutical','International reference standards for antibiotics (WHO)', products)
# for page in range(0,17):
# 	getProductList("https://www.lgcstandards.com/US/en/lgcwebservices/lgcstandards/categories/323817/products?currentPage="+str(page)+"&q=&sort=relevance-code&pageSize=100&country=US&lang=en&fields=FULL&defaultB2BUnit=",'Pharmaceutical','Building blocks', products)
# for page in range(0,30):
# 	getProductList("https://www.lgcstandards.com/US/en/lgcwebservices/lgcstandards/categories/324179/products?currentPage="+str(page)+"&q=&sort=relevance-code&pageSize=100&country=US&lang=en&fields=FULL&defaultB2BUnit=",'Pharmaceutical','Enzyme activators, inhibitors & substrates', products)
# for page in range(0,5):
# 	getProductList("https://www.lgcstandards.com/US/en/lgcwebservices/lgcstandards/categories/323822/products?currentPage="+str(page)+"&q=&sort=relevance-code&pageSize=100&country=US&lang=en&fields=FULL&defaultB2BUnit=",'Pharmaceutical','Neurochemicals', products)
# for page in range(0,11):
# 	getProductList("https://www.lgcstandards.com/US/en/lgcwebservices/lgcstandards/categories/323824/products?currentPage="+str(page)+"&q=&sort=relevance-code&pageSize=100&country=US&lang=en&fields=FULL&defaultB2BUnit=",'Pharmaceutical','Carbohydrates', products)
# for page in range(0,2):
# 	getProductList("https://www.lgcstandards.com/US/en/lgcwebservices/lgcstandards/categories/323827/products?currentPage="+str(page)+"&q=&sort=relevance-code&pageSize=100&country=US&lang=en&fields=FULL&defaultB2BUnit=",'Pharmaceutical','Cross-linkers', products)
# for page in range(0,28):
# 	getProductList("https://www.lgcstandards.com/US/en/lgcwebservices/lgcstandards/categories/323816/products?currentPage="+str(page)+"&q=&sort=relevance-code&pageSize=100&country=US&lang=en&fields=FULL&defaultB2BUnit=",'Pharmaceutical','Chiral molecules', products)
# for page in range(0,81):
# 	getProductList("https://www.lgcstandards.com/US/en/lgcwebservices/lgcstandards/categories/323830/products?currentPage="+str(page)+"&q=&sort=relevance-code&pageSize=100&country=US&lang=en&fields=FULL&defaultB2BUnit=",'Pharmaceutical','Pharmaceutical toxicology', products)
# for page in range(0,7):
# 	getProductList("https://www.lgcstandards.com/US/en/lgcwebservices/lgcstandards/categories/279509/products?currentPage="+str(page)+"&q=&sort=relevance-code&pageSize=100&country=US&lang=en&fields=FULL&defaultB2BUnit=",'Pharmaceutical','Elemental impurities', products)
# for page in range(0,2):
# 	getProductList("https://www.lgcstandards.com/US/en/lgcwebservices/lgcstandards/categories/279527/products?currentPage="+str(page)+"&q=&sort=relevance-code&pageSize=100&country=US&lang=en&fields=FULL&defaultB2BUnit=",'Pharmaceutical','Physical properties', products)
# for page in range(0,2):
# 	getProductList("https://www.lgcstandards.com/US/en/lgcwebservices/lgcstandards/categories/279507/products?currentPage="+str(page)+"&q=&sort=relevance-code&pageSize=20&country=US&lang=en&fields=FULL&defaultB2BUnit=",'Pharmaceutical','Pharmaceutical proficiency testing', products)

headers=[
	'link','nav', 'type1','type2','Product Name','Synonyms','Product Code','CAS Number','Product Format','Matrix','Molecular Formula',
	'Molecular Weight','API Family','Product Categories','Product Type','Accurate Mass','Smiles','InChI','IUPAC','Storage Temperature',
	'Shipping Temperature','Country of Origin'
]
for index,head in enumerate(headers):
    workSheet.cell(1, index+1).value = head.strip()
for index,p in enumerate(products):
    writeExcel(workSheet, headers, index + 2, p)
print("flish")

wb.save(excelFileName)


import torch
from torchvision import transforms
from torch import nn
import os
from im2mesh import data
from im2mesh import config
from im2mesh.encoder import encoder_dict
from im2mesh.point_completion import model as pc_model
from im2mesh.point_completion import training
from im2mesh.encoder.world_mat_encoder import WorldMatEncoder

def get_model(cfg, device=None, dataset=None, **kwargs):
    ''' Return the OccupancyWithDepth Network model.

    Args:
        cfg (dict): imported yaml config
        device (device): pytorch device
        dataset (dataset): dataset
    '''
    encoder = cfg['model']['encoder']
    assert encoder.startswith('point')

    c_dim = cfg['model']['c_dim']
    encoder_kwargs = cfg['model']['encoder_kwargs']

    if 'input_points_count' in cfg['model']:
        input_points_count = cfg['model']['input_points_count']
    else:
        input_points_count = 2048

    if 'output_points_count' in cfg['model']:
        output_points_count = cfg['model']['output_points_count']
    else:
        output_points_count = 2048

    if 'preserve_input' in cfg['model']:
        preserve_input = cfg['model']['preserve_input']
    else:
        preserve_input = False

    encoder = encoder_dict[encoder](
        c_dim=c_dim,
        **encoder_kwargs
    )

    if 'use_encoder_world_mat' in cfg['model']:
        use_encoder_world_mat = cfg['model']['use_encoder_world_mat']
    else:
        use_encoder_world_mat = False

    if use_encoder_world_mat:
        encoder_world_mat = WorldMatEncoder(c_dim=c_dim)
    else:
        encoder_world_mat = None

    model = pc_model.PointCompletionNetwork(encoder, device=device, c_dim=c_dim,
        input_points_count=input_points_count,
        output_points_count=output_points_count,
        preserve_input=preserve_input,
        encoder_world_mat=encoder_world_mat
    )

    return model

def get_trainer(model, optimizer, cfg, device, **kwargs):
    ''' Returns the trainer object.

    Args:
        model (nn.Module): the Occupancy Network model
        optimizer (optimizer): pytorch optimizer object
        cfg (dict): imported yaml config
        device (device): pytorch device
    '''
    out_dir = cfg['training']['out_dir']
    vis_dir = os.path.join(out_dir, 'vis')
    input_type = cfg['data']['input_type']

    trainer_params = {}

    if 'depth_pointcloud_transfer' in cfg['model']:
        trainer_params['depth_pointcloud_transfer'] = cfg['model']['depth_pointcloud_transfer']

    if 'gt_pointcloud_transfer' in cfg['model']:
        trainer_params['gt_pointcloud_transfer'] = cfg['model']['gt_pointcloud_transfer']

    if 'view_penalty' in cfg['training']:
        trainer_params['view_penalty'] = cfg['training']['view_penalty']

        if cfg['training']['view_penalty']:
            if 'loss_mask_flow_ratio' in cfg['training']:
                trainer_params['loss_mask_flow_ratio'] = cfg['training']['loss_mask_flow_ratio']
            if 'mask_flow_eps' in cfg['training']:
                trainer_params['mask_flow_eps'] = cfg['training']['mask_flow_eps']
            if 'loss_depth_test_ratio' in cfg['training']:
                trainer_params['loss_depth_test_ratio'] = cfg['training']['loss_depth_test_ratio']
            if 'depth_test_eps' in cfg['training']:
                trainer_params['depth_test_eps'] = cfg['training']['depth_test_eps']

    if 'loss_type' in cfg['training']:
        assert cfg['training']['loss_type'] in ('cd', 'emd')
        trainer_params['loss_type'] = cfg['training']['loss_type']

    trainer = training.PointCompletionTrainer(model, optimizer,
        device=device, input_type=input_type,
        vis_dir=vis_dir, **trainer_params
    )
    return trainer

def get_data_fields(mode, cfg):
    ''' Returns the data fields.

    Args:
        mode (str): the mode which is used
        cfg (dict): imported yaml config
    '''
    fields = {}
    if 'output_points_count' in cfg['model']:
        output_points_count = cfg['model']['output_points_count']
    else:
        output_points_count = 2048

    transform = transforms.Compose([
        data.SubsamplePointcloud(output_points_count)
    ])

    fields['pointcloud'] = data.PointCloudField(
        cfg['data']['pointcloud_file'], transform,
        with_transforms=True
    )

    return fields


from collections import Counter, defaultdict
from knn import Knearest, Numbers

data = Numbers("../data/mnist.pkl.gz")

acc = defaultdict(dict)
lstart = 100
dindex = 0
for i in range(1,10):
    for j in range(1,10):
        dindex += 1
        print("k=%i, limit=%i\n" % (i, j*lstart))
        myknn = Knearest(data.train_x[:j*lstart],data.train_y[:j*lstart:],i)
        cm = myknn.confusion_matrix(data.test_x,data.test_y)
        acc[i][j] = myknn.acccuracy(cm)

print("done")


import numpy as np
import pandas as pd
import xlsxwriter

import gurobipy as gp
from gurobipy import GRB

####################### INDEX ################################

j = 3  #Customer sub index
m = 1  #Manufacturer sub index
g = 1  #GMSD index
s = 1  #State sub index
r = 9  #Region sub index
d = 10  #District sub index
i = 151 #Clinic sub index
t = 12  #Time sub index

clinic_breakpoints = [10,16,28,40,59,76,92,103,123,151,178,194,205,213,226,249,256,266,274,290,312,322,340,361,376,413,432,451,462,483,504,511,517,535,555,568,585,606]   #CLinic breakpoints for each districts
clinic_breakpoints = clinic_breakpoints[0:d]
i = clinic_breakpoints[d-1]

customers = list(range(1,j+1))
manufacturers = list(range(1,m+1))
gmsd = list(range(1,g+1))
svs = list(range(1,s+1))
rvs = list(range(1,r+1))
dvs = list(range(1,d+1))
clinics = list(range(1,i+1))
time = list(range(1,t+1))
########################### PARAMETERS ################################
l = GRB.INFINITY #large number for consistency constraints
fraction_storage = 0.25 #Fraction of total capacity in cold chain points to be considered for COVID-19 vaccine
fraction_transport = 0.25 #Fraction of total capacity in vehicles to be considered for COVID-19 vaccine

#Transportation cost
diesel_cost = 14
booking_cost = {
	"MG" : 40000,
	"GS" : 20000,
	"SR" : 12000,
	"RD" : 10000,
	"DI" : 5000
}
np.random.seed(133)

#Distances
Dgm = [[1000]] #From M to G (confirm)
Dsg = [[550]] #From G to S (confirm)

#From S to R
df_Drs = pd.read_csv("Input_data/distances_sr.csv")
Drs = [[0 for R in range(r)] for S in range(s)]
for index in df_Drs.index:
	Drs[df_Drs['s'][index]-1][df_Drs['r'][index]-1] = df_Drs['Distance'][index]

#From R to D
df_Ddr = pd.read_csv("Input_data/distances_rd.csv")
Ddr = [[0 for D in range(d)] for R in range(r)]
for index in df_Ddr.index:
	if (df_Ddr['d'][index] > d):
		continue
	Ddr[df_Ddr['r'][index]-1][df_Ddr['d'][index]-1] = df_Ddr['Distance'][index]

#From D to I
df_Did = pd.read_csv("Input_data/distances_di.csv")
Did = [[0 for I in range(i)] for D in range(d)]
for index in df_Did.index:
	if (df_Did['d'][index] > d or df_Did['i'][index] > i):
		continue
	Did[df_Did['d'][index]-1][df_Did['i'][index]-1] = df_Did['Distance'][index]

#Capacity of trucks
cap_veh_gm = round(fraction_transport*2932075) #Refrigerated van
cap_veh_sg = round(fraction_transport*2932075) #Refrigerated van
cap_veh_rs = round(fraction_transport*290880) #Insulated van
cap_veh_dr = round(fraction_transport*290880) #Insulated van
cap_veh_id = round(fraction_transport*290880) #Insulated van

#Final transportation costs
Kgmt = np.array([[[Dgm[M][G]*diesel_cost+booking_cost["MG"] for G in range(0,g)] for M in range(0,m)] for T in range(0,t)])
Ksgt = np.array([[[Dsg[G][S]*diesel_cost+booking_cost["GS"] for S in range(0,s)] for G in range(0,g)] for T in range(0,t)])
Krst = np.array([[[Drs[S][R]*diesel_cost+booking_cost["SR"] for R in range(0,r)] for S in range(0,s)] for T in range(0,t)])
Kdrt = np.array([[[Ddr[R][D]*diesel_cost+booking_cost["RD"] for D in range(0,d)] for R in range(0,r)] for T in range(0,t)])
Kidt = np.array([[[Did[D][I]*diesel_cost+booking_cost["DI"] for I in range(0,i)] for D in range(0,d)] for T in range(0,t)])

#Shortage costs;
Pjt = [[0 for J in range(j)] for T in range(t)]
for T in range(t):
    Pjt[T][0] = 75000      #children
    Pjt[T][1] = 50000      #Old
    Pjt[T][2] = 50000      #hcw

#Clinical cost per unit of vaccine
Vj = 225

#Inventory holding costs
hgt = [[0.3 for G in range(g)] for T in range(t)]
hst = [[0.3 for S in range(s)] for T in range(t)]
hrt = np.random.normal(0.4,0.05,r*t).reshape(t,r)
hdt = np.random.normal(0.4,0.05,d*t).reshape(t,d)
hit = np.random.normal(0.4,0.05,i*t).reshape(t,i)

#Ordering costs
Cgmt = [[[200000 for G in range(g)] for M in range(m)] for T in range(t)]
Csgt = [[[100000 for S in range(s)] for G in range(g)] for T in range(t)]
Crst = [[[75000 for R in range(r)] for S in range(s)] for T in range(t)]
Cdrt = [[[25000 for D in range(d)] for R in range(r)] for T in range(t)]
Cidt = [[[15000 for I in range(i)] for D in range(d)] for T in range(t)]

#Demand
wastage_factor = 0.5 #This value will depend on the vaccine, we are talking about. Here, it is BCG.

#Fraction of demand
Fr_d = 1
#Fr_d = 0.5
#Fr_d = 0.75

df_demand = pd.read_csv("Input_data/weekly_demand.csv")
dijt = [[[0 for I in range(1,i+1)] for J in range(j)] for T in range(1,t+1)]
for index in df_demand.index:
	if (df_demand['i'][index] > i):
		break

	dijt[df_demand['t'][index]-1][df_demand['j'][index]-1][df_demand['i'][index]-1] = round(df_demand['demand'][index]*Fr_d)

#Capacity of cold chain points
Bgt = [[round(fraction_storage*24545455) for G in range(g)] for T in range(t)]
Bst = [[round(fraction_storage*6818182) for S in range(s)] for T in range(t)]

df_brt = pd.read_csv("Input_data/capacity_RVS.csv")
Brt = [[0 for R in range(r)] for T in range(t)]
for index in df_brt.index:
	Brt[df_brt['t'][index]-1][df_brt['r'][index]-1] = fraction_storage*df_brt['Capacity'][index]

df_bdt = pd.read_csv("Input_data/capacity_DVS.csv")
Bdt = [[0 for D in range(d)] for T in range(t)]
for index in df_bdt.index:
	if(df_bdt['d'][index] > d):
		break
	Bdt[df_bdt['t'][index]-1][df_bdt['d'][index]-1] = fraction_storage*df_bdt['Capacity'][index]

df_bit = pd.read_csv("Input_data/capacity_clinics.csv")
Bit = [[0 for I in range(i)] for T in range(t)]
for index in df_bit.index:
	if(df_bit['i'][index] > i):
		break
	Bit[df_bit['t'][index]-1][df_bit['i'][index]-1] = fraction_storage*df_bit['Capacity'][index]

model = gp.Model('Vaccine_Distribution')

#Production Capacity
Bmt = [[350000 for M in range(m)] for T in range(t)]

#Average time required to administer the vaccine (minutes)
No = 5

#Number of medical personnel hours available (minutes)
Nit = [[3360 for I in range(i)] for T in range(t)]

#Hiring Cost of nurses
hc = 25000

#Firing Cost of nurses
fc = 10000

#Weekly wages of nurses
wg = 6175

################### DECISION VARIABLES ##########################

#Inventory
Igt = model.addVars(time,gmsd,vtype=GRB.INTEGER, name="Igt")
Ist = model.addVars(time,svs,vtype=GRB.INTEGER, name="Ist")
Irt = model.addVars(time,rvs,vtype=GRB.INTEGER, name="Irt")
Idt = model.addVars(time,dvs,vtype=GRB.INTEGER, name="Idt")
Iit = model.addVars(time,clinics,vtype=GRB.INTEGER, name="Iit")

#Quantity
Qgmt = model.addVars(time,manufacturers,gmsd,vtype=GRB.INTEGER, name="Qgmt")
Qsgt = model.addVars(time,gmsd,svs,vtype=GRB.INTEGER, name="Qsgt")
Qrst = model.addVars(time,svs,rvs,vtype=GRB.INTEGER, name="Qrst")
Qdrt = model.addVars(time,rvs,dvs,vtype=GRB.INTEGER, name="Qdrt")
Qidt = model.addVars(time,dvs,clinics,vtype=GRB.INTEGER, name="Qidt")

#Shortage and Consumption
Sijt = model.addVars(time,customers,clinics,vtype=GRB.INTEGER, name="Sijt")
Wijt = model.addVars(time,customers,clinics,vtype=GRB.INTEGER, name="Wijt")

#Assignment Variables
Xgmt = model.addVars(time,manufacturers,gmsd,vtype=GRB.BINARY, name="Xgmt")
Xsgt = model.addVars(time,gmsd,svs,vtype=GRB.BINARY, name="Xsgt")
Xrst = model.addVars(time,svs,rvs,vtype=GRB.BINARY, name="Xrst")
Xdrt = model.addVars(time,rvs,dvs,vtype=GRB.BINARY, name="Xdrt")
Xidt = model.addVars(time,dvs,clinics,vtype=GRB.BINARY, name="Xidt")

#Number of trucks
Ngmt = model.addVars(time,manufacturers,gmsd,vtype=GRB.INTEGER, name="Ngmt")
Nsgt = model.addVars(time,gmsd,svs,vtype=GRB.INTEGER, name="Nsgt")
Nrst = model.addVars(time,svs,rvs,vtype=GRB.INTEGER, name="Nrst")
Ndrt = model.addVars(time,rvs,dvs,vtype=GRB.INTEGER, name="Ndrt")
Nidt = model.addVars(time,dvs,clinics,vtype=GRB.INTEGER, name="Nidt")

#Nurses
N_nurses_it = model.addVars(time,clinics,vtype=GRB.INTEGER, name = "N_nurses_it")
H_nurses_it = model.addVars(time,clinics,vtype=GRB.INTEGER, name = "H_nurses_it")
F_nurses_it = model.addVars(time,clinics,vtype=GRB.INTEGER, name = "F_nurses_it")

############################# OBJECTIVE FUNCTION ###########################
transport_part = gp.quicksum(Kgmt[T-1][M-1][G-1]*Ngmt[T,M,G] for G in gmsd for M in manufacturers for T in time)
transport_part += gp.quicksum(Ksgt[T-1][G-1][S-1]*Nsgt[T,G,S] for S in svs for G in gmsd for T in time)
transport_part += gp.quicksum(Krst[T-1][S-1][R-1]*Nrst[T,S,R] for R in rvs for S in svs for T in time)
transport_part += gp.quicksum(Kdrt[T-1][R-1][D-1]*Ndrt[T,R,D] for D in dvs for R in rvs for T in time)
transport_part += gp.quicksum(Kidt[T-1][D-1][I-1]*Nidt[T,D,I] for I in clinics for D in dvs for T in time)

inventory_part = gp.quicksum(hgt[T-1][G-1]*Igt[T,G] for G in gmsd for T in time)
inventory_part += gp.quicksum(hst[T-1][S-1]*Ist[T,S] for S in svs for T in time)
inventory_part += gp.quicksum(hrt[T-1][R-1]*Irt[T,R] for R in rvs for T in time)
inventory_part += gp.quicksum(hdt[T-1][D-1]*Idt[T,D] for D in dvs for T in time)
inventory_part += gp.quicksum(hit[T-1][I-1]*Iit[T,I] for I in clinics for T in time)

shortage_part = gp.quicksum(Pjt[T-1][J-1]*Sijt[T,J,I] for J in customers for I in clinics for T in time)

consumption_part = gp.quicksum(Vj*Wijt[T,J,I] for J in customers for I in clinics for T in time) #Do we even need this?

ordering_part = gp.quicksum(Cgmt[T-1][M-1][G-1]*Xgmt[T,M,G] for G in gmsd for M in manufacturers for T in time)
ordering_part += gp.quicksum(Csgt[T-1][G-1][S-1]*Xsgt[T,G,S] for S in svs for G in gmsd for T in time)
ordering_part += gp.quicksum(Crst[T-1][S-1][R-1]*Xrst[T,S,R] for R in rvs for S in svs for T in time)
ordering_part += gp.quicksum(Cdrt[T-1][R-1][D-1]*Xdrt[T,R,D] for D in dvs for R in rvs for T in time)
ordering_part += gp.quicksum(Cidt[T-1][D-1][I-1]*Xidt[T,D,I] for I in clinics for D in dvs for T in time)

nurses_part = gp.quicksum(wg*N_nurses_it[T,I] for I in clinics for T in time)
nurses_part += gp.quicksum(hc*H_nurses_it[T,I] for I in clinics for T in time)
nurses_part += gp.quicksum(fc*F_nurses_it[T,I] for I in clinics for T in time)

model.setObjective(transport_part+inventory_part+shortage_part+consumption_part+ordering_part+nurses_part,GRB.MINIMIZE)

###################################### CONSTRAINTS ################################

#Inventory Balance
gmsd_inventory = model.addConstrs(((Igt[T-1,G] if T>1 else 0) + gp.quicksum(Qgmt[T,M,G] for M in manufacturers)
                                    - Igt[T,G] == gp.quicksum(Qsgt[T,G,S] for S in svs) for G in gmsd for T in time),
                                     name="gmsd_inventory")
svs_inventory = model.addConstrs(((Ist[T-1,S] if T>1 else 0) + gp.quicksum(Qsgt[T,G,S] for G in gmsd)
                                    - Ist[T,S] == gp.quicksum(Qrst[T,S,R] for R in rvs) for S in svs for T in time),
                                     name="svs_inventory")
rvs_inventory = model.addConstrs(((Irt[T-1,R] if T>1 else 0) + gp.quicksum(Qrst[T,S,R] for S in svs)
                                    - Irt[T,R] == gp.quicksum(Qdrt[T,R,D] for D in dvs) for R in rvs for T in time),
                                     name="rvs_inventory")
dvs_inventory = model.addConstrs(((Idt[T-1,D] if T>1 else 0) + gp.quicksum(Qdrt[T,R,D] for R in rvs)
                                    - Idt[T,D] == gp.quicksum(Qidt[T,D,I] for I in clinics) for D in dvs for T in time),
                                     name="dvs_inventory")
clinic_inventory = model.addConstrs(((Iit[T-1,I] if T>1 else 0) + gp.quicksum(Qidt[T,D,I] for D in dvs)
                                    - Iit[T,I] == gp.quicksum(Wijt[T,J,I] for J in customers) for I in clinics for T in time),
                                     name="clinic_inventory")

#Consumption by demand
consumption_demand = model.addConstrs((Wijt[T,J,I] <= dijt[T-1][J-1][I-1] for I in clinics for J in customers for T in time),
                                    name = "consumption_demand")

#Consumption Balance
consumption_balance = model.addConstrs((Wijt[T,J,I] + Sijt[T,J,I] == dijt[T-1][J-1][I-1] for I in clinics for J in customers for T in time),
                                    name = "consumption_balance")

#Inventory Capacity constraints
gmsd_cap = model.addConstrs((Igt[T,G]<=Bgt[T-1][G-1] for G in gmsd for T in time),name = "gmsd_cap")
svs_cap = model.addConstrs((Ist[T,S]<=Bst[T-1][S-1] for S in svs for T in time),name = "svs_cap")
rvs_cap = model.addConstrs((Irt[T,R]<=Brt[T-1][R-1] for R in rvs for T in time),name = "rvs_cap")
dvs_cap = model.addConstrs((Idt[T,D]<=Bdt[T-1][D-1] for D in dvs for T in time),name = "dvs_cap")
clinic_cap = model.addConstrs((Iit[T,I]<=Bit[T-1][I-1] for I in clinics for T in time),name = "clinic_cap")

#Production capacity constraints
production_cap = model.addConstrs((gp.quicksum(Qgmt[T,M,G] for G in gmsd)<= Bmt[T-1][M-1] for M in manufacturers for T in time)
                                ,name = "production_cap")

#Facility selection constraints
fac_sg = model.addConstrs((gp.quicksum(Xsgt[T,G,S] for G in gmsd)<=1 for S in svs for T in time),name = "fac_sg")
fac_rs = model.addConstrs((gp.quicksum(Xrst[T,S,R] for S in svs)<=1 for R in rvs for T in time),name = "fac_rs")
fac_dr = model.addConstrs((gp.quicksum(Xdrt[T,R,D] for R in rvs)<=1 for D in dvs for T in time),name = "fac_dr")
fac_id = model.addConstrs((gp.quicksum(Xidt[T,D,I] for D in dvs)<=1 for I in clinics for T in time),name = "fac_id")

#Constraints for consistency of q and X
cons_1 = model.addConstrs((Xgmt[T,M,G]<=l*Qgmt[T,M,G] for G in gmsd for M in manufacturers for T in time),name = "cons_1")
cons_2 = model.addConstrs((Qgmt[T,M,G]<=l*Xgmt[T,M,G] for G in gmsd for M in manufacturers for T in time),name = "cons_2")
cons_3 = model.addConstrs((Xsgt[T,G,S]<=l*Qsgt[T,G,S] for S in svs for G in gmsd for T in time),name = "cons_3")
cons_4 = model.addConstrs((Qsgt[T,G,S]<=l*Xsgt[T,G,S] for S in svs for G in gmsd for T in time),name = "cons_4")
cons_5 = model.addConstrs((Xrst[T,S,R]<=l*Qrst[T,S,R] for R in rvs for S in svs for T in time),name = "cons_5")
cons_6 = model.addConstrs((Qrst[T,S,R]<=l*Xrst[T,S,R] for R in rvs for S in svs for T in time),name = "cons_6")
cons_7 = model.addConstrs((Xdrt[T,R,D]<=l*Qdrt[T,R,D] for D in dvs for R in rvs for T in time),name = "cons_7")
cons_8 = model.addConstrs((Qdrt[T,R,D]<=l*Xdrt[T,R,D] for D in dvs for R in rvs for T in time),name = "cons_8")
cons_9 = model.addConstrs((Xidt[T,D,I]<=l*Qidt[T,D,I] for I in clinics for D in dvs for T in time),name = "cons_9")
cons_10 = model.addConstrs((Qidt[T,D,I]<=l*Xidt[T,D,I] for I in clinics for D in dvs for T in time),name = "cons_10")

#Number of trucks constraints
num_trucks_1 = model.addConstrs((Qgmt[T,M,G]/cap_veh_gm<=Ngmt[T,M,G] for G in gmsd for M in manufacturers for T in time),name = "num_trucks_1")
num_trucks_2 = model.addConstrs((Ngmt[T,M,G]-Qgmt[T,M,G]/cap_veh_gm<=((cap_veh_gm-1)/cap_veh_gm) for G in gmsd for M in manufacturers for T in time),name = "num_trucks_2")
num_trucks_3 = model.addConstrs((Qsgt[T,G,S]/cap_veh_sg<=Nsgt[T,G,S] for S in svs for G in gmsd for T in time),name = "num_trucks_3")
num_trucks_4 = model.addConstrs((Nsgt[T,G,S]-Qsgt[T,G,S]/cap_veh_sg<=((cap_veh_sg-1)/cap_veh_sg) for S in svs for G in gmsd for T in time),name = "num_trucks_4")
num_trucks_5 = model.addConstrs((Qrst[T,S,R]/cap_veh_rs<=Nrst[T,S,R] for R in rvs for S in svs for T in time),name = "num_trucks_5")
num_trucks_6 = model.addConstrs((Nrst[T,S,R]-Qrst[T,S,R]/cap_veh_rs<=((cap_veh_rs-1)/cap_veh_rs) for R in rvs for S in svs for T in time),name = "num_trucks_6")
num_trucks_7 = model.addConstrs((Qdrt[T,R,D]/cap_veh_dr<=Ndrt[T,R,D] for D in dvs for R in rvs for T in time),name = "num_trucks_7")
num_trucks_8 = model.addConstrs((Ndrt[T,R,D]-Qdrt[T,R,D]/cap_veh_dr<=((cap_veh_dr-1)/cap_veh_dr) for D in dvs for R in rvs for T in time),name = "num_trucks_8")
num_trucks_9 = model.addConstrs((Qidt[T,D,I]/cap_veh_id<=Nidt[T,D,I] for I in clinics for D in dvs for T in time),name = "num_trucks_9")
num_trucks_10 = model.addConstrs((Nidt[T,D,I]-Qidt[T,D,I]/cap_veh_id<=((cap_veh_id-1)/cap_veh_id) for I in clinics for D in dvs for T in time),name = "num_trucks_10")

#Medical personnel availability constraints
med_constraint = model.addConstrs((gp.quicksum(No*Wijt[T,J,I] for J in customers)<=Nit[T-1][I-1]*N_nurses_it[T,I] for I in clinics for T in time),name = "med_constraint")

#Nurses Balance Constraint
nurses_constraint = model.addConstrs((N_nurses_it[T,I] == (N_nurses_it[T-1,I] if T>1 else 0)+ H_nurses_it[T,I] - F_nurses_it[T,I] for I in clinics for T in time),name = "nurses_constraint")

#################################Solving the problem##########################
model.optimize()

names = []
sol = []
for v in model.getVars():
    #print(v.varName,"=", v.x)
    names.append(v.varName)
    sol.append(v.x)
print("Done")

# ###########################Code for full excel sheet results generation##########################
workbook = xlsxwriter.Workbook('fraction-0.25.xlsx')
worksheet = workbook.add_worksheet()
merge_format = workbook.add_format({
    'bold': 1,
    'border': 1,
    'align': 'center',
    'valign': 'vcenter'})

worksheet.merge_range('A1:B1', 'Inventory', merge_format)
worksheet.merge_range('C1:D1', 'Consumption', merge_format)
worksheet.merge_range('E1:F1', 'Shortage', merge_format)
worksheet.merge_range('G1:H1', 'Delivery from M to G', merge_format)
worksheet.merge_range('I1:J1', 'X from M to G', merge_format)
worksheet.merge_range('K1:L1', 'No of Trucks from M to G', merge_format)
worksheet.merge_range('M1:N1', 'Distance from M to G', merge_format)
worksheet.merge_range('O1:P1', 'Delivery from G to S', merge_format)
worksheet.merge_range('Q1:R1', 'X from G to S', merge_format)
worksheet.merge_range('S1:T1', 'No of Trucks from G to S', merge_format)
worksheet.merge_range('U1:V1', 'Distance from G to S', merge_format)
worksheet.merge_range('W1:X1', 'Delivery from S to R', merge_format)
worksheet.merge_range('Y1:Z1', 'X from S to R', merge_format)
worksheet.merge_range('AA1:AB1', 'No of Trucks from S to R', merge_format)
worksheet.merge_range('AC1:AD1', 'Distance from S to R', merge_format)
worksheet.merge_range('AE1:AF1', 'Delivery from R to D', merge_format)
worksheet.merge_range('AG1:AH1', 'X from R to D', merge_format)
worksheet.merge_range('AI1:AJ1', 'No of Trucks from R to D', merge_format)
worksheet.merge_range('AK1:AL1', 'Distance from R to D', merge_format)
worksheet.merge_range('AM1:AN1', 'Delivery from D to I', merge_format)
worksheet.merge_range('AO1:AP1', 'X from D to I', merge_format)
worksheet.merge_range('AQ1:AR1', 'No of Trucks from D to I', merge_format)
worksheet.merge_range('AS1:AT1', 'Distance from D to I', merge_format)

#Inventory
row = 1
for T in time:
    for G in gmsd:
        worksheet.write(row,0,Igt[T,G].varName)
        worksheet.write(row,1,round(Igt[T,G].x))
        row += 1

for T in time:
    for S in svs:
        worksheet.write(row,0,Ist[T,S].varName)
        worksheet.write(row,1,round(Ist[T,S].x))
        row += 1

for T in time:
    for R in rvs:
        worksheet.write(row,0,Irt[T,R].varName)
        worksheet.write(row,1,round(Irt[T,R].x))
        row += 1

for T in time:
    for D in dvs:
        worksheet.write(row,0,Idt[T,D].varName)
        worksheet.write(row,1,round(Idt[T,D].x))
        row += 1

for T in time:
    for I in clinics:
        worksheet.write(row,0,Iit[T,I].varName)
        worksheet.write(row,1,round(Iit[T,I].x))
        row += 1

#Qgmt, Xgmt, Ngmt
row = 1
for T in time:
    for M in manufacturers:
        for G in gmsd:
            worksheet.write(row,6,Qgmt[T,M,G].varName)
            worksheet.write(row,7,round(Qgmt[T,M,G].x))
            worksheet.write(row,8,Xgmt[T,M,G].varName)
            worksheet.write(row,9,round(Xgmt[T,M,G].x))
            worksheet.write(row,10,Ngmt[T,M,G].varName)
            worksheet.write(row,11,round(Ngmt[T,M,G].x))
            row += 1
#Dgm
row = 1
for M in manufacturers:
    for G in gmsd:
        variable = "Dgm["+str(M)+","+str(G)+"]"
        worksheet.write(row,12,variable)
        worksheet.write(row,13,Dgm[M-1][G-1])
        row += 1

#Qsgt,Xsgt,Nsgt
row = 1
for T in time:
    for G in gmsd:
        for S in svs:
            worksheet.write(row,14,Qsgt[T,G,S].varName)
            worksheet.write(row,15,round(Qsgt[T,G,S].x))
            worksheet.write(row,16,Xsgt[T,G,S].varName)
            worksheet.write(row,17,round(Xsgt[T,G,S].x))
            worksheet.write(row,18,Nsgt[T,G,S].varName)
            worksheet.write(row,19,round(Nsgt[T,G,S].x))
            row += 1
#Dsg
row = 1
for G in gmsd:
    for S in svs:
        variable = "Dsg["+str(G)+","+str(S)+"]"
        worksheet.write(row,20,variable)
        worksheet.write(row,21,Dsg[G-1][S-1])
        row += 1

#Qrst,Xrst,Nrst
row = 1
for T in time:
    for S in svs:
        for R in rvs:
            worksheet.write(row,22,Qrst[T,S,R].varName)
            worksheet.write(row,23,round(Qrst[T,S,R].x))
            worksheet.write(row,24,Xrst[T,S,R].varName)
            worksheet.write(row,25,round(Xrst[T,S,R].x))
            worksheet.write(row,26,Nrst[T,S,R].varName)
            worksheet.write(row,27,round(Nrst[T,S,R].x))
            row += 1
#Drs
row = 1
for S in svs:
    for R in rvs:
        variable = "Drs["+str(S)+","+str(R)+"]"
        worksheet.write(row,28,variable)
        worksheet.write(row,29,Drs[S-1][R-1])
        row += 1

#Qdrt,Xdrt,Ndrt
row = 1
for T in time:
    for R in rvs:
        for D in dvs:
            worksheet.write(row,30,Qdrt[T,R,D].varName)
            worksheet.write(row,31,round(Qdrt[T,R,D].x))
            worksheet.write(row,32,Xdrt[T,R,D].varName)
            worksheet.write(row,33,round(Xdrt[T,R,D].x))
            worksheet.write(row,34,Ndrt[T,R,D].varName)
            worksheet.write(row,35,round(Ndrt[T,R,D].x))
            row += 1
#Ddr
row = 1
for R in rvs:
    for D in dvs:
        variable = "Ddr["+str(R)+","+str(D)+"]"
        worksheet.write(row,36,variable)
        worksheet.write(row,37,Ddr[R-1][D-1])
        row += 1

#Qidt,Xidt,Nidt
row = 1
for T in time:
    for D in dvs:
        for I in clinics:
            worksheet.write(row,38,Qidt[T,D,I].varName)
            worksheet.write(row,39,round(Qidt[T,D,I].x))
            worksheet.write(row,40,Xidt[T,D,I].varName)
            worksheet.write(row,41,round(Xidt[T,D,I].x))
            worksheet.write(row,42,Nidt[T,D,I].varName)
            worksheet.write(row,43,round(Nidt[T,D,I].x))
            row += 1
#Did
row = 1
for D in dvs:
    for I in clinics:
        variable = "Did["+str(D)+","+str(I)+"]"
        worksheet.write(row,44,variable)
        worksheet.write(row,45,Did[D-1][I-1])
        row += 1

#Shortage
row = 1
for T in time:
    for J in customers:
        for I in clinics:
            worksheet.write(row,4,Sijt[T,J,I].varName)
            worksheet.write(row,5,round(Sijt[T,J,I].x))
            row += 1

#Consumption
row = 1
for T in time:
    for J in customers:
        for I in clinics:
            worksheet.write(row,2,Wijt[T,J,I].varName)
            worksheet.write(row,3,round(Wijt[T,J,I].x))
            row += 1

workbook.close()

###########################Code for generating CSV files for graphical analysis##################

import pandas as pd
start = (g+s+r+d+i)*t
T = 1
for T in range(1,13):
    x = start + (T-1)*m*g
    address = "Excel files/"
    address += str(T)
    address += "-M to G"
    address += ".xlsx"
    #print(address)

    #M to G
    workbook = xlsxwriter.Workbook(address)
    worksheet = workbook.add_worksheet("M to G")
    row = 0
    count = 0
    for M in range(m):
        for G in range(g):
            if (round(sol[x+count]) != 0):
                worksheet.write(row,0,M+1)
                worksheet.write(row,1,G+1)
                worksheet.write(row,2,sol[x+count])
                count += 1
                row += 1
            else:
                count += 1
    #print("M to G done")
    workbook.close()
    read_file = pd.read_excel (address)
    csv_address ="CSV files/"
    csv_address += str(T)
    csv_address += "-M to G"
    csv_address += ".csv"
    read_file.to_csv (csv_address, index = None, header=True)

    #G to S
    x = x + (t-T+1)*m*g +(T-1)*s*g
    address = "Excel files/"
    address += str(T)
    address += "-G to S"
    address += ".xlsx"
    #print(address)
    workbook = xlsxwriter.Workbook(address)
    worksheet = workbook.add_worksheet("G to S")
    row = 0
    count = 0
    for G in range(g):
        for S in range(s):
            if (round(sol[x+count]) != 0):
                worksheet.write(row,0,G+1)
                worksheet.write(row,1,S+1)
                worksheet.write(row,2,sol[x+count])
                row += 1
                count += 1
            else:
                count += 1
    #print("G to S done")
    workbook.close()
    read_file = pd.read_excel (address)
    csv_address ="CSV files/"
    csv_address += str(T)
    csv_address += "-G to S"
    csv_address += ".csv"
    read_file.to_csv (csv_address, index = None, header=True)

    #S to R
    x = x + (t-T+1)*g*s + (T-1)*r*s
    address = "Excel files/"
    address += str(T)
    address += "-S to R"
    address += ".xlsx"
    #print(address)
    workbook = xlsxwriter.Workbook(address)
    worksheet = workbook.add_worksheet("S to R")
    row = 0
    count = 0
    for S in range(s):
        for R in range(r):
            if (round(sol[x+count]) != 0):
                worksheet.write(row,0,S+1)
                worksheet.write(row,1,R+1)
                worksheet.write(row,2,sol[x+count])
                row += 1
                count += 1
            else:
                count += 1
    #print("S to R done")
    workbook.close()
    read_file = pd.read_excel (address)
    csv_address ="CSV files/"
    csv_address += str(T)
    csv_address += "-S to R"
    csv_address += ".csv"
    read_file.to_csv (csv_address, index = None, header=True)

    #R to D
    x = x + (t-T+1)*s*r + (T-1)*r*d
    address = "Excel files/"
    address += str(T)
    address += "-R to D"
    address += ".xlsx"
    #print(address)
    workbook = xlsxwriter.Workbook(address)
    worksheet = workbook.add_worksheet("R to D")
    row = 0
    count = 0
    for R in range(r):
        for D in range(d):
            if (round(sol[x+count]) != 0):
                worksheet.write(row,0,R+1)
                worksheet.write(row,1,D+1)
                worksheet.write(row,2,sol[x+count])
                row += 1
                count += 1
            else:
                count += 1
    #print("R to D done")
    workbook.close()
    read_file = pd.read_excel (address)
    csv_address ="CSV files/"
    csv_address += str(T)
    csv_address += "-R to D"
    csv_address += ".csv"
    read_file.to_csv (csv_address, index = None, header=True)

    #D to I
    x = x + (t-T+1)*r*d + (T-1)*d*i
    address = "Excel files/"
    address += str(T)
    address += "-D to I"
    address += ".xlsx"
    #print(address)
    workbook = xlsxwriter.Workbook(address)
    worksheet = workbook.add_worksheet("D to I")
    row = 0
    count = 0
    for D in range(d):
        for I in range(i):
            if (round(sol[x+count]) != 0):
                worksheet.write(row,0,D+1)
                worksheet.write(row,1,I+1)
                worksheet.write(row,2,sol[x+count])
                row += 1
                count += 1
            else:
                count += 1
    #print("D to I done")
    workbook.close()
    read_file = pd.read_excel (address)
    csv_address ="CSV files/"
    csv_address += str(T)
    csv_address += "-D to I"
    csv_address += ".csv"
    read_file.to_csv (csv_address, index = None, header=True)

############################################ Summary #####################################################

############## transport part ###############
no_of_times_M = ""
cost_M = ""
total_cost_M = 0
for M in manufacturers:
    number = 0
    cost = 0
    for G in gmsd:
        for T in time:
            number =  number + Xgmt[T,M,G].x
            cost = cost + Kgmt[T-1][M-1][G-1]*Ngmt[T,M,G].x
    cost = round(cost)
    if(number!=0):
        if(no_of_times_M==""):
            no_of_times_M += (str(M)+"("+str(number)+" times"+")")
            cost_M += (str(M)+"("+str(cost)+" Rs"+")")
        else:
            no_of_times_M += (", "+str(M)+"("+str(number)+" times"+")")
            cost_M += (", "+str(M)+"("+str(cost)+" Rs"+")")
        total_cost_M += cost

no_of_times_G = ""
cost_G = ""
total_cost_G = 0
for G in gmsd:
    number = 0
    cost = 0
    for S in svs:
        for T in time:
            number =  number + Xsgt[T,G,S].x
            cost = cost + Ksgt[T-1][G-1][S-1]*Nsgt[T,G,S].x
    cost = round(cost)
    if(number!=0):
        if(no_of_times_G==""):
            no_of_times_G += (str(G)+"("+str(number)+" times"+")")
            cost_G += (str(G)+"("+str(cost)+" Rs"+")")
        else:
            no_of_times_G += (", "+str(G)+"("+str(number)+" times"+")")
            cost_G += (", "+str(G)+"("+str(cost)+" Rs"+")")
        total_cost_G += cost

no_of_times_S = ""
cost_S = ""
total_cost_S = 0
for S in svs:
    number = 0
    cost = 0
    for R in rvs:
        for T in time:
            number =  number + Xrst[T,S,R].x
            cost = cost + Krst[T-1][S-1][R-1]*Nrst[T,S,R].x
    cost = round(cost)
    if(number!=0):
        if(no_of_times_S==""):
            no_of_times_S += (str(S)+"("+str(number)+" times"+")")
            cost_S += (str(S)+"("+str(cost)+" Rs"+")")
        else:
            no_of_times_S += (", "+str(S)+"("+str(number)+" times"+")")
            cost_S += (", "+str(S)+"("+str(cost)+" Rs"+")")
        total_cost_S += cost

no_of_times_R = ""
cost_R = ""
total_cost_R = 0
for R in rvs:
    number = 0
    cost = 0
    for D in dvs:
        for T in time:
            number =  number + Xdrt[T,R,D].x
            cost = cost + Kdrt[T-1][R-1][D-1]*Ndrt[T,R,D].x
    cost = round(cost)
    if(number!=0):
        if(no_of_times_R==""):
            no_of_times_R += (str(R)+"("+str(number)+" times"+")")
            cost_R += (str(R)+"("+str(cost)+" Rs"+")")
        else:
            no_of_times_R += (", "+str(R)+"("+str(number)+" times"+")")
            cost_R += (", "+str(R)+"("+str(cost)+" Rs"+")")
        total_cost_R += cost

no_of_times_D = ""
cost_D = ""
total_cost_D = 0
for D in dvs:
    number = 0
    cost = 0
    for I in clinics:
        for T in time:
            number =  number + Xidt[T,D,I].x
            cost = cost + Kidt[T-1][D-1][I-1]*Nidt[T,D,I].x
    cost = round(cost)
    if(number!=0):
        if(no_of_times_D==""):
            no_of_times_D += (str(D)+"("+str(number)+" times"+")")
            cost_D += (str(D)+"("+str(cost)+" Rs"+")")
        else:
            no_of_times_D += (", "+str(D)+"("+str(number)+" times"+")")
            cost_D += (", "+str(D)+"("+str(cost)+" Rs"+")")
        total_cost_D += cost

transport_summary = {
    "From":["M->G","G->S","S->R","R->D","D->I"],
    "Number of times transport occurs over the entire planning horizon":[no_of_times_M,no_of_times_G,no_of_times_S,no_of_times_R,no_of_times_D],
    "Cost Incurred":[cost_M,cost_G,cost_S,cost_R,cost_D],
    "Total Cost":[total_cost_M,total_cost_G,total_cost_S,total_cost_R,total_cost_D]
}

################ ordering part ##############

average_quantity_M = ""
cost_M = ""
total_cost_M = 0
for M in manufacturers:
    number = 0
    cost = 0
    quantity = 0
    for G in gmsd:
        for T in time:
            number =  number + Xgmt[T,M,G].x
            cost = cost + Cgmt[T-1][M-1][G-1]*Xgmt[T,M,G].x
            quantity = quantity + Qgmt[T,M,G].x
    cost = round(cost)
    if(number!=0):
        average_quantity = quantity/number
        if(average_quantity_M==""):
            average_quantity_M += (str(M)+"("+str(round(average_quantity))+" units"+")")
            cost_M += (str(M)+"("+str(cost)+" Rs"+")")
        else:
            average_quantity_M += (", "+str(M)+"("+str(round(average_quantity))+" units"+")")
            cost_M += (", "+str(M)+"("+str(cost)+" Rs"+")")
        total_cost_M += cost

average_quantity_G = ""
cost_G = ""
total_cost_G = 0
for G in gmsd:
    number = 0
    cost = 0
    quantity = 0
    for S in svs:
        for T in time:
            number =  number + Xsgt[T,G,S].x
            cost = cost + Csgt[T-1][G-1][S-1]*Xsgt[T,G,S].x
            quantity = quantity + Qsgt[T,G,S].x
    cost = round(cost)
    if(number!=0):
        average_quantity = quantity/number
        if(average_quantity_G==""):
            average_quantity_G += (str(G)+"("+str(round(average_quantity))+" units"+")")
            cost_G += (str(G)+"("+str(cost)+" Rs"+")")
        else:
            average_quantity_G += (", "+str(G)+"("+str(round(average_quantity))+" units"+")")
            cost_G += (", "+str(G)+"("+str(cost)+" Rs"+")")
        total_cost_G += cost

average_quantity_S = ""
cost_S = ""
total_cost_S = 0
for S in svs:
    number = 0
    cost = 0
    quantity = 0
    for R in rvs:
        for T in time:
            number =  number + Xrst[T,S,R].x
            cost = cost + Crst[T-1][S-1][R-1]*Xrst[T,S,R].x
            quantity = quantity + Qrst[T,S,R].x
    cost = round(cost)
    if(number!=0):
        average_quantity = quantity/number
        if(average_quantity_S==""):
            average_quantity_S += (str(S)+"("+str(round(average_quantity))+" units"+")")
            cost_S += (str(S)+"("+str(cost)+" Rs"+")")
        else:
            average_quantity_S += (", "+str(S)+"("+str(round(average_quantity))+" units"+")")
            cost_S += (", "+str(S)+"("+str(cost)+" Rs"+")")
        total_cost_S += cost

average_quantity_R = ""
cost_R = ""
total_cost_R = 0
for R in rvs:
    number = 0
    cost = 0
    quantity = 0
    for D in dvs:
        for T in time:
            number =  number + Xdrt[T,R,D].x
            cost = cost + Cdrt[T-1][R-1][D-1]*Xdrt[T,R,D].x
            quantity = quantity + Qdrt[T,R,D].x
    cost = round(cost)
    if(number!=0):
        average_quantity = quantity/number
        if(average_quantity_R==""):
            average_quantity_R += (str(R)+"("+str(round(average_quantity))+" units"+")")
            cost_R += (str(R)+"("+str(cost)+" Rs"+")")
        else:
            average_quantity_R += (", "+str(R)+"("+str(round((average_quantity)))+" units"+")")
            cost_R += (", "+str(R)+"("+str(cost)+" Rs"+")")
        total_cost_R += cost

average_quantity_D = ""
cost_D = ""
total_cost_D = 0
for D in dvs:
    number = 0
    cost = 0
    quantity = 0
    for I in clinics:
        for T in time:
            number =  number + Xidt[T,D,I].x
            cost = cost + Cidt[T-1][D-1][I-1]*Xidt[T,D,I].x
            quantity = quantity + Qidt[T,D,I].x
    cost = round(cost)
    if(number!=0):
        average_quantity = quantity/number
        if(average_quantity_D==""):
            average_quantity_D += (str(D)+"("+str(round(average_quantity))+" units"+")")
            cost_D += (str(D)+"("+str(cost)+" Rs"+")")
        else:
            average_quantity_D += (", "+str(D)+"("+str(round(average_quantity))+" units"+")")
            cost_D += (", "+str(D)+"("+str(cost)+" Rs"+")")
        total_cost_D += cost

ordering_summary = {
    "From":["M->G","G->S","S->R","R->D","D->I"],
    "Average quantities ordered over the entire planning horizon":[average_quantity_M,average_quantity_G,average_quantity_S,average_quantity_R,average_quantity_D],
    "Cost Incurred":[cost_M,cost_G,cost_S,cost_R,cost_D],
    "Total Cost":[total_cost_M,total_cost_G,total_cost_S,total_cost_R,total_cost_D]
}

################ inventory part #############

no_of_times_G = ""
avg_inv_G = ""
cost_G = ""
total_cost_G = 0
for G in gmsd:
    number = 0
    cost = 0
    total_inventory_G = 0
    for T in time:
        if(Igt[T,G].x>0):
            number += 1
            total_inventory_G += Igt[T,G].x
            cost += hgt[T-1][G-1]*Igt[T,G].x
    cost = round(cost)
    if(number!=0):
        if(no_of_times_G==""):
            no_of_times_G += (str(G)+"("+str(number)+" times"+")")
            cost_G += (str(G)+"("+str(cost)+" Rs"+")")
            avg_inv_G += (str(G)+"("+str(total_inventory_G/number)+" units"+")")

        else:
            no_of_times_G += (", "+str(G)+"("+str(number)+" times"+")")
            cost_G += (", "+str(G)+"("+str(cost)+" Rs"+")")
            if(number!=0):
                avg_inv_G += (", "+str(G)+"("+str(total_inventory_G/number)+" units"+")")
            else:
                avg_inv_G += (", "+str(G)+"("+str(0)+" units"+")")
    total_cost_G += cost

no_of_times_S = ""
avg_inv_S = ""
cost_S = ""
total_cost_S = 0
for S in svs:
    number = 0
    cost = 0
    total_inventory_S = 0
    for T in time:
        if(Ist[T,S].x>0):
            number += 1
            total_inventory_S += Ist[T,S].x
            cost += hst[T-1][S-1]*Ist[T,S].x
    cost = round(cost)
    if(number!=0):
        if(no_of_times_S==""):
            no_of_times_S += (str(S)+"("+str(number)+" times"+")")
            cost_S += (str(S)+"("+str(cost)+" Rs"+")")
            avg_inv_S += (str(S)+"("+str(total_inventory_S/number)+" units"+")")

        else:
            no_of_times_S += (", "+str(S)+"("+str(number)+" times"+")")
            cost_S += (", "+str(S)+"("+str(cost)+" Rs"+")")
            if(number!=0):
                avg_inv_S += (", "+str(S)+"("+str(total_inventory_S/number)+" units"+")")
            else:
                avg_inv_S += (", "+str(S)+"("+str(0)+" units"+")")
    total_cost_S += cost

no_of_times_R = ""
avg_inv_R = ""
cost_R = ""
total_cost_R = 0
for R in rvs:
    number = 0
    cost = 0
    total_inventory_R = 0
    for T in time:
        if(Irt[T,R].x>0):
            number += 1
            total_inventory_R += Irt[T,R].x
            cost += hrt[T-1][R-1]*Irt[T,R].x
    cost = round(cost)
    if(number!=0):
        if(no_of_times_R==""):
            no_of_times_R += (str(R)+"("+str(number)+" times"+")")
            cost_R += (str(R)+"("+str(cost)+" Rs"+")")
            if(number!=0):
                avg_inv_R += (str(R)+"("+str(total_inventory_R/number)+" units"+")")
            else:
                avg_inv_R += (str(R)+"("+str(0)+" units"+")")
        else:
            no_of_times_R += (", "+str(R)+"("+str(number)+" times"+")")
            cost_R += (", "+str(R)+"("+str(cost)+" Rs"+")")
            if(number!=0):
                avg_inv_R += (", "+str(R)+"("+str(total_inventory_R/number)+" units"+")")
            else:
                avg_inv_R += (", "+str(R)+"("+str(0)+" units"+")")
    total_cost_R += cost

no_of_times_D = ""
avg_inv_D = ""
cost_D = ""
total_cost_D = 0
for D in dvs:
    number = 0
    cost = 0
    total_inventory_D = 0
    for T in time:
        if(Idt[T,D].x>0):
            number += 1
            total_inventory_D += Idt[T,D].x
            cost += hdt[T-1][D-1]*Idt[T,D].x
    cost = round(cost)
    if(number!=0):
        if(no_of_times_D==""):
                no_of_times_D += (str(D)+"("+str(number)+" times"+")")
                cost_D += (str(D)+"("+str(cost)+" Rs"+")")
                if(number!=0):
                    avg_inv_D += (str(D)+"("+str(total_inventory_D/number)+" units"+")")
                else:
                    avg_inv_D += (str(D)+"("+str(0)+" units"+")")
        else:
            no_of_times_D += (", "+str(D)+"("+str(number)+" times"+")")
            cost_D += (", "+str(D)+"("+str(cost)+" Rs"+")")
            if(number!=0):
                avg_inv_D += (", "+str(D)+"("+str(total_inventory_D/number)+" units"+")")
            else:
                avg_inv_D += (", "+str(D)+"("+str(0)+" units"+")")
    total_cost_D += cost

I_s = 1
total_cost_I = 0
no_of_times_I = ""
D = 1
cost_I = ""
avg_inv_I = ""
for I_b in clinic_breakpoints:
    number_average_district = 0
    avg_inv_avg_district = 0
    cost_avg_district = 0
    for I in range(I_s,I_b+1):
        number = 0
        cost = 0
        total_inventory_I = 0
        for T in time:
            if(Iit[T,I].x>0):
                number += 1
                total_inventory_I += Iit[T,I].x
                cost += hit[T-1][I-1]*Iit[T,I].x
        number_average_district += number
        if(number!=0):
            avg_inv_avg_district += total_inventory_I/number
        else:
            avg_inv_avg_district += 0
        cost_avg_district += cost
        total_cost_I += cost

    number_average_district /= (I_b-I_s+1)
    number_average_district = round(number_average_district)

    avg_inv_avg_district /= (I_b-I_s+1)
    avg_inv_avg_district = round(avg_inv_avg_district)

    cost_avg_district /= (I_b-I_s+1)

    if(no_of_times_I==""):
            no_of_times_I += (str(D)+"("+str(number_average_district)+" times"+")")
            cost_I += (str(D)+"("+str(round(cost_avg_district))+" Rs"+")")
            avg_inv_I += (str(D)+"("+str(round(avg_inv_avg_district))+" units"+")")
    else:
        no_of_times_I += (", "+str(D)+"("+str(number_average_district)+" times"+")")
        cost_I += (", "+str(D)+"("+str(round(cost_avg_district))+" Rs"+")")
        avg_inv_I += (", "+str(D)+"("+str(round(avg_inv_avg_district))+" units"+")")

    D = D+1
    I_s = I_b+1

inventory_summary = {
    "CCP": ["G","S","R","D","I"],
    "Number of times Inventory is non zero":[no_of_times_G,no_of_times_S,no_of_times_R,no_of_times_D,no_of_times_I],
    "Average Inventory carried":[avg_inv_G,avg_inv_S,avg_inv_R,avg_inv_D,avg_inv_I],
    "Cost Incurred":[cost_G,cost_S,cost_R,cost_D,cost_I],
    "Total Cost":[total_cost_G,total_cost_S,total_cost_R,total_cost_D,total_cost_I]
}

########################### Shortages summary ##############################

I_s = 1
num1 = 0
costs_list = []
average_costs_list = []
number_of_clinics = []
count = 0
clinic_num = []
for num in clinic_breakpoints:
	cost = 0
	avg_cost = 0
	num_clinics = num - num1
	count += 1
	for x in range(num_clinics):
		I = I_s + x
		for J in customers:
			for T in time:
				if(Sijt[T,J,I].x!=0):
					cost += Pjt[T-1][J-1]*Sijt[T,J,I].x
	avg_cost = cost/num_clinics
	I_s += num_clinics
	num1 = num
	costs_list.append(cost)
	average_costs_list.append(avg_cost)
	number_of_clinics.append(num_clinics)
	clinic_num.append(count)

shortage_summary = {
    "District Number": clinic_num,
    "Number of clinics": number_of_clinics,
    "Total shortage cost Incurred": costs_list,
    "Average shortage cost incurred per clinic":average_costs_list
}

transport_df = pd.DataFrame.from_dict(transport_summary)
inventory_df = pd.DataFrame.from_dict(inventory_summary)
ordering_df = pd.DataFrame.from_dict(ordering_summary)
shortage_df = pd.DataFrame.from_dict(shortage_summary)

# transport_df.to_excel("transport.xlsx")
# inventory_df.to_excel("inventory.xlsx")
# ordering_df.to_excel("ordering.xlsx")
# shortage_df.to_excel("shortage.xlsx")

###########################################Compiled Results##################################################
writer = pd.ExcelWriter('compiled.xlsx',engine='xlsxwriter')
workbook=writer.book
worksheet=workbook.add_worksheet('Compiled')
writer.sheets['Compiled'] = worksheet
worksheet.write(0,0,"Transport part")
transport_df.to_excel(writer,sheet_name='Compiled',startrow=2 , startcol=0)

x = 4 + len(transport_df.index)
worksheet.write(x,0,"Inventory part")
x += 2
inventory_df.to_excel(writer,sheet_name='Compiled',startrow=x , startcol=0)

x += 4 + len(inventory_df.index)
worksheet.write(x,0,"Ordering part")
x += 2
ordering_df.to_excel(writer,sheet_name='Compiled',startrow=x , startcol=0)

x += 4 + len(ordering_df.index)
worksheet.write(x,0,"Shortage part")
x += 2
shortage_df.to_excel(writer,sheet_name='Compiled',startrow=x , startcol=0)
workbook.close()

################################################# The End #########################################################


import matplotlib.pyplot as plt
import numpy as np
import random
import timeit

def generator_1(n):  # generator №1  for numpy
    numb_np = np.random.uniform(0, 1, n)
    return numb_np

def generator_2(n):  # generator №2  for random
    numb_rand = []
    for x in range(n):
        numb_rand.append(random.randint(0, 1))
    return numb_rand

data_1 = []
data_2 = []
for i in range(10):  # I set 10 because my computer "thinks" for a very long time
    data_1.append(timeit.timeit("generator_1(i)", "from __main__ import generator_1, i"))
    data_2.append(timeit.timeit("generator_2(i)", "from __main__ import generator_2, i"))

x = range(10)
plt.title('Comparison')
plt.xlabel('how many numbers')
plt.ylabel('time')
plt.grid(True)
plt.plot(x, data_1)
plt.plot(x, data_2)
plt.legend(['numpy ', 'random'], loc='upper left')
plt.show()


"""
Modeled after unix command line.

>>> z = ZipWrap("foo.zip")

Can touch files (preceeding / is optional root is either "" or "/")

>>> z.touch("/bar", "hello world\\nstuff")

Can ``cat`` files

>>> z.cat("bar")
'hello world\\nstuff'

Can ``mkdir``

>>> z.mkdir("foo/bar/baz/biz")

Can ``cat`` root directory
>>> z.cat("/")
['foo', 'bar']

>>> z.touch("foo/bar/baz/junk", "stuff")
>>> z.cat("foo/bar/baz")
['junk', 'biz']
>>> z.cat("foo/bar/baz/junk")
'stuff'
>>> z.touch("empty")
>>> z.cat("empty")
''

Can ``rm``

>>> z.rm("bar")
>>> z.cat("bar")

Can ``save``

>>> z.zipit("test/foo.zip")

Can open existing ZIP files

>>> z2 = ZipWrap("test/foo.zip")
>>> z2.cat("foo/bar/baz/junk")
'stuff'

>>> os.remove("test/foo.zip")

Can open existing directories

>>> z3 = ZipWrap("test")
>>> z3.cat("/") # root dir
['testzipwrap.py']
>>> z3.cat("/") # root dir

Note that implementation actually uses a temp directory and puts
everything there.  It's cleaned up upon garbage collection.

"""
import zipfile
import tempfile
import os
import shutil

__version__ = "0.1"
__author__ = "matt harrison"
__email__ = "matthewharrison@gmail.com"
__license__ = "psf"

class ZipWrap(object):
    def __init__(self, path):
        """
        Path can be an existing filename, or just a filename.
        """
        self.path = path
        self.src_dir = tempfile.mkdtemp()

        self.cleanup = True
        if os.path.exists(self.path):
            self._read_existing()

    def __del__(self):
        if self.cleanup:
            shutil.rmtree(self.src_dir)

    def load_zipfile(self, path):
        """
        import contents of a zipfile
        """
        #try to add as zipfile
        zin = zipfile.ZipFile(path)
        for zinfo in zin.infolist():
            name = zinfo.filename
            if name.endswith("/"):
                self.mkdir(name)
            else:
                content = zin.read(name)
                self.touch(name, content)

    def load_dir(self, path):
        """
        import contents of a directory
        """
        def visit_path(arg, dirname, names):
            for name in names:
                fpath = os.path.join(dirname, name)
                new_path = fpath[len(path):]
                if os.path.isfile(fpath):
                    content = open(fpath).read()
                    self.touch(new_path, content)
                else:
                    self.mkdir(new_path)
        os.path.walk(path, visit_path, None)

    def _read_existing(self):
        if os.path.isfile(self.path):
            #try to add as zipfile
            self.load_zipfile(self.path)
        elif os.path.isdir(self.path):
            self.load_dir(self.path)

    def cat(self, path):
        path = self._clean_path(path)
        path = os.path.join(self.src_dir, path)
        if os.path.exists(path):
            if os.path.isfile(path):
                return open(path).read()
            elif os.path.isdir(path):
                return os.listdir(path)
        else:
            raise IOError("no such file or dir %s" % path)

    def touch(self, path, contents=None):
        # make parent dirs first
        self.mkdir(os.path.dirname(path))
        path = self._clean_path(path)
        path = os.path.join(self.src_dir, path)
        fout = open(path, 'w')
        if contents:
            fout.write(contents)

    def _clean_path(self, path):
        """os.path.join acts wierd if second item starts with /"""
        if path.startswith("/"):
            path = path[1:]
        return path

    def mkdir(self, path):
        path = self._clean_path(path)
        full_path = os.path.join(self.src_dir, path)
        if not os.path.exists(full_path):
            os.makedirs(full_path)

    def rm(self, path):
        path = self._clean_path(path)
        path = os.path.join(self.src_dir, path)
        if os.path.exists(path):
            if os.path.isfile(path):
                os.remove(path)
            elif os.path.isdir(path):
                shutil.rmtree(path)

    def _rel_path(self, path, basepath=None):
        """
        trim off basepath
        """
        basepath = basepath or self.src_dir
        return path[len(basepath)+1:]

    def unzip(self, directory):
        """
        Write contents of zipfile to directory
        """
        if not os.path.exists(directory):
            os.makedirs(directory)
        shutil.copytree(self.src_dir, directory)

    def zipit(self, save_as=None):
        name = save_as or self.path
        zout = zipfile.ZipFile(name, 'w')

        dirs_n_files = dict(dirs=[], files=[])
        def visit_path(dnf, dirname, names):
            for name in names:
                path = os.path.join(dirname, name)

                if os.path.isfile(path):
                    dnf["files"].append(path)
                else:
                    dnf["dirs"].append(path)

        os.path.walk(self.src_dir, visit_path, dirs_n_files)

        # add dirs first
        # Note has issues with empty directories
        for d in dirs_n_files["dirs"]:
            new_path = d[len(self.src_dir):]
            if not new_path.endswith("/"):
                new_path = new_path+"/"
            zinfo = zipfile.ZipInfo(new_path)
            #zinfo.external_attr = 48
            zinfo.external_attr = 16
            ##zout.writestr(zinfo, "")

        for f in dirs_n_files["files"]:
            new_path = f[len(self.src_dir):]
            zout.write(f, new_path)

def _test():
    import doctest
    doctest.testmod()

if __name__ == "__main__":
    _test()


#!/usr/bin/env python3
from flask import Flask, request, abort

import sys, os
import sqlalchemy as db
from sqlalchemy import and_
from web3.auto import w3

import logging
import queue
import argparse

app = Flask(__name__)
logger = logging.getLogger(__name__)

DB_FILE = 'eth.db'

@app.route("/create", methods=["POST"])
def create():
    """
    Create challenge given a player_id. If force_new is true,
    a new instance must be created and the old instance may be deleted.

    Return a description containing any
    information needed to access the challenge

    > return challenge_details
    """

    engine = db.create_engine("sqlite:///" + DB_FILE)
    connection = engine.connect()
    metadata = db.MetaData()
    contracts = db.Table('contracts', metadata, autoload=True, autoload_with=engine)

    data = request.form or request.get_json()
    player_id = str(data["player_id"])

    # Check if there is an existing assigned address
    query = db.select([contracts.columns.address]).where(contracts.columns.player == player_id)
    contract_addr = connection.execute(query).scalar()

    if not contract_addr:

        # Fetch an unused contract and unsolved address
        query = db.select([contracts.columns.address]).where(
            and_(contracts.columns.solved == 0, contracts.columns.player == None))
        contract_addr = connection.execute(query).scalar()

        if not contract_addr:
            logger.error("No contract addresses are available.")
            return "No contract addresses are available. Please contact admin."

        # Assign the contract address to the player
        query = db.update(contracts).values(player=player_id).where(contracts.columns.address == contract_addr)
        connection.execute(query)

        logger.info("New challenge for player %s: %s", player_id, contract_addr)
    else:
        logger.info("Existing challenge for player %s: %s", player_id, contract_addr)

    return (
        "Cause the contract at "
        '{0} '
        "to selfdestruct itself."
    ).format(contract_addr)

@app.route("/attempt", methods=["POST"])
def check_solve():
    """
    Check a solve, given a player_id

    Return with a 200 code on successful solve or abort on
    a failed solve attempt
    """

    engine = db.create_engine("sqlite:///" + DB_FILE)
    connection = engine.connect()
    metadata = db.MetaData()
    contracts = db.Table('contracts', metadata, autoload=True, autoload_with=engine)

    data = request.form or request.get_json()

    player_id = str(data["player_id"])

    # Check if there is an existing assigned address
    query = db.select([contracts.columns.address]).where(contracts.columns.player == player_id)
    contract_addr = connection.execute(query).scalar()

    if not contract_addr:
        abort(401)

    logger.info(
        "Checking for solving of challenge at address %s for team %s", contract_addr, player_id
    )

    if len(w3.eth.getCode(contract_addr)) > 2:
        abort(403)

    query = db.update(contracts).values(solved=1).where(contracts.columns.address == contract_addr)
    connection.execute(query)

    return "Success"

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)

    parser = argparse.ArgumentParser()

    parser.add_argument("--dbfile", action='store', help="specify database file", default=DB_FILE)
    parser.add_argument("--port", action='store', type=int, help="set listener port", default=4002)

    args = parser.parse_args()

    # Change database
    if args.dbfile and args.dbfile != DB_FILE:
        DB_FILE = args.dbfile
        logger.info("Using db file: %s" % DB_FILE)

    # Start database connection
    if not os.path.isfile(DB_FILE):
        logger.error("Database file %s does not exist!" % DB_FILE)
        sys.exit(1)

    app.run(debug=True, threaded=True, host="127.0.0.1", port=args.port)


import os
import glob
import numpy as np
from PIL import Image
from itertools import cycle
import random
#
def save_all_img_names_and_labels(save_to, data_root, case_list, class_maps, ext=".jpg"):
    '''
    List all the name of image patches from cases which are listed in case_list
    list all the class labels for the images
    then save them to a txt file, format: each row is an example, consists of label and image file path
    :param save_to:  file name where the data will save to
    :param data_root: root dir to the image files
    :param case_list:  example, case_list = ["OCMC-016", "OCMC-017", "OCMC-001", "OCMC-002"]
    :param class_maps: example, class_maps = {0: ["OCMC-016", "OCMC-017"], 1: ["OCMC-001", "OCMC-002"]}
    :param ext: extension of the image file name
    :return:
    '''
    if not os.path.exists(save_to):
        fp = open(save_to, 'a')
        for case in case_list:
            wrt_str = ""
            f_list = glob.glob(os.path.join(data_root, case, "*"+ext))
            label = "0"
            for key, value in class_maps.items():
                if case in value:
                    label = str(key)
                    break
            for f in f_list:
                wrt_str += label + "," + f + "\n"
            fp.write(wrt_str)
        fp.close()
    else:
        print("file has already exists")

#
def save_random_img_names_and_labels_per_case(save_to, data_root, case_list, class_maps, random_sample=0.1, ext=".jpg"):
    '''
    List all the name of image patches from cases which are listed in case_list
    list all the class labels for the images
    then save them to a txt file, format: each row is an example, consists of label and image file path
    :param save_to:  file name where the data will save to
    :param data_root: root dir to the image files
    :param case_list:  example, case_list = ["OCMC-016", "OCMC-017", "OCMC-001", "OCMC-002"]
    :param class_maps: example, class_maps = {0: ["OCMC-016", "OCMC-017"], 1: ["OCMC-001", "OCMC-002"]}
    :param ext: extension of the image file name
    :return:
    '''
    if not os.path.exists(save_to):
        fp = open(save_to, 'a')
        for case in case_list:
            wrt_str = ""
            f_list = glob.glob(os.path.join(data_root, case, "*"+ext))
            if random_sample < 1:  # random number is percentage
                random_sample = int(random_sample * len(f_list))
            elif random_sample > len(f_list):
                print("warning! Can't get %d samples in this case" % random_sample)
                random_sample = len(f_list)
            f_list = random.sample(f_list, random_sample)
            label = "0"
            for key, value in class_maps.items():
                if case in value:
                    label = str(key)
                    break
            for f in f_list:
                wrt_str += label + "," + f + "\n"
            fp.write(wrt_str)
        fp.close()
    else:
        print("file has already exists")

def list_all_img_names(data_root, case_list, ext=".jpg"):
    all_f_list = []
    for case in case_list:
        f_list = glob.glob(os.path.join(data_root, case, "*"+ext))
        all_f_list += f_list
    return all_f_list

def patch_data_generator(img_fn_list, batch_size, mode="train"):
    img_total_cnt = len(img_fn_list)
    img_idx = 0
    pool = cycle(img_fn_list)
    while True:
        images = []
        while len(images) < batch_size:
            img_fn = next(pool)
            if img_idx == img_total_cnt:
                img_idx = 0
                if mode == "eval":  # don't need to repeat several rounds for evaluation
                    break
            image = np.array(Image.open(img_fn, 'r'))
            images.append(image)
            img_idx += 1
        yield np.array(images)

def patch_data_label_generator(data_list_txt, batch_size, mode="train", aug=None):
    f = open(data_list_txt, "r")
    while True:
        images = []
        labels = []
        while len(images) < batch_size:
            line = f.readline()
            if line == "":
                f.seek(0)  # go to the beginning of the file
                line = f.readline()
                if mode == "eval":  # don't need to repeat several rounds for evaluation
                    break
            line = line.strip().split(",")
            label = int(line[0])
            if label == 0:
                label = [0, 1]
            else:
                label = [1, 0]
            image = np.array(Image.open(line[1], 'r')).astype(np.float32) / 255.0
            images.append(image)
            labels.append(label)
        if aug is not None:
            (images, labels) = next(aug.flow(np.array(images), labels, batch_size=batch_size))
        yield (np.array(images), labels)

if __name__ == "__main__":
    patch_root = "/infodev1/non-phi-data/junjiang/OvaryCancer/auto_enc_patches_256"
    case_list = ["OCMC-016", "OCMC-001"]

    # borderline_case_id_list = ["OCMC-016"]
    # high_grade_case_id_list = ["OCMC-001"]

    borderline_case_id_list = ["OCMC-016", "OCMC-017", "OCMC-018", "OCMC-019", "OCMC-020",
                               "OCMC-021", "OCMC-022", "OCMC-023", "OCMC-024", "OCMC-025",
                               "OCMC-026", "OCMC-027", "OCMC-028", "OCMC-029", "OCMC-030"]
    high_grade_case_id_list = ["OCMC-001", "OCMC-002", "OCMC-003", "OCMC-004", "OCMC-005",
                               "OCMC-006", "OCMC-007", "OCMC-008", "OCMC-009", "OCMC-010",
                               "OCMC-011", "OCMC-012", "OCMC-013", "OCMC-014", "OCMC-015"]

    borderline_train = ["OCMC-016", "OCMC-017", "OCMC-018", "OCMC-019", "OCMC-020",
                        "OCMC-021", "OCMC-022", "OCMC-023", "OCMC-024"]
    borderline_validate = ["OCMC-025", "OCMC-026", "OCMC-027"]
    borderline_test = ["OCMC-028", "OCMC-029", "OCMC-030"]

    high_grade_train = ["OCMC-001", "OCMC-002", "OCMC-003", "OCMC-004", "OCMC-005",
                        "OCMC-006", "OCMC-007", "OCMC-008", "OCMC-009"]
    high_grade_validate = ["OCMC-010", "OCMC-011", "OCMC-012"]
    high_grade_test = ["OCMC-013", "OCMC-014", "OCMC-015"]

    class_maps = {0: borderline_case_id_list, 1: high_grade_case_id_list}

    '''
    Test 1:
    '''
    # all_list = list_all_img_names(patch_root, case_list, ext=".jpg")
    # gen = patch_data_generator(all_list, batch_size=16, mode='eval')
    # print(next(gen))

    '''
    Test 2:
    '''
    data_train_txt = os.path.join(patch_root, "training.txt")
    data_validate_txt = os.path.join(patch_root, "validation.txt")
    data_test_txt = os.path.join(patch_root, "testing.txt")
    save_all_img_names_and_labels(data_train_txt, patch_root, borderline_train+high_grade_train, class_maps)
    save_all_img_names_and_labels(data_validate_txt, patch_root, borderline_validate + high_grade_validate, class_maps)
    save_all_img_names_and_labels(data_test_txt, patch_root, borderline_test + high_grade_test, class_maps)

    '''
    save_random_img_names_and_labels_per_case
    '''
    # data_train_txt = os.path.join(patch_root, "training_sampled.txt")
    # data_validate_txt = os.path.join(patch_root, "validation_sampled.txt")
    # data_test_txt = os.path.join(patch_root, "testing_sampled.txt")
    # save_random_img_names_and_labels_per_case(data_train_txt, patch_root, borderline_train+high_grade_train, class_maps)
    # save_random_img_names_and_labels_per_case(data_validate_txt, patch_root, borderline_validate + high_grade_validate, class_maps)
    # save_random_img_names_and_labels_per_case(data_test_txt, patch_root, borderline_test + high_grade_test, class_maps)

    # test function
    '''
    d = patch_data_label_generator(data_test_txt, batch_size=2)

    # validate the data use print
    print(next(d)[0])
    print(next(d)[1])

    print(d.__next__())

    '''


import requests

# patient = {"name": "Keith",
#            "id": 8,
#            "blood_type": "A+"}
#
# r = requests.post("http://127.0.0.1:5000/new_patient", json=patient)
# print(r.status_code)
# print(r.text)

new_test = {"id": 8,
            "test_name": "HDL",
            "test_result": 78}
r = requests.post("http://127.0.0.1:5000/add_test", json=new_test)
print(r.status_code)
print(r.text)

# r = requests.get("http://127.0.0.1:5000/get_results/8")
# print(r.status_code)
# print(r.text)


import keras as K
from pandas import read_csv
import numpy as np
import json
import os

path = os.path.abspath(os.path.dirname(os.getcwd()))

def data_load():
    X_train = read_csv(path + '\\X_train_shuffled.csv', dtype=float)
    Y_train = read_csv(path + '\\Y_train_shuffled.csv', dtype=float)
    Y_train_onehot = K.utils.to_categorical(Y_train.values)
    return X_train.values, Y_train_onehot

X_train, Y_train = data_load()

def model_Ding(input_size):
    X_input = K.layers.Input(shape=input_size, name='input')
    X = K.layers.Dense(units=250, activation='relu', kernel_initializer=K.initializers.he_normal(seed=1), use_bias=True,
                       bias_initializer=K.initializers.Zeros(), name='Dense1')(X_input)
    X = K.layers.Dense(units=100, activation='relu', kernel_initializer=K.initializers.he_normal(seed=1), use_bias=True,
                       bias_initializer=K.initializers.Zeros(), name='Dense2')(X)
    X = K.layers.Dropout(rate=0.2)(X)
    X = K.layers.Dense(units=50, activation='relu', kernel_initializer=K.initializers.he_normal(seed=1), use_bias=True,
                       bias_initializer=K.initializers.Zeros(), name='Dense3')(X)
    X = K.layers.Dropout(rate=0.2)(X)
    X = K.layers.Dense(units=3, activation='softmax', kernel_initializer=K.initializers.he_normal(seed=1), use_bias=True,
                       bias_initializer=K.initializers.Zeros(), name='Dense4')(X)
    model = K.Model(inputs=X_input, outputs=X)
    return model

Ding_model = model_Ding((31,))
Ding_model.compile(optimizer=K.optimizers.Adam(lr=0.0001), loss=K.losses.categorical_crossentropy, metrics=['accuracy'])
his = Ding_model.fit(X_train, Y_train, validation_split=0.1, batch_size=64, epochs=1, shuffle=True, verbose=2)

with open('Ding_history.json', 'w') as f:
    json.dump(his.history, f)

Ding_model.save('Ding_model.h5')

#onehot_decoding = np.argmax(onehot_encoded[0])# one hot decoding


import turtle
bob = turtle.Turtle()
# print(bob)

def square(t, length):
    for i in range(4):
        t.fd(length)
        t.lt(90)

def polygon(t, length, n):
    for i in range(n):
        t.fd(length)
        t.lt(360/n)

square(bob, 100)

bob.penup()
bob.backward(200)
bob.pendown()

polygon(bob, 80, 8)

bob.screen.mainloop()


import os.path as path
import random
from contextlib import contextmanager

import tensorflow as tf

from chi.logger import logger

class GraphKeys:
  MODULE_PROPERTIES = "module_properties"
  RESET_OPS = "reset_ops"

def in_collections(var):
  return [k for k in tf.get_default_graph().get_all_collection_keys() if var in tf.get_collection(k)]

def basename(name):
  return name.split('/')[-1].split(':')[0]

def relpath(name, module):
  m = module + '/'
  end = ':0'
  if not (name.startswith(m) and name.endswith(end)):
    raise Exception("'{}' should start with '{}' and end with {}.".format(name, m, end))

  return name[len(m):-len(end)]

flags = {}

def configure(**kwargs):
  """

  """
  flags.update(kwargs)

def get_value(var):
  return var.eval(session=flags.get('session'))

def set_value(var, value):
  var.initializer.run({var.initial_value: value}, flags.get('session'))

@contextmanager
def module(mod, reuse_vars=None):
  '''
  Args:
    mod: name string or Module object
    reuse_vars: a dict {relative_name1 : var1, ...} of vars to be reused

  Yields: a Module object which mainly consists of a name and variable scope
    and helper functions for collecting operations and variables from that scope.
    After the context closes the Module object create properties for each
    variable in the "module_properties" collection which can be used to
    directly feed and fetch these variables. (:rtype: Module)
  '''

  # with tf.name_scope(name) as ns: # make unique scope
  m = mod if isinstance(mod, Module) else Module(mod, reuse_vars)
  m  # type: Module
  with tf.variable_scope(m._scope):
    yield m
  m.finalize()

class Module:
  """
  Args:
    name:
    reuse_vars:
    session:
    logging_path:

  """

  def __init__(self, name, reuse_vars=None, session=None, logging_path=None, **kwargs):
    self._finalized = False
    self.output = None
    self.inputs = None
    self.reuse_vars = reuse_vars or {}

    with tf.variable_scope(name, reuse=False) as self._scope:
      pass

    logger.debug("module: " + self._scope.name)
    # print("variables: ", variables)

    self._scope.set_custom_getter(self.custom_getter)
    self._session = session or tf.get_default_session()
    self._logging_path = logging_path
    self._writer = None

  def custom_getter(self, getter, name, *args, **kwargs):
    # print(kwargs)
    # assert not getter(name, *args, **kwargs) # Variable should not exist in scope yet

    # if not kwargs.get("reuse"):
    #   # return getter(name,*args,**kwargs)
    #   raise Exception()

    n = relpath(name + ':0', self._scope.name)
    # v = self.reuse_vars.get(n + ':0')
    v = self.reuse_vars.get(n)

    # if v: logger.debug("reuse " + n + ':0' + " - " + v.name)
    if v: logger.debug("reuse " + n + " - " + v.name)

    if not v:
      v = getter(name, *args, **kwargs)

      logger.debug("create {} - {}".format(n, v.name))

      if True:  # logger.level == logging.DEBUG:
        col = in_collections(v)
        if not any([tf.GraphKeys.VARIABLES in col, tf.GraphKeys.LOCAL_VARIABLES in col]):
          raise Exception("Error: collections have to contain tf.GraphKeys.VARIABLES or tf.GraphKeys.LOCAL_VARIABLES")

    return v

  def get_ops(self):
    all_ops = tf.get_default_graph().get_operations()
    scope_ops = [x for x in all_ops if x.name.startswith(self._scope.name)]
    return scope_ops

  def get_ops_by_type(self, type_name):
    return [op for op in self.get_ops() if op.type == type_name]

  def get_tensors_by_optype(self, type_name):
    return [op.outputs[0] for op in self.get_ops_by_type(type_name)]

  def get_collection(self, name):
    return tf.get_collection(name, self._scope.name)

  def collectionToDict(self, collection):
    return {relpath(e.name, self._scope.name): e for e in collection}

  def get_var(self, name):
    name = name + ':0'
    v = self.local_variables_dict.get(name) or self.variables_dict[name]
    return v

  @property
  def variables(self):
    return self.get_collection(tf.GraphKeys.VARIABLES)

  @property
  def trainable_variables(self):
    return self.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES)

  @property
  def model_variables(self):
    return self.get_collection(tf.GraphKeys.MODEL_VARIABLES)

  @property
  def local_variables(self):
    return self.get_collection(tf.GraphKeys.LOCAL_VARIABLES)

  @property
  def summaries(self):
    return tf.get_collection(tf.GraphKeys.SUMMARIES, self._scope.name)

  @property
  def update_ops(self):
    return tf.get_collection(tf.GraphKeys.UPDATE_OPS, self._scope.name)

  @property
  def reset_ops(self):
    """ get ops in collection "reset_ops"
    """
    return tf.get_collection(GraphKeys.RESET_OPS, self._scope.name)

  @property
  def module_properties(self):
    """ get variables in collection "module_properties"
    """
    return tf.get_collection(GraphKeys.MODULE_PROPERTIES, self._scope.name)

  @property
  def variables_dict(self):
    return self.collectionToDict(self.variables)

  @property
  def trainable_variables_dict(self):
    return self.collectionToDict(self.trainable_variables)

  @property
  def model_variables_dict(self):
    return self.collectionToDict(self.model_variables)

  @property
  def local_variables_dict(self):
    return self.collectionToDict(self.local_variables)

  def histogram_summaries(self, tensors, prefix=""):
    summaries = []
    for t in tensors:
      assert t.name.startswith(self._scope.name)
      name = prefix + '/' + t.name[len(self._scope.name):]
      summaries.append(tf.histogram_summary(name, t))

    return summaries

  def finalize(self):
    self._finalized = True

    if self.output is not None:
      # make this module callable
      self.inputs = self.inputs or self.get_tensors_by_optype("Placeholder")

      # logging
      self._step = 0
      self.log = 0.  # logging probability
      # random.seed(Module._session.graph.seed)
      activations = self.get_tensors_by_optype('Relu')  # TODO: generalize to non-Relu
      activations = self.histogram_summaries(activations, 'activations')
      summaries = self.summaries
      summaries += activations
      if summaries and self._logging_path:
        self._summary_op = tf.merge_summary(summaries)
        self._writer = tf.train.SummaryWriter(
          self._logging_path + path.basename(self._scope.name),
          self._session.graph)

  def reset(self):
    local_inits = [v.initializer for v in self.local_variables]
    self._session.run(self.reset_ops + local_inits)

  def __call__(self, *args, **kwargs):
    return self.run(*args, **kwargs)

  def run(self, *args, **kwargs):
    assert self._finalized

    # log = kwargs.get('log',False)
    log = self._writer is not None and random.random < self.log

    feeds = {}
    for (argpos, arg) in enumerate(args):
      feeds[self.inputs[argpos]] = arg

    out = self.output + [self._summary_op] if log else self.output
    res = self._session.run(out, feeds)

    if log:
      # i = kwargs['global_step']
      self._writer.add_summary(res[-1], global_step=self._step)
      res = res[:-1]

    return res

  # TODO:
  def save(self):
    # save parameters etc.
    # if (self.t+45000) % 50000 == 0: # TODO: correct
    #   s = self.saver.save(self.sess,FLAGS.outdir+"f/tf/c",self.t)
    #   print("DDPG Checkpoint: " + s)
    pass

class SummaryWriter:
  def __init__(self, tf_summary_writer):
    self.writer = tf_summary_writer

  def write_scalar(self, tag, val):
    s = tf.Summary(value=[tf.Summary.Value(tag=tag, simple_value=val)])
    self.writer.add_summary(s, self.t)

    # TODO: more functions

class ExponentialMovingAverage:
  """
  Creates shadow EMA variables colocated with variables.
  The shadow variables have differnet names than variables.
  The update op is added to the tf.GraphKEys.UPDATE_OPS collection.

  parameters:
    variables_dict: {name1: var1, ...}

  returns:
    averages: {name1: avg1, ...}
  """

  def __init__(self, variables_dict, tau=0.001):
    vs = tf.get_variable_scope().name
    with tf.name_scope(""):
      self.vars = variables_dict
      name = "{}/ExponentialMovingAverage".format(vs) if vs else "ExponentialMovingAverage"
      self.ema = tf.train.ExponentialMovingAverage(decay=1 - tau, name=name)

      self.upd = self.ema.apply(self.vars.values())  # also creates shadow vars

      self.averages = {n: self.ema.average(v) for n, v in variables_dict.items()}
      logger.debug(self.averages.values()[0].name)

  def update(self):
    # with tf.control_dependencies([self.upd]):
    #   update = tf.no_op()
    vs = tf.get_variable_scope().name
    with tf.control_dependencies([self.upd]):
      with tf.name_scope(""):
        # update = tf.group(self.upd, name = )
        name = "{}/ema_update".format(vs) if vs else "ema_update"
        update = tf.no_op(name=name)
    # print(update.name)
    tf.add_to_collection(tf.GraphKeys.UPDATE_OPS, update)
    return update

def test_get_set_value():
  with tf.Session().as_default():

    b = tf.get_variable('bla', initializer=0)

    tf.initialize_variables([b]).run()

    assert get_value(b) == 0
    set_value(b, 3)
    assert get_value(b) == 3

def test_module():
  # collect variables and ops in a scope
  with module('foo') as foo:
    a = tf.get_variable('a', [0], trainable=False)
    b = tf.get_variable('b', [0])
    c = tf.get_variable('c', [0], trainable=False, collections=[tf.GraphKeys.LOCAL_VARIABLES])

  assert foo.variables_dict == {'a': a, 'b': b}
  assert foo.variables == [a, b]
  assert foo.trainable_variables_dict == {'b': b}

  # inject variables into a scope
  with module('bar', reuse_vars={'b': b}) as bar:
    b2 = tf.get_variable('b', [0])
  assert b2 is b

  bla = Module('bla', reuse_vars={'x': a})  # use this to make autocomplete work
  with module(bla):
    x = tf.get_variable('x', [0])
  assert x is a

  # use module as function
  with tf.Session().as_default():
    with module('fun') as fun:
      x = tf.placeholder(tf.float32)
      fun.output = 2 * x

    assert fun(3.) == 6.

def test_reset():
  with tf.Session().as_default():
    with module('fun') as fun:
      x = tf.get_variable('x', initializer=0., collections=[tf.GraphKeys.LOCAL_VARIABLES])

    tf.initialize_all_variables().run()  # this does not initialize local variables
    fun.reset()  # reset / initialize local variables in fun
    assert x.eval() == 0.
    set_value(x, 3.)
    assert x.eval() == 3.
    fun.reset()
    assert x.eval() == 0.

def test_get_ops_by_type():
  # a = tf.zeros(2) + 3
  a = tf.placeholder(tf.float32)

  with module("bla") as bla:
    b = tf.placeholder(tf.float32)
    b + a

  # which tf function creates which ops:
  # {tf.placeholder: "Placeholder", tf.nn.relu: "Relu", tf.nn.zeros: "Const"} ...
  assert bla.get_ops_by_type("Placeholder") == [b.op]
  assert bla.get_tensors_by_optype("Placeholder") == [b]

if __name__ == "__main__":
  pass


import random
from collections import deque, namedtuple
from typing import Tuple

import numpy as np
import torch
from torch import Tensor

Experience = namedtuple("Experience",
                        field_names=["state", "action", "reward", "next_state",
                                     "done"])
"""Experience tuple."""

class ReplayBuffer(object):
    """Fixed-size buffer for storing experience tuples."""

    def __init__(self, buffer_size, batch_size, device):
        """Initialize the replay buffer.

        Args:
            buffer_size (int): Max number of stored experiences
            batch_size (int): Size of training batches
            device (torch.device): Device for tensors
        """
        self.batch_size = batch_size
        """Size of training batches"""

        self.memory = deque(maxlen=buffer_size)
        """Stored experiences."""

        self.device = device
        """Device to be used for tensors."""

    def add(self, state, action, reward, next_state, done):
        """Add an experience to memory.

        Args:
            state (Tensor): Current state
            action (int): Chosen action
            reward (float): Resulting reward
            next_state (Tensor): State after action
            done (bool): True if terminal state
        """
        self.memory.append(Experience(state, action, reward, next_state, done))

    def sample(self):
        """Returns a sample batch of experiences from memory.

        Returns:
            Tuple[Tensor, Tensor, Tensor, Tensor, Tensor]: SARS'+done tuple"""
        experiences = random.sample(self.memory, k=self.batch_size)

        device = self.device

        state_list = [e.state for e in experiences if e is not None]
        action_list = [e.action for e in experiences if e is not None]
        reward_list = [e.reward for e in experiences if e is not None]
        next_state_list = [e.next_state for e in experiences if e is not None]
        done_list = [e.done for e in experiences if e is not None]

        states = torch.from_numpy(np.vstack(state_list)).float().to(device)
        actions = torch.from_numpy(np.vstack(action_list)).float().to(device)
        rewards = torch.from_numpy(np.vstack(reward_list)).float().to(device)
        next_states = torch.from_numpy(np.vstack(next_state_list)).float() \
            .to(device)
        dones = torch.from_numpy(np.vstack(done_list).astype(np.uint8)).float() \
            .to(device)

        return (states, actions, rewards, next_states, dones)

    def __len__(self):
        """Returns the current number of stored experiences.

        Returns:
            int: Number of stored experiences"""
        return len(self.memory)


from flask import jsonify
import json
import pytest
import os
from grandpyapp.parser import QuestionParser
from grandpyapp.api_google import ApiGoogle
from grandpyapp.api_mediawiki import ApiMediawiki

#################################################################################
#################### TEST GATHERING USER INPUT AND API OUTPUT ###################
#################################################################################
def test_Gather(monkeypatch):

    class Test_Gatherer:

        def test_fail_call_api(self, question):
            """ Check that unclear input goes to fail path """
            question = 'blablabla'
            location = {'html_attributions': [], 'results': [], 'status': 'ZERO_RESULTS'}

            if location == "ZERO_RESULTS":
                failed_input == {"validation" : "fail"}
                return failed_input

            monkeypatch.setattr('googlemaps.Client', Test_Gatherer)
            google = api_google.ApiGoogle()
            assert google.request_google_places(question) == location

        def test_success_call_api(self, question):
            """ Check that the good input goes to success path """
            question = 'trocadero'
            location = {'html_attributions': [],
            'results': [{'formatted_address': 'Place du Trocadéro et du 11 Novembre, 75016 Paris, France',
            'geometry': {'location': {'lat': 48.8615963, 'lng': 2.2892823},
            'viewport': {'northeast': {'lat': 48.86493295, 'lng': 2.294195749999999},
            'southwest': {'lat': 48.85799514999999, 'lng': 2.28408435}}},
            'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/generic_recreational-71.png',
            'id': '7da4eae9a54012ee168318852829a8263e29fe52',
            'name': 'Trocadéro Gardens',
            'opening_hours': {'open_now': True},
            'photos': [{'height': 2592,
            'html_attributions': ['Clint Fernandez'],
            'photo_reference': 'CmRaAAAAaB-WsCf5Yl2YZsXYqyq5bdXpHPjEXefXijE8UDYgMF2yixY9byK8Cu6C-rs-zhqSurjqNHbKUnwNh5dfy-iZlQkT6n4gxLZTo5kt-lgTwFfMh4cERea9s8u_ASdZXXJlEhAwzadayQxmFLl-_QeP49jUGhR-qGBGgSBbmtfp4fa9DkNOIc6auQ', 'width': 3872}],
            'place_id': 'ChIJoxY3R-Nv5kcRWsRDGBoNIOk',
            'plus_code': {'compound_code': 'V76Q+JP Paris, France', 'global_code': '8FW4V76Q+JP'},
            'rating': 4.5, 'reference': 'ChIJoxY3R-Nv5kcRWsRDGBoNIOk',
            'types': ['park', 'point_of_interest', 'establishment']}],
            'status': 'OK'}

            if location == {"status": "OK"}:
                response = {"validation" : "pass"}
                return response

            monkeypatch.setattr('googlemaps.Client', Test_Gatherer)
            google = api_google.ApiGoogle()
            assert google.request_google_places(question) == location


#!/usr/bin/env python
#########################################################################################
#
# Test function for sct_warp_template script
#
#   replace the shell test script in sct 1.0
#
# ---------------------------------------------------------------------------------------
# Copyright (c) 2014 Polytechnique Montreal <www.neuro.polymtl.ca>
# Author: Augustin Roux
# modified: 2014/09/28
#
# About the license: see the file LICENSE.TXT
#########################################################################################

#import sct_utils as sct
import commands

def test(path_data):

    # parameters
    folder_data = ['mt/', 'template/']
    file_data = ['mt1.nii.gz', 'warp_template2mt.nii.gz']

    # define command
    cmd = 'sct_warp_template' \
        ' -d '+path_data+folder_data[0]+file_data[0]+ \
        ' -w '+path_data+folder_data[0]+file_data[1]+ \
        ' -a 0 '+ \
        ' -s 0 '+ \
        ' -ofolder label'+ \
        ' -t '+path_data+folder_data[1]+ \
        ' -qc 0'+ \
        ' -v 1'

    # return
    #return sct.run(cmd, 0)
    return commands.getstatusoutput(cmd)

# call to function
if __name__ == "__main__":
    # call main function
    test()