import scrapy
import requests
import sys
import pandas as pd
from scrapy.http import FormRequest
from scrapy.utils.response import open_in_browser
import json
from scrapy_splash import SplashRequest, SplashFormRequest

if sys.version_info[0] < 3:
    from StringIO import StringIO
else:
    from io import StringIO

script = """
function main(splash)
  splash:init_cookies(splash.args.cookies)
  assert(splash:go{
    splash.args.url,
    headers=splash.args.headers,
    http_method=splash.args.http_method,
    body=splash.args.body,
    })
  assert(splash:wait(0.5))

  local entries = splash:history()
  local last_response = entries[#entries].response
  return {
    url = splash:url(),
    headers = last_response.headers,
    http_status = last_response.status,
    cookies = splash:get_cookies(),
    html = splash:html(),
  }
end
"""

class PdonlineSpider(scrapy.Spider):
    name = 'pdonline'

    def start_requests(self):
        self.dynamic_cookie = {}

        yield SplashRequest(
            url="https://pdonline.brisbane.qld.gov.au/MasterPlan/Modules/Enquirer/PropertySearch.aspx",
            # cookies=self.dynamic_cookie,
            callback=self.search_result,
            endpoint='execute',
            cache_args=['lua_source'],
            args={
                'timeout': '90',
                'wait': '30',
                'lua_source': script,
            },
            session_id='1',
            meta={
                "input_data":{
                    'Lot Number':'',
                    'Plan Number': '',
                    'Unit Number To':'',
                    'Unit Number From':'',
                    'Street Name': 'Mcconaghy St',
                    'Street Number From': 92,
                    'Street Number To': 92,
                    'Suburb': 'Mitchelton'
                    },
                "current_url":"https://pdonline.brisbane.qld.gov.au/MasterPlan/Modules/Enquirer/PropertySearch.aspx"
                }
            )

        # Commented below section is about google sheet reading etc.

        """
        google_sheet_id =  "1ItXlYbNKUh9buALC-3WObEFJIrXILlCiRBIUJHvX3AA" # https://docs.google.com/spreadsheets/d/1ItXlYbNKUh9buALC-3WObEFJIrXILlCiRBIUJHvX3AA/edit?usp=sharing
        try:
            res = requests.get('https://docs.google.com/spreadsheet/ccc?key=' + google_sheet_id + '&output=csv')
        except:
            pass
        if not res.status_code == 200:
            print("Wrong status code")
            sys.exit(1)
        df = pd.read_csv(StringIO(res.text), sep=",")
        for index, row in df.iterrows():
            self.input_data.append(row.to_dict())

        self.input_data.pop(0)
        urls = list()
        urls = 'https://pdonline.brisbane.qld.gov.au/MasterPlan/Modules/Enquirer/PropertySearch.aspx'

        if self.input_data: # input_data
            yield scrapy.Request(url=urls, cookies=self.dynamic_cookie, callback=self.search_result, meta={"input_data": self.input_data.pop(), "current_url":urls})
        """

    def search_result(self, response):
        if response.css("#ctl00_RadWindow1_C_btnOk"):

            form_data = dict()
            input_fields = response.css("form input")
            for ifield in input_fields:
                if ifield.css("input::attr(name)").extract_first() == None:
                    continue
                if ifield.css("input::attr(value)").extract_first() == None:
                    form_data[ifield.css("input::attr(name)").extract_first()] = ''
                elif ifield.css("input::attr(value)").extract_first() == 'I Disagree':
                    continue
                elif ifield.css("input::attr(value)").extract_first() == '':
                    form_data[ifield.css("input::attr(name)").extract_first()] = ''
                else:
                    form_data[ifield.css("input::attr(name)").extract_first()] = ifield.css("input::attr(value)").extract_first()

            yield SplashFormRequest(
                url='https://pdonline.brisbane.qld.gov.au/MasterPlan/Modules/Enquirer/PropertySearch.aspx',
                formdata=form_data,
                callback=self.search_result,
                endpoint='execute',
                args={
                    'timeout': '90',
                    'wait': '30',
                    'lua_source': script,
                },
                session_id='1',
                meta={
                    'input_data': response.meta["input_data"],
                }
                )
        else:
            # Cookie handling
            for cookie in response.data["cookies"]:
                self.dynamic_cookie[ cookie["name"] ] = cookie["value"]

            form_data = dict()
            input_fields = response.css("form input")
            for ifield in input_fields:
                if ifield.css("input::attr(name)").extract_first() == None:
                    continue
                if ifield.css("input::attr(value)").extract_first() == None:
                    form_data[ifield.css("input::attr(name)").extract_first()] = ''
                else:
                    form_data[ifield.css("input::attr(name)").extract_first()] = ifield.css("input::attr(value)").extract_first()
            for key in response.meta["input_data"]:
                #  if response.meta["input_data"][key]:

                if key == "Suburb":
                    form_data["ctl00$MainContent$SuburbCombo"] = response.meta["input_data"][key]
                elif key == "Street Name":
                    street_name_define = {"logEntries":[],"value":"","text":"","enabled":True,"checkedIndices":[],"checkedItemsTextOverflows":False}
                    street_name_define["value"] = response.meta["input_data"][key]
                    street_name_define["text"] =response.meta["input_data"][key]
                    form_data["ctl00_MainContent_StreetCombo_ClientState"] = street_name_define
                    form_data["ctl00$MainContent$StreetCombo"] = response.meta["input_data"][key]
                elif key == "Unit Number From":
                    form_data["ctl00$MainContent$FromUnitNumberTextBox"] = response.meta["input_data"][key]
                    ctl00_MainContent_FromUnitNumberTextBox_ClientState = {"enabled":True,"emptyMessage":"","validationText":"","valueAsString":"","lastSetTextBoxValue":""}
                    ctl00_MainContent_FromUnitNumberTextBox_ClientState["validationText"] = response.meta["input_data"][key]
                    ctl00_MainContent_FromUnitNumberTextBox_ClientState["valueAsString"] = response.meta["input_data"][key]
                    ctl00_MainContent_FromUnitNumberTextBox_ClientState["lastSetTextBoxValue"] = response.meta["input_data"][key]
                    form_data["ctl00_MainContent_FromUnitNumberTextBox_ClientState"] = ctl00_MainContent_FromUnitNumberTextBox_ClientState
                elif key == "Unit Number To":
                    form_data["ctl00$MainContent$ToUnitNumberTextBox"] = response.meta["input_data"][key]
                    ctl00_MainContent_ToUnitNumberTextBox_ClientState = {"enabled":True,"emptyMessage":"","validationText":"","valueAsString":"","lastSetTextBoxValue":""}
                    ctl00_MainContent_ToUnitNumberTextBox_ClientState["validationText"] = response.meta["input_data"][key]
                    ctl00_MainContent_ToUnitNumberTextBox_ClientState["valueAsString"] = response.meta["input_data"][key]
                    ctl00_MainContent_ToUnitNumberTextBox_ClientState["lastSetTextBoxValue"] = response.meta["input_data"][key]
                    form_data["ctl00_MainContent_ToUnitNumberTextBox_ClientState"] = ctl00_MainContent_ToUnitNumberTextBox_ClientState
                elif key == "Street Number From":
                    form_data["ctl00$MainContent$FromStreetNumberTextBox"] = response.meta["input_data"][key]
                    ctl00_MainContent_FromStreetNumberTextBox_ClientState = {"enabled":True,"emptyMessage":"","validationText":"","valueAsString":"","lastSetTextBoxValue":""}
                    ctl00_MainContent_FromStreetNumberTextBox_ClientState["validationText"] = response.meta["input_data"][key]
                    ctl00_MainContent_FromStreetNumberTextBox_ClientState["valueAsString"] = response.meta["input_data"][key]
                    ctl00_MainContent_FromStreetNumberTextBox_ClientState["lastSetTextBoxValue"] = response.meta["input_data"][key]
                    form_data["ctl00_MainContent_FromStreetNumberTextBox_ClientState"] = ctl00_MainContent_FromStreetNumberTextBox_ClientState
                elif key == "Street Number To":
                    form_data["ctl00$MainContent$ToStreetNumberTextBox"] = response.meta["input_data"][key]
                    ctl00_MainContent_ToStreetNumberTextBox_ClientState = {"enabled":True,"emptyMessage":"","validationText":"","valueAsString":"","lastSetTextBoxValue":""}
                    ctl00_MainContent_ToStreetNumberTextBox_ClientState["validationText"] = response.meta["input_data"][key]
                    ctl00_MainContent_ToStreetNumberTextBox_ClientState["valueAsString"] = response.meta["input_data"][key]
                    ctl00_MainContent_ToStreetNumberTextBox_ClientState["lastSetTextBoxValue"] = response.meta["input_data"][key]
                    form_data["ctl00_MainContent_ToStreetNumberTextBox_ClientState"] = ctl00_MainContent_ToStreetNumberTextBox_ClientState

                elif key == "Plan Number":
                    form_data["ctl00$MainContent$PlanTextBox"] = response.meta["input_data"][key]
                    ctl00_MainContent_PlanTextBox_ClientState = {"enabled":True,"emptyMessage":"","validationText":"","valueAsString":"","lastSetTextBoxValue":""}
                    ctl00_MainContent_PlanTextBox_ClientState["validationText"] = response.meta["input_data"][key]
                    ctl00_MainContent_PlanTextBox_ClientState["valueAsString"] = response.meta["input_data"][key]
                    ctl00_MainContent_PlanTextBox_ClientState["lastSetTextBoxValue"] = response.meta["input_data"][key]
                elif key == "Lot Number":
                    form_data["ctl00$MainContent$LotTextBox"] = response.meta["input_data"][key]
                    ctl00_MainContent_LotTextBox_ClientState = {"enabled":True,"emptyMessage":"","validationText":"","valueAsString":"","lastSetTextBoxValue":""}
                    ctl00_MainContent_LotTextBox_ClientState["validationText"] = response.meta["input_data"][key]
                    ctl00_MainContent_LotTextBox_ClientState["valueAsString"] = response.meta["input_data"][key]
                    ctl00_MainContent_LotTextBox_ClientState["lastSetTextBoxValue"] = response.meta["input_data"][key]
                    form_data["ctl00_MainContent_LotTextBox_ClientState"] = ctl00_MainContent_LotTextBox_ClientState
                else:
                    pass

            for key in form_data:
                if isinstance(form_data[key], dict):
                    form_data[key] = json.dumps(form_data[key])
                if isinstance(form_data[key], int):
                    form_data[key] = str(form_data[key])

            # first method that i used to submit form
            yield FormRequest(
                url='https://pdonline.brisbane.qld.gov.au/MasterPlan/Modules/Enquirer/PropertySearch.aspx',
                formdata=form_data,
                callback=self.submit_form,
                cookies=self.dynamic_cookie
                )

            # Second method that i have used to submit form
            yield SplashFormRequest(
            url='https://pdonline.brisbane.qld.gov.au/MasterPlan/Modules/Enquirer/PropertySearch.aspx',
            formdata=form_data,
            callback=self.submit_form,
            endpoint='execute',
            args={
                'timeout': '90',
                'wait': '30',
                'lua_source': script,
            },
            session_id='1'
            )

    def submit_form(self, response):
        var_temp = 1


#-*- coding:utf-8 -*-
from HTMLTestRunner import HTMLTestRunner
from email.mime.text import MIMEText
from email.header import Header
import smtplib
import unittest
import time
import os

def send_mail(file_new):
    f = open(file_new,"r")
    mail_body = f.read()
    f.close()

    msg = MIMEText(mail_body,'HTML','utf-8')
    msg['Subject'] = Header("自动化测试报告",'utf-8')

    smtp = smtplib.SMTP()
    smtp.connect("smtp.126.com")
    smtp.login("m18128866322@126.com", "cxc02125053")
    smtp.sendmail("m18128866322@126.com", "993372246@qq.com", msg.as_string())
    smtp.quit()
    print("email has send out")

    #----查找测试报告找到最新的测试报告---
