import random
import operator
import matplotlib.pyplot
import time
import agentframework
import csv

#a = agentframework.Agent(environment, agents)
#a.o_agents

#input agent from agentframework
start = time.clock()

##################################################################
#####                DISTANCE CALC                           #####
##################################################################
def distance_between(agents_row_a, agents_row_b):
    return (((agents_row_a.x - agents_row_b.x)**2) + ((agents_row_a.y - agents_row_b.y)**2))**0.5

##################################################################
#####                    PARAMETERS                          #####
##################################################################
num_of_agents = 5
num_of_iterations = 1
neighbourhood = 20

##################################################################
#####                INITIALISE VARIABLES                    #####
##################################################################
agents = []
data = []
processed_data = []

##################################################################
#####                GETTING THE ENVIRONMENT                 #####
##################################################################
#initialising environment
environment = []
#initialising the csv reader to convert .txt to .csv
f = open('in.txt', newline='')
reader = csv.reader(f, quoting=csv.QUOTE_NONNUMERIC)
for row in reader: # A list of rows
    rowlist = []
    #append the environment in a loop
    environment.append(rowlist)
    for value in row:
        rowlist.append(value)
        #print(value) # Floats
f.close()
# Fill with random data.
for i in (range(1,98)):
    datarow = []
    for j in (range(1,98)):
        datarow.append(random.randint(0,99))
    data.append(datarow)

# =============================================================================
# #ensuring dataset is rectangular i.e. col value for every row value
# nrows = len(environment)
# print (nrows)
# ncols = len(environment[0])
# print (ncols)
# #show the 299th by 299th value for ref
# #print(environment[299][299])
#total = 0
#for row in nrows
    #for col in cols:
        #total += environment[row][col]
# =============================================================================

#random.seed(10) #uncomment for testing purposes

##################################################################
#####                CREATE AGENTS                           #####
##################################################################
for i in range(num_of_agents):
    y = random.randint(0,299)
    x = random.randint(0,299)
    agents.append(agentframework.Agent(environment, agents, y, x))

#shuffle the agent list
random.shuffle(agents)
#Commence movement & mastication
for j in range(num_of_iterations):
    for i in range(num_of_agents):
        agents[i].move()
        agents[i].eat()
        agents[i].share_with_neighbours(neighbourhood)

#plot the data
matplotlib.pyplot.ylim(299, 0)
matplotlib.pyplot.xlim(0, 299)
matplotlib.pyplot.imshow(environment)
for i in range (num_of_agents):
    matplotlib.pyplot.scatter(agents[i].x,agents[i].y)

#identify the left and rightmost agents
# =============================================================================
# ## Agents do not support indexing so this section ##
# ## cannot be executed                             ##
# leftmostagent = min(agents, key=operator.itemgetter(0))
# rightmostagent = max(agents, key=operator.itemgetter(0))
# matplotlib.pyplot.scatter(leftmostagent[0],leftmostagent[1], color='green')
# matplotlib.pyplot.scatter(rightmostagent[0],rightmostagent[1], color='red')
# =============================================================================

matplotlib.pyplot.show()

#calculate the maximum distance
#max_distance = distance_between(agents[1], agents[0])
print("*"*20)
for i in range (0,num_of_agents):
    for j in range (i+1 ,num_of_agents):
        distance = distance_between(agents[i], agents[j])
        #max_distance = max(max_distance, distance)
        print("distance between agent", i, "and", j, distance)
        #print(max_distance)

f2 = open('dataout.csv', 'w', newline='')
writer = csv.writer(f2, delimiter=' ')
for row in data:
    writer.writerow(row) # List of values.
f2.close()

end=time.clock()

print("time=",str(end-start))
print(agents[i])


from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import render, get_object_or_404
from django.urls import reverse_lazy
from chat.utils import login_required
from .utils import *
from .forms import *
from django.views.generic.list import ListView, View
from django.views.generic.detail import DetailView
from django.views.generic.edit import CreateView, FormMixin
from MagrasBox.settings import BASE_DIR
import os
from authsys.forms import SignInFormSecurity, SignUpForm

# Create your views here.
from django.http import HttpResponse, Http404, HttpResponseRedirect, JsonResponse
from .models import *

from django.shortcuts import redirect