def new_report(testreport):
    lists = os.listdir(testreport)
    #按照每个文件修改的时间，从小到大排列
    lists.sort(key=lambda fn:os.path.getmtime(testreport + "\\" + fn))
    file_new = os.path.join(testreport,lists[-1])
    print(file_new)
    return file_new

if __name__ == "__main__":
    test_dir = r'C:\Users\xuchun.chen\PycharmProjects\base\mztestpro\bbs\test_case'
    test_dir1 = './'
    # C:\Users\xuchun.chen\PycharmProjects\base\mztestpro\hello_sta.py
    now = time.strftime("%Y-%m-%d-%H-%M-%S")
    filename = "./bbs/report/"+now+'result.html'
    #fp = open("./bbs/report/"+now+'result.html',"wb")
    fp = open(filename,"wb")
    runner = HTMLTestRunner(stream=fp,title="魅族自动化测试报告",description="环境：windows 7 浏览器：Firefox")
    discover = unittest.defaultTestLoader.discover(test_dir, pattern='search_sta.py')
    runner.run(discover)
    print(time.time())
    fp.close()
    file_path = new_report('./bbs/report/')
    # send_mail(file_path)


# -*- coding: utf-8 -*-
#------------------------------------------------------------------------------
# regex_name.py
# Use regex to fix filenames of lidar tile index geojsons
# Hayden Elza (hayden.elza@gmail.com)
# Created: 2022-06-03
# Modified:
#------------------------------------------------------------------------------

# Import libraries
import json
from os.path import dirname, join
import re

# Parameters
wd = dirname(__file__)
print(wd)
datasets = ["marquette-2018-PointsClassifiedLAS.geojson"]

# Iterate through datasets
for dataset in datasets:

    # Build paths
    file_path = join(wd, "output/", dataset)
    out_path = join(wd, "fixed/", dataset)
    print(file_path)

    # Open geojson
    with open(file_path, "r") as f:
        metadata = json.load(f)

    # Iterrate through features
    for feature in metadata['features']:
        # Read the download URL
        download_url = feature["properties"]["downloadUrl"]

        # Update download URL using regular expresion
        feature["properties"]["downloadUrl"] = re.sub("(?<=USGS_LPC_WI_FEMAHQ_2018_16T)C(?=P2)", "B", download_url)

    # Write the GeoJSON to a new file (indent=2)
    with open(out_path, 'w') as f:
        json.dump(metadata, f, indent=2)

migrate from lidar tile viewer/regex_name.py


import cv2
import tensorflow as tf
from tkinter import *
from tkinter import filedialog
from PIL import Image, ImageTk

# Load the trained model
model = tf.keras.models.load_model('child_detection_model.h5')

# Create the GUI window
window = Tk()
window.title("Child Detection")
window.geometry("400x350")

# Function to process and display the selected image
def display_selected_image():
    # Open a file dialog to select an image
    file_path = filedialog.askopenfilename(filetypes=(("Image files", "*.jpg;*.jpeg;*.png"), ("All files", "*.*")))

    # Read the image using OpenCV
    image = cv2.imread(file_path)

    # Convert the image from BGR to RGB
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

    # Resize the image to fit the GUI window
    image = cv2.resize(image, (300, 250))

    # Convert the image to PIL format
    image = Image.fromarray(image)

    # Create a Tkinter-compatible photo image
    photo = ImageTk.PhotoImage(image)

    # Display the selected image
    image_label.configure(image=photo)
    image_label.image = photo

# Function to detect whether the selected image contains a child or not
def detect_child():
    # Open a file dialog to select an image
    file_path = filedialog.askopenfilename(filetypes=(("Image files", "*.jpg;*.jpeg;*.png"), ("All files", "*.*")))

    # Read the image using OpenCV
    image = cv2.imread(file_path)

    # Preprocess the image
    image = cv2.resize(image, (100, 100))  # Resize the image to match the input size of the model
    image = image.astype("float") / 255.0  # Normalize the pixel values to the range [0, 1]
    image = tf.expand_dims(image, axis=0)  # Add an extra dimension for batch size

    # Use the trained model to predict the class
    prediction = model.predict(image)

    # Get the predicted class label
    if prediction[0][0] > 0.5:
        label = "Child"
    else:
        label = "Not a child"

    # Display the result
    result_label.configure(text=label)

# Create a button to select and display an image
select_button = Button(window, text="Select Image", command=display_selected_image)
select_button.pack(pady=10)

# Create an image label to display the selected image
image_label = Label(window)
image_label.pack()

# Create a button to detect whether the selected image contains a child or not
detect_button = Button(window, text="Detect Image", command=detect_child)
detect_button.pack(pady=10)

# Create a label to display the result
result_label = Label(window, text="")
result_label.pack()

# Start the GUI main loop
window.mainloop()


# -*- coding: utf-8 -*-
"""
This is a very minor modification from the Guttag Object he uses as an
example in his book.

Created on Mon Oct  5 22:42:46 2015
@author: jonbruno
"""
from __future__ import print_function
import numpy as np
import operator

#page 147 plotting mortgages, fig 11.1 and 11.3
def findPayment(loan, r, m):
    """Assumes: loan and r are floats, m an int
       Returns the montly payment for a mortgage of size
       loan at a monthly rate of r and m months"""
    return loan*((r*(1+r)**m)/((1+r)**m-1))

class Mortgage(object):
    """Abstract class for building different kinds of mortgages"""
    def __init__(self, loan, annRate, months):
        """Create a new mortgage"""
        self.loan = loan
        self.rate = annRate/12.0
        self.months = months
        self.paid = [0.0] #
        self.owed = [loan]
        self.payment = findPayment(loan, self.rate, months) #Min Payment
        self.interest = [0.0]
        self.legend = None #description of mortgage
        self.complete = self.loan_complete()
    def makePayment(self, amt=0.0):
        """Make a payment, if amt > 0.0 pay extra towards principal"""
        period_payment = self.payment + amt
        self.paid.append(period_payment)
        reduction = period_payment - self.owed[-1]*self.rate
        self.owed.append(self.owed[-1] - reduction)
        self.interest.append(self.owed[-1]*self.rate)
        self.complete = self.loan_complete()
    def getTotalPaid(self):
        """Return the total amount paid so far"""
        return sum(self.paid)
    def getInterestPaid(self):
        """Return the total interest paid so far"""
        return sum(self.interest)
    def __str__(self):
        return self.legend

    def sim_summary(self):
        annual_rate = self.rate*12.0
        months_paid = len(self.paid)
        total_paid = self.getTotalPaid()
        interest_paid = self.getInterestPaid()
        self.sim_list = [annual_rate,months_paid,total_paid,interest_paid]
        return self.sim_list
    def print_sim_summary(self):
        self.sim_list  = self.sim_summary()
        print('Annual Rate:\t\t {0}'.format(self.sim_list[0]))
        print('Months Paid:\t\t {0}'.format(self.sim_list[1]))
        print('Total Paid:\t\t {0}'.format(self.sim_list[2]))
        print('Total Interest:\t\t {0}'.format(self.sim_list[3]))
        print('\n')

    def sim(self,amt=0.0):
        while self.loan_complete() == False:
            self.makePayment(amt)

    def loan_complete(self):
        if self.owed[-1] <= 0:
            self.complete = True
        else:
            self.complete = False
        return self.complete

class Fixed(Mortgage):
    def __init__(self, loan, r, months):
        Mortgage.__init__(self, loan, r, months)
        self.legend = 'Fixed, ' + str(r*100) + '%'

class FixedWithPts(Mortgage):
    def __init__(self, loan, r, months, pts):
        Mortgage.__init__(self, loan, r, months)
        self.pts = pts
        self.paid = [loan*(pts/100.0)]
        self.legend = 'Fixed, ' + str(r*100) + '%, '\
                        + str(pts) + ' points'

class TwoRate(Mortgage):
    def __init__(self, loan, r, months, teaserRate, teaserMonths):
        Mortgage.__init__(self, loan, teaserRate, months)
        self.teaserMonths = teaserMonths
        self.teaserRate = teaserRate
        self.nextRate = r/12.0
        self.legend = str(teaserRate*100)\
                        + '% for ' + str(self.teaserMonths)\
                        + ' months, then ' + str(r*100) + '%'
    def makePayment(self):
        if len(self.paid) == self.teaserMonths + 1:
            self.rate = self.nextRate
            self.payment = findPayment(self.owed[-1], self.rate,
                                       self.months - self.teaserMonths)
        Mortgage.makePayment(self)

if __name__ == '__main__':

    #===========================================================================
    # simulations
    #===========================================================================
    # a simple simulation
    ex = Fixed(loan=110000.0, r=.0375, months=360)

    budget = 1000 # monthly budget

    # a simple sim of one loan (to shoq proof of concept)
    # while ex.loan_complete() == False:
    #     amt = budget - ex.payment
    #     ex.makePayment(amt)

    # can we optimize payments to multiple loans
    loan1 = Fixed(loan=8742.83, r=0.085, months=240)
    loan2 = Fixed(loan=5511.13, r=0.068, months=240)
    loan3 = Fixed(loan=9682.62, r=0.068, months=240)
    loan4 = Fixed(loan=5511.13, r=0.068, months=240)
    loan5 = Fixed(loan=9144.04, r=0.068, months=240)
    loan6 = Fixed(loan=6761.26, r=0.085, months=240)
    loan7 = Fixed(loan=5562.55, r=0.068, months=240)
    loan8 = Fixed(loan=8661.62, r=0.068, months=240)
    loan9 = Fixed(loan=13114.05, r=0.079, months=240)

    loan_list = [loan1,loan2,loan3,
                 loan4,loan5,loan6,
                 loan7,loan8,loan9]

    # a = pd.Series(loan_list)
    # loan_list[0].run_sim()
    # b = pd.Series([loan.complete==False for loan in loan_list])
    # final = a[a[b]]

    # we need to know how to allocate the budget
    '''avalance allocation method
       apply all extra princial to the highest interest rate loan '''

    # if loan is not complete add it to the list that we will evaluate
    def check_loan_status(loan_list):
        """check loans to see if they are complete,
           return a list of incomplete loans"""
        incomplete_loans = []
        for loan in loan_list:
            if loan.complete == False:
                incomplete_loans.append(loan)
        return incomplete_loans

    def calculate_prin_pmt(loan_list, budget):
        """return the amount we can put towards the loan principal"""
        # calculate the monthly min
        monthly_min = sum([loan.payment for loan in loan_list])
        # calculate the additional principal payment
        amt = budget - monthly_min
        return amt

    def select_loan_rate(loan_list):
        """select the loan with the highest interest rate
           and lowest outstanding amount,
           return the loan object"""
        # select loans with max interest rate
        _max = max([loan.rate for loan in loan_list])
        output_list = [i for i in loan_list if i.rate == _max]
        # select the remaining loans with the lowest payment amount
        _min = min([loan.loan for loan in output_list])
        final = [i for i in output_list if i.loan == _min]
        return final[0]

    def select_loan_pmt(loan_list):
        """select the loan with the highest interest payment,
           return the loan object

           THIS COULD BE CLEANED UP"""
        # select loans with max interest payment
        _max = max([loan.rate*loan.owed[-1] for loan in loan_list])
        output_list = [i for i in loan_list if i.rate*i.owed[-1] == _max]
        return output_list[0]

    #===========================================================================
    # avalance simulation
    #===========================================================================
    def avalanche(loan_list, budget, select_loan):
        """simulate paying off loans on a budget given
           you have to select the method of selecting the loan to payoff first
        """
        # while at least 1 loan is incomplete
        while len(check_loan_status(loan_list)) > 0:
            # take all incomplete loans
            _loan_list = check_loan_status(loan_list)
            # calculate the amount of principal we can put towards
            amt = calculate_prin_pmt(_loan_list, budget)
            # find which loan to put the principal payment towards
            loan_to_pay = select_loan(_loan_list)
            # while the loan to pay is incomplete... make payments to all loans
            print(loan_to_pay)
            while loan_to_pay.complete == False:
                for _loan in _loan_list:
                    if _loan == loan_to_pay:
                        _loan.makePayment(amt)
                    else:
                        _loan.makePayment()
        return loan_list

    def avalanche_summary(loan_list):
        """prints summary results for the simulation"""
        for loan in loan_list:
            loan.print_sim_summary()

    def totals(loan_list):
        """returns a list of the simulation total paid and interest paid"""
        paid = sum([loan.sim_summary()[2] for loan in loan_list])
        interest = sum([loan.sim_summary()[3] for loan in loan_list])
        return [paid, interest]

    # # some fake loans
    # a = Fixed(1000.0,0.35,12) # credit card
    # b = Fixed(200000.0,0.035,360) # mortgage
    # c = Fixed(25000.0,0.02,60) # car loan
    # d = Fixed(20000.0, 0.04,120) # student loan

    import copy

    # loan_list_a = [a,b,c,d]
    # loan_list_b = copy.deepcopy([a,b,c,d])

    loan_list_a = copy.deepcopy(loan_list)
    loan_list_b = copy.deepcopy(loan_list)

    print('='*10,'avalanche method','='*10)
    ava = avalanche(loan_list_a,budget,select_loan_rate)
    avalanche_summary(ava)
    print(totals(ava))

    #===========================================================================
    # interst payment method
    #===========================================================================

    print('='*10,'interest payment method','='*10)
    int_pmt = avalanche(loan_list_b,budget,select_loan_pmt)
    avalanche_summary(int_pmt)
    print(totals(int_pmt))


import torch
import torch.nn as nn
import torch.nn.functional as F

class Conv2dReLU(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, padding=0,
                 stride=1, use_batchnorm=True, **batchnorm_params):
        super().__init__()

        layers = [
            nn.Conv2d(in_channels, out_channels, kernel_size,
                      stride=stride, padding=padding, bias=not (use_batchnorm)),
            nn.ReLU(inplace=True),
        ]

        if use_batchnorm:
            layers.insert(1, nn.BatchNorm2d(out_channels, **batchnorm_params))

        self.block = nn.Sequential(*layers)

    def forward(self, x):
        return self.block(x)

class VGGBlock(nn.Module):
    def __init__(self, in_channels, out_channels, use_batchnorm = True, act_func=nn.ReLU(inplace=True)):
        super(VGGBlock, self).__init__()
        self.use_batchnorm = use_batchnorm

        self.act_func = act_func
        self.conv1 = nn.Conv2d(in_channels, out_channels, 3, padding=1)
        self.bn1 = nn.BatchNorm2d(out_channels)
        self.conv2 = nn.Conv2d(out_channels, out_channels, 3, padding=1)
        self.bn2 = nn.BatchNorm2d(out_channels)

    def forward(self, x):
        out = self.conv1(x)
        if (self.use_batchnorm):
            out = self.bn1(out)
        out = self.act_func(out)

        out = self.conv2(out)
        if (self.use_batchnorm):
            out = self.bn2(out)
        out = self.act_func(out)
        return out

###########################################################################
############################ MAIN MODEL BLOCKS ############################
###########################################################################

class Model(nn.Module):

    def __init__(self):
        super().__init__()

    def initialize(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
            elif isinstance(m, nn.BatchNorm2d):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)

class EncoderDecoder(Model):

    def __init__(self, encoder, decoder, activation):
        super().__init__()
        self.encoder = encoder
        self.decoder = decoder

        if callable(activation) or activation is None:
            self.activation = activation
        elif activation == 'softmax':
            self.activation = nn.Softmax(dim=1)
        elif activation == 'sigmoid':
            self.activation = nn.Sigmoid()
        else:
            raise ValueError('Activation should be "sigmoid"/"softmax"/callable/None')

    def forward(self, x):
        """Sequentially pass `x` trough model`s `encoder` and `decoder` (return logits!)"""
        x = self.encoder(x)
        x = self.decoder(x)
        return x

    def predict(self, x):
        """Inference method. Switch model to `eval` mode, call `.forward(x)`
        and apply activation function (if activation is not `None`) with `torch.no_grad()`

        Args:
            x: 4D torch tensor with shape (batch_size, channels, height, width)

        Return:
            prediction: 4D torch tensor with shape (batch_size, classes, height, width)

        """
        if self.training:
            self.eval()

        with torch.no_grad():
            x = self.forward(x)
            if self.activation:
                x = self.activation(x)

        return x

class DecoderBlock(nn.Module):
    def __init__(self, in_channels, out_channels, use_batchnorm=True):
        super().__init__()
        self.block = nn.Sequential(
            Conv2dReLU(in_channels, out_channels, kernel_size=3, padding=1, use_batchnorm=use_batchnorm),
            Conv2dReLU(out_channels, out_channels, kernel_size=3, padding=1, use_batchnorm=use_batchnorm),
        )

    def forward(self, x):
        x, skip = x
        x = F.interpolate(x, scale_factor=2, mode='nearest')
        if skip is not None:
            x = torch.cat([x, skip], dim=1)
        x = self.block(x)
        return x

class CenterBlock(DecoderBlock):

    def forward(self, x):
        return self.block(x)

###########################################################################
########################## PYRAMID POOLING BLOCKS #########################
###########################################################################

class PyramidPoolingModule(nn.Module):
    def __init__(self, pool_list, in_channels, size=(128, 128), mode='bilinear'):
        super(PyramidPoolingModule, self).__init__()
        self.pool_list = pool_list
        self.relu = nn.ReLU(inplace=True)
        self.conv1 = nn.ModuleList([
            nn.Conv2d(in_channels, in_channels, kernel_size=1, stride=1, padding=0) for _ in range(len(pool_list))])
        if mode == 'bilinear':
            self.upsample = nn.Upsample(size=size, mode=mode, align_corners=True)
        else:
            self.upsample = nn.Upsample(size=size, mode=mode)
            # self.conv2 = nn.Conv2d(in_channels * (1 + len(pool_list)), in_channels, kernel_size=1)

    def forward(self, x):
        cat = [x]
        for (k, s), conv in zip(self.pool_list, self.conv1):
            out = F.avg_pool2d(x, kernel_size=k, stride=s)
            out = conv(out)
            out = self.upsample(out)
            cat.append(out)
        out = torch.cat(cat, 1)
        # out = self.conv2(out)
        # out = self.relu(out)
        return out

class AtrousSpatialPyramidPooling(nn.Module):
    def __init__(self, in_channels, depth, atrous_rates=[12, 24, 36]):
        super(AtrousSpatialPyramidPooling, self).__init__()
        self.conv1 = ConvBn2d(in_channels, depth, kernel_size=1, stride=1, padding=0)
        self.conv3_1 = ConvBn2d(in_channels, depth, kernel_size=3, padding=atrous_rates[0], dilation=atrous_rates[0])
        self.conv3_2 = ConvBn2d(in_channels, depth, kernel_size=3, padding=atrous_rates[1], dilation=atrous_rates[1])
        self.conv3_3 = ConvBn2d(in_channels, depth, kernel_size=3, padding=atrous_rates[2], dilation=atrous_rates[2])
        self.pool = nn.AdaptiveAvgPool2d(1)
        self.im_conv1 = ConvBn2d(in_channels, depth, kernel_size=1, stride=1, padding=0)
        self.upsample = nn.Upsample(size=(128, 128), mode='bilinear', align_corners=True)
        self.final_conv1 = ConvBn2d(depth * 5, depth, kernel_size=1, stride=1, padding=0)

    def forward(self, x):
        rate1 = self.conv1(x)
        rate2 = self.conv3_1(x)
        rate3 = self.conv3_2(x)
        rate4 = self.conv3_3(x)

        im_level = self.pool(x)
        im_level = self.im_conv1(im_level)
        im_level = self.upsample(im_level)

        out = torch.cat([
            rate1,
            rate2,
            rate3,
            rate4,
            im_level
        ], 1)

        out = self.final_conv1(out)
        return out

###########################################################################
############################ EMANet BLOCKS #################################
###########################################################################

class EMAModule(nn.Module):

    def __init__(self, channels, K, lbda=1, alpha=0.1, T=3):
        super().__init__()
        self.T = T
        self.alpha = alpha
        self.lbda = lbda
        self.conv1_in = nn.Conv2d(channels, channels, kernel_size=1, padding=0)
        self.conv1_out = nn.Conv2d(channels, channels, kernel_size=1, padding=0)
        self.bn_out = nn.BatchNorm2d(channels)
        self.register_buffer('bases', torch.empty(K, channels)) # K x C
        # self.bases = Parameter(torch.empty(K, channels), requires_grad=False) # K x C
        nn.init.kaiming_uniform_(self.bases, a=math.sqrt(5))
        # self.bases.data = F.normalize(self.bases.data, dim=-1)

    def forward(self, x):
        B, C, H, W = x.shape
        residual = x
        x = self.conv1_in(x).view(B, C, -1).transpose(1, -1) # B x N x C

        bases = self.bases[None, ...]
        x_in = x.detach()
        for i in range(self.T):
            # Expectation
            if i == (self.T - 1):
                x_in = x
            z = torch.softmax(self.lbda * torch.matmul(x_in, bases.transpose(1, -1)), dim=-1)  # B x N x K
            # Maximization
            bases = torch.matmul(z.transpose(1, 2), x_in) / (z.sum(1)[..., None] + 1e-12) # B x K x C
            bases = F.normalize(bases, dim=-1)
        if self.training:
            self.bases.data = (1 - self.alpha) * self.bases + self.alpha * bases.detach().mean(0)

        x = torch.matmul(z, bases).transpose(1, -1).view(B, C, H, W)
        x = self.conv1_out(x)
        x = self.bn_out(x)
        x += residual
        return x

class GlobalAttentionUpsample(nn.Module):
    def __init__(self, skip_channels, channels, out_channels=None):
        super(GlobalAttentionUpsample, self).__init__()
        self.out_channels = out_channels
        if out_channels is None:
            out_channels = channels
        self.conv3 = nn.Conv2d(skip_channels, channels, kernel_size=3, padding=1)
        self.relu = nn.ReLU(inplace=True)
        self.conv1 = ConvBn2d(channels, channels, kernel_size=1, padding=0)
        self.GPool = nn.AdaptiveAvgPool2d(output_size=1)
        self.upsample = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)
        if out_channels is not None:
            self.conv_out = ConvBn2d(channels, out_channels, kernel_size=1, padding=0)

    def forward(self, x, skip, up=True):
        # Reduce channels
        skip = self.conv3(skip)
        # Upsample
        if up:
            x = self.upsample(x)
        # GlobalPool and conv1
        cal1 = self.GPool(x)
        cal1 = self.conv1(cal1)
        cal1 = self.relu(cal1)

        # Calibrate skip connection
        skip = cal1 * skip
        # Add
        x = x + skip
        if self.out_channels is not None:
            x = self.conv_out(x)
        return x

###########################################################################
############################ PANet BLOCKS #################################
###########################################################################