class Main(ListView):
    paginate_by = 10
    model = Rooms
    context_object_name = 'rooms'
    template_name = 'mainapp/showrooms.html'
    extra_context = {'title': 'Main', 'form_login': SignInFormSecurity, 'form_signup': SignUpForm}

    def get(self, request, *args, **kwargs):
        self.query = {}
        return super().get(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        self.query = {}
        if 'search_inp' in self.request.POST:
            self.query['room_name__contains'] = request.POST.get('search_inp')
        else:
            del self.query['room_name__contains']
        self.object_list = self.get_queryset()
        context = self.get_context_data()
        return self.render_to_response(context)

    def get_context_data(self, *, object_list=None, **kwargs):
        context = super().get_context_data()
        context['types'] = RoomType.objects.all()
        if 'search_inp' in self.request.POST:
            context['search_init'] = self.request.POST.get('search_inp')
        context['pk'] = 0
        return context

    def get_queryset(self):
        if 'typid' in self.request.GET.keys() and self.request.GET['typid'].isdigit():
            self.query['type_id'] = int(self.request.GET['typid'])
        if self.query != {}:
            queryset = Rooms.objects.filter(**self.query).select_related('author', 'type').order_by('-create_date')
        else:
            queryset = Rooms.objects.all().select_related('author', 'type').order_by('-create_date')
        return queryset

class ShowRoom(LoginRequiredMixin, DetailView):
    model = Rooms
    pk_url_kwarg = 'roomid'
    template_name = 'mainapp/room.html'

    def get_context_data(self, *, object_list=None, **kwargs):
        context = super().get_context_data()
        context = super().get_context_data()
        context['title'] = self.object.room_name
        return context

def show_user(request, userid):
    return HttpResponse('User')

def delete_room(request, room_id):
    room =  get_object_or_404(Rooms, pk = room_id)
    if request.user != room.author:
        raise PermissionError('You are not author of this room')
    else:
        room.delete()
        return redirect('get_to_main')

class CreateRoomView(LoginRequiredMixin, CreateView):
    model = Rooms
    template_name = 'mainapp/create_room.html'
    login_url = 'login'
    form_class = CreateRoom
    extra_context = {'title': 'Create room page'}

    def create_data(self, room):
        path_t = f"{BASE_DIR}/chat/chats_data/"
        path_a = f"{BASE_DIR}/chat/actions_data/"

        if not os.path.exists(path_t):
            os.makedirs(path_t)
        if not os.path.exists(path_a):
            os.makedirs(path_a)

        with open(f'{path_t}{room.pk}.txt', "w") as f:
            f.write("Welcome\n")
        with open(f'{path_a}{room.pk}.txt', "w") as f:
            f.write("")

    def form_valid(self, form):
        room = form.save(commit=False)
        room.author = self.request.user
        room.save()
        Membership.objects.create(room = room, user = self.request.user, can_write=True)
        self.success_url = reverse_lazy('get_to_main')
        self.create_data(room)
        return super(CreateRoomView, self).form_valid(form)

@login_required
def rate(request, room_id, type):
    value = 1
    if type == 'down':
        value = -1
    elif type == 'up':
        pass
    else:
        raise ValueError('Invalid rate type')
    room = Rooms.objects.get(pk=int(room_id))
    blue_button = True
    if request.user in room.rated_persons.all():
        rating = Rating.objects.get(room_id = room.pk, user_id = request.user.pk)
        if (rating.is_positive and value > 0) or (not rating.is_positive and value < 0):
            if value > 0:
                room.rate -= 1
            else:
                room.rate += 1
            blue_button = False
            rating.delete()
        else:
            rating.is_positive = not rating.is_positive
            room.rate += 2*value
            rating.save()

    else:
        room.rate+=value
        Rating.objects.create(user_id = request.user, room_id = room, is_positive = value>0)
    room.save()
    if blue_button:
        if value > 0:
            blue_button = 'r'
        else:
            blue_button = 'l'
    ans = f'<b id="rate" style="color: {room.get_rate_color()}">{room.rate}</b>'
    return JsonResponse({'rate': ans, 'pk': room.pk, 'blue_button': blue_button})


#!/usr/bin/env python3

import os # for os.path.plittext (remove .png from filename)
import PIL
import numpy as np
import scipy.ndimage
from scipy.spatial import Delaunay
from matplotlib import pyplot
import math
import argparse

PIL.Image.MAX_IMAGE_PIXELS = None # disable decompression bomb error

# empty config: (False, (r,g,b))
#               (True,  alpha)

# global vars, get set by command line parser
file_name = "Ansicht Ost_0.25.tif"
empty_config = (True, 0) #empty_config = (False, (255, 0, 255))

# still not changeable by command line argumets
max_distance = 10 # in pixels
chunk_size = 1000 # chunk_size² (output) pixels per chunk

def compute_is_empty(img):
	(use_alpha, value) = empty_config
	if use_alpha:
		print(f"Compute empty pixels using alpha = {value} ...")
		is_empty = img[:,:,3] == value
	else:
		print(f"Compute empty pixels using rgb = {value} ...")
		(r,g,b) = value
		is_empty = (img[:,:,0] == r) & (img[:,:,1] == g) & (img[:,:,2] == b)
	print(f"is_empty uses {humansize(is_empty.nbytes)}.")
	return is_empty

def compute_is_vertex(img, is_empty):
	print(f"Compute is_vertex pixels without optimization")

	is_vertex = ~is_empty
	# TODO: optimize away points inside filled surface

	print(f"is_vertex uses {humansize(is_vertex.nbytes)}.")
	return is_vertex

def encode_image(img):
	""" return (vertices, is_empty, is_vertex, colors) as numpy arrays """

	print("in encode_image:")

	#(h,w) = img.shape[:2]
	(use_alpha, value) = empty_config

	# compute is_empty numpy array
	is_empty = compute_is_empty(img)

	# compute is_vertex numpy array
	is_vertex = compute_is_vertex(img, is_empty)

	print("compute number of vertices...")
	vertex_count = np.sum(is_vertex)
	if vertex_count == 0:
		print("Warning: no vertices in this chunk, leave empty.")
		return (None, None, None, None)

	print(f"image contains {vertex_count} vertices.")

	print(f"compute vertex coordinates...")
	# [y,x] arrays
	vertices = np.argwhere(is_vertex).astype(np.uint16)
	print(f"vertices uses {humansize(vertices.nbytes)}.")

	print(f"extract vertex colors...")

	colors = np.zeros((vertex_count, 3), dtype=np.uint8)
	colors[:,0] = np.extract(is_vertex, img[:,:,0])
	colors[:,1] = np.extract(is_vertex, img[:,:,1])
	colors[:,2] = np.extract(is_vertex, img[:,:,2])

	print(f"colors uses {humansize(colors.nbytes)}.")

	return (vertices, is_empty, is_vertex, colors)

def fill_image(src_img, dst_img, colors, triangulation, is_empty, is_vertex, dst_offset):
	(dst_h, dst_w) = dst_img.shape[:2]
	should_interpolate = is_empty[
		dst_offset[0] : dst_h + dst_offset[0],
		dst_offset[1] : dst_w + dst_offset[1]]

	print("Search for triangles to interpolate from...")
	interpolation_coords = np.argwhere(should_interpolate)
	simplex_ids = triangulation.find_simplex(interpolation_coords + dst_offset)

	print("compute output colors")
	for i in range(len(interpolation_coords)):
		(y,x) = interpolation_coords[i]
		simplex_id = simplex_ids[i]

		# skip points outside of triangulation
		if simplex_id == -1:
			should_interpolate[y,x] = False
			continue

		# read triangle values
		simplex_vertexids = triangulation.simplices[simplex_id]
		simplex_vertices = triangulation.points[simplex_vertexids]

		(p1, p2, p3) = simplex_vertices

		v1 = p2 - p1
		v2 = p3 - p2
		v3 = p1 - p3

		# skip if triangle is too large
		if max(	np.linalg.norm(v1),
				np.linalg.norm(v1),
				np.linalg.norm(v3) ) > max_distance:
			should_interpolate[y,x] = False
			continue

		# compute barycentric coordinates using affine transformation
		# provided by scipy Delaunay
		barycentric = np.dot(
			triangulation.transform[simplex_id,:2],
			np.array([y,x]) + dst_offset - triangulation.transform[simplex_id,2])

		# interpolate final color
		v1i = (int(p1[0]), int(p1[1]))
		v2i = (int(p2[0]), int(p2[1]))
		v3i = (int(p3[0]), int(p3[1]))

		dst_img[y,x] =	barycentric[0] * src_img[v1i] \
			+			barycentric[1] * src_img[v2i] \
			+ (1 - barycentric[0] - barycentric[1]) * src_img[v3i]

def parse_args():
	parser = argparse.ArgumentParser(description='Fill holes in Images using delaunay triangulation. This program splits work into smaller chunks to be able to parallelize the workload and overcome memory limitations.')
	parser.add_argument('-a','--use-alpha', help='use alpha color to specify empty regions')
	parser.add_argument('-r','--use-rgb', nargs=3, help='use alpha color to specify empty regions')
	parser.add_argument('-c','--chunk-size', help='set size of blocks in which the image is computed. smaller chunks reduce memory usage and triangulation work, but increases overhead due to smaller arrays')
	parser.add_argument('-d','--max-distance', help='maximal distance between two points for interpolation')
	parser.add_argument('filename', help="the image to fill the holes")
	args = parser.parse_args()

	global empty_config
	if args.use_alpha is not None:
		empty_config = (True, int(args.use_alpha))
	elif args.use_rgb is not None:
		empty_config = (False, (int(args.use_rgb[0]), int(args.use_rgb[1]), int(args.use_rgb[2])))
	else:
		if input("Use alpha channel to decide if points are empty? (y/n)").lower() == 'y':
			empty_config = (True, int(input("Enter alpha value for empty cells (probably 0)")))
		else:
			empty_config = (False, (
				int(input("Enter red value")),
				int(input("Enter green value")),
				int(input("Enter blue value"))
			))
	global file_name
	file_name = args.filename

	if args.chunk_size is not None:
		global chunk_size
		chunk_size = int(args.chunk_size)
		print(f"use chunk size {chunk_size}")
	if args.max_distance is not None:
		global max_distance
		max_distance = int(args.max_distance)
		print(f"use max distance {max_distance}")

def process_chunk(in_img, out_img, dst_offset):
	print(f"dst_offset: {dst_offset}, in_img.shape: {in_img.shape}, out_img.shape: {out_img.shape}")

	(vertices, is_empty, is_vertex, colors) = encode_image(in_img)
	if vertices is None:
		return

	print("Compute delaunay triangulation...")
	triangulation = Delaunay(vertices)
	fill_image(in_img, out_img, colors, triangulation, is_empty, is_vertex, dst_offset)

def main():
	parse_args()

	print(f"load image {file_name}...")
	img = np.array(PIL.Image.open(file_name))
	(h,w,channels) = img.shape
	print(f"Image size: w={w}, h={h}, channels={channels}, dtype={img.dtype}, memory={humansize(img.nbytes)}")

	dst_img = img.copy()
	chunk_count_x = math.ceil(w / chunk_size)
	chunk_count_y = math.ceil(h / chunk_size)

	for chunk_y in range(chunk_count_y):
		for chunk_x in range(chunk_count_x):
			print(f"= {int(100.0*(chunk_y * chunk_count_x + chunk_x) / (chunk_count_x * chunk_count_y))}% ===============================")
			print(f"=== fill chunk x:{chunk_x+1}/{chunk_count_x} y:{chunk_y+1}/{chunk_count_y} ===")

			src_img_chunk =     img[max(chunk_y * chunk_size - max_distance, 0) : (chunk_y + 1) * chunk_size + max_distance,
									max(chunk_x * chunk_size - max_distance, 0) : (chunk_x + 1) * chunk_size + max_distance]
			dst_img_chunk = dst_img[chunk_y * chunk_size                        : (chunk_y + 1) * chunk_size,
									chunk_x * chunk_size                        : (chunk_x + 1) * chunk_size]
			dst_offset = (chunk_y * chunk_size - max(chunk_y * chunk_size - max_distance, 0),
			              chunk_x * chunk_size - max(chunk_x * chunk_size - max_distance, 0))

			process_chunk(src_img_chunk, dst_img_chunk, dst_offset)

		#print("Show graph..")
		#pyplot.imshow(dst_img)
		#pyplot.show()
		#print("done.")

	dst_img_pil = PIL.Image.fromarray(dst_img)
	dst_img_pil.save(os.path.splitext(file_name)[0] + "_interpolated.png", "PNG")

	pyplot.imshow(dst_img)
	pyplot.show()

# ------- other stuff

suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
def humansize(nbytes):
    i = 0
    while nbytes >= 1024 and i < len(suffixes)-1:
        nbytes /= 1024.
        i += 1
    f = ('%.2f' % nbytes).rstrip('0').rstrip('.')
    return '%s %s' % (f, suffixes[i])

if __name__ == "__main__":
	main()


#!/usr/bin/env python3

import random, logging

logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')

logging.info('Start of game')

guess = ''
while guess not in ('heads', 'tails'):
    print('Guess the coin toss! Enter heads or tails:')
    guess = input()
    guess = guess.lower()

toss = random.randint(0, 1) # 0 is tails, 1 is heads
if toss == 0:
    toss = 'tails'
else:
    toss = 'heads'

logging.debug(f'Value by user {guess} - Coin toss value {toss}')
if toss == guess:
    print('You got it!')
else:
    print('Nope! Guess again!')
    guess = input()
    logging.debug(f'Value by user {guess} - Coin toss value {toss}')
    if toss == guess:
        print('You got it!')
    else:
        print('Nope. You are really bad at this game.')

logging.info('End of game')


import math
import torch
from torch import nn
from torch.nn import init
import torch as T
import torch.nn.functional as F
from models.encoders.S4DWrapper import S4DWrapper
from models.encoders.OrderedMemory import OrderedMemory
from models.encoders.RecurrentGRCX import RecurrentGRCX

class HGRC(nn.Module):
    def __init__(self, config):
        super(HGRC, self).__init__()
        self.config = config
        self.word_dim = config["hidden_size"]
        self.hidden_dim = config["hidden_size"]
        self.model_chunk_size = config["model_chunk_size"]
        self.small_d = 64
        self.chunk_size = 30

        self.RNN = S4DWrapper(config)
        self.initial_transform = nn.Linear(self.hidden_dim, self.hidden_dim)
        if config and "rvnn_norm" in config:
            self.norm = config["rvnn_norm"]
        else:
            self.norm = "layer"

        if self.norm == "batch":
            self.NT = nn.BatchNorm1d(self.hidden_dim)
        elif self.norm == "skip":
            pass
        else:
            self.NT = nn.LayerNorm(self.hidden_dim)

        self.GRC = RecurrentGRCX(config)

    def normalize(self, state):
        if self.norm == "batch":
            return self.NT(state.permute(0, 2, 1).contiguous()).permute(0, 2, 1).contiguous()
        elif self.norm == "skip":
            return state
        else:
            return self.NT(state)

    def forward(self, input, input_mask):

        sequence = self.RNN(input, input_mask)["sequence"]
        osequence = sequence.clone()
        oinput_mask = input_mask.clone()

        sequence = self.normalize(self.initial_transform(sequence))
        N, S, D = sequence.size()
        if not self.config["chunk_mode_inference"] and not self.training:
            self.chunk_size = S
        else:
            self.chunk_size = self.model_chunk_size

        while S > 1:
            N, S, D = sequence.size()
            if S >= (self.chunk_size + self.chunk_size // 2):
                if S % self.chunk_size != 0:
                    e = ((S // self.chunk_size) * self.chunk_size) + self.chunk_size - S
                    S = S + e
                    pad = T.zeros(N, e, D).float().to(sequence.device)
                    input_mask = T.cat([input_mask, T.zeros(N, e).float().to(sequence.device)], dim=-1)
                    sequence = T.cat([sequence, pad], dim=-2)
                    assert sequence.size() == (N, S, D)
                    assert input_mask.size() == (N, S)
                S1 = S // self.chunk_size
                chunk_size = self.chunk_size
            else:
                S1 = 1
                chunk_size = S
            sequence = sequence.view(N, S1, chunk_size, D)
            sequence = sequence.view(N * S1, chunk_size, D)

            input_mask = input_mask.view(N, S1, chunk_size)
            input_mask = input_mask.view(N * S1, chunk_size)

            N0 = N
            N, S, D = sequence.size()
            assert N == N0 * S1

            sequence = self.GRC(sequence, input_mask)["global_state"]
            assert sequence.size() == (N, D)
            sequence = sequence.view(N0, S1, D)
            input_mask = input_mask.view(N0, S1, chunk_size)[:, :, 0]
            S = S1
            N = N0

        assert sequence.size() == (N, 1, D)
        global_state = sequence.squeeze(1)

        return {"sequence": osequence,
                "global_state": global_state,
                "input_mask": oinput_mask,
                "aux_loss": None}


#!/usr/bin/python3
#coding=utf-8
import urllib3
import json
import datetime as dt
import time
import sys
import logging
import traceback
import random
'''
特别声明:
本程序只有甜糖客户端和server酱的相关的api的访问，请仔细查阅程序安全性。
本程序仅用于测试和学习研究，禁止用于商业用途，不能保证其合法性，准确性，完整性和有效性，请根据情况自行判断.
本脚本的唯一下载地址https://www.right.com.cn/forum/thread-4048219-1-1.html  其它地方下载的可能存在危险，概不负责。
对任何脚本问题概不负责，包括但不限于由任何脚本错误导致的任何损失或损害.
请勿将本程序的任何内容用于商业或非法目的，否则后果自负.

如果任何单位或个人认为本程序可能涉嫌侵犯其权利，则应及时通知并提供身份证明，所有权证明，我们将在收到认证文件后删除相关程序.
任何以任何方式查看此程序的人或直接或间接使用该程序的使用者都应仔细阅读此声明。作者保留随时更改或补充此免责声明的权利。
一旦使用并复制了任何相关程序，则视为您已接受此免责声明.
您使用或者复制了本程序且本人制作的任何脚本，则视为已接受此声明，请仔细阅读
您必须在下载后的24小时内从计算机或手机中完全删除以上内容.
'''
def HandleException( excType, excValue, tb):
	ErrorMessage = traceback.format_exception(excType, excValue, tb)  # 异常信息
	logging.exception('ErrorMessage: %s' % ErrorMessage)  # 将异常信息记录到日志中
	str=[]
	for item in ErrorMessage:
		str.append(item)

	msg_content=[]
	msg_content.append("程序运行错误，请暂停使用程序，手动领取星愿，截图错误消息推送，并联系程序开发者！-三只松鼠")
	msg_content.append("ErrorMessage:")
	msg_content.append(str)
	msg_content.append(end)
	sendMSG("[甜糖星愿]程序错误警报",msg_content)
	return

sys.excepthook = HandleException #全局错误异常处理！

path=sys.path[0] #脚本所在目录
logging.basicConfig(filename=path + '/AutoTTnodeClient.log',format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s', level=logging.DEBUG)
logging.debug("日志开始")
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
####################以下内容请不要乱动，程序写得很菜，望大佬手下留情#########################################
devices=''
inactivedPromoteScore=0
total=0
accountScore=0
msgTitle="[甜糖星愿]星愿日结详细"
msg="\n"

def sendPlusPlus(text,desp):#发送PlusPlus代码
    url="http://pushplus.hxtrip.com/send"
    header={"Content-Type":"application/json"}
    body_json={"token":plusplus_token,"title":text,"content":desp,"template":"html"}
    encoded_body=json.dumps(body_json).encode('utf-8')
    http = urllib3.PoolManager()
    response= http.request('POST', url,body=encoded_body,headers=header)
    if response.status!=200:
       print("sendPlusPlus方法请求失败，结束程序")
       logging.debug("sendPlusPlus方法请求失败，结束程序")
       exit()
    data=response.data.decode('utf-8')
    data=json.loads(data)
    return

def sendTelegram(desp):#发送Telegram代码
    url="https://api.telegram.org/bot"+tg_bot_token+"/sendMessage"
    header={"Content-Type":"application/json"}
    body_json={"chat_id":chat_id,"text":desp}
    encoded_body=json.dumps(body_json).encode('utf-8')
    http = urllib3.PoolManager()
    response= http.request('POST', url,body=encoded_body,headers=header)
    if response.status!=200:
       print("sendPlusPlus方法请求失败，结束程序，请确保连接了外国网络！")
       logging.debug("sendPlusPlus方法请求失败，结束程序，请确保连接了外国网络！")
       exit()
    data=response.data.decode('utf-8')
    data=json.loads(data)
    return

def getInitInfo():#甜糖用户初始化信息，可以获取待收取的推广信息数，可以获取账户星星数
    url="http://tiantang.mogencloud.com/web/api/account/message/loading"
    header={"Content-Type":"application/json","authorization":authorization}
    http = urllib3.PoolManager()
    response= http.request('POST', url,headers=header)
    if response.status!=200:
       print("getInitInfo方法请求失败，结束程序")
       logging.debug("getInitInfo方法请求失败，结束程序")
       raise Exception("响应状态码:"+str(response.status)+"\n请求url:"+url+"\n消息:API出现异常，请暂停使用程序！")
    data=response.data.decode('utf-8')
    data=json.loads(data)
    if data['errCode']!=0:
        print("发送推送微信，authorization已经失效")
        msg_content=[]
        msg_content.append("甜糖登录状态已经失效，请通过手机号码和验证码进行重新生成配置")
        msg_content.append("docker版运行下面命令：")
        item=[]
        item.append("docker exec  autottnode python3 /root/ttnode/TTnodeLogin.py")
        msg_content.append(item)
        msg_content.append("源码版运行下面命令：")
        item=[]
        item.append("python3 /你文件的路径/TTnodeLogin.py")
        msg_content.append(item)
        msg_content.append(end)
        sendMSG("[甜糖星愿]-Auth失效通知",msg_content)
        exit()
    data=data['data']

    return data

def getDevices():#获取当前设备列表，可以获取待收的星星数
    url="http://tiantang.mogencloud.com/api/v1/devices?page=1&type=2&per_page=200"
    header={"Content-Type":"application/json","authorization":authorization}
    http = urllib3.PoolManager()
    response= http.request('GET', url,headers=header)
    if response.status!=200:
        print("getDevices方法请求失败，结束程序")
        logging.debug("getDevices方法请求失败，结束程序")
        raise Exception("响应状态码:"+str(response.status)+"\n请求url:"+url+"\n消息:API出现异常，请暂停使用程序！")
    data=response.data.decode('utf-8')
    data=json.loads(data)
    if data['errCode']!=0:
       raise Exception("响应状态码:"+str(response.status)+"\n请求url:"+url+"\n消息:API可能已经变更，请暂停使用程序！")

    data=data['data']['data']
    if len(data)==0:
        msg_content=[]
        msg_content.append("该账号尚未绑定设备，请绑定设备后再运行！")
        msg_content.append(end)
        sendMSG("[甜糖星愿]获取设备失败通知",msg_content)
        exit()
    return data

def promote_score_logs(score):#收取推广奖励星星
    global msg
    if score==0:

        return "[推广奖励]0-🌟"
    url="http://tiantang.mogencloud.com/api/v1/promote/score_logs"
    header={"Content-Type":"application/json","authorization":authorization}
    body_json={'score':score}
    encoded_body=json.dumps(body_json).encode('utf-8')
    http = urllib3.PoolManager()
    response= http.request('POST', url,body=encoded_body,headers=header)
    if response.status!=201 and response.status!=200:
       print("promote_score_logs方法请求失败，结束程序")
       logging.debug("promote_score_logs方法请求失败，结束程序")
       raise Exception("响应状态码:"+str(response.status)+"\n请求url:"+url+"\n消息:API出现异常，请暂停使用程序！")
    data=response.data.decode('utf-8')
    data=json.loads(data)

    if data['errCode']!=0:

        return "[推广奖励]0-🌟(收取异常)"

    global total
    total=total+score
    data=data['data']
    #发送微信推送，啥设备，获取了啥星星数
    return "[推广奖励]"+str(score)+"-🌟"

def score_logs(device_id,score,name):#收取设备奖励
    global msg
    if score==0:

        return "["+name+"]0-🌟"
    url="http://tiantang.mogencloud.com/api/v1/score_logs"
    header={"Content-Type":"application/json","authorization":authorization}
    body_json={'device_id':device_id,'score':score}
    encoded_body=json.dumps(body_json).encode('utf-8')
    http = urllib3.PoolManager()
    response= http.request('POST', url,body=encoded_body,headers=header)
    if response.status!=201 and response.status!=200:
       print("score_logs方法请求失败，结束程序")
       logging.debug("score_logs方法请求失败，结束程序")
       raise Exception("响应状态码:"+str(response.status)+"\n请求url:"+url+"\n消息:API出现异常，请暂停使用程序！")
    data=response.data.decode('utf-8')
    data=json.loads(data)

    if data['errCode']!=0:
        return "["+name+"]0-🌟(收取异常)"

    global total
    total=total+int(score)
    data=data['data']
    #发送微信推送，啥设备，获取了啥星星数
    return "["+name+"]"+str(score)+"-🌟"

def sign_in():#签到功能
	url="http://tiantang.mogencloud.com/web/api/account/sign_in"
	header={"Content-Type":"application/json","authorization":authorization}
	http = urllib3.PoolManager()
	response= http.request('POST', url,headers=header)
	if response.status!=201 and response.status!=200:
		print("sign_in方法请求失败，结束程序")
		logging.debug("sign_in方法请求失败，结束程序")
		raise Exception("响应状态码:"+str(response.status)+"\n请求url:"+url+"\n消息:API出现异常，请暂停使用程序！")
	data=response.data.decode('utf-8')
	data=json.loads(data)
	global msg

	if data['errCode']!=0:

		return "[签到奖励]0-🌟(失败:"+data['msg']+")"

	global total
	total=total+data['data']
	return "[签到奖励]"+str(data['data'])+"-🌟"

def readConfig(filePath):#读取配置文件
	try:
		file=open(filePath,"a+",encoding="utf-8",errors="ignore")
		file.seek(0)
		result=file.read()
	finally:
		if file:
			file.close()
			print("文件流已经关闭")

	return result
def zfb_withdraw(bean):#支付宝提现
    url="http://tiantang.mogencloud.com/api/v1/withdraw_logs"
    score=bean["score"]
    score=score-score%100
    real_name=bean["real_name"]
    card_id=bean["card_id"]
    bank_name="支付宝"
    sub_bank_name=""
    type="zfb"

    if score<1000:
        return "[自动提现]支付宝提现失败，星愿数不足1000",""
    if score>=10000:
        score=9900
    body_json="score="+str(score)+"&real_name="+real_name+"&card_id="+card_id+"&bank_name="+bank_name+"&sub_bank_name="+sub_bank_name+"&type="+type
    encoded_body=body_json.encode('utf-8')
    header={"Content-Type":"application/x-www-form-urlencoded;charset=UTF-8","authorization":authorization}
    http = urllib3.PoolManager()
    response= http.request('POST', url,body=encoded_body,headers=header)
    if response.status!=201 and response.status!=200:
        logging.debug("withdraw_logs方法请求失败")
        return "[自动提现]支付宝提现失败，请关闭自动提现等待更新并及时查看甜糖客户端app的账目",""

    data=response.data.decode('utf-8')
    data=json.loads(data)
    if data['errCode']==403002:
        logging.debug("[自动提现]支付宝提现失败，"+data['msg'])
        return "[自动提现]支付宝提现失败，"+data['msg'],""
    if data['errCode']!=0:
        print(""+data['msg']+str(score))
        logging.debug(""+data['msg']+str(score))
        return "[自动提现]支付宝提现失败，请关闭自动提现等待更新并及时查看甜糖客户端app的账目",""

    data=data['data']
    zfbID=data['card_id']
    pre=zfbID[0:4]
    end=zfbID[len(zfbID)-4:len(zfbID)]
    zfbID=pre+"***"+end
    item=[]
    item.append("-------提现方式：支付宝")
    item.append("-------支付宝号："+zfbID)
    return "[自动提现]扣除"+str(score)+"-🌟",item

def yhk_withdraw(bean):#银行卡提现
    url="http://tiantang.mogencloud.com/api/v2/withdraw_logs"
    score=bean["score"]
    score=score-score%100
    real_name=bean["real_name"]
    card_id=bean["card_id"]
    bank_name=bean["bank_name"]
    sub_bank_name=bean["sub_bank_name"]
    type="bank_card"

    if score<1000:
        return "[自动提现]银行卡提现失败，星愿数不足1000",""
    body_json="score="+str(score)+"&real_name="+real_name+"&card_id="+card_id+"&bank_name="+bank_name+"&sub_bank_name="+sub_bank_name+"&type="+type
    encoded_body=body_json.encode('utf-8')
    header={"Content-Type":"application/x-www-form-urlencoded;charset=UTF-8","authorization":authorization}
    http = urllib3.PoolManager()
    response= http.request('POST', url,body=encoded_body,headers=header)
    if response.status!=201 and response.status!=200:
        logging.debug("withdraw_logs方法请求失败")
        return "[自动提现]银行卡提现失败，请关闭自动提现等待更新并及时查看甜糖客户端app的账目",""

    data=response.data.decode('utf-8')
    data=json.loads(data)
    if data['errCode']==403002:
        logging.debug("[自动提现]银行卡提现失败，"+data['msg'])
        return "[自动提现]银行卡提现失败，"+data['msg'],""
    if data['errCode']!=0:
        print(""+data['msg']+str(score))
        logging.debug(""+data['msg']+str(score))
        return "[自动提现]银行卡提现失败，请关闭自动提现等待更新并及时查看甜糖客户端app的账目",""

    data=data['data']
    yhkID=data['card_id']
    pre=yhkID[0:4]
    end=yhkID[len(yhkID)-4:len(yhkID)]
    yhkID=pre+"****"+end
    item=[]
    item.append("-------提现方式：银行卡")
    item.append("-------银行卡号："+yhkID)
    return "[自动提现]扣除"+str(score)+"-🌟",item

def withdraw_type(userInfo):#根据用户是否签约来决定提现方式
	isEContract=userInfo['isEContract']
	bean={}
	if isEContract:
		#已经实名签约的采用银行卡提现
		bankCardList=userInfo['bankCardList']#获取支付宝列表
		if len(bankCardList)==0:
			withdraw_str="[自动提现]银行卡提现失败，原因是未绑定银行卡，请绑定一张银行卡"
			return withdraw_str,""
		else:
			bean["score"]=userInfo['score']
			bean["real_name"]=bankCardList[0]['name']
			bean["card_id"]=bankCardList[0]['bankCardNum']
			bean["bank_name"]=bankCardList[0]['bankName']
			bean["sub_bank_name"]=bankCardList[0]['subBankName']
			withdraw_str,item=yhk_withdraw(bean)
			return withdraw_str,item
	else:
		#未实名签约采用支付宝提现
		zfbList=userInfo['zfbList']#获取支付宝列表
		if len(zfbList)==0:
			withdraw_str="[自动提现]支付提现失败，原因是未绑定支付宝号，请绑定支付宝账户"
			return withdraw_str,""
		else:
			bean["score"]=userInfo['score']
			bean["real_name"]=zfbList[0]['name']
			bean["card_id"]=zfbList[0]['account']
			withdraw_str,item=zfb_withdraw(bean)
			return withdraw_str,item

def sendMSG(title,content):

    if len(plusplus_token)>10:
        msgContent=""
        num=0
        for item in content:
            num=num+1
            if len(content)==num:
                msgContent=msgContent+"
"
            if isinstance(item,list):
                msgContent=msgContent+"

"
                for i in item:
                    msgContent=msgContent+""+i+"
"
                msgContent=msgContent+"

"
            else:
                msgContent=msgContent+""+item+"
"
        sendPlusPlus(title,msgContent)
    if len(tg_bot_token)>10 and len(chat_id)!=0:
        msgContent=title+"\n\n"
        num=0
        for item in content:
            num=num+1
            if len(content)==num:
                msgContent=msgContent+"\n"
            if isinstance(item,list):
                for i in item:
                    msgContent=msgContent+"    "+i+"\n"
            else:
                msgContent=msgContent+""+item+"\n"
        sendTelegram(msgContent)

#*********************************main***********************************************************************************
#*********************************读取配置*************************************
end="注意:以上统计仅供参考，一切请以甜糖客户端APP为准。填写邀请码123463支持作者！"
config=readConfig(path+"/ttnodeConfig.config")
print("config:"+config)

if len(config)==0:
	print("错误提示ttnodeConfig.config为空，请重新运行ttnodeconfig.py")
	logging.debug("错误提示ttnodeConfig.config为空，请重新运行ttnodeconfig.py")
	exit()

config=eval(config)#转成字典
#获取甜糖授权码
authorization=config.get("authorization","")
#获取Plus+推送授权码
plusplus_token=config.get("plusplus_token","")
#获取Telegram机器人推送授权码
tg_bot_token=config.get("tg_bot_token","")
chat_id=config.get("chat_id","")

#提现配置参数
week=config.get("week",0)
if len(authorization)==0:
	print("错误提示authorization为空，请重新运行ttnodeconfig.py")
	exit()

week=int(week)

#*********************************错峰延时执行*************************************
sleep_time=random.randint(1,300)
print("错峰延时执行"+str(sleep_time)+"秒，请耐心等待")
logging.debug("错峰延时执行"+str(sleep_time)+"秒，请耐心等待")
#time.sleep(sleep_time)
#*********************************获取用户信息*************************************
content=[]
data=getInitInfo()
inactivedPromoteScore=data['inactivedPromoteScore']
accountScore=data['score']

devices=getDevices()#获取设备列表信息
#*********************************收取星星*************************************
score_info=[]
sign_in_msg=sign_in()#收取签到收益
score_info.append(sign_in_msg)
promote_score_msg=promote_score_logs(inactivedPromoteScore)#收取推广收益
score_info.append(promote_score_msg)
for device in devices:
    string=score_logs(device['hardware_id'],device['inactived_score'],device['alias'])#收取设备收益
    score_info.append(string)
    time.sleep(1)

#*********************************自动提现*************************************
withdraw=""
now_week=dt.datetime.now().isoweekday()#获取今天是星期几返回1-7
now_week=int(now_week)
items=[]
if week==now_week:
    userInfo=getInitInfo()
    withdraw,items=withdraw_type(userInfo)

#*********************************收益统计并发送微信消息*************************************
total_str="[总共收取]"+str(total)+"-🌟"
nowdata=getInitInfo()
accountScore=nowdata['score']
nickName="[账户昵称]"+nowdata['nickName']
accountScore_str="[账户星愿]"+str(accountScore)+"-🌟"
now_time = dt.datetime.now().strftime('%F %T')
now_time_str="[当前时间]"+now_time

content.append(now_time_str)
content.append(nickName)
content.append(accountScore_str)
content.append(total_str)

if week==now_week:
    content.append(withdraw)
    if len(items)!=0:
        content.append(items)

content.append("[收益详细]：")
content.append(score_info)
content.append(end)
sendMSG(msgTitle,content)

print("微信消息已推送。请注意查看。")
title="[甜糖星愿]"
content="####"

exit()


import time
import random
import itertools
pop_size=50
k_n_generations = 50
tournment=16
mutation=1
crossover=1
arr2=[   [0,1,2,3,4],
	        [1,0,5,6,7],
			[2,5,0,8,9],
			[3,6,8,0,10],
			[4,7,9,10,0]]
arr=[[0,66,21,3,500,26,77,69,125,650],
	[66,0,35,115,36,65,85,90,44,54],
	[21,35,0,450,448,846,910,47,11,145],
	[3,115,450,0,65,478,432,214,356,251],
	[500,36,448,65,0,258,143,325,125,39],
	[26,65,846,478,258,0,369,256,345,110],
	[77,85,910,432,143,369,0,45,120,289],
	[69,90,47,214,325,256,45,0,325,981],
	[125,44,11,356,125,345,120,325,0,326],
	[650,54,145,251,39,110,289,981,326,0]]
def fitness(r):
	distance=0

	for i in range(len(r)-1):
		distance=distance+arr[r[i]-1][r[i+1]-1]
	return distance

def sum_distance(gen):
	sum=0
	for i in range(pop_size):
		sum=sum+gen[i][10]
	return sum
def prob(r,gen):
	return 1-(r[10]/sum_distance(gen))
def selection(gen):
	selected=[]
	count=0

	for i in range(pop_size):
		sel=gen[i]
		if count==tournment:
		  break
		if sel in selected:
		  continue
		for j in range(pop_size):
		  if(prob(sel,gen)<prob(gen[j],gen) and gen[j] not in selected):
		    sel=gen[j]
		selected.append(sel)
		count=count+1
	return selected

def crossover(p1,p2):

        child_rt1 = []
        child_rt2= []
        for x in range(0,len(p1)):
            child_rt1.append( None)
            child_rt2.append(None)

        # Two random integer indices of the parent1:
        start_pos = random.randint(0,len(p1))
        end_pos = random.randint(0,len(p1))
        if start_pos==end_pos:
          if start_pos>0: start_pos-1
          else: end_pos+1
        # print("pos")
        # print(start_pos)
        # print(end_pos)
        #### takes the sub-route from parent one and sticks it in itself:
        # if the start position is before the end:
        if start_pos < end_pos:
            # do it in the start-->end order
            for x in range(start_pos,end_pos):
                a=p1[x]
                b=p2[x]
                child_rt1[x]=b
                child_rt2[x]=a
                # print(a)
                # print(b)
				# if the start position is after the end:
        elif start_pos > end_pos:
            # do it in the end-->start order
            for i in range(end_pos,start_pos):
                a=p1[i]
                b=p2[i]
                child_rt2[i] = a # set the values to eachother
                child_rt1[i] = b
                # print(a)
                # print(b)
        # Cycles through the parent2. And fills in the child_rt

        for i in range(len(p1)):
            # if parent2 has a city that the child2 doesn't have yet:
            if not p2[i] in child_rt2:
                # it puts it in the first 'None' spot and breaks out of the loop.
                for x in range(len(child_rt2)):
                    if child_rt2[x] == None:
                        child_rt2[x] = p2[i]
                        break
            # if parent1 has a city that the child1 doesn't have yet:

            if not p1[i] in child_rt1:
                # it puts it in the first 'None' spot and breaks out of the loop.
                for x in range(len(child_rt1)):
                    if child_rt1[x] == None:
                        child_rt1[x] = p1[i]
                        break
        # repeated until all the cities are in the child route

        return child_rt1,child_rt2
def mutate( route_to_mut):

    if random.random() < mutation:

        mut_pos1 = random.randint(0,len(route_to_mut)-1)
        mut_pos2 = random.randint(0,len(route_to_mut)-1)
         # if they're the same, skip to the chase
        if mut_pos1 == mut_pos2:
            return route_to_mut

        # Otherwise swap them:
        city1 = route_to_mut[mut_pos1]
        city2 = route_to_mut[mut_pos2]
        route_to_mut[mut_pos2] = city1
        route_to_mut[mut_pos1] = city2

    return route_to_mut
def evolve_population(first_gen,s):

	m=[]
	count=0
	for a in range(pop_size):
		max=first_gen[a]
		if count==len(s): break
		if max in m: continue

		for b in range(pop_size):
		  #if first_gen[b][5]>max[5] or max not in m:
		  if(prob(max,first_gen)>prob(first_gen[b],first_gen) and first_gen[b] not in m):
		    max=first_gen[b]
		m.append(max)
		count+=1
	next=first_gen
	def replace(L, X, Y):
		while X in L:
		  i = L.index(X)
		  L.insert(i, Y)
		  L.remove(X)

	for i in range(len(s)):
		if s[i] not in first_gen:
		  replace(first_gen,m[i],s[i])

	return next

def GA(gen,n=0):
	start_time = time.time()
	# time
	# selection(gen)
	# crossover
	# mutate
	# evolve_population
	# best yet
	def run(gen):
		children=[]
		p=selection(gen)
		best_route_yet=p[0]
		print("selected")
		print(p)
		#for i in range(len(p)-1):
		for index, item in enumerate(p):
			next = index + 1
			if next < len(p):
				#print( index, item, next)
				f1=p[index].pop()
				f2=p[next].pop()
				c1,c2=crossover(p[index],p[next])
				#print("children crossed")
				#print(c1,c2)
				c1=mutate(c1)
				c2=mutate(c2)
				#print("children mutated")
				#print(c1,c2)
				c1.append(fitness(c1))
				c2.append(fitness(c2))
				children.append(c1)
				children.append(c2)
				p[index].append(f1)
				p[next].append(f2)

		return children	,best_route_yet
	#print("previous generation")

	children,best_route_yet=run(gen)
	next_gen=evolve_population(gen,children)
	if selection(next_gen)[0][10]<best_route_yet[10]:
		best_route_yet=selection(next_gen)[0]

	for n in itertools.count():
		if n<k_n_generations:
			n+=1
			run(next_gen)
		else:
			end_time = time.time()
	#print(start_time,end_time)
			print("Elapsed time was %f seconds."%(end_time - start_time))
			return best_route_yet

def main():

	first_gen =[]
	for population in range(pop_size):
		route = random.sample(range(1,11), 10)
		route.append(fitness(route))
		first_gen.append(route)

	print(first_gen)

	print("initial shortest distance")
	print(selection(first_gen)[0])

	print("shortest distance after %d generations"%k_n_generations)
	s=GA(first_gen)
	print("hhhhhhhhhhhhh")
	print(s)

if __name__ == "__main__":
    main()


import boto3
import time

# AWS credentials and region
aws_access_key_id = 'accesskey'
aws_secret_access_key = 'secretaccesskey'
region = 'ap-south-1'

# User data script (replace with your script content)
user_data_script = '''#!/bin/bash
# Your startup script commands here
# Update the package repository
yum update -y

# Install Apache
yum install -y httpd

# Start Apache and enable it to start on boot
systemctl start httpd
systemctl enable httpd

# Configure AWS CLI with access keys
aws configure set aws_access_key_id accesskey
aws configure set aws_secret_access_key secretaccesskey
aws configure set default.region ap-south-1

# Copy website files from S3 to the Apache web root directory
aws s3 cp s3://boto-bucket84/website/ /var/www/html --recursive

# Ensure correct ownership and permissions
chown -R apache:apache /var/www/html
chmod -R 755 /var/www/html

# http port range =80
curl localhost:80

# Restart Apache to apply changes
systemctl restart httpd

echo "Website setup complete!"
'''

# Security group settings
security_group_name = 'apacheee-server-group'
security_group_description = 'Security group for web server'
security_group_port = 80

# Launch an EC2 instance
def launch_ec2_instance():
    ec2 = boto3.resource('ec2', region_name=region, aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key)

    # Create security group
    security_group = ec2.create_security_group(
        GroupName=security_group_name,
        Description=security_group_description
    )

    # Allow incoming traffic on port 80- http
    security_group.authorize_ingress(
        IpProtocol='tcp',
        FromPort=security_group_port,
        ToPort=security_group_port,
        CidrIp='0.0.0.0/0'
    )
    # Allow incoming traffic on port 22 - ftp
    security_group.authorize_ingress(
        IpProtocol='tcp',
        FromPort=22,
        ToPort=22,
        CidrIp='0.0.0.0/0'
    )
    # Allow incoming traffic on port 443 - https
    security_group.authorize_ingress(
        IpProtocol='tcp',
        FromPort=443,
        ToPort=443,
        CidrIp='0.0.0.0/0'
    )

    # Launch instance
    instance = ec2.create_instances(
        ImageId='ami-xxxxxxxxxxx',  # Replace with the appropriate AMI ID
        InstanceType='t2.micro',
        MinCount=1,
        MaxCount=1,
        SecurityGroups=[security_group_name],
        UserData=user_data_script,
        KeyName='sarthak'  # Replace with your EC2 key pair name
    )[0]

    print(f"Instance launched: {instance.id}")
    # Add a name tag to the instance
    ec2_client = boto3.client('ec2', region_name=region,
                              aws_access_key_id=aws_access_key_id,
                              aws_secret_access_key=aws_secret_access_key)

    ec2_client.create_tags(Resources=[instance.id], Tags=[{'Key': 'Name', 'Value': 'lab2_practice4'}])

    print("Instance name tag added.")
    return instance

# Wait for instance to reach "running" state and return public DNS
def get_instance_public_dns(instance):
    instance.wait_until_running()
    instance.reload()
    public_dns = instance.public_dns_name
    return public_dns

def check_instance_status(instance):
    print("Waiting for instance to reach 'running' state...")
    while instance.state['Name'] != 'running':
        time.sleep(5)  # Wait for 5 seconds before checking again
        instance.reload()  # Refresh instance information
    print("Instance is now in 'running' state.")

if __name__ == '__main__':
    launched_instance = launch_ec2_instance()
    check_instance_status(launched_instance)
    public_dns_address = get_instance_public_dns(launched_instance)
    print(f"Instance public DNS: {public_dns_address}")


import itertools

import cftime
import numpy as np

from iris._lazy_data import as_lazy_data, multidim_lazy_stack
from iris.fileformats.um._optimal_array_structuring import (
    optimal_array_structure,
)

class BasicFieldCollation:
    """
    An object representing a group of UM fields with array structure that can
    be vectorized into a single cube.

    For example:

    Suppose we have a set of 28 fields repeating over 7 vertical levels for
    each of 4 different data times.  If a BasicFieldCollation is created to
    contain these, it can identify that this is a 4*7 regular array structure.

    This BasicFieldCollation will then have the following properties:

    * within 'element_arrays_and_dims' :
        Element 'blev' have the array shape (7,) and dims of (1,).
        Elements 't1' and 't2' have shape (4,) and dims (0,).
        The other elements (lbft, lbrsvd4 and lbuser5) all have scalar array
        values and dims=None.

    .. note::

        If no array structure is found, the element values are all
        either scalar or full-length 1-D vectors.

    """

    def __init__(self, fields):
        """
        Args:

        * fields (iterable of :class:`iris.fileformats.pp.PPField`):
            The fields in the collation.

        """
        self._fields = tuple(fields)
        self._data_cache = None
        assert len(self.fields) > 0
        self._structure_calculated = False
        self._vector_dims_shape = None
        self._primary_dimension_elements = None
        self._element_arrays_and_dims = None

    @property
    def fields(self):
        return self._fields

    @property
    def data(self):
        if not self._structure_calculated:
            self._calculate_structure()
        if self._data_cache is None:
            stack = np.empty(self.vector_dims_shape, "object")
            for nd_index, field in zip(
                np.ndindex(self.vector_dims_shape), self.fields
            ):
                stack[nd_index] = as_lazy_data(field._data)
            self._data_cache = multidim_lazy_stack(stack)
        return self._data_cache

    def core_data(self):
        return self.data

    @property
    def realised_dtype(self):
        return np.result_type(
            *[field.realised_dtype for field in self._fields]
        )

    @property
    def data_proxy(self):
        return self.data

    @property
    def bmdi(self):
        bmdis = set([f.bmdi for f in self.fields])
        if len(bmdis) != 1:
            raise ValueError("Multiple bmdi values defined in FieldCollection")
        return bmdis.pop()

    @property
    def vector_dims_shape(self):
        """The shape of the array structure."""
        if not self._structure_calculated:
            self._calculate_structure()
        return self._vector_dims_shape

    @property
    def _UNUSED_primary_dimension_elements(self):
        """A set of names of the elements which are array dimensions."""
        if not self._structure_calculated:
            self._calculate_structure()
        return self._primary_dimension_elements

    @property
    def element_arrays_and_dims(self):
        """
        Value arrays for vector metadata elements.

        A dictionary mapping element_name: (value_array, dims).

        The arrays are reduced to their minimum dimensions.  A scalar array
        has an associated 'dims' of None (instead of an empty tuple).

        """
        if not self._structure_calculated:
            self._calculate_structure()
        return self._element_arrays_and_dims

    def _field_vector_element_arrays(self):
        """Define the field components used in the structure analysis."""

        # Define functions to make t1 and t2 values as date-time tuples.
        # These depend on header version (PPField2 has no seconds values).
        def t1_fn(fld):
            return (
                fld.lbyr,
                fld.lbmon,
                fld.lbdat,
                fld.lbhr,
                fld.lbmin,
                getattr(fld, "lbsec", 0),
            )

        def t2_fn(fld):
            return (
                fld.lbyrd,
                fld.lbmond,
                fld.lbdatd,
                fld.lbhrd,
                fld.lbmind,
                getattr(fld, "lbsecd", 0),
            )

        # Return a list of (name, array) for the vectorizable elements.
        component_arrays = [
            ("t1", np.array([t1_fn(fld) for fld in self.fields])),
            ("t2", np.array([t2_fn(fld) for fld in self.fields])),
            ("lbft", np.array([fld.lbft for fld in self.fields])),
            ("blev", np.array([fld.blev for fld in self.fields])),
            ("lblev", np.array([fld.lblev for fld in self.fields])),
            ("bhlev", np.array([fld.bhlev for fld in self.fields])),
            ("bhrlev", np.array([fld.bhrlev for fld in self.fields])),
            ("brsvd1", np.array([fld.brsvd[0] for fld in self.fields])),
            ("brsvd2", np.array([fld.brsvd[1] for fld in self.fields])),
            ("brlev", np.array([fld.brlev for fld in self.fields])),
        ]
        return component_arrays

    # Static factors for the _time_comparable_int routine (seconds per period).
    _TIME_ELEMENT_MULTIPLIERS = np.cumprod([1, 60, 60, 24, 31, 12])[::-1]

    def _time_comparable_int(self, yr, mon, dat, hr, min, sec):
        """
        Return a single unique number representing a date-time tuple.

        This calculation takes no account of the time field's real calendar,
        instead giving every month 31 days, which preserves the required
        time ordering.

        """
        elements = np.array((yr, mon, dat, hr, min, sec))
        return np.sum(elements * self._TIME_ELEMENT_MULTIPLIERS)

    def _calculate_structure(self):
        # Make value arrays for the vectorisable field elements.
        element_definitions = self._field_vector_element_arrays()

        # Identify the vertical elements and payload.
        blev_array = dict(element_definitions).get("blev")
        vertical_elements = (
            "lblev",
            "bhlev",
            "bhrlev",
            "brsvd1",
            "brsvd2",
            "brlev",
        )

        # Make an ordering copy.
        ordering_definitions = element_definitions[:]
        # Replace time value tuples with integers and bind the vertical
        # elements to the (expected) primary vertical element "blev".
        for index, (name, array) in enumerate(ordering_definitions):
            if name in ("t1", "t2"):
                array = np.array(
                    [self._time_comparable_int(*tuple(val)) for val in array]
                )
                ordering_definitions[index] = (name, array)
            if name in vertical_elements and blev_array is not None:
                ordering_definitions[index] = (name, blev_array)

        # Perform the main analysis: get vector dimensions, elements, arrays.
        (
            dims_shape,
            primary_elements,
            vector_element_arrays_and_dims,
        ) = optimal_array_structure(ordering_definitions, element_definitions)

        # Replace time tuples in the result with real datetime-like values.
        # N.B. so we *don't* do this on the whole (expanded) input arrays.
        for name in ("t1", "t2"):
            if name in vector_element_arrays_and_dims:
                arr, dims = vector_element_arrays_and_dims[name]
                arr_shape = arr.shape[:-1]
                extra_length = arr.shape[-1]
                # Flatten out the array apart from the last dimension,
                # convert to cftime objects, then reshape back.
                arr = np.array(
                    [
                        cftime.datetime(*args)
                        for args in arr.reshape(-1, extra_length)
                    ]
                ).reshape(arr_shape)
                vector_element_arrays_and_dims[name] = (arr, dims)

        # Write the private cache values, exposed as public properties.
        self._vector_dims_shape = dims_shape
        self._primary_dimension_elements = primary_elements
        self._element_arrays_and_dims = vector_element_arrays_and_dims
        # Do all this only once.
        self._structure_calculated = True

def _um_collation_key_function(field):
    """
    Standard collation key definition for fast structured field loading.

    The elements used here are the minimum sufficient to define the
    'phenomenon', as described for :meth:`group_structured_fields`.

    """
    return (
        field.lbuser[3],  # stashcode first
        field.lbproc,  # then stats processing
        field.lbuser[6],  # then model
        field.lbuser[4],  # then pseudo-level : this one is a KLUDGE.
    )
    # NOTE: including pseudo-level here makes it treat different pseudo-levels
    # as different phenomena.  These will later be merged in the "ordinary"
    # post-load merge.
    # The current structured-load code fails to handle multiple pseudo-levels
    # correctly: because pseudo-level is not on in its list of "things that may
    # vary within a phenomenon", it will create a scalar pseudo-level
    # coordinate when it should have been a vector of values.
    # This kludge fixes that error, but it is inefficient because it bypasses
    # the structured load, producing n-levels times more 'raw' cubes.
    # It will also fail if any phenomenon occurs with multiple 'normal' levels
    # (i.e. lblev) *and* pseudo-levels (lbuser[4]).
    # TODO: it should be fairly easy to do this properly -- i.e. create a
    # vector pseudo-level coordinate directly in the structured load analysis.

def group_structured_fields(
    field_iterator, collation_class=BasicFieldCollation, **collation_kwargs
):
    """
    Collect structured fields into identified groups whose fields can be
    combined to form a single cube.

    Args:

    * field_iterator (iterator of :class:`iris.fileformats.pp.PPField`):
        A source of PP or FF fields.  N.B. order is significant.

    Kwargs:

    * collation_class (class):
        Type of collation wrapper to create from each group of fields.
    * collation_kwargs (dict):
        Additional constructor keywords for collation creation.

    The function sorts and collates on phenomenon-relevant metadata only,
    defined as the field components: 'lbuser[3]' (stash), 'lbproc' (statistic),
    'lbuser[6]' (model).
    Each distinct combination of these defines a specific phenomenon (or
    statistical aggregation of one), and those fields appear as a single
    iteration result.

    Implicitly, within each result group, *all* other metadata components
    should be either:

    *  the same for all fields,
    *  completely irrelevant, or
    *  used by a vectorised rule function (such as
       :func:`iris.fileformats.pp_load_rules._convert_time_coords`).

    Returns:
        A generator of 'collation_class' objects, each of which contains a
        single collated group from the input fields.

    .. note::

         At present, fields with different values of 'lbuser[4]' (pseudo-level)
         are *also* treated as different phenomena.  This is a temporary fix,
         standing in place for a more correct handling of pseudo-levels.

    """
    _fields = sorted(field_iterator, key=_um_collation_key_function)
    for _, fields in itertools.groupby(_fields, _um_collation_key_function):
        yield collation_class(tuple(fields), **collation_kwargs)


from .base_scraper import BaseScraper
from datetime import datetime
from utils.helpers import retry_on_request
from bs4 import BeautifulSoup
import requests

class DiarioOficialScraper(BaseScraper):
    def __init__(self, date=None):
        super().__init__()
        self.date = date if date else datetime.now().strftime("%d-%m-%Y")
        self.url = f"https://www.diariooficial.interior.gob.cl/edicionelectronica/index.php?date={self.date}"

    def fetch_editions(self):
        response = self.fetch_url(self.url)
        soup = self.parse_html(response)

        # Check if the page has a "No existen publicaciones" message
        if soup.find("p", class_="nofound"):
            print(f"No publications on {self.url}")
            return []
        else:
            # If there are multiple editions, find the hrefs
            if "select_edition" in response.url:
                edition_links = [
                    link.get("href")
                    for link in soup.find_all("a")
                    if "edition=" in link.get("href", "")
                ]
                # Append the base url to these hrefs
                edition_links = [
                    "https://www.diariooficial.interior.gob.cl/edicionelectronica/"
                    + link
                    for link in edition_links
                ]
            else:
                # If there's just one edition, get its URL
                edition_links = [response.url]

            return edition_links

def soup_to_dictionary(soup):
    soup_dictionary = {}  # Dictionary to store the soup_dictionary

    # Temporary variables to store the current titles
    title1 = title2 = title3 = title4 = title5 = None

    for row in soup.select("tr"):
        if "title1" in row.td.get("class", []):
            title1 = row.td.get_text(strip=True)
            soup_dictionary[title1] = {}
            title2 = title3 = title4 = title5 = None
        elif "title2" in row.td.get("class", []):
            title2 = row.td.get_text(strip=True)
            soup_dictionary[title1][title2] = {}
            title3 = title4 = title5 = None
        elif "title3" in row.td.get("class", []):
            title3 = row.td.get_text(strip=True)
            soup_dictionary[title1][title2][title3] = {}
            title4 = title5 = None
        elif "title4" in row.td.get("class", []):
            title4 = row.td.get_text(strip=True)
            soup_dictionary[title1][title2][title3][title4] = {}
            title5 = None
        elif "title5" in row.td.get("class", []):
            title5 = row.td.get_text(strip=True)
            soup_dictionary[title1][title2][title3].setdefault(title4, {})[title5] = []
        elif "content" in row.get("class", []):
            name_div = row.select_one('td > div[style="float:left; width:550px;"]')
            rut_div = row.select_one('td > div[style="float:right;"]')
            link_a = row.select_one("td > a")
            if name_div and link_a:
                company_info = {
                    "company": name_div.text.strip(),
                    "link": link_a["href"],
                    "link_text": link_a.get_text(strip=True),
                }
                if rut_div:
                    company_info["RUT"] = rut_div.text.strip()
                soup_dictionary[title1][title2][title3].get(title4, {}).get(
                    title5, []
                ).append(company_info)

    return soup_dictionary

@retry_on_request
def fetch_url(url):
    response = requests.get(url)
    response.raise_for_status()  # Ensure we got a successful response
    return response

def parse_html(response):
    soup = BeautifulSoup(response.content, "html.parser")
    return soup


"""Represents the machine that picks numbers"""

import random

import pygame as pg

from data.components import common
from data.components import loggable
from .settings import SETTINGS as S
from . import statemachine

class Ball(object):
    """A ball representing a number in the game"""

    def __init__(self, number):
        """Initialise the ball"""
        self.number = number
        #
        # Get the name for this ball (eg B1, I20)
        number_lookup = S['card-numbers']
        for letter, col in zip('BINGO', sorted(number_lookup.keys())):
            numbers = number_lookup[col]
            if number in numbers:
                self.letter = letter
                self.col = col
                break
        else:
            raise ValueError('Could not locate details for {0}'.format(number))
        #
        self.full_name = '{0}{1}'.format(self.letter, self.number)

class BallMachine(common.Drawable, loggable.Loggable):
    """A machine to pick balls at random"""

    def __init__(self, name, state):
        """Initialise the machine"""
        self.addLogger()
        self.name = name
        self.state = state
        #
        self.all_balls = [Ball(n) for n in S['machine-balls']]
        self.balls = []
        self.called_balls = []
        self.speed_buttons = common.DrawableGroup()
        self.buttons = common.ClickableGroup()
        self.current_ball = None
        self.interval = self.initial_interval = S['machine-speeds'][0][1] * 1000
        self.running = False
        self.timer = None
        self.speed_transitions = {}
        #
        self.ui = self.create_ui()
        self.reset_machine()

    def create_ui(self):
        """Create the UI components"""
        components = common.DrawableGroup()
        #
        # The display of all the balls that have been called
        self.called_balls_ui = CalledBallTray(S['called-balls-position'], self.state)
        components.append(self.called_balls_ui)
        #
        # Speed increases based on the number of balls called
        for idx, (name, interval, number_balls) in enumerate(S['machine-speeds']):
            self.speed_transitions[number_balls] = (idx, interval)
        #
        self.cog = CogWheel(self)
        components.append(self.cog)
        #
        # The spout showing progress towards a new ball
        self.spout_sprites = [
            common.NamedSprite('bingo-spout-{0}'.format(i), S['spout-position']) for i in range(S['spout-number'])
        ]
        #
        return components

    def change_speed(self, obj,  arg, silent=False):
        """Change the speed of the ball machine"""
        selected_idx, interval = arg
        self.log.info('Changing machine speed to index {0}, {1}s'.format(selected_idx, interval))
        #
        # Play appropriate sound
        if not silent:
            if interval < self.interval / 1000:
                self.state.play_sound('bingo-speed-up')
            else:
                self.state.play_sound('bingo-slow-down')
        #
        # Set cog
        self.cog.set_speed(selected_idx)
        #
        # Set speed of the machine
        self.reset_timer(interval * 1000)

    def start_machine(self):
        """Start the machine"""
        self.running = True
        if self.timer:
            try:
                self.state.stop_generator('ball-machine')
            except statemachine.NotFound:
                # OK, must have already completed
                pass

        self.timer = self.state.add_generator('ball-machine', self.pick_balls())

    def stop_machine(self):
        """Stop the machine"""
        self.running = False

    def reset_timer(self, interval):
        """Reset the timer on the machine"""
        self.interval = interval
        if self.timer:
            self.timer.update_interval(interval)

    def reset_machine(self, interval=None):
        """Reset the machine"""
        self.balls = list(self.all_balls)
        self.called_balls = []
        random.shuffle(self.balls)
        self.called_balls_ui.reset_display()
        self.change_speed(None, (0, S['machine-speeds'][0][1]), silent=True)
        self.start_machine()

    def pick_balls(self):
        """Pick the balls"""
        for idx, ball in enumerate(self.balls):
            #
            # Under some circumstances we will restart this iterator so this
            # makes sure we don't repeat balls
            if ball.number in self.called_balls:
                continue
            #
            self.called_balls.append(ball.number)
            self.set_current_ball(ball)
            self.state.play_sound('bingo-ball-chosen')
            #
            # Watch for speed transition
            try:
                button_idx, new_interval = self.speed_transitions[idx]
            except KeyError:
                # No transition
                pass
            else:
                self.change_speed(None, (button_idx, new_interval))
            #
            # Wait for next ball
            yield self.interval

    def set_current_ball(self, ball):
        """Set the current ball"""
        self.log.info('Current ball is {0}'.format(ball.full_name))
        #
        self.current_ball = ball
        self.state.ball_picked(ball)
        self.called_balls_ui.call_ball(ball)

    def draw(self, surface):
        """Draw the machine"""
        self.ui.draw(surface)
        if not self.timer.paused:
            self.called_balls_ui.update(self.state.dt * S['conveyor-speed'] / self.interval)
            self.cog.update(self.state.dt * S['machine-cog-speed'] / self.interval)
        #
        # Calculate how close we are to choosing a new ball
        fraction = 1.0 - self.timer.get_fraction_to_go()
        if fraction > 0.95:
            self.spout_sprites[-1].draw(surface)
        else:
            self.spout_sprites[int(fraction * (S['spout-number'] - 1))].draw(surface)

    def call_next_ball(self):
        """Immediately call the next ball"""
        self.timer.next_step()

    def pause(self):
        """Pause the machine"""
        self.timer.paused = True

    def unpause(self):
        """Unpause the machine"""
        self.timer.paused = False

class CalledBallTray(common.Drawable, loggable.Loggable):
    """A display of the balls that have been called"""

    def __init__(self, position, state):
        """Initialise the display"""
        self.addLogger()
        self.state = state
        #
        self.x, self.y = position
        self.called_balls = []
        #
        self.conveyor = common.NamedSprite(
            'bingo-conveyor',
            S['conveyor-position'],
        )
        self.initial_x = S['conveyor-position'][0]
        self.current_x = 0
        #
        self.background = common.NamedSprite('bingo-grill', S['machine-background-position'])
        self.dropping_balls = common.DrawableGroup()
        self.moving_balls = common.DrawableGroup()

    def call_ball(self, ball):
        """Call a particular ball"""
        self.called_balls.append(ball)
        ball_ui = SingleBallDisplay('ball', S['machine-ball-position'], ball, self)
        self.dropping_balls.append(ball_ui)
        self.state.add_generator('ball-falling', self.ball_falling(ball_ui))

    def draw(self, surface):
        """Draw the tray"""
        self.background.draw(surface)
        self.moving_balls.draw(surface)
        self.dropping_balls.draw(surface)
        self.conveyor.draw(surface)

    def reset_display(self):
        """Reset the display of the balls"""
        self.called_balls = []
        self.dropping_balls.clear()
        self.moving_balls.clear()

    def update(self, increment):
        """Update the display of the tray"""
        self.current_x += increment
        if self.current_x > S['conveyor-repeat']:
            self.current_x -= S['conveyor-repeat']
        self.conveyor.rect.x = self.initial_x + self.current_x
        self.move_balls(increment)

    def ball_falling(self, ball):
        """Cause a ball to fall down to the conveyor"""
        drop_speed = S['machine-ball-drop-initial-speed']
        while ball.y < S['conveyor-ball-position']:
            ball.y += drop_speed
            drop_speed += S['machine-ball-drop-acceleration']
            yield 10
        self.moving_balls.append(ball)
        #
        # Remove from the list - note that we have to check the ball is still there
        # because the machine may have been reset between the 'yield' and here
        if ball in self.dropping_balls:
            self.dropping_balls.remove(ball)

    def move_balls(self, increment):
        """Move the balls"""
        for ball in reversed(self.moving_balls):
            ball.x += increment
            if ball.x >= S['conveyor-ball-drop-off']:
                self.moving_balls.remove(ball)

class SingleBallDisplay(common.Drawable, loggable.Loggable):
    """A ball displayed on the screen"""

    def __init__(self, name, position, ball, state):
        """Initialise the ball"""
        self.addLogger()
        #
        self.name = name
        self.state = state
        #
        # Create the background chip
        self.background = common.NamedSprite.from_sprite_sheet(
            'chips', (2, 5),
            S['called-ball-sprite-lookup'][ball.col], position,
            scale=S['machine-ball-sprite-scale']
        )
        #
        # And the text for the number
        self.text = common.getLabel(
            'machine-ball',
            (self.background.rect.width / 2, self.background.rect.height / 2), str(ball.number), S
        )
        self.text.color = pg.Color(S['called-ball-font-color'][ball.col])
        self.text.update_text()
        #
        # Write the number on the background
        self.text.draw(self.background.sprite)
        #
        # And rotate a bit
        self.background.rotate_to(random.uniform(*S['machine-ball-angle-range']))
        #
        self._x, self._y = self.background.rect.x, self.background.rect.y

    @property
    def y(self):
        return self._y

    @y.setter
    def y(self, value):
        self._y = value
        self.background.rect.y = value

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, value):
        self._x = value
        self.background.rect.x = value

    def draw(self, surface):
        """Draw the ball"""
        self.background.draw(surface)

class CogWheel(common.Drawable):
    """Visual display of the cog"""

    def __init__(self, state):
        """Initialise the cog"""
        self.state = state
        #
        self.sprites = [
            common.NamedSprite(
                'bingo-cog-{0}'.format(i),
                S['machine-cog-position'],
            ) for i in range(len(S['machine-speeds']))
        ]
        self.speed = 0
        self.angle = 0
        self.set_speed(0)
        self.current_sprite = self.sprites[0].sprite
        self.x, self.y = S['machine-cog-position']

    def set_speed(self, speed):
        """Set the current speed"""
        self.speed = speed

    def draw(self, surface):
        """Draw the cog"""
        w, h = self.current_sprite.get_size()
        rect = pg.Rect(self.x - w / 2, self.y - h / 2, w, h)
        surface.blit(self.current_sprite, rect)

    def update(self, increment):
        """Update the display of the cog"""
        self.angle = (self.angle + increment) % 360
        # TODO: refactor the rotation logic - should be built into sprite
        surface = self.sprites[self.speed].sprite.copy()
        self.current_sprite = pg.transform.rotozoom(surface, self.angle, 1.0)


# Script to train machine learning model.

from sklearn.model_selection import train_test_split

# Add the necessary imports for the starter code.
import pickle
import pandas as pd
from ml.data import process_data
from ml.model import train_model
from ml.model import inference
from ml.model import compute_model_metrics

# Add code to load in the data.
data = pd.read_csv("data/clean_census.csv")
# Optional enhancement, use K-fold cross validation instead of a train-test split.
train, test = train_test_split(data, test_size=0.20)

cat_features = [
    "workclass",
    "education",
    "marital-status",
    "occupation",
    "relationship",
    "race",
    "sex",
    "native-country",
]
X_train, Y_train, encoder, lb = process_data(
    train, categorical_features=cat_features, label="salary", training=True
)

# Proces the test data with the process_data function.
X_test, y_test, encoder_test, lb_test = process_data(
    test, categorical_features=cat_features, label="salary", training=True
)
# Train and save the model and encoder.
def train_save_model(x_train, y_train, encoder):
    model = train_model(x_train, y_train)
    model_filename = './model/model.sav'
    encoder_filename = './model/encoder.sav'
    pickle.dump(model, open(model_filename, 'wb'))
    pickle.dump(encoder, open(encoder_filename, 'wb'))
    return model

#Model inference
pred = inference(train_save_model(X_train, Y_train, encoder), X_train)

#Get prediction metrics
precision, recall, fbeta = compute_model_metrics(Y_train, pred)


import datetime
import math
import time

import db_helper
import utils
from config import *

def exec_volatility(ticker):
    # 잔고 조회
    balance = upbit.get_balance(ticker="KRW")
    # balances = upbit.get_balances()

    # True -> 신규 포지션 진입 가능
    op_mode = False

    # 목표 수익률 | 손절율
    take_profit_rate = 3.0
    loss_cut_rate = -2.0

    # 분할 매도 비율
    split_sell_rate = 0.8

    position = {
        'type': None,
        'time': None,
        'order_price': 0,
        'volume': 0
    }

    try:
        # 현재 시간
        now = datetime.datetime.now()

        # 현재 가격
        cur_price = pyupbit.get_current_price(ticker=ticker)

        # 목표 가격
        table = 'target_table'
        row = db_helper.select_db(table=table, ticker=ticker)
        if row:
            target = row['target']
            op_mode = row['op_mode']
        else:
            return

        # btc sma 20 이격률
        btc_sma20_sep_rate = utils.calc_btc_sma20_sep_rate()

        # rsi14
        rsi14 = utils.calc_rsi14(ticker)

        print(now)
        # TODO position table에 매수 시 티커 타입 시간 가격 볼륨 저장
        # TODO position table에 매도 시 티커 타입 시간 가격 볼륨 저장
        # TODO postion dict를 pyupbit에서 balance에서 가져와 채우기
        if position['type'] is None:
            print(
                'ticker:', ticker,
                "목표가:", target,
                "현재가:", cur_price, '\n'
                                   "btc sma 20 이격도:", btc_sma20_sep_rate,
                "rsi14:", rsi14,
                "op_mode:", op_mode
            )
        else:
            print(
                "진입시간:", position['time'],
                "주문가:", position["order_price"],
                "주문수량:", position['volume'],
                "현재가:", cur_price, '\n'
                                   "수익률:", utils.calc_pnl(position["order_price"], cur_price),
                "BTC 20일선 이격률:", btc_sma20_sep_rate,
                "op_mode:", op_mode
            )
        print("#" * 100)

        # 목표가 갱신
        if position['type'] is None and now.minute == 0 and (10 <= now.second < 20):
            print("=" * 100)
            print("목표가 갱신")
            target = utils.calc_target(ticker)
            op_mode = 1

            # update db
            db_helper.update_target_db(ticker=ticker, target=target, op_mode=op_mode)
            return
        # 포지션 없을 경우
        if op_mode and position['type'] is None:
            # rsi14가 70이상이면 포지션 진입 X
            if rsi14 > 70:
                print("rsi14 > 70: overbuying...!")

            # 포지션 진입
            # btc over sma20
            elif btc_sma20_sep_rate > 0.5:
                if target < cur_price:
                    price = 15_000
                    volume, order_price, position_type = utils.buy_order(ticker=ticker, price=price)
                    position['type'] = position_type
                    position['time'] = now
                    position['order_price'] = order_price
                    position['volume'] = volume

                    print(now)
                    print("매수 주문")
                    print("매수 수량: ", volume)
                    print("매수 금액: ", order_price)
                    print("=" * 100)

                    # telegram send
                    msg = "매수주문\n매수수량: {0}\n매수 평단가: {1}".format(volume, order_price)
                    utils.telegramMassageBot(msg)

        # 포지션이 있는 경우
        if op_mode and position['type'] is not None:
            # 주문시간과 현재시간의 차이
            time_diff = now - position['time']

            # 수익률
            pnl = utils.calc_pnl(position['order_price'], cur_price)

            # btc sma20이 음전하면 reversal -> True
            reversal = btc_sma20_sep_rate < 0

            # 익절 시나리오
            # 포지션을 잡은 후 1시간 이내
            if time_diff.seconds <= 3600:
                if pnl > take_profit_rate * split_sell_rate:
                    sell_volume = math.trunc(position['volume'] / 5)

                    # 주문금액이 5,000원 이하일 경우 전량 매도
                    if sell_volume * cur_price <= 5000:
                        sell_volume = position['volume']

                    utils.sell_order(ticker=ticker, volume=sell_volume)
                    position['volume'] -= sell_volume

                    # 남은 개수가 없으면 포지션 없음
                    if position['volume'] == 0:
                        position['type'] = None
                        op_mode = False

                    split_sell_rate *= 1.1

                    print(now)
                    print("매도 주문")
                    print("매도 수량: ", sell_volume)
                    print("매도 금액: ", cur_price)
                    print("=" * 100)

                    # 텔레그램 알림
                    utils.telegramMassageBot("매도주문\n매도수량: {0}\n매도금액: {1}".format(sell_volume, cur_price))

            # 포지션을 잡은 후 1시간 ~ 4시간
            elif 3600 + 10 < time_diff.seconds < 3600 * 4:
                if pnl > take_profit_rate:
                    sell_volume = position['volume']
                    utils.sell_order(ticker=ticker, volume=sell_volume)

                    position['type'] = None
                    op_mode = False

                    print(now)
                    print("매도 주문")
                    print("매도 수량: ", sell_volume)
                    print("매도 금액: ", cur_price)
                    print("=" * 100)

                    # 텔레그램 알림
                    utils.telegramMassageBot("매도주문\n매도수량: {0}\n매도금액: {1}".format(sell_volume, cur_price))

            elif time_diff >= 3600 * 4:
                sell_volume = position['volume']
                utils.sell_order(ticker=ticker, volume=sell_volume)

                position['type'] = None
                op_mode = False

                print(now)
                print("매도 주문")
                print("매도 수량: ", sell_volume)
                print("매도 금액: ", cur_price)
                print("=" * 100)

                # 텔레그램 알림
                utils.telegramMassageBot("매도주문\n매도수량: {0}\n매도금액: {1}".format(sell_volume, cur_price))

            # 손절 시나리오
            # 손절률 도달시 | btc sma20 하회시
            if pnl < loss_cut_rate or reversal:
                sell_volume = position['volume']
                utils.sell_order(ticker=ticker, volume=sell_volume)

                position['type'] = None
                op_mode = False

                print(now)
                print("매도 주문")
                print("매도 수량: ", sell_volume)
                print("매도 금액: ", cur_price)
                print("=" * 100)

                # 텔레그램 알림
                utils.telegramMassageBot("매도주문\n매도수량: {0}\n매도금액: {1}".format(sell_volume, cur_price))

        time.sleep(1)
    except Exception as e:
        print("Volatility Trading Bot Error:", e)


from selenium import webdriver
import pyautogui
import time
browser = webdriver.Chrome('C:/Users/sudhan/Documents/git_repo/Google-forms-bot/chromedriver.exe')
browser.get("https://forms.gle/EzMJpE31bndwei79A")
browser.maximize_window()
time.sleep(1)
#email filling
mail = "abc@gmail.com"
email = browser.find_element_by_xpath('//*[@id="mG61Hd"]/div[2]/div/div[2]/div[1]/div/div/div[2]/div/div[1]/div/div[1]/input')
email.send_keys(mail)
#name filling
name = "user_name"
user_name = browser.find_element_by_xpath('//*[@id="mG61Hd"]/div[2]/div/div[2]/div[2]/div/div/div[2]/div/div[1]/div/div[1]/input')
user_name.send_keys(name)
#USN or register number filling
usn = "4JN19CS107"
user_usn = browser.find_element_by_xpath('//*[@id="mG61Hd"]/div[2]/div/div[2]/div[3]/div/div/div[2]/div/div[1]/div/div[1]/input')
user_usn.send_keys(usn)
#drop down menu selection
dropmenu = browser.find_element_by_class_name('quantumWizMenuPaperselectOption')
dropmenu.click()
time.sleep(1)
dropdown1 = browser.find_element_by_css_selector('.exportSelectPopup [data-value="4B"]')
dropdown1.click()
time.sleep(1)
#automating mouse scroll using selenium
browser.execute_script("window.scrollTo(0,document.body.scrollHeight)")
#phone number filling
number = "1234567891"
phone_number = browser.find_element_by_xpath('//*[@id="mG61Hd"]/div[2]/div/div[2]/div[5]/div/div/div[2]/div/div[1]/div/div[1]/input')
phone_number.send_keys(number)
#to select date I am using pyautogui module
pyautogui.PAUSE = 0.5
cords = pyautogui.locateCenterOnScreen('dateicon.png')
pyautogui.click(cords)
pyautogui.PAUSE = 0.5
cords1 = pyautogui.locateCenterOnScreen('v2.png')
pyautogui.click(cords1)
#automating mouse click on submit button
submit_button = browser.find_element_by_xpath('//*[@id="mG61Hd"]/div[2]/div/div[3]/div[1]/div/div/span/span')
submit_button.click()
time.sleep(1)
#closing the browser
browser.quit()


from setuptools import find_packages
from setuptools import setup

try:
    README = open("README.rst").read()
except IOError:
    README = None

setup(
    name="guillotina_amqp",
    version="6.0.0",
    description="Integrate amqp into guillotina",
    long_description=README,
    install_requires=[
        "guillotina>=6.0.0<7",
        "aiohttp>=3.6.0,<4.0.0",
        "aioamqp",
        "lru-dict",
        "aioredis",
        "backoff",
        "mypy-extensions",
    ],
    author="Nathan Van Gheem",
    author_email="vangheem@gmail.com",
    url="https://github.com/guillotinaweb/guillotina_amqp",
    packages=find_packages(exclude=["demo"]),
    include_package_data=True,
    package_data={"": ["*.txt", "*.rst"], "guillotina_amqp": ["py.typed"]},
    tests_require=["pytest"],
    extras_require={
        "test": [
            "asynctest>=0.13.0",
            "pytest>=3.8.0<=5.0.0",
            "docker",
            "psycopg2-binary",
            "pytest-asyncio>=0.12.0",
            "pytest-cov>=2.6.1",
            "coverage>=4.4",
            "pytest-docker-fixtures[rabbitmq]==1.3.5",
            "async_asgi_testclient==1.4.4",
            "prometheus-client",
        ]
    },
    license="BSD",
    classifiers=[
        "License :: OSI Approved :: BSD License",
        "Development Status :: 3 - Alpha",
        "Programming Language :: Python :: 3.7",
        "Programming Language :: Python :: 3.8",
        "Topic :: Software Development :: Libraries :: Python Modules",
        "Topic :: Internet :: WWW/HTTP",
        "Intended Audience :: Developers",
    ],
    entry_points={},
)


from typing import List, Any, Dict

import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
import torch
import torchvision

from agent.simple import BacktrackingMazeAgent, Grid2PointWrapper
from agent import SMARTAgent, IAgent
from agent.goal_manager import SimpleGoalManager, IGoalManager
from agent.goal_manager.evaluator import GridworldEvaluator, IEvaluator
from agent.goal_manager.generator import SimpleGridworldGenerator, IGenerator
from agent.memory import IMemory, CompleteMemory
from env.mazeworld import MazeWorldCache, MazeWorldGenerator, MazeWorld, State
from misc.utils import array_equal

YDIMS = 10
XDIMS = 10
generator = MazeWorldGenerator(YDIMS, XDIMS, 2,  100, 10)
cache = MazeWorldCache(generator)
global env
env = MazeWorld(cache._get_cached_board(0))
device: torch.device = torch.device("cuda:0")

settings : Dict[str, Any] = {
    "device" : torch.device("cuda:0"),
    "tensorboard" : SummaryWriter()
}

fig = plt.figure()
images = []

low_level_agent: IAgent = BacktrackingMazeAgent(env)
low_level_agent: IAgent = Grid2PointWrapper(low_level_agent)
evaluator: IEvaluator = GridworldEvaluator(XDIMS+2, YDIMS+2, settings, gamma=0.99)
generator: IGenerator = SimpleGridworldGenerator()
fulfils_goal = lambda state, goal: array_equal(state[:,:,-1], goal[:,:,0])
goal_manager: IGoalManager = SimpleGoalManager(evaluator, generator, 1, fulfils_goal)
memory: IMemory = CompleteMemory(100, 3)
agent = SMARTAgent(goal_manager, low_level_agent, memory)

totals = []

step: int = 0

for iter, seed in enumerate([0] * 500):
    total_reward: int = 0
    print(f"================={seed}=================")
    env= MazeWorld(cache._get_cached_board(seed))

    state, goal = env.reset(3)
    agent.reset(env, state, goal)
    done = False
    states: List[State] = [state]

    t: int = 0

    while not done:
        print('step')
        action = agent.act(state)
        state, reward, done, info = env.step(action)
        total_reward += reward
        states.append(state)
        agent.view(state, action, reward)
        print(env._location)

        agent.optimize(step)
        t += 1
        step += 1

    settings['tensorboard'].add_scalar('duration', t, iter)
    settings['tensorboard'].add_scalar('reward', total_reward, iter)
    totals.append(total_reward)

    def render(env: MazeWorld, state: State):
        grid: np.ndarray = env._grid
        # np.ndarray[float64] : [YDIMS, XDIMS, 2]
        image: np.ndarray = grid[:,:,0] + (2 * grid[:,:,1])
        image += (state[:,:,2] * 3)
        image += env._goal_as_grid[:,:,0] * 4
        # np.ndarray[float64] : [YDIMS, XDIMS]
        return plt.imshow(image, animated=True)

    for state in states:
        images.append([render(env, state)])

ani = animation.ArtistAnimation(fig, images, interval=100,blit=True, repeat=False)
plt.show()


from gestionusuarios.models import usuariooperador,registro
from django.shortcuts import render
from django.http import HttpResponse, request
from django.db import models

# Create your views here.

def datos_vuelo(request):
    if request.GET["usuario"]:
        if request.GET["contraseña"]:
            nombre=request.GET["usuario"]
            A=usuariooperador.objects.filter(usuario__icontains=nombre)
            if A:
                contra=request.GET["contraseña"]
                B=usuariooperador.objects.filter(contraseña__icontains=contra)
                if B:
                    return render(request, "boleto.html")
                else:
                    B="Contraseña Incorrecta"
                    return HttpResponse(B)
            else:
                B="usuario no encontrado"
                return HttpResponse(B)
            #if user==nombre:
             #   return render(request, "boleto.html")
            #else:
             #   mensaje="Error el usuario no existe"
              #  return HttpResponse(mensaje)
        else:
            mensaje="Error Ingrese contraseña"
            return HttpResponse(mensaje)
    else:
        mensaje="Error Ingrese nombre"
        return HttpResponse(mensaje)

def mostrar_datos(request):
    datos=registro.objects.all()
    return render(request,"resultados_busqueda.html",{"datos":datos})

def borrar(request):
    datos=registro.objects.all()
    datos.delete()
    mensaje="Datos Borrados"
    return HttpResponse(mensaje)

def sesion(request):

    return render(request, "sesion.html")

def guardar(request):
    if request.GET["clase"]:
        if request.GET["comida"] or request.GET["bebida"] or request.GET["pelicula"]:
            c1=request.GET["clase"]
            clas=int(c1)
            a1=request.GET["comida"]
            alimento=int(a1)
            b1=request.GET["bebida"]
            bebid=int(b1)
            p=request.GET["pelicula"]
            peli=int(p)

            if clas==1:
                pcomi=50
                pbeb=35
                ppeli=70
                clase=1

            elif clas==2:
                pcomi=40
                pbeb=25
                ppeli=55
                clase=2

            elif clas==3:
                pcomi=25
                pbeb=10
                ppeli=25
                clase=3

            sercombeb= alimento + bebid
            sertotal= sercombeb+peli
            servicio=str(sertotal)
            serpri=(alimento> 0) & (bebid>0)
            serprima=serpri & (peli>0)
            serprimera=serprima & (clas==1)
            serquince=serprimera & (sertotal >=10)

            subcombeb= alimento*pcomi + bebid*pbeb
            subtot= subcombeb+peli*ppeli
            subtotal2=(str(subtot))

            if serquince==1:
                desc=subtot*0.15
                descuento2=(str(desc))

            elif serprimera==1:
                desc=subtot*0.05
                descuento2=(str(desc))

            elif sertotal >=10:
                desc=subtot*0.1
                descuento2=(str(desc))

            else :
                desc=0
                descuento2=(str(desc))

            tot=subtot - desc
            total2=(str(tot))

            p1=registro(clase=clas, subtotal=subtotal2, total=total2, descuento=descuento2)
            p1.save()
            mensaje="Datos guardatos"
            return HttpResponse(mensaje)
        else:
            mensaje="Advertencia, debe ingresar algun servicio"
            return HttpResponse(mensaje)
    else:
        mensaje="No ingresó la clase del vuelo"
        return HttpResponse(mensaje)


from dataclasses import dataclass
from typing import Dict, List

from app.settings import ROOT_DIR
from app.orders_processing.order_data_handler import OrderDataHandler
from app.data_models.order.order_details import OrderDetails
from app.data_models.order.customer_details import CustomerDetails
from app.data_models.order.item_details import ItemDetails

@dataclass
class EbayOrderDataHandler(OrderDataHandler):
    def __init__(self) -> None:
        self.config_data: Dict = self.get_config(ROOT_DIR + r"/app/data/order_data_handler.json")["ebay"]

    def get_order_details(self, order_dict_flatten: Dict, customer_details: CustomerDetails, items_details: List[ItemDetails]) -> OrderDetails:
        object_dict: Dict = {key: order_dict_flatten.get(value) for (key, value) in self.config_data["get_order_details"].items()}

        return OrderDetails(object_dict["order_ebay_id"], object_dict["platform"],
                            object_dict["order_date"], object_dict["currency"],
                            object_dict["payment_date"], object_dict["payment_status"],
                            object_dict["total"], object_dict["delivery_total"],
                            customer_details, items_details)

    def get_items_details(self, order_dict_flatten) -> List[ItemDetails]:
        items_list: List[ItemDetails] = []
        item_index: int | None = 0
        while item_index is not None:
            object_dict: Dict = {}
            for key, value in self.config_data["get_items_details"].items():
                object_dict_key = value.replace("{id}", str(item_index))
                if order_dict_flatten.get(object_dict_key) is None and key != "sku":
                    item_index = None
                    break
                object_dict[key] = order_dict_flatten.get(object_dict_key)
            if item_index is not None:
                object_dict["price"] = str(float(object_dict["price"]) / object_dict["quantity"])
                items_list.append(ItemDetails(object_dict["item_ebay_id"], object_dict["sku"], object_dict["quantity"], object_dict["price"]))
                item_index += 1
        return items_list


from production import forward_chain
import rules

answers = []

def tourist_type(input_str):
    tourist_types = {
        'mexican': 'mexican tourist',
        'turkish': 'is a turkish tourist',
        'chinese': 'chinese tourist',
        'naughty black': 'naughty black tourist',
        'educated black': 'educated black tourist'
    }

    for key in tourist_types:
        if key in input_str.lower():
            return tourist_types[key]

    return None

def ask_questions(tree, name):
    if tree is None:
        return False

    answer = input(tree.cargo.format(name) + '? y/n ')
    while answer not in ['y', 'n']:
        answer = input("Please enter 'y' or 'n': ")

    subtree_explored = False
    if answer == 'y':
        for subtree in tree.subtrees:
            if ask_questions(subtree, name):
                answers.append(tree.cargo.format(name))
                return True
            if answers and answers[-1] == tree.cargo.format(name):
                subtree_explored = True
        if not subtree_explored and not tree.subtrees:
            answers.append(tree.cargo.format(name))
            return True
    elif tree.right:
        if ask_questions(tree.right, name):
            return True
    return False

results = []
while True:
    print('Give name')
    name = input('Name: ')
    type_of_chain = input('Forward or Backward chain?(F/B):')
    if type_of_chain == "F":
        ask_questions(rules.tree, name)
        result = forward_chain(rules.RULES, answers)
        print(result)
        tourist_found = False
        for item in result:
            if 'tourist' in item:
                tourist_found = True
                if 'mexican tourist' or 'is a turkish tourist' or 'chinesse tourist' or 'naughty black tourist' or 'educated black tourist' in item:
                    print(item)
        else:
            print('It is not a tourist')

    else:
        from backchain import backchain_to_goal_tree
        tourist_types = {
            "educated black": '(?y) is an educated black tourist',
            "naughty black": '(?y) is a naughty black tourist',
            "chinese": '(?y) is a chinesse tourist',
            "turkish": '(?y) is a turkish tourist',
            "mexican": '(?y) is a mexican tourist'
        }
        tourist_type = input('What type of tourist are you? ')
        hypothesis = tourist_types[tourist_type.lower()]
        result = backchain_to_goal_tree(rules.RULES, hypothesis)
        print(result)

    answers = []