class FeaturePyramidAttention(nn.Module):
    def __init__(self, channels, out_channels=None):
        super(FeaturePyramidAttention, self).__init__()
        if out_channels is None:
            out_channels = channels
        self.conv1 = nn.Conv2d(channels, out_channels, kernel_size=1, stride=1, padding=0)
        self.conv1p = nn.Conv2d(channels, out_channels, kernel_size=1, stride=1, padding=0)

        self.conv3a = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1)
        self.conv3b = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1)

        self.conv5a = nn.Conv2d(out_channels, out_channels, kernel_size=5, stride=1, padding=2)
        self.conv5b = nn.Conv2d(out_channels, out_channels, kernel_size=5, stride=1, padding=2)

        self.conv7a = nn.Conv2d(channels, out_channels, kernel_size=7, stride=1, padding=3)
        self.conv7b = nn.Conv2d(out_channels, out_channels, kernel_size=7, stride=1, padding=3)

        self.GPool = nn.AdaptiveAvgPool2d(output_size=1)

        self.downsample = nn.AvgPool2d(kernel_size=2, stride=2)
        self.upsample = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)

    def forward(self, x, mode='std'):
        H, W = x.shape[2:]
        # down-path
        if mode == 'std':
            xup1 = self.downsample(x)
            xup1 = self.conv7a(xup1)
        elif mode == 'reduced':
            xup1 = self.conv7a(x)
        elif mode == 'extended':
            xup1 = F.avg_pool2d(x, kernel_size=4, stride=4)
            xup1 = self.conv7a(xup1)

        xup2 = self.downsample(xup1)
        xup2 = self.conv5a(xup2)

        xup3 = self.downsample(xup2)
        xup3 = self.conv3a(xup3)

        # Skips
        x1 = self.conv1(x)
        xup1 = self.conv7b(xup1)
        xup2 = self.conv5b(xup2)
        xup3 = self.conv3b(xup3)

        # up-path

        xup2 = self.upsample(xup3).view(xup2.shape) + xup2
        xup1 = self.upsample(xup2) + xup1

        # Global Avg Pooling
        gp = self.GPool(x)
        gp = self.conv1p(gp)
        gp = F.upsample(gp, size=(H, W), mode='bilinear', align_corners=True)

        # Merge
        if mode == 'std':
            x1 = self.upsample(xup1) * x1
        elif mode == 'reduced':
            x1 = xup1 * x1
        elif mode == 'extended':
            x1 = F.upsample(xup1, scale_factor=4, mode='bilinear', align_corners=True) * x1
        x1 = x1 + gp
        return x1

class FeaturePyramidAttention_v2(nn.Module):
    def __init__(self, channels, out_channels=None):
        super().__init__()
        if out_channels is None:
            out_channels = channels
        self.conv1 = ConvBn2d(channels, out_channels, kernel_size=1, stride=1, padding=0, act=True)
        self.conv1p = ConvBn2d(channels, out_channels, kernel_size=1, stride=1, padding=0, act=True)

        self.conv3a = ConvBn2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1, act=True)
        self.conv3b = ConvBn2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1, act=True)

        self.conv5a = ConvBn2d(out_channels, out_channels, kernel_size=5, stride=1, padding=2, act=True)
        self.conv5b = ConvBn2d(out_channels, out_channels, kernel_size=5, stride=1, padding=2, act=True)

        self.conv7a = ConvBn2d(channels, out_channels, kernel_size=7, stride=1, padding=3, act=True)
        self.conv7b = ConvBn2d(out_channels, out_channels, kernel_size=7, stride=1, padding=3, act=True)

        self.GPool = nn.AdaptiveAvgPool2d(output_size=1)

        self.downsample = nn.AvgPool2d(kernel_size=2, stride=2)
        self.upsample = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)

    def forward(self, x, mode='std'):
        H, W = x.shape[2:]
        # down-path
        if mode == 'std':
            xup1 = self.downsample(x)
            xup1 = self.conv7a(xup1)
        elif mode == 'reduced':
            xup1 = self.conv7a(x)

        xup2 = self.downsample(xup1)
        xup2 = self.conv5a(xup2)

        xup3 = self.downsample(xup2)
        xup3 = self.conv3a(xup3)

        # Skips
        x1 = self.conv1(x)
        xup1 = self.conv7b(xup1)
        xup2 = self.conv5b(xup2)
        xup3 = self.conv3b(xup3)

        # up-path
        xup2 = self.upsample(xup3) + xup2
        xup1 = self.upsample(xup2) + xup1

        # Global Avg Pooling
        gp = self.GPool(x)
        gp = self.conv1p(gp)
        gp = F.upsample(gp, size=(H, W), mode='bilinear', align_corners=True)

        # Merge
        if mode == 'std':
            x1 = self.upsample(xup1) * x1
        elif mode == 'reduced':
            x1 = xup1 * x1
        x1 = x1 + gp
        return x1


import gdax, time
import pandas as pd
from bintrees import RBTree
from decimal import Decimal
from bson.decimal128 import Decimal128

from DBService import DBService
from Logging import Logging

class DataFeed():
    def __init__(self, public_client, book, whale_tracker, ticker):
        self._public_client = public_client
        self._book = book
        self._ticker = ticker
        self._whale_tracker = whale_tracker
        self._db_service = DBService()

    def start(self):
        print("starting feed...")
        self._open = True
        while self._open:
            self.fetchTicker()
            self.fetchBookState()
            self.fetchWhaleState()

    def stop(self):
        self._open = False

    def fetchTicker(self):
        #Logging.logger.info("fetching ticker...")
        tick = self._public_client.get_product_ticker(product_id=self._ticker)
        self._db_service.write_ticker(tick)

    def fetchBookState(self):
        #Logging.logger.info("fetching book state...")
        book_state = self._book.get_current_book()
        self._db_service.write_book_state(book_state)

    def fetchWhaleState(self):
        #Logging.logger.info("fetching whale state...")
        whale_state = self._whale_tracker.get_current_whales()
        self._db_service.write_whale_state(whale_state)


"""
Infers the requirement of a lambda by detecting which expressions use the
``?`` placeholder.

Only expressions in an assignment or in parameter positions are transformed.

>>> pipe.map( 'foo' + ?.lower() )
  # pipe.map( lambda __1, *args: 'foo' + __1.lower() )

TODO: Support multiple placeholders `?1 + ?2` -- `??` is whole varargs

"""

import ast
from io import StringIO

from pysh.transforms import TokenIO

PLACEHOLDER = '__INFERRED_LAMBDA_PLACEHOLDER__'

def lexer(code: StringIO) -> StringIO:
    """
    Lexer just replaces the ``?`` placeholder with something that doesn't
    make the Python parser chock up.
    """
    out = TokenIO()
    tokens = TokenIO(code).iter_tokens()
    for tkn in tokens:
        if tkn.string == '?':
            out.write_token(tkn, override=PLACEHOLDER)
        else:
            out.write_token(tkn)

    return out

class InferredLambdaTransformer(ast.NodeTransformer):

    def __init__(self):
        self.placeholder = PlaceholderTransformer()
        self.found = False

    def do_placeholder(self, node: ast.expr) -> ast.expr:
        self.placeholder.reset()
        node = self.placeholder.visit(node)
        if self.placeholder.replaced:
            node = ast.Lambda(
                args=ast.arguments(
                    args=[],
                    vararg=ast.arg(arg='__varargs'),
                    kwonlyargs=[],
                    kw_defaults=[],
                    kwarg=None,
                    defaults=[]),
                body=node,
                lineno=node.lineno,
                col_offset=node.col_offset)

            ast.fix_missing_locations(node)

        return node

    def visit_Name(self, node: ast.Name) -> ast.Name:
        if node.id == PLACEHOLDER:
            self.found = True

        return node

    def visit_Assign(self, node: ast.Assign) -> ast.Assign:
        self.found = False
        self.generic_visit(node)
        if self.found:
            node.value = self.do_placeholder(node.value)

        return node

    def visit_Call(self, node: ast.Call) -> ast.Call:
        self.found = False
        self.generic_visit(node)
        if self.found:
            node.args = [self.do_placeholder(x) for x in node.args]
            node.keywords = [(arg, self.do_placeholder(value)) for arg,value in node.keywords]

        return node

class PlaceholderTransformer(ast.NodeTransformer):

    def __init__(self):
        self.replaced = False

    def reset(self):
        self.replaced = False

    def visit_Name(self, node: ast.Name) -> ast.Name:
        if node.id == PLACEHOLDER:
            self.replaced = True
            node = ast.Subscript(
                value=ast.Name(id='__varargs', ctx=ast.Load()),
                slice=ast.Index(value=ast.Num(0)),
                ctx=ast.Load(),
                lineno=node.lineno,
                col_offset=node.col_offset)
            ast.fix_missing_locations(node)

        return node

class PlaceholderVisitor(ast.NodeVisitor):

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

    def visit_Name(self, node: ast.Name) -> ast.Name:
        if node.id == PLACEHOLDER:
            from warnings import warn_explicit
            message = (
                'Detected an un-transformed lazyexpr `?` symbol. '
                'Only valid in assignments or argument positions. '
                '(from pysh.transform.alpha.lazyexpr)'
            ).format(id)

            warn_explicit(message, SyntaxWarning, self.fname, node.lineno)

def parser(node: ast.AST, fname: str) -> ast.AST:
    node = InferredLambdaTransformer().visit(node)
    PlaceholderVisitor(fname).visit(node)
    return node

code = '''\
print(list( map(?.lower(), ['Foo', 'Bar']) ))
'''

out = lexer(StringIO(code))
print(out.getvalue())

import ast, pprint
node = ast.parse(out.getvalue())
node = parser(node, '<code>')
print(ast.dump(node).replace("],", "\n],\n").replace('=[', '=[\n'))
co_code = compile(node, '<code>', 'exec')
exec(co_code)


# PROBLEM 54 Poker hands

# https://projecteuler.net/problem=54

# ----------- PSEUDOCODE -------------

# load the file and loop over rows
#   split each row for two players
#   check card rankings for players and compare
#   add 1 for the winner
# print player 1 wins

# -------------- CODE ----------------
from time import time

def timing(func):
    """ Decorator function for calculating working time of another function."""
    def wrapper(*args, **kwargs):
        time_1 = time()
        return_var = func(*args, **kwargs)
        time_2 = time()
        print('Function worked: ', str(time_2-time_1)[:5], ' sec.')
        return return_var
    return wrapper()

class FileHandler():
    """Class for handling poker files."""

    def __init__(self, file_path: str):
        self.file_path = file_path

    def get_file_data(self) -> list:
        """ Generator function yields next list of cards in txt file row"""
        with open(self.file_path, mode='r') as file:
            while True:
                line = file.readline()
                if len(line) == 0:
                    break
                line_list = line[0:-1].split(' ')

                split_players = self._split_players(line_list)

                yield split_players

    def _split_players(self, card_list: list) -> tuple:
        """ Returns cards split for players """
        cards_split = []
        no_cards_for_plr = int(len(card_list) / 2)
        no_of_plrs = int(len(card_list) / 5)

        for i in range(0, no_of_plrs):
            ran_start = i * no_cards_for_plr
            ran_stop = ((i + 1) * no_cards_for_plr)
            plr = [i for i in card_list[ran_start:ran_stop]]
            cards_split.append(plr)

        return cards_split

class PokerOperator():
    """Class works as operator for players and game."""

    @staticmethod
    def compare_cards(scores: list, highest_cards: list) -> int:
        """ Compares card rankings of players. """

        # Known issue: Cards comparission works only for highest cards in sets, so if in both sets are same cards

        score_values = {
            '2': 2,
            '3': 3,
            '4': 4,
            '5': 5,
            '6': 6,
            '7': 7,
            '8': 8,
            '9': 9,
            'T': 10,
            'J': 11,
            'Q': 12,
            'K': 13,
            'A': 14,
            'Pair': 20,
            'Two Pairs': 30,
            'Triple': 40,
            'Straight': 50,
            'Flush': 60,
            'Full House': 70,
            'Four of a Kind': 80,
            'Straight Flush': 90,
        }

        score_list = []
        score_highest = []

        # Scores are equal -> compare highest cards
        if scores[0] == scores[1]:
            for player in highest_cards:
                key = list(player.keys())[0]
                value = score_values.get(key)
                score_highest.append(value)

            if score_highest[0] == score_highest[1]:
                raise Exception('Tie in first highest card check!')

            winner = score_highest.index(max(score_highest))+1
            return winner

        # Scores are same type but different score highest card
        plr1_key = list(scores[0].keys())[0]
        plr2_key = list(scores[1].keys())[0]
        if plr1_key == plr2_key:
            if scores[0].get(plr1_key) > scores[1].get(plr2_key):
                winner = 1
            else:
                winner = 2
            return winner

            # Else
        for player in scores:
            score = list(player.keys())[0]
            value = score_values.get(score)
            score_list.append(value)

        check_set = set(score_list)

        winner = score_list.index(max(score_list))+1
        return winner

class Cards():
    """Class represents cards in player's hand."""
    values = ['2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A']
    colors = ['H', 'C', 'S', 'D']
    scoring = {k: v for v, k in enumerate(values, start=2)}

    def __init__(self, cards: list):
        self.cards = cards
        self.cards.sort()
        self.cards_string = self._cards_str()

    def _cards_str(self):
        cards_string = ''

        for i in self.cards:
            cards_string += i

        return cards_string

    def _all_color(self) -> bool:
        """ Checks if all cards are the same color."""
        check_set = set()

        for card in self.cards:
            color = card[1]
            check_set.add(color)

        if len(check_set) == 1:
            return True
        return False

    def _consecutive_cards(self) -> bool:
        """ Checks if all cards are consecutive."""
        check_list = [self.scoring.get(card[0]) for card in self.cards]
        check_list.sort()

        for i in range(1, 5):
            if check_list[0] != check_list[i]-i:
                return False
        return True

    def has_ranked_cards(self) -> bool:
        """ Method checks if card set has any ranked figures. If has, returns True."""

        for i in self.values:
            check = self.cards_string.count(i)
            if check > 1:
                return True

        for i in self.colors:
            check = self.cards_string.count(i)
            if check > 4:
                return True

        if self._consecutive_cards():
            return True

        return False

    def highest_card(self) -> dict:
        """ Method checks the highest card in card set."""
        highest_card = {}
        highest_score = 0

        for card in self.cards:
            key = card[0]
            if self.scoring[key] > highest_score:
                highest_score = self.scoring[key]
                highest_card = {key: self.scoring[key]}

        return highest_card

    def repeated_card_values(self) -> dict:
        """ Method checks if pairs, threes and fours of cards of one kind occurs in a set. If no repeated cards found then returns highest card"""
        help_result = dict()
        result = dict()

        for val in self.values:
            count = self.cards_string.count(val)
            if count > 1:
                help_result.update({val: count})

        if len(help_result) == 0:
            return self.highest_card()

        dict_key = list(help_result.keys())
        dict_val = list(help_result.values())
        val_set = set(dict_val)
        key = dict_key[0]
        value = help_result.get(key)
        score = self.scoring.get(key)

        if len(help_result) > 1:
            key_for_3 = ''
            score_for_2 = 0

            if val_set == {2}:
                for key in dict_key:
                    val = help_result.get(key)
                    if val == 2:
                        scr = self.scoring.get(key)
                        if scr > score_for_2:
                            score_for_2 = scr

                result.update({'Two Pairs': score_for_2})
                return result

            elif val_set == {2, 3}:
                for key in dict_key:
                    if help_result.get(key) == 3:
                        key_for_3 = key

                score_tri = self.scoring.get(key_for_3)
                result.update({'Full House': score_tri})
                return result

        if value == 2:
            result.update({'Pair': score})
            return result
        elif value == 3:
            result.update({'Triple': score})
            return result
        elif value == 4:
            result.update({'Four of a Kind': score})
            return result

    def straight_flush(self) -> dict:
        """ Method checks Straight, Flush, Straight Flush and Royal Flush type figures for a card set."""
        result = {}

        consecutive_cards = self._consecutive_cards()
        all_color = self._all_color()
        highest = self.highest_card()
        val = list(highest.values())[0]

        if consecutive_cards and all_color:
            result = {'Straight Flush': val}
        elif consecutive_cards:
            result = {'Straight': val}
        elif all_color:
            result = {'Flush': val}
        else:
            return None
        return result

    def score(self) -> dict:
        """ Method returns highest score rank of the card set."""
        if not self.has_ranked_cards():
            return self.highest_card()

        check = self.straight_flush()
        if check != None:
            return check
        else:
            return self.repeated_card_values()

# -------------- TESTS ---------------

def test_FileHandler():
    # given
    test_file_path = './0054poker.txt'
    test_file_handler = FileHandler(test_file_path)

    iterator = test_file_handler.get_file_data()
    # when
    first_row = next(iterator)
    # then
    assert first_row == [['8C', 'TS', 'KC', '9H',
                          '4S'], ['7D', '2S', '5D', '3S', 'AC']]
    assert next(iterator) == [['5C', 'AD', '5D', 'AC',
                               '9C'], ['7C', '5H', '8D', 'TD', 'KS']]

def test_PokerOperator():
    # given
    operator = PokerOperator()
    compare = [{'Full House': 10}, {'K': 13}]
    highest = [{'Q': 12}, {'K': 13}]
    # when
    result = operator.compare_cards(compare, highest)
    # then
    assert result == 1
    assert operator.compare_cards(
        [{'Full House': 10}, {'Full House': 10}], [{'Q': 12}, {'K': 13}]) == 2

def test_Cards():
    card_set_1 = ['8C', 'TS', 'KC', '9H', '4S']
    card_set_2 = ['8C', '8S', 'TS', 'JS', 'QS']
    card_set_3 = ['8C', '8S', 'TS', 'TC', 'TD']
    card_set_4 = ['QC', 'QS', 'QD', 'QH', 'AS']
    card_set_5 = ['2S', '5S', '7S', 'TS', 'QS']
    card_set_6 = ['4S', '5S', '6S', '7S', '8S']
    card_set_7 = ['QC', 'QS', 'QD', 'QH', 'AS']
    card_set_8 = ['QC', 'QS', 'QD', 'KH', 'AS']
    card_set_9 = ['3S', 'QH', '5S', '6S', 'AS']
    card_set_10 = ['6D', '6C', 'TD', 'TH', 'KD']

    cards_1 = Cards(card_set_1)
    cards_2 = Cards(card_set_2)
    cards_3 = Cards(card_set_3)
    cards_4 = Cards(card_set_4)
    cards_5 = Cards(card_set_5)
    cards_6 = Cards(card_set_6)
    cards_7 = Cards(card_set_7)
    cards_8 = Cards(card_set_8)
    cards_9 = Cards(card_set_9)
    cards_10 = Cards(card_set_10)

    # then
    assert cards_1.has_ranked_cards() == False
    assert cards_2.has_ranked_cards() == True
    assert cards_9.has_ranked_cards() == False
    assert cards_1.highest_card() == {'K': 13}
    assert cards_1.repeated_card_values() == {'K': 13}
    assert cards_2.repeated_card_values() == {'Pair': 8}
    assert cards_3.repeated_card_values() == {'Full House': 10}
    assert cards_4.repeated_card_values() == {'Four of a Kind': 12}
    assert cards_8.repeated_card_values() == {'Triple': 12}
    assert cards_5.straight_flush() == {'Flush': 12}
    assert cards_6.straight_flush() == {'Straight Flush': 8}
    assert cards_6.score() == {'Straight Flush': 8}
    assert cards_3.score() == {'Full House': 10}
    assert cards_9.score() == {'A': 14}
    assert cards_10.score() == {'Two Pairs': 10}

# --------------- RUN ---------------
if __name__ == '__main__':
    path = './0054poker.txt'
    file = FileHandler(path)

    plr1_wins = 0
    plr2_wins = 0

    for i in file.get_file_data():
        print(i)
        player_1 = Cards(i[0])
        player_2 = Cards(i[1])

        scores = [player_1.score(), player_2.score()]
        highest_cards = [player_1.highest_card(), player_2.highest_card()]

        winner = PokerOperator.compare_cards(scores, highest_cards)

        print(f'Player 1 score: {scores[0]}.',
              f'Player 2 score: {scores[1]}.', f'\nWinner is player {winner}')

        if winner == 1:
            plr1_wins += 1
        elif winner == 2:
            plr2_wins += 1
        else:
            raise Exception('Something is wrong!')

    print('Player 1 wins:', plr1_wins, '\nPlayer 2 wins:', plr2_wins)

# ------------ RESULT -------------

# Player 1 wins: 376
# Player 2 wins: 624


#!/usr/bin/python3

import sys
import queue
import math

class AStar:
    def __init__(self, n, adj, cost, x, y):
        # See the explanations of these fields in the starter for friend_suggestion
        self.n = n
        self.adj = adj
        self.cost = cost
        self.inf = n*10**6
        self.d = [self.inf]*n
        self.visited = [False]*n
        # Coordinates of the nodes
        self.x = x
        self.y = y

    # See the explanation of this method in the starter for friend_suggestion
    def clear(self):
        for v in range(self.n):
            self.d[v] = self.inf
            self.visited[v] = False

    # See the explanation of this method in the starter for friend_suggestion
    def visit(self, q, v, u, dist, t):
        self.visited[v] = True
        if self.d[v] > self.d[u] + dist:
            self.d[v] = self.d[u] + dist
            q.put(v, self.compute_distance(v, t))

    def compute_distance(self, v, t):
        return math.sqrt((self.x[t] - self.x[v])**2 + (self.y[t] - self.y[v])**2)
    def extract_min(self, q):
        v = q.get()
        return int(v)
    # Returns the distance from s to t in the graph
    def query(self, s, t):
        self.clear()
        q = queue.PriorityQueue()
        self.d[s] = 0
        q.put(self.compute_distance(s, t), s)
        u = self.extract_min(q)
        while not q.empty():
            u = self.extract_min(q)
            if u == t:
                return self.d[u]
            for v, w in zip(adj[u], cost[u]):
                if not self.visited[v]:
                    self.visit(q, v, u, w, t)
                elif v == t:
                    return self.d[v]
                else:
                    return -1
        return -1

def readl():
    return map(int, sys.stdin.readline().split())

if __name__ == '__main__':
    n,m = readl()
    x = [0 for _ in range(n)]
    y = [0 for _ in range(n)]
    adj = [[] for _ in range(n)]
    cost = [[] for _ in range(n)]
    for i in range(n):
        a, b = readl()
        x[i] = a
        y[i] = b
    for e in range(m):
        u,v,c = readl()
        adj[u-1].append(v-1)
        cost[u-1].append(c)
    t, = readl()
    astar = AStar(n, adj, cost, x, y)
    for i in range(t):
        s, t = readl()
        print(astar.query(s-1, t-1))


def create_BASIN(model,DIR_out,fname):
    '''
    ----------------------------------------------------------------------
    Note
       surface basin index
    ----------------------------------------------------------------------
    '''
    import os
    import shutil
    import subprocess
    from post_process import execute_ncl_calculate
    script=os.environ["SRCDIR"]+"create_BASIN_step1.ncl"
    sname=os.path.splitext(os.path.basename(script))[0]
    ncl=os.environ["SRCDIR"]+sname+"_"+fname+".ncl"
    shutil.copy(script,ncl)
    subprocess.call(["sed", "-i", "s#CCSM4#"+model+"#g", ncl])
    subprocess.call(["sed", "-i", "s#vo#"+fname+"#g", ncl])

    print("Initializing Surface BASIN INDEX ...")
    execute_ncl_calculate(ncl)
    os.system("rm -f "+ncl)

    script=os.environ["SRCDIR"]+"create_BASIN_step3.ncl"
    sname=os.path.splitext(os.path.basename(script))[0]
    ncl=os.environ["SRCDIR"]+sname+"_"+fname+".ncl"
    shutil.copy(script,ncl)
    subprocess.call(["sed", "-i", "s#CCSM4#"+model+"#g", ncl])
    subprocess.call(["sed", "-i", "s#vo#"+fname+"#g", ncl])
    print("Finalizing Surface BASIN INDEX ...")
    execute_ncl_calculate(ncl)
    os.system("rm -f "+ncl)

    fp2=open(os.environ["OUTDIR"]+model+".BASIN_"+fname+"_step.txt","r")
    num=fp2.readline()[0:-1]
    fp2.close()
    os.rename(DIR_out+model+".BASIN_"+fname+"_step"+num+".nc", DIR_out+model+".BASIN_"+fname+".fx.nc")
    os.system("rm -f "+DIR_out+model+".BASIN_"+fname+"_step*.nc")
    os.system("rm -f "+DIR_out+model+".BASIN_"+fname+"_step.txt")

# ======================================================================
# create_INDEX.py
#
#   Create 3D land/basin Mask
#    as part of functionality provided by (basin_lat_dxdydz.py)
#
#   Version 1 revision 2 8-Jan-2017 Fuchang Wang (FSU/COAPS)
#   Contributors:
#   PI: Xiaobiao Xu (FSU/COAPS)
#
#   Method:
#    Use calculated model's basin Mask as reference
#     (1) Assign all levels' mask same as surface
#     (2) Identify model's land grids and set them to missing value
#       For those whose variables over land is 0 instead of missing value, how to identify land?
#       same as create_BASIN.py does. If all time-span and all column are 0, then it is land.
#
#   Depends on the following scripts:
#    (1) create_BASIN.py
#
#   The following 3 variables are required:
#     (1) 2D calculated basin mask (ind, units: "1", create_BASIN.py)
#     (2) 4D velocity (vo, units: m/s, models outputs)
#     (3) 4D salinity (so, units: psu or g/kg or kg/kg, models outputs)
#
# OPEN SOURCE COPYRIGHT Agreement TBA
# ======================================================================
def create_INDEX(model,DIR_out,fname):
    '''
    ----------------------------------------------------------------------
    Note
       3D basin index
    ----------------------------------------------------------------------
    '''
    import os
    import shutil
    import subprocess
    from post_process import execute_ncl_calculate
    script=os.environ["SRCDIR"]+"create_INDEX.ncl"
    sname=os.path.splitext(os.path.basename(script))[0]
    ncl=os.environ["SRCDIR"]+sname+"_"+fname+".ncl"
    shutil.copy(script,ncl)
    subprocess.call(["sed", "-i", "s#CCSM4#"+model+"#g", ncl])
    subprocess.call(["sed", "-i", "s#vo#"+fname+"#g", ncl])
    print("COMPUTING 3D BASIN INDEX ...")
    execute_ncl_calculate(ncl)
    os.system("rm -f    "+ncl)


from typing import Optional
from fastapi import APIRouter, Query
#from apis.api_components.wikipedia_fetch import wikipedia_fetch_prof
import urllib.request as req
import urllib.parse as up
#import lxml.html as lh
import json

router = APIRouter()

@router.get("/get_wikipedia_prof/")
def get_wikipedia_prof(q: str, count: Optional[int] = Query(None, ge=1)):
    """
    try:
        prof = wikipedia_fetch_prof(q)
    except Exception as e:
        # Wikipedia にページ/Infobox がない場合？
        prof = {}

    if count:
        # python>=3.7
        prof = dict(list(prof.items())[:count])
    """
    prof = {}
    try:
        s_url = 'https://ja.wikipedia.org/api/rest_v1/page/summary/' + up.quote(q)
        request = req.Request(url=s_url)
        res = req.urlopen(request, timeout=10).read()
        resd = json.loads(res.decode('utf-8'))
        prof = resd
    except:
        return None, 404

    return prof, 200


import argparse
import io
from nltk.translate.bleu_score import corpus_bleu
import sys

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--input", required=False, type=str)
    parser.add_argument("--order", type=int, default=4)
    args = parser.parse_args()

    weights = [1. / args.order] * args.order

    input_lines = (io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8')
                   if args.input is None else open(args.input, encoding='utf-8'))

    hypotheses = [line.strip().split(' ') for line in input_lines]

    references = [hypotheses[:k] + hypotheses[k + 1:]
                  for k in range(len(hypotheses))]

    bleu = corpus_bleu(references, hypotheses, weights=weights)
    print(bleu)

if __name__ == '__main__':
    main()


from PyQt5.QtWidgets import QFileDialog
import webbrowser
from numpy import load, array
from os.path import splitext
from PIL import Image, ImageQt, ImageEnhance
from numpy.lib.npyio import save
DarkStyleSheet = '''QSlider::groove:horizontal{height:10px;margin:0 0}QSlider::handle:horizontal{background-color:#0096fa;border:1px;border-radius:3px;height:40px;width:40px;margin:0 0}QSlider::handle:horizontal:hover{background-color:#00c896;border:1px;border-radius:3px;height:40px;width:40px;margin:0 0}*{font:8pt "MS Shell Dlg 2"}#Tool_Box QLabel{font:10pt "MS Shell Dlg 2"}QGroupBox{color:#fff}QPushButton{background-color:#282828;border:none;border-radius:5px}QPushButton:hover{background-color:#323232;border:none}QPushButton:pressed{background-color:#0a0a0a;border:none}#VImage_Main{background-color:#1e1e1e}QLabel{color:#fff}QMenuBar{background:#282828;color:#fff}QMenu{background:#282828;color:#fff}QPushButton{color:white}'''
LightStyleSheet = '''QSlider::groove:horizontal{height:10px;margin:0 0}QSlider::handle:horizontal{background-color:#0096fa;border:1px;border-radius:3px;height:40px;width:40px;margin:0 0}QSlider::handle:horizontal:hover{background-color:#00c896;border:1px;border-radius:3px;height:40px;width:40px;margin:0 0}*{font:8pt "MS Shell Dlg 2"}#Tool_Box QLabel{font:10pt "MS Shell Dlg 2"}QPushButton{background-color:#e6f0f0;border:none;border-radius:5px}QPushButton:hover{background-color:#e6ffff;border:none}QPushButton:pressed{background-color:#c8ffff;border:none}#VImage_Main{background-color:#fff}'''

def Open():
    src_path, _ = QFileDialog.getOpenFileName(filter="Images (*.png *.jpg *.npy *.jpeg)")
    if(src_path != "" or src_path != None):
        name, exten = splitext(src_path)
        image = None
        if(exten == ".npy"):
            data = load(src_path)
            image = Image.fromarray(data)
        else:
            image = Image.open(src_path)
        return(src_path, ImageQt.ImageQt(image), image)
    else:
        return
def Save(image, dst_path):
    data = array(image)
    save(dst_path, data)

def SaveAs(image):
    dst_path, _ = QFileDialog.getSaveFileName(filter="VImage (*.npy)")
    if(dst_path == ""):
        return
    elif(dst_path != None):
        data = array(image)
        save(dst_path, data)
        return dst_path
    else:
        return

def DarkMode(window):
    window.setStyleSheet(DarkStyleSheet)

def LightMode(window):
    window.setStyleSheet(LightStyleSheet)

def AboutVCF():
    webbrowser.open("http://vcfstudio.in/about")

def AboutVImage():
    webbrowser.open("http://vcfstudio.in/vimage")

def ExportPNG(image):
    dst_path, _ = QFileDialog.getSaveFileName(filter="PNG (*.png)")
    if(dst_path == ""):
        return
    image.save(dst_path)

def ExportJPG(image):
    dst_path, _ = QFileDialog.getSaveFileName(filter="JPG (*.jpg *.jpeg)")
    if(dst_path == ""):
        return
    jpg_image = image.convert("RGB")
    jpg_image.save(dst_path)

def ExportPDF(image):
    dst_path, _ = QFileDialog.getSaveFileName(filter="PDF (*.pdf)")
    if(dst_path == ""):
        return
    pdf_image = image.convert("RGB")
    pdf_image.save(dst_path)


from enum import IntEnum
from abc import ABC, abstractmethod
import random
import numpy as np
from typing import List
from copy import deepcopy

from .game import Game, Agent, Action

# Tic-Tac-Toe implementation

class GamePlayer(IntEnum):
  EMPTY = 0
  NAUGHT = 1
  CROSS = 2

BOARD_DIM = 3
BOARD_SIZE = BOARD_DIM**2

# Easier to just hardcode the lines we have to check for the winner.
# Board dimensions won't change anyways.
CHECK_LINES = [
  [0, 1, 2], # rows
  [3, 4, 5],
  [6, 7, 8],
  [0, 3, 6], # cols
  [1, 4, 7],
  [2, 5, 8],
  [0, 4, 8], # diagonals
  [2, 4, 6]
]

def agent_id_to_char(cell: GamePlayer):
  if (cell == GamePlayer.CROSS):
    return "x"
  if (cell == GamePlayer.NAUGHT):
    return "o"
  return " "

class TicTacToeAction(Action):
  def __init__(self, i_agent: int, position: int):
    super().__init__(i_agent)
    self.position = position

  def is_legal(self, game: 'TicTacToeGame') -> bool:
    return game.board[self.position] == GamePlayer.EMPTY

  def run(self, game: 'TicTacToeGame'):
    assert self.is_legal(game)
    game.board[self.position] = game.players[self.i_agent]

class TicTacToeGame(Game):
  def __init__(self):
    super().__init__(n_agents = 2)
    self.players = [GamePlayer.NAUGHT, GamePlayer.CROSS]
    self.board = np.ndarray(shape=(1, BOARD_SIZE), dtype=int)[0]
    self.board.fill(GamePlayer.EMPTY)

  def is_game_over(self) -> bool:
    for indexes in CHECK_LINES:
      line = [self.board[i] for i in indexes]
      if (line[0] != GamePlayer.EMPTY and line[0] == line[1] == line[2]):
        return True

    for value in self.board:
      if (value == GamePlayer.EMPTY):
        return False

    return True

  def get_score(self, i_agent: int) -> int:
    winner = self.get_winner()
    if (winner == self.players[i_agent]):
      return 1
    return 0

  def get_winner(self) -> GamePlayer:
    for indexes in CHECK_LINES:
      line = [self.board[i] for i in indexes]
      if (line[0] != GamePlayer.EMPTY and line[0] == line[1] == line[2]):
        return line[0]
    return None

  def get_legal_actions(self, i_agent: int) -> List[TicTacToeAction]:
    return [TicTacToeAction(i_agent, i) for i in range(len(self.board)) if self.board[i] == GamePlayer.EMPTY]

  def get_hash(self) -> int:
    res = 0
    for i in range(BOARD_SIZE):
        res *= 3
        res += self.board[i]
    return res

  def __str__(self) -> str:
    result = ""
    for y in range(BOARD_DIM):
      if y > 0:
        result += "\n-----\n"
      for x in range(BOARD_DIM):
        if x > 0:
          result += "|"
        result += agent_id_to_char(self.board[x + y * BOARD_DIM])

    return result


import scrapy

from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule

from scrapy.http import FormRequest
import logging

#from sicop_project.items import PgsCategoryItem

class ProvidersPerWgscategorySpider(scrapy.Spider):
    name = 'providers_per_wgscategory'
    allowed_domains = ['www.sicop.go.cr']
    #global custom_count
    #custom_count = 0

#   -------------------------------------------------
#   CONFIGURATION VARIABLES
#   -------------------------------------------------

    log_root_dir =  '/usr/src/app/sicop_project/sicop_project/spider_logs'
    log_filename =  'providers_per_wgscategory_level4_spider_2023_test_v5.log'
    log_level = 'INFO'

#   -------------------------------------------------

    custom_settings = {
        'LOG_FILE': log_root_dir + '/' + log_filename,
        'LOG_LEVEL': log_level
     }

    def start_requests(self):
        import csv

        #   -------------------------------------------------
        #   CONFIGURATION VARIABLES
        #   -------------------------------------------------

        input_root_dir =  '/usr/src/app/sicop_project/sicop_project/crawled_data'
        input_filename = 'wgscategories_level4_onlyid_noheader_test_v5.csv'

        #   -------------------------------------------------
        category_id_list = []
        with open(input_root_dir + '/' + input_filename,'rt', encoding='utf-16') as csvfile:
            reader = csv.reader(csvfile, delimiter=',', quotechar='"')
            for row in reader:
                #print(', '.join(row))
                #logging.info(row[0])
                category_id_list.append(row[0])

        #category_id_list = [
        #    "10101599"
        #    ,"10101501"
        #    ,"10101502"
#
#
#        ]

        for category_id in category_id_list:
            # logging.info(category_id)
            frmdata = {
                "page_size": "1000000"
                ,"cate_id": category_id
                ,"query_fl" : "Y"
                ,"cate_nm" : category_id
            }
            url = "https://www.sicop.go.cr/usemn/co/UM_COJ_CIQ003.jsp"
            yield FormRequest(url, callback=self.parse, formdata=frmdata, headers={
                "Content-Type": "application/x-www-form-urlencoded"
            })

    def parse(self, response):
        #category_id = response.css('input[name="cate_id"]::attr(value)').get()
        category_id = response.request.body.decode(encoding="utf-8").split("cateId=",1)[1].split("&",1)[0]
        for row in response.css('.trow'):
            #columns = row.css('td::text').getall()
            values = []
            for column in row.css('td'):
                value = column.css('::text').get()
                if value is None:
                    value = ''
                values.append(value)
            if values[0].strip() != 'Los datos consultados no existen.':
                yield {
                    'category_id' : category_id
                   ,'provider_id' : values[1].strip()
                   ,'provider_name' : values[3].strip()
                   ,'provider_location' : values[5].strip()
                }
"""        from scrapy.shell import inspect_response
        inspect_response(response, self)
"""
"""        global custom_count
        custom_count = custom_count + 1
        filename = f'providers-' + str(custom_count) + '.html'
        with open(filename, 'wb') as f:
            f.write(response.body)
        self.log(f'Saved file {filename}')
"""
"""
        category_id = response.css('input[name="cate_id"]::attr(value)').get()
        for row in response.css('.trow'):
            #columns = row.css('td::text').getall()
            values = []
            for column in row.css('td'):
                value = column.css('::text').get()
                if value is None:
                	value = ''
                values.append(value)
            yield {
                'category_id' : category_id
               ,'provider_id' : values[1].strip()
               ,'provider_name' : values[3].strip()
               ,'provider_location' : values[5].strip()
            }

            #logging.info(values[0].strip())
"""

"""        from scrapy.shell import inspect_response
        inspect_response(response, self)"""
    	#for raw_category in response.css('.tdl a'):
    	#	logging.info(category_id)
"""filename = f'providers.html'
        with open(filename, 'wb') as f:
            f.write(response.body)
        self.log(f'Saved file {filename}')"""

""""for row in response.css('.trow'):
            #columns = row.css('td::text').getall()
            columns = row.css('td').getall()

            logging.info(columns[0].strip())"""
"""response.css('.trow').css('td')"""
"""
        filename = f'providers.html'
        with open(filename, 'wb') as f:
            f.write(response.body)
        self.log(f'Saved file {filename}')"""


import argparse
import os

import torch
import torch.distributed as dist
from guided_diffusion import dist_util, logger
from guided_diffusion.script_util import add_dict_to_argparser

def main():
    args = create_argparser().parse_args()
    dist_util.setup_dist(args.gpus)
    logger.configure(dir=args.log_path)

    from deepfloyd_if.modules import IFStageI, IFStageII, StableStageIII
    from deepfloyd_if.pipelines.uncond_dream import uncond_dream
    if args.hf_token:
        from huggingface_hub import login
        login(token=args.hf_token)
    logger.log("creating diffusion models...")
    logger.log(f"stage: {args.stage}")
    if_I = None
    if_II = None
    if args.stage >= 1:
        os.makedirs(os.path.join(logger.get_dir(), "I"), exist_ok=True)
        if_I = IFStageI('IF-I-L-v1.0', device=dist_util.dev())
    if args.stage >= 2:
        os.makedirs(os.path.join(logger.get_dir(), "II"), exist_ok=True)
        if_II = IFStageII('IF-II-M-v1.0', device=dist_util.dev())

    n_saved = 0
    while n_saved * dist.get_world_size() + dist.get_rank() < args.num_samples:
        result = uncond_dream(
            if_I=if_I, if_II=if_II, if_III=None,
            batch_size=args.batch_size,
            if_I_kwargs={
                "sample_timestep_respacing": "smart100",
                "sample_loop": "ddim"
            },
            if_II_kwargs={
                "sample_timestep_respacing": "smart50",
                "sample_loop": "ddim"
            },
            disable_watermark=True,
            return_tensors=False
        )
        img = result

        for key, value in img.items():
            n_saved_tmp = n_saved
            for i in value:
                imgpath = os.path.join(logger.get_dir(), f"{key}/{n_saved_tmp * dist.get_world_size() + dist.get_rank():06}.png")
                if n_saved_tmp * dist.get_world_size() + dist.get_rank() > args.num_samples:
                    break
                i.save(imgpath)
                n_saved_tmp += 1
        n_saved = n_saved_tmp
        logger.log(f"{n_saved * dist.get_world_size() + dist.get_rank()} images are saved.")
    logger.log("sampling complete")

def create_argparser():
    default = dict(
        num_samples=10000,
        batch_size=10,
        log_path="sample_logs",
        hf_token=None,
        stage=3
    )
    parser = argparse.ArgumentParser()
    add_dict_to_argparser(parser, default)
    parser.add_argument("--gpus", type=str, nargs="+", default="0")
    return parser

if __name__ == "__main__":
    main()


from fileinput import filename
import os
import time
import random
import io
import json

from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from google.oauth2.credentials import Credentials
from google.auth.transport.requests import Request
from googleapiclient import http
from datetime import date
from datetime import timedelta

import pandas as pd

# LINK DOCUMENTAÇÃO
# https://github.com/googleads/googleads-dfa-reporting-samples/tree/master/python/v3_5

# As variáveis a seguir controlam o comportamento de tentativas enqaunto o relatório está sendo processado.
# Mínimo de tempo entre requerimentos. Padrão de 10 segundos.
MIN_RETRY_INTERVAL = 10
# Máximo tempo entre requerimentos. Padrão de 1 minuto.
MAX_RETRY_INTERVAL = 1 * 60
# Máximo de tempo passando fazendo requerimentos. Padrão de 5 minutos.
MAX_RETRY_ELAPSED_TIME = 5 * 60

# Tamanho do chunk quando tiver fazendo download do relatório. Padrão 32MB.
CHUNK_SIZE = 32 * 1024 * 1024

def get_google_credentials() -> Credentials:
    '''Confirma / atualiza as credenciais de OAuth 2.0 para utilização das APIs.'''

    secrets_path =  os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..', 'tokens', 'google_secret.json'))
    credentials_path =  os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..', 'tokens', 'google_credentials.json'))

    scopes = ['https://www.googleapis.com/auth/dfareporting',
            'https://www.googleapis.com/auth/ddmconversions',
            'https://www.googleapis.com/auth/dfatrafficking']

    credentials = None

    if os.path.exists(credentials_path):
        credentials = Credentials.from_authorized_user_file(credentials_path, scopes)

    if not credentials or not credentials.valid:
        if credentials and credentials.expired and credentials.refresh_token:
            credentials.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(secrets_path, scopes)
            credentials = flow.run_local_server()
        with open(credentials_path, 'w') as token:
                token.write(credentials.to_json())

    return credentials

def start_service(credentials: Credentials):
    '''Começa o serviço para extração de dados da API.'''
    # Ficar atento a versão da API pois ela pode mudar.
    # Versão mais recente em: https://developers.google.com/doubleclick-advertisers/rel_notes

    api_version = 'v3.5'
    service = build('dfareporting', api_version, credentials = credentials)

    return service

def get_profileId(service) -> str:
    '''Extrai o ID de perfil da conta, necessário para quase todas as operações.'''

    userProfile = service.userProfiles().list().execute()
    profile_id = userProfile['items'][0]['profileId']

    return profile_id

def define_report(report_name: str, start_date: str, end_date: str) -> dict:
    '''
    Define a estrutura do relatório (dimensões/métricas).
    O formato do relatório é de um json com alguns campos a serem preenchidos:
    - name: nome do relatório no CM.
    - type: tipo de relatório do CM.
    - fileName: nome do arquivo caso baixado direto do CM. (Opcional)
    - format: formato do arquivo, pode ser CSV ou Excel. (Opcional)
    - criteria: neste argumento se define o relatório.

    Criteria recebe os seguintes argumentos:
    - dateRange: dicionário que contém a faixa de dias que serão puxados no relatório.
    - dimensions: lista de dicionários com os nomes das dimensões que serão puxadas.
    - metricNames: lista de métricas que se deseja puxar.
    '''

    report = {
        'name': report_name,
        'type': 'STANDARD',
        'format': 'CSV'
    }

    criteria = {
        'dateRange': {
            'startDate': start_date,
            'endDate': end_date
        }
    }

    # As dimesões utilizadas nos relatórios diários (preps) são diferentes dos utilizados
    # em relatórios com o checking.

    # lista de dimensões/métricas: https://developers.google.com/doubleclick-advertisers/v3.5/dimensions

    criteria['dimensions'] = [
        {'name': 'campaign'},
        {'name': 'campaignId'},
        {'name': 'site'},
        {'name': 'placement'},
        {'name': 'placementId'},
        {'name': 'creative'},
        {'name': 'creativeId'},
        {'name': 'date'}
    ]

    criteria['metricNames'] = [
        'mediaCost',
        'clicks',
        'impressions',
        'activeViewMeasurableImpressions',
        'activeViewViewableImpressions',
        'richMediaVideoPlays',
        'richMediaVideoFirstQuartileCompletes',
        'richMediaVideoMidpoints',
        'richMediaVideoThirdQuartileCompletes',
        'richMediaVideoCompletions'
    ]

    report['criteria'] = criteria

    return report

def add_filters(service, report, profile_id, campaign_list):
    '''Adiciona filtros de dimensões para puxar apenas as campanhas/fontes necessárias.'''

    campaign_filter_request = {
        'dimensionName': 'campaign',
        'startDate': report['criteria']['dateRange']['startDate'],
        'endDate': report['criteria']['dateRange']['endDate']
    }

    source_filter_request = {
        'dimensionName': 'site',
        'endDate': report['criteria']['dateRange']['endDate'],
        'startDate': report['criteria']['dateRange']['startDate']
    }

    exclude_sources = [
        'Facebook Brasil', 'Google Display Network', 'Twitter - Official', 'Youtube BR',
        'br.linkedin.com', 'TWITTER-OFFICIAL', 'Twitter', 'Youtube - Google Ads',
        'Google Ads: Display Remarketing', 'Google Ads', 'Instagram BR', 'Linkedin', 'Tik Tok BR'
    ]

    sources = service.dimensionValues().query(profileId = profile_id, body = source_filter_request).execute()
    campaigns = service.dimensionValues().query(profileId = profile_id, body = campaign_filter_request).execute()

    campaign_filter = [campaign for campaign in campaigns['items'] if campaign['value'] in campaign_list]
    source_filter = [source for source in sources['items'] if source['value'] not in exclude_sources]

    report['criteria']['dimensionFilters'] = campaign_filter + source_filter

    return report

def create_report(service, report, profile_id):
    '''Cria o relatório no CM.'''
    return service.reports().insert(profileId = profile_id, body = report).execute()

def next_sleep_interval(previous_sleep_interval):
  """Calcula o próximo intervalo de silêncio baseado no anterior."""

  min_interval = previous_sleep_interval or MIN_RETRY_INTERVAL
  max_interval = previous_sleep_interval * 3 or MIN_RETRY_INTERVAL
  return min(MAX_RETRY_INTERVAL, random.randint(min_interval, max_interval))

def run_report(service, profile_id, report_id):
    '''Executa o relatório.'''

    report_file = service.reports().run(profileId = profile_id, reportId = report_id).execute()
    file_id = report_file['id']

    sleep = 0
    start_time = time.time()

    while True:

        report_file = service.files().get(reportId = report_id, fileId = file_id).execute()

        status = report_file['status']

        if status == 'REPORT_AVAILABLE':
            print(f'[{status}] Relatório pronto pra download!')
            return report_file
        elif status != 'PROCESSING':
            print(f'[{status}] Processo falhou!')
            return
        elif time.time() - start_time > MAX_RETRY_ELAPSED_TIME:
            print('Tempo de processamento ultrapassou o limite')
            return

        sleep = next_sleep_interval(sleep)
        print(f'[{status}] Dormindo por {sleep} segundos.')
        time.sleep(sleep)

def download_report(campaign_path, service, report_file):
    '''Baixa o relatório.'''

    report_id = report_file['reportId']
    file_id = report_file['id']

    file_path = os.path.abspath(os.path.join(campaign_path, 'data', 'cm_prep.csv'))

    out_file = io.FileIO(file_path, mode = 'wb')

    request = service.files().get_media(reportId = report_id, fileId = file_id)

    downloader = http.MediaIoBaseDownload(out_file, request, chunksize = CHUNK_SIZE)

    download_finished = False
    while not download_finished:
        _, download_finished = downloader.next_chunk()

    return

def make_df(campaign_path):
    blank = 0
    file_path = os.path.abspath(os.path.join(campaign_path, 'data', 'cm_prep.csv'))

    with open(file_path, 'r') as text:
        for num, line in enumerate(text, 1):
            if 'Report Fields' in line:
                break
            if line == '\n':
                blank += 1

    df = pd.read_csv(file_path, header = num - blank)

    rename_columns = {
        'Campaign': 'campaign',
        'Campaign ID': 'campaign_id',
        'Site (CM360)': 'source',
        'Placement': 'placement',
        'Placement ID': 'placement_id',
        'Creative': 'cm_creative',
        'Creative ID': 'cm_creative_id',
        'Date': 'date',
        'Media Cost': 'cost',
        'Clicks': 'clicks',
        'Impressions': 'impressions',
        'Active View: Measurable Impressions': 'measurable_impressions',
        'Active View: Viewable Impressions': 'viewable_impressions',
        'Video Plays': 'video_views',
        'Video First Quartile Completions' : 'w25_views',
        'Video Midpoints': 'w50_views',
        'Video Third Quartile Completions': 'w75_views',
        'Video Completions': 'w100_views'
    }

    df.rename(columns = rename_columns, inplace = True)
    df.drop(df.index.max(), inplace = True)

    df['date'] = pd.to_datetime(df['date'])
    df.sort_values('date', ignore_index = True, inplace = True)

    os.remove(file_path)
    return df

def get_CampaignManager(campaign_path: str, campaigns: list, start_date: str, end_date: str):

    credentials = get_google_credentials()
    service = start_service(credentials)
    profile_id = get_profileId(service)

    report = define_report('report', start_date, end_date)
    report = add_filters(service, report, profile_id, campaigns)

    created_report = create_report(service, report, profile_id)

    report_file = run_report(service, profile_id, created_report['id'])

    download_report(campaign_path, service, report_file)

    df = make_df(campaign_path)

    return df

#if __name__ == '__main__':
#    main()


from pygame import *
import random
from pygame.math import Vector2

init()

block_size = 45
menu_color = (60, 60, 60)
font_size = 30
screen_size = (block_size*20+300, block_size*20+40)
count_column, count_row = 20, 20
snake_color = (0, 90, 10)
head_color = (0, 102, 0)
border_color = (150, 200, 30)
ms = 150

class SNAKE():
    def __init__(self):
          # starting postion
          self.body = [Vector2(5, 10), Vector2(4, 10), Vector2(3, 10)]
          # doesn't move at the beginning
          self.direction = Vector2(0,0)
          self.new_block = False

    def draw_snake(self):
         # draw head
         draw_block(head_color, self.body[0].x, self.body[0].y)
         # draw body
         for block in self.body[1:]:
              draw_block(snake_color, block.x, block.y)

    def move_snake(self):
        # in case you've eaten pochita
        if self.new_block == True:
            body_copy = self.body[:]
            body_copy.insert(0,body_copy[0]+self.direction)
            self.body = body_copy[:]
            self.new_block = False
        else:
            # copy without tail
            body_copy = self.body[:-1]
            # insert a head and move it to direction of input
            body_copy.insert(0,body_copy[0]+self.direction)
            self.body = body_copy[:]

    def reset(self):
        # when game over start at this position again
        self.body = [Vector2(5,10),Vector2(4,10),Vector2(3,10)]
        self.direction = Vector2(0,0)

class POCHITA(SNAKE):
    def __init__(self):
        super().__init__()
        self.random_spawn()

    def random_spawn(self):
        # take random point that are within borders
        self.x = random.randint(0, count_column - 1)
        self.y = random.randint(0, count_row - 1)
        # if point is inside snake take another one
        while(Vector2(self.x, self.y) in self.body):
            self.x = random.randint(0, count_column - 1)
            self.y = random.randint(0, count_row - 1)
        # initialize the point
        self.pos = Vector2(self.x, self.y)

    def draw_pochita(self):
        # draws pochita at a randomrly created position
        screen.blit(poch, (int(self.pos.x * block_size+20) , int(self.pos.y * block_size+20)))

class MAIN():
    def __init__(self):
        self.snake = SNAKE()
        self.pochita = POCHITA()
        self.score = 0
        self.level = 0
        # every 150 miliseconds game.update() method is triggered
        self.speed = 150
    # checks for any updates and acts accrodingly
    def update(self):
        self.snake.move_snake()
        self.check_collision()
        self.check_dead()
    # draws everything that's needed
    def draw_elements(self):
        self.pochita.draw_pochita()
        self.snake.draw_snake()
        self.draw_menu()
    # makes a menu at the right side which shows current score and level
    def draw_menu(self):
        draw.rect(screen, menu_color, [block_size*count_column+40, 0, 1000, 1000])
        score_text = fonts.render('score: ' + str(self.score), True, (255,255,255), menu_color)
        level_text = fonts.render('level: ' + str(self.level), True, (255,255,255), menu_color)
        screen.blit(score_text, (block_size*20+50, 20))
        screen.blit(level_text, (block_size*20+50, 20+font_size))
    #checks if snake has eaten pochita
    def check_collision(self):
        if self.pochita.pos == self.snake.body[0]:
           self.pochita.random_spawn()
           self.snake.new_block = True
           self.score += 1
           if self.score % 4 == 0:
               self.level +=1
               self.update_speed()

    def update_speed(self):
        # increases speed by 1/5th of current speed
        self.speed -= self.speed//5
        time.set_timer(USEREVENT, self.speed)

    def check_dead(self):
        # if snake touched border it's dead
        if not 0 <= self.snake.body[0].x < count_column or not 0 <= self.snake.body[0].y < count_row:
            self.game_over()

        # if snake touched itseld it's dead
        for block in self.snake.body[1:]:
            if block == self.snake.body[0]:
                self.game_over()

    def game_over(self):
        # reset all parameters
        self.speed = 150
        time.set_timer(USEREVENT, self.speed)
        self.level = 0
        self.score = 0
        self.snake.reset()

def draw_block(colour, column, row):
            draw.rect(screen, colour, [20+block_size*column, 20+row*block_size, block_size, block_size])

# render an image of pochita
poch = image.load(r"C:\PP 2\lab_8\sprite_snake\pochita.png")
# make the image the size of block
poch = transform.scale(poch, (block_size, block_size))

# create font
fonts = font.Font('freesansbold.ttf', font_size)

game = MAIN()

screen = display.set_mode(screen_size)
screen.fill(border_color)
clock = time.Clock()

# before game.update_speed() is called we use this
time.set_timer(USEREVENT, 150)

done = False

while not done:
    for ev in event.get():
        if ev.type == QUIT:
            done = True
        if ev.type == USEREVENT:
                game.update()
        if ev.type == KEYDOWN:
            if ev.key == K_UP:
                game.snake.direction = Vector2(0, -1)
            if ev.key == K_DOWN:
                game.snake.direction = Vector2(0, 1)
            if ev.key == K_RIGHT:
                game.snake.direction = Vector2(1, 0)
            if ev.key == K_LEFT:
                game.snake.direction = Vector2(-1, 0)

    for row in range(count_column):
        for column in range(count_row):
            if (column+row) % 2 == 0:
                colour = (0, 100, 90)
            else: colour = (0, 80, 80)
            draw_block(colour, column, row)

    game.draw_elements()

    display.flip()

    clock.tick(60)


'''
Author       : ZHP
Date         : 2021-05-28 23:05:16
LastEditors  : ZHP
LastEditTime : 2022-04-24 12:32:58
FilePath     : /train_partseg.py
Description  : 项目说明
Copyright    : ZHP
'''
import os
import sys
import argparse
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import traceback
import torch
from trainer import shapePart_train
import models
from utils import utils

SEED = 10

def get_args():
    # Training settings
    parser = argparse.ArgumentParser(description='ShapePart Segmentation!')
    parser.add_argument('--task', type=str, default='PartSeg', help='Task')
    parser.add_argument('--model_name', type=str, default='Trans_Global_Part_SSG', help='model name')
    parser.add_argument('--ckpt_folder', type=str, default='Results/TrainLogs', help='Train Logs save dir')
    parser.add_argument('--model_save_dir', type=str, default='Results/models', help='model save dir')
    parser.add_argument('--enc_num', type=int, default=1, help='the transformer encoder num')
    parser.add_argument('--share', action='store_true', default=False, help='Resume training at a breakpoint')

    parser.add_argument('--batch_size', type=int, default=16, help='batch Size during training')
    parser.add_argument('--optimizer', type=str, default='Adam', help='Adam or SGD')
    parser.add_argument('--learning_rate', default=0.001, type=float, help='initial learning rate')
    parser.add_argument('--weight_decay', type=float, default=1e-4, help="weight decay")
    parser.add_argument('--min_lr', type=float, default=0.001, help="weight decay")
    parser.add_argument('--lr_decay', action='store_false', default=True, help='decay rate for learning rate')
    parser.add_argument('--lr_step', type=int, default=40, help='decay step for learning rate')
    parser.add_argument('--decay_ratio', type=float, default=0.5, help='decay ratio for learning rate')
    parser.add_argument('--nEpochs', type=int, default=200, help='number of epochs to train')
    parser.add_argument('--init', type=str, default='xavier', help='weight initial mode')
    parser.add_argument('--gpus', type=str, default='0,1', help='specify GPU devices')

    # data config
    parser.add_argument('--data_dir', type=str, default='/root/zhp/dataset/ShapeNet', help='data dir')
    parser.add_argument('--npoints', type=int, default=2048, help='point Number')
    parser.add_argument('--normalize', action='store_true', default=True, help='use normals')
    parser.add_argument('--resume', action='store_true', default=False, help='Resume training at a breakpoint')

    args = parser.parse_args()
    print('主要参数配置如下：\n')
    for key, value in args.__dict__.items():
        print(f'{key:^20} : {str(value):<}')
    return args

def main():
    torch.cuda.empty_cache()
    utils.fix_seed(SEED)
    args = get_args()
    model_dict = {
        "target_num" : 50,
        "embed_list" : [[128, 256], [256, 512], [512, 1024]],
        "pos_mode" : "relative",
        "res" : False
    }
    partseg = shapePart_train.PartSegTrainer(args.__dict__, models.get_loss, model_dict)
    try:
        partseg.run()
    except:
        partseg.trace_end()

if __name__ == "__main__":
    main()
    # python train_partseg.py --model_name=PPLT_Model_Seg