import json
import os
import re

class ExManager:
    ext_path = os.path.join(os.path.dirname(__file__),
                            '../regexes/expressions.txt')

    with open(ext_path) as fh:
        expressions = json.load(fh)

    def get_compiled(self):
        regexes = {k.lower(): re.compile(self.expressions[k]) for k, v in
                   self.expressions.items()}
        return regexes

    def print_expressions(self):
        {print(k.lower(), ":", self.expressions[k])
         for k, v in sorted(self.expressions.items())}


import os
import re
import wget

import zipfile

from django.core.management.base import BaseCommand, CommandError
from core.models import Locode

def _process_file(file):
    for line in file.readlines():
        print(line)
        Locode.create_from_csv(line, save=True)

class Command(BaseCommand):
    _db_folder = 'db_folder'
    help = 'test command'

    def add_arguments(self, parser):
        parser.add_argument('--url', default='http://www.unece.org/fileadmin/DAM/cefact/locode/loc201csv.zip')
        parser.add_argument('--no-download', default=False, type=bool)

    def handle(self, *args, **options):
        if not options.get('no_download'):
            url = options.get('url')
            db_zip_file = wget.download(url)
            with zipfile.ZipFile(db_zip_file, 'r') as zip_file:
                zip_file.extractall(self._db_folder)
            os.remove(db_zip_file)

        for db_file in os.listdir(self._db_folder):
            if re.match('.*UNLOCODE CodeList.*', db_file):
                with open(os.path.join(self._db_folder, db_file), 'r', encoding='cp1252') as file_data:
                    _process_file(file_data)


"""Situation Awareness Module"""

import enum
import operator
import time

import numpy as np
from sklearn.cluster import DBSCAN

from driver_awareness_msgs.msg import ROI, SA

class SituationAwareness:
    """Class to calculate the situation awareness"""

    def __init__(self, punishment_model):
        self.__optimal_sa = 0
        self.__actual_sa = 0
        self.__punishment = punishment_model

    @property
    def sa_msg(self):
        sa_msg = SA()
        sa_msg.optimal_sa = self.__optimal_sa
        sa_msg.actual_sa = self.__actual_sa
        return sa_msg

    def calculate_sa(self, se_array, non_roi_gazes):
        type_weights = [situation_element.type_weight for situation_element in se_array]
        classifications = [
            situation_element.classification_value for situation_element in se_array
        ]
        self.__optimal_sa = sum(type_weights)
        actual_sa = sum(list(map(operator.mul, type_weights, classifications)))
        self.__actual_sa = actual_sa - self.__punishment.punishment(non_roi_gazes)
        self.__actual_sa = max(0.0, self.__actual_sa)

class PunishmentModel:
    """Class to calculate the punishment score"""

    def __init__(
        self, dbscan_max_distance_px, dbscan_min_samples, punishment_factor=0.25
    ):
        self.__dbscan = DBSCAN(
            eps=float(dbscan_max_distance_px),
            min_samples=dbscan_min_samples,
        )
        self.__punishment_factor = punishment_factor

    def punishment(self, non_roi_gazes):
        if not non_roi_gazes:
            return 0.0

        gaze_coordinates = [
            (gaze.gaze_pixel.x, gaze.gaze_pixel.y) for gaze in non_roi_gazes
        ]
        labels = self.__dbscan.fit_predict(gaze_coordinates)
        num_clusters = len(set(labels)) - (1 if -1 in labels else 0)
        return self.__punishment_factor * num_clusters

class GazeBuffer:
    """Buffer for gaze data"""

    def __init__(self):
        self.__data = []
        self.__current_gaze = (0, 0)

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

    @property
    def current_gaze(self):
        return self.__current_gaze

    def push_array(self, gaze_array):
        self.__data.extend(gaze_array)
        self.__current_gaze = (gaze_array[-1].gaze_pixel.x, gaze_array[-1].gaze_pixel.y)

    def clear(self):
        self.__data = []

class SituationAwarenessParameter:
    """Collection of Parameter for detection/comprehension decisions"""

    def __init__(
        self, comprehension_alive_time, num_gaze_comprehended, num_gaze_detected
    ):
        self.__comprehension_alive_time = comprehension_alive_time
        self.__num_gaze_comprehended = num_gaze_comprehended
        self.__num_gaze_detected = num_gaze_detected

    @property
    def num_gaze_detected(self):
        return self.__num_gaze_detected

    @property
    def num_gaze_comprehended(self):
        return self.__num_gaze_comprehended

    @property
    def comprehension_alive_time(self):
        return self.__comprehension_alive_time

class SituationElement:
    """Situation Element"""

    class TypeWeight:
        """Defines the type weights for situation elements"""

        REQUIRED = 2.0
        DESIRED = 1.0

    class ClassificationWeight:
        """Defines the classification weights for situation elements"""

        COMPREHENDED = 1.0
        DETECTED = 0.5
        UNDETECTED = 0.0

    class Classification(enum.Enum):
        """Defines classification types for situation elements"""

        COMPREHENDED = "comprehended"
        DETECTED = "detected"

    SE_ALIVE_COUNTER = 1

    def __init__(self, roi_msg, sa_parameter):
        self.__msg = roi_msg
        self.__sa_parameter = sa_parameter
        self.__changed = True
        self.__alive_counter = self.SE_ALIVE_COUNTER
        self.__time_last_looked = time.time()
        self.__num_gazes_inside = 0

    @property
    def roi_msg(self):
        return self.__msg

    @property
    def is_alive(self):
        return self.__alive_counter > 0

    @property
    def has_changed(self):
        return self.__changed

    def is_gaze_inside(self, gaze_data):
        return (
            pow(gaze_data.gaze_pixel.x - self.roi_msg.roi.center.x, 2)
            + pow(gaze_data.gaze_pixel.y - self.roi_msg.roi.center.y, 2)
        ) <= pow(self.roi_msg.roi.radius, 2)

    def is_comprehension_expired(self):
        return (
            time.time() - self.__time_last_looked
            > self.__sa_parameter.comprehension_alive_time
            and self.roi_msg.classification
            == SituationElement.Classification.COMPREHENDED
        )

    def update_msg(self, roi_msg):
        self.__msg.roi = roi_msg.roi
        self.__msg.type = roi_msg.type
        self.__changed = True
        self.__alive_counter = self.SE_ALIVE_COUNTER

    def update(self, num_gazes_inside):
        self.__time_last_looked = time.time()
        self.__num_gazes_inside += num_gazes_inside
        if self.__num_gazes_inside > self.__sa_parameter.num_gaze_comprehended:
            self.__msg.classification = SituationElement.Classification.COMPREHENDED
        elif self.__num_gazes_inside >= self.__sa_parameter.num_gaze_detected:
            self.__msg.classification = SituationElement.Classification.DETECTED
        if self.is_comprehension_expired():
            self.__num_gazes_inside = self.__sa_parameter.num_gaze_detected
            self.__msg.classification = SituationElement.Classification.DETECTED
        if self.__changed:
            self.__changed = False
            return
        self.__alive_counter -= 1

    @property
    def classification_value(self):
        if self.__msg.classification == self.Classification.COMPREHENDED:
            return self.ClassificationWeight.COMPREHENDED
        if self.__msg.classification == self.Classification.DETECTED:
            return self.ClassificationWeight.DETECTED
        return self.ClassificationWeight.UNDETECTED

    @property
    def type_weight(self):
        return (
            self.TypeWeight.DESIRED
            if self.__msg.type == ROI.DESIRED
            else self.TypeWeight.REQUIRED
        )

    def distance_to(self, roi_msg):
        roi_center = np.array([roi_msg.roi.center.x, roi_msg.roi.center.y])
        center = np.array([self.roi_msg.roi.center.x, self.roi_msg.roi.center.y])
        return np.linalg.norm(center - roi_center)

class SituationElementTracker:
    """Keeps track of the current SEs in the FOV"""

    def __init__(self, tracking_strategy, sa_parameter):
        self.__se_list = []
        self.__non_roi_gazes = []
        self.__tracking_strategy = tracking_strategy
        self.__sa_parameter = sa_parameter

    @property
    def se_list(self):
        return self.__se_list

    @property
    def non_roi_gazes(self):
        return self.__non_roi_gazes

    @staticmethod
    def update_best_candidate(candidates, roi_msg):
        for candidate in candidates:
            if not candidate.has_changed:
                candidate.update_msg(roi_msg)
                break

    def update_elements(self, gaze_points):
        """Update all SEs and remove if not alive"""
        gazes_inside_list = [[False] * len(gaze_points)]
        for tracking_object in self.__se_list:
            # TODO test for update called with ...
            gazes_inside = [
                tracking_object.is_gaze_inside(gaze) for gaze in gaze_points
            ]
            tracking_object.update(sum(gazes_inside))
            gazes_inside_list.append(gazes_inside)
        gazes_in_any_roi = np.any(np.array(gazes_inside_list), axis=0)
        self.__non_roi_gazes = list(np.array(gaze_points)[~gazes_in_any_roi])
        dead_elements = [
            tracking_object
            for tracking_object in self.__se_list
            if not tracking_object.is_alive
        ]
        for dead_element in dead_elements:
            self.__se_list.remove(dead_element)

    def add_or_update_ses(self, roi_array):
        """Add new SEs to the list of tracked elements or update if they already exist"""
        for roi_msg in roi_array:
            best_candidates = self.__tracking_strategy.find_best_candidates(
                self.__se_list, roi_msg
            )
            if best_candidates:
                self.update_best_candidate(best_candidates, roi_msg)
            else:
                self.__se_list.append(SituationElement(roi_msg, self.__sa_parameter))

class DistanceTrackingStrategy:
    """Distance based SE tracking strategy"""

    def __init__(self, max_tracking_distance):
        self.__max_tracking_distance = max_tracking_distance

    def find_best_candidates(self, se_list, roi_msg):
        return [
            current_se
            for current_se in se_list
            if current_se.distance_to(roi_msg) < self.__max_tracking_distance
        ]

class IdTrackingStrategy:
    """Id based SE tracking strategy"""

    @staticmethod
    def find_best_candidates(se_list, roi_msg):
        return [
            current_se for current_se in se_list if current_se.roi_msg.id == roi_msg.id
        ]


import requests
from bs4 import BeautifulSoup

# Send a GET request to the website
response = requests.get('https://books.toscrape.com/')

# Parse the HTML content
soup = BeautifulSoup(response.text, 'html.parser')

# Extract the information you want to scrape
for article in soup.find_all('article'):
    title = article.find('h3').find('a').get('title')
    price = article.find(class_='price_color').get_text()
    print(f'Title: {title}\nPrice: {price}\n---')


import io
import csv
import datetime
from flask import (
    render_template,
    Blueprint,
    redirect,
    url_for,
    send_from_directory,
    flash,
)
from flask import current_app as app, send_file, request, session
from flask_login import login_required, current_user
from app.models import (
    User,
    Product,
    Account,
    Reseller,
    Phone,
)
from app.logger import log
from sqlalchemy import or_

main_blueprint = Blueprint("main", __name__)

@main_blueprint.route("/")
@login_required
def index():
    if current_user.user_type.name == "super_admin":
        return redirect(url_for("main.users"))
    return redirect(url_for("main.accounts"))

@main_blueprint.route("/accounts")
@login_required
def accounts():
    log(log.INFO, "/accounts")
    page = request.args.get("page", 1, type=int)
    filter = request.args.get("filter", "")
    rows_per_page = request.args.get(
        "rows_per_page", app.config["ACCOUNTS_PER_PAGE"], type=int
    )
    session["rows_per_page"] = rows_per_page
    session["page"] = page
    query = (
        Account.query.join(Product, Account.product_id == Product.id)
        .join(Reseller, Account.reseller_id == Reseller.id)
        .filter(Account.deleted == False)  # noqa 712
    )
    if filter:
        filters = filter.split(";")
        for flt in filters:
            # Search is a formatted filter for db query, example : "startsfrom%"
            search = f"{flt}%"
            query = query.filter(
                or_(
                    Account.name.ilike(search),
                    Account.sim.ilike(search),
                    Product.name.ilike(search),
                    Reseller.name.ilike(search),
                )
            )
    ordered_accounts = query.order_by(Account.id.desc()).paginate(
        page, rows_per_page, False
    )
    next_url = (
        url_for("main.accounts", page=ordered_accounts.next_num)
        if ordered_accounts.has_next
        else None
    )
    prev_url = (
        url_for("main.accounts", page=ordered_accounts.prev_num)
        if ordered_accounts.has_prev
        else None
    )
    return render_template(
        "index.html",
        main_content="Accounts",
        table_data=[acc.to_dict() for acc in ordered_accounts.items],
        columns=Account.columns(),
        edit_href=url_for("account.edit"),
        accounts=ordered_accounts,
        next_url=next_url,
        prev_url=prev_url,
        filter=filter,
        rows_per_page=session["rows_per_page"],
    )

@main_blueprint.route("/users")
@login_required
def users():
    log(log.INFO, "/users")
    if current_user.user_type.name != "super_admin":
        return redirect(url_for("main.index"))
    return render_template(
        "index.html",
        main_content="Users",
        table_data=[u.to_dict() for u in User.query.all()],
        columns=User.columns(),
        edit_href=url_for("user.edit"),
    )

@main_blueprint.route("/resellers")
@login_required
def resellers():
    log(log.INFO, "/resellers")
    if current_user.user_type.name not in ["super_admin", "admin"]:
        return redirect(url_for("main.index"))
    return render_template(
        "index.html",
        main_content="Resellers",
        table_data=[
            i.to_dict()
            for i in Reseller.query.filter(Reseller.deleted == False)  # noqa E712
        ],
        columns=Reseller.columns(),
        edit_href=url_for("reseller.edit"),
    )

@main_blueprint.route("/products")
@login_required
def products():
    if current_user.user_type.name not in ["super_admin", "admin"]:
        return redirect(url_for("main.index"))
    return render_template(
        "index.html",
        main_content="Products",
        table_data=[
            p.to_dict()
            for p in Product.query.filter(Product.deleted == False)  # noqa E712
        ],
        columns=Product.columns(),
        edit_href=url_for("product.edit"),
    )

@main_blueprint.route("/phones")
@login_required
def phones():
    if current_user.user_type.name not in ["super_admin", "admin"]:
        return redirect(url_for("main.index"))
    return render_template(
        "index.html",
        main_content="Phones",
        table_data=[
            p.to_dict() for p in Phone.query.filter(Phone.deleted == False)  # noqa E712
        ],
        columns=Phone.columns(),
        edit_href=url_for("phone.edit"),
    )

@main_blueprint.route("/report")
@login_required
def report():
    log(log.INFO, "report")

    if "content" not in request.args:
        return

    content = request.args["content"]

    Class = {
        "Users": User,
        "Products": Product,
        "Accounts": Account,
        "Phones": Phone,
        "Resellers": Reseller,
    }[content]

    entities = Class.query.filter(Class.deleted == False)  # noqa

    if not entities.first():
        log(log.INFO, "no entities")
        flash("Nothing to report", "danger")
        return redirect(url_for(f"main.{content}".lower()))

    proxy = io.StringIO()
    writer = csv.writer(proxy)
    row = [v for v in entities[0].to_dict().keys()]
    writer.writerow(row)
    for entity in entities:
        row = [v for v in entity.to_dict().values()]
        writer.writerow(row)

    # Creating the byteIO object from the StringIO Object
    mem = io.BytesIO()
    mem.write(proxy.getvalue().encode("utf-8"))
    mem.seek(0)
    proxy.close()

    now = datetime.datetime.now()
    return send_file(
        mem,
        as_attachment=True,
        attachment_filename="{content}_{now}.csv".format(
            content=content, now=now.strftime("%Y-%m-%d-%H-%M-%S")
        ),
        mimetype="text/csv",
        cache_timeout=0,
        last_modified=now,
    )

@main_blueprint.route("/css/<path:filename>")
def css(filename):
    return send_from_directory(app.config["CSS_FOLDER"], filename)

@main_blueprint.route("/js/<path:filename>")
def javascript(filename):
    return send_from_directory(app.config["JAVASCRIPT_FOLDER"], filename)

@main_blueprint.route("/images/<path:filename>")
def images(filename):
    return send_from_directory(app.config["IMAGES_FOLDER"], filename)


from scapy.all import *

def pkt_sorter(packets):
    print("start")

    for p in packets:
        # print("reading packets")
        if  p.haslayer(DNSQR) and p.haslayer(DNSRR):
            # print("packet response")
            a_count = p.ancount

            i = 0
            # print(i)
            p.show()
            print("this is the count",a_count,"i equals %d" %i)
            print(p.qd.qname)
            f.write("%s " %str(p.qd.qname))
            while i < a_count:
                # print (p[0][i].rdata, p[0][i].rrname)
                print(p.an[i].rdata)
                f.write("%s"%str(p.an[i].rdata))
                # ans[counter][i]=p.an[i].rdata
                # print ("rdata:"+str(p.ttl))

                i += 1
            f.write("\n")
        print("GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG")

if __name__ =="__main__":
    print("dsa")
    f=open("list_ip_example2.txt","w+")
    packets = rdpcap('example2.pcap')
    pkt_sorter(packets)
    print("part 1 done")
    f.close()
    packets = rdpcap('google check.pcapng')
    f = open("list_ip_google.txt", "w+")
    pkt_sorter(packets)
    print("part 2 done")
    f.close()


import treetaggerwrapper

# sentence to process
sentence = "La matematica è come l'amore - un'idea semplice, che però può diventare complicata."

# open the tagger
tagger = treetaggerwrapper.TreeTagger(TAGLANG="it")

# process the sentence
tags = tagger.tag_text(sentence)
# "tags" is an array of strings; every string consists of word form, pos-tag and lemma separated by tabs

# print every string in the array
for tag in tags:
	print(tag)


from tkinter import *
from tkinter import filedialog
from tkinter import messagebox
from tkinter.filedialog import asksaveasfile
from ctypes import windll
import os

root = Tk()
root.iconbitmap(default="icon.ico")
root.geometry("1000x800")
root.minsize(1000,800)
root.maxsize(1000,800)
windll.shcore.SetProcessDpiAwareness(1)

# Clear Window and all Widgets
def clear_window():
    for widget in root.winfo_children():
        widget.destroy()

# Task Not Available Function
def task_not_available():
    messagebox.showerror("Task Not Available", "Sorry! This task is still in development is currently not available.")

# Closing Confirmation
def on_closing():
    if messagebox.askokcancel("Quit", "Do you want to quit?"):
        root.destroy()

# Main Menu Class
class main_menu:
    def __init__(self, master):
        root.title("Grades2Date | Calculate the Future!")
        # Menu Frame
        self.menu_frame = Frame(master)
        self.menu_frame.pack()

        # Title & Subtitle Label
        self.title_label = Label(self.menu_frame, text="Grades 2 Date", font="Helvetica 55 bold")
        self.title_label.grid(row=0, column=0, pady=(100,0))
        self.subtitle_label = Label(self.menu_frame, text="Calculate the Future!", font="Helvetica 20")
        self.subtitle_label.grid(row=1, column=0, pady=(0,100))

        # Menu Buttons
        self.calc_btn = Button(self.menu_frame, text="Calculate", font="Helvetica 20", padx=34, command=lambda:[clear_window(),gpa_page(root)])
        self.calc_btn.grid(row=2, column=0, pady=(0,20))
        #self.import_btn = Button(self.menu_frame, text="Import Data", font="Helvetica 20", command=lambda:[task_not_available(),self.import_data()], padx=19)
        self.import_btn = Button(self.menu_frame, text="Import Data", font="Helvetica 20", command=lambda:[self.import_data()], padx=19)
        self.import_btn.grid(row=3, column=0, pady=(0,20))
        self.exit_btn = Button(self.menu_frame, text="Close Program", font="Helvetica 20", command=on_closing)
        self.exit_btn.grid(row=4, column=0, pady=(0,20))

        # Version Label
        self.version_num_label = Label(master, text="Version 1.0.1", font="Helvetica 18")
        self.version_num_label.pack(side=LEFT, anchor=SW, padx=(5,0))

    # Import Data Function
    def import_data(self):
        files = [('Text Document', '*.txt')]
        root.datalocation = filedialog.askopenfilename(initialdir="~/Downloads", title="Select a File", filetypes= files)
        if root.datalocation == "":
            return
        clear_window()
        imported_gpa(root, root.datalocation)
        return root.datalocation

# Calculator Page Class
class gpa_page:
    def __init__(self, master):
        root.title("Untitled - Grades2Date")

        #Initialization of Entry Boxes
        self.course_entries = []
        self.grade_entries = []
        self.unit_entries = []

        # Calculator Frame
        self.calc_frame = Frame(master)
        self.calc_frame.pack(side=LEFT, anchor=NW, padx=(0,0), pady=(80,0))

        # Button Frame
        self.btn_frame=Frame(master)
        self.btn_frame.pack(ipadx=100)

        # Results Frame
        self.result_frame=LabelFrame(master, borderwidth=5)
        self.result_frame.pack(pady=(50,0), ipadx=20, padx=(3,0))

        # Main Menu Button
        self.menu_frame=Frame(master, bg="orange")
        self.menu_frame.pack(side=RIGHT, anchor=SE, padx=(0,5), pady=(0,5))
        self.main_menu_btn = Button(self.menu_frame, text="Main Menu", font="Helvetica 18", command=lambda:[clear_window(),main_menu(root)])
        self.main_menu_btn.pack()

        # Header Labels
        self.course_label = Label(self.calc_frame, text="Course Name", font="Helvetica 20 bold")
        self.course_label.grid(row=0, column=0)
        self.grade_label = Label(self.calc_frame, text="Grade", font="Helvetica 20 bold")
        self.grade_label.grid(row=0, column=1)
        self.units_label = Label(self.calc_frame, text="# of Units", font="Helvetica 20 bold")
        self.units_label.grid(row=0, column=2)

        # Entry Box Frame
        self.entry_frame = Frame(self.calc_frame, borderwidth=0, highlightthickness=0)
        self.entry_frame.grid(row=1, column=0, columnspan=3, padx=(40,0), pady=(20,0), ipady=120)

        # Entry Canvas
        self.entry_canvas = Canvas(self.entry_frame, borderwidth=0, highlightthickness=0)
        self.entry_canvas.pack(side=LEFT, fill=BOTH, expand=1, ipadx=100)

        # Entry Scrollbar & Canvas Setup
        self.scrollbar = Scrollbar(self.entry_frame, orient=VERTICAL, command=self.entry_canvas.yview)
        self.scrollbar.pack(side=RIGHT, fill=Y)

        self.entry_canvas.configure(yscrollcommand=self.scrollbar.set)
        self.entry_canvas.bind("<Configure>", lambda e: self.entry_canvas.configure(scrollregion=self.entry_canvas.bbox("all")))

        # Inner Frame for Entry Boxes
        self.inner_frame = Frame(self.entry_canvas, borderwidth=0, highlightthickness=0)
        self.entry_canvas.create_window((0,0), window=self.inner_frame, anchor="nw")

        # Entry Creation Loop
        def entry_creation():
            for x in range(10):
                self.course_entry = Entry(self.inner_frame, font="Helvetica 18", justify="center", width=14)
                self.course_entry.grid(row=x, column=0, padx=(0,54), pady=(0,20))
                self.grade_entry = Entry(self.inner_frame, font="Helvetica 18", justify="center", width=10)
                self.grade_entry.grid(row=x, column=1, padx=(0,55), pady=(0,20))
                self.unit_entry = Entry(self.inner_frame, font="Helvetica 18", justify="center", width=10)
                self.unit_entry.grid(row=x, column=2, pady=(0,20))
                self.course_entries.append(self.course_entry)
                self.grade_entries.append(self.grade_entry)
                self.unit_entries.append(self.unit_entry)
        entry_creation()

        # Calculate Button
        self.calculate_btn = Button(self.btn_frame, text="Calculate", font="Helvetica 18", command=self.calculate, width=5, padx=100)
        self.calculate_btn.grid(row=0, column=0, padx=(40,0), pady=(150,10), columnspan=2)

        # Add Rows Button
        self.add_rows_btn = Button(self.btn_frame, text="Add Rows", font="Helvetica 18", command=self.add_rows, width=5, padx=28)
        self.add_rows_btn.grid(row=1, column=0, padx=(40,0))

        # Clear Rows Button
        self.clear_rows_btn = Button(self.btn_frame, text="Clear Rows", font="Helvetica 18", command=self.clear_rows, width=5, padx=28)
        self.clear_rows_btn.grid(row=1, column=1, padx=(10,0))

        # Export Data Button
        self.export_btn = Button(self.btn_frame, text="Export Data", font="Helvetica 18", command=self.save_data, width=5, padx=100)
        self.export_btn.grid(row=2, column=0, padx=(40,0), pady=(10,0), columnspan=2)

        # Results Labels
        self.gpa_label = Label(self.result_frame, text="Overall GPA: ", font="Helvetica 18", width=18)
        self.gpa_label.pack(pady=(60,5), anchor=CENTER)
        self.units_label = Label(self.result_frame, text="Total Units: ", font="Helvetica 18", width=18)
        self.units_label.pack(pady=(5,60))

    # Clear Rows Function
    def clear_rows(self):
        for entry in self.grade_entries:
            entry.delete(0, END)
        for entry in self.unit_entries:
            entry.delete(0, END)
        for entry in self.course_entries:
            entry.delete(0, END)

    # Add Rows Function
    def add_rows(self):
        self.num_rows = self.inner_frame.grid_size()[1]
        self.course_entry = Entry(self.inner_frame, font="Helvetica 18", justify="center", width=14)
        self.course_entry.grid(row=self.num_rows + 1, column=0, padx=(0,54), pady=(0,20))
        self.grade_entry = Entry(self.inner_frame, font="Helvetica 18",justify="center", width=10)
        self.grade_entry.grid(row=self.num_rows + 1, column=1, padx=(0,55), pady=(0,20))
        self.unit_entry = Entry(self.inner_frame, font="Helvetica 18", justify="center", width=10)
        self.unit_entry.grid(row=self.num_rows + 1, column=2)
        self.entry_canvas.configure(scrollregion=self.entry_canvas.bbox("all"))
        self.grade_entries.append(self.grade_entry)
        self.unit_entries.append(self.unit_entry)
        self.course_entries.append(self.course_entry)

    #GPA Calculate Function
    def calculate(self):
        self.grades = []
        self.unit = []
        self.total = 0
        self.unit_total = 0

        for entry in self.grade_entries:
            try:
                self.current_grade = float(entry.get())
                self.grades.append(self.current_grade)
            except ValueError:
                pass
        for entry in self.unit_entries:
            self.grade_weighting = entry.get()
            try:
                self.grade_weighting = float(self.grade_weighting)
                self.unit.append(self.grade_weighting)
            except ValueError:
                pass
        i = 0
        while i < len(self.grades):
            self.unit_total += self.unit[i]
            self.total += self.grades[i] * self.unit[i]
            i += 1
        try:
            self.average = self.total / self.unit_total
            self.gpa_label.configure(text="Overall GPA: " + str(round(self.average, 3)))
            self.units_label.configure(text="Total Units: " + str(self.unit_total))
        except ZeroDivisionError:
            pass
        except ValueError:
            self.gpa_label.configure(text="Overall GPA: ERROR")
            self.units_label.configure(text="Total Units: ERROR")
        if self.grades == [] and self.unit == []:
            self.gpa_label.configure(text="Overall GPA: ")
            self.units_label.configure(text="Total Units: ")

    def save_data(self):
        files = [('Text Document', '*.txt')]
        file = asksaveasfile(mode = 'w', filetypes = files, defaultextension = files)
        if file == None:
            return
        file_name = os.path.basename(file.name)
        root.title(file_name[:-4] + " - Grades2Date")
        self.file = open(file.name, "w")
        self.file.write("=====Courses=====\n")
        for entry in self.course_entries:
            self.course = entry.get()
            self.file.write(self.course + "--\n")
        self.file.write("=====Grades=====\n")
        for entry in self.grade_entries:
            self.grade = entry.get()
            self.file.write(self.grade + "--\n")
        self.file.write("=====Units=====\n")
        for entry in self.unit_entries:
            self.numunit = entry.get()
            self.file.write(self.numunit + "--\n")
        self.file.close()

    # Exit Confirmation
    root.protocol("WM_DELETE_WINDOW", on_closing)

# GPA page w/ imported data
class imported_gpa(gpa_page):
    def __init__(self, master, import_info):
        super(imported_gpa, self).__init__(master)
        print("imported info " + import_info)
        file_name = os.path.basename(import_info)
        root.title(file_name[:-4] + " - Grades2Date")
        file = open(import_info, "r")
        data = file.read()
        data_info_list = data.split("\n")
        courses_list = []
        grade_list = []
        unit_list = []
        for i in range(len(data_info_list)):
            if data_info_list[i] == "=====Grades=====":
                break
            if data_info_list[i] == "=====Courses=====":
                continue
            else:
                courses_list.append(data_info_list[i][:-2])

        for j in range(len(courses_list) + 1, len(data_info_list)):
            if data_info_list[j] == "=====Units=====":
                break
            if data_info_list[j] == "=====Grades=====":
                continue
            else:
                grade_list.append(data_info_list[j][:-2])

        for k in range(2*len(courses_list) + 2, len(data_info_list)):
            if data_info_list[k] == "":
                break
            if data_info_list[k] == "=====Units=====":
                continue
            else:
                unit_list.append(data_info_list[k][:-2])
        print(courses_list)
        print(grade_list)
        print(unit_list)
        file.close()
        def gpa_import():
            num_rows = 10
            if len(courses_list) > 10:
                num_rows = len(courses_list)
            for x in range(num_rows-1):
                self.course_entry = Entry(self.inner_frame, font="Helvetica 18", justify="center", width=14)
                self.course_entry.grid(row=x, column=0, padx=(0,54), pady=(0,20))
                self.course_entry.insert(0, courses_list[x])
                self.grade_entry = Entry(self.inner_frame, font="Helvetica 18", justify="center", width=10)
                self.grade_entry.grid(row=x, column=1, padx=(0,55), pady=(0,20))
                self.grade_entry.insert(0, grade_list[x])
                self.unit_entry = Entry(self.inner_frame, font="Helvetica 18", justify="center", width=10)
                self.unit_entry.grid(row=x, column=2, pady=(0,20))
                self.unit_entry.insert(0,unit_list[x])
                self.course_entries.append(self.course_entry)
                self.grade_entries.append(self.grade_entry)
                self.unit_entries.append(self.unit_entry)
        gpa_import()

homepage = main_menu(root)
root.mainloop()


"""Contains the pyvista.Cell class."""
from __future__ import annotations

from typing import List, Tuple, cast

import numpy as np

import pyvista

from . import _vtk_core as _vtk
from .celltype import CellType
from .dataset import DataObject
from .utilities.cells import ncells_from_cells, numpy_to_idarr

def _get_vtk_id_type():
    """Return the numpy datatype responding to ``vtk.vtkIdTypeArray``."""
    VTK_ID_TYPE_SIZE = _vtk.vtkIdTypeArray().GetDataTypeSize()
    if VTK_ID_TYPE_SIZE == 4:
        return np.int32
    elif VTK_ID_TYPE_SIZE == 8:
        return np.int64
    return np.int32

class Cell(_vtk.vtkGenericCell, DataObject):
    """Wrapping of vtkCell.

    This class provides the capability to access a given cell topology and can
    be useful when walking through a cell's individual faces or investigating
    cell properties.

    Parameters
    ----------
    vtk_cell : vtk.vtkCell, optional
        The vtk object to wrap as Cell, that must be of ``vtk.vtkCell`` type.

    cell_type : int, optional
        VTK cell type. Determined from ``vtk_cell`` if not input.

    deep : bool, default: False
        Perform a deep copy of the original cell.

    Notes
    -----
    Accessing individual cells from a :class:`pyvista.DataSet` using this class
    will be much slower than accessing bulk data from the
    :attr:`pyvista.PolyData.faces` or :attr:`pyvista.UnstructuredGrid.cells` attributes.

    Also note that the cell object is a deep copy of the original cell and
    is unassociated with the original cell. Changing any data of
    that cell (for example, :attr:`pyvista.Cell.points`) will not change the original dataset.

    Examples
    --------
    Get the 0-th cell from a :class:`pyvista.PolyData`.

    >>> import pyvista as pv
    >>> mesh = pv.Sphere()
    >>> cell = mesh.get_cell(0)
    >>> cell  # doctest: +SKIP
    Cell (0x7fa760075a10)
      Type:       <CellType.TRIANGLE: 5>
      Linear:     True
      Dimension:  2
      N Points:	  3
      N Faces:    0
      N Edges:    3
      X Bounds:   -5.406e-02, -5.551e-17
      Y Bounds:	  0.000e+00, 1.124e-02
      Z Bounds:   -5.000e-01, -4.971e-01

    Get the 0-th cell from a :class:`pyvista.UnstructuredGrid`.

    >>> from pyvista import examples
    >>> mesh = examples.load_hexbeam()
    >>> cell = mesh.get_cell(0)
    >>> cell  # doctest: +SKIP
    Cell (0x7fdc71a3c210)
      Type:       <CellType.HEXAHEDRON: 12>
      Linear:     True
      Dimension:  3
      N Points:   8
      N Faces:    6
      N Edges:    12
      X Bounds:   0.000e+00, 5.000e-01
      Y Bounds:   0.000e+00, 5.000e-01
      Z Bounds:   0.000e+00, 5.000e-01

    """

    def __init__(self, vtk_cell=None, cell_type=None, deep=False):
        """Initialize the cell."""
        super().__init__()
        if vtk_cell is not None:
            if not isinstance(vtk_cell, _vtk.vtkCell):
                raise TypeError(f'`vtk_cell` must be a vtkCell, not {type(vtk_cell)}')
            # cell type must be set first before deep or shallow copy
            if cell_type is None:
                self.SetCellType(vtk_cell.GetCellType())
            else:
                self.SetCellType(cell_type)

            if deep:
                self.DeepCopy(vtk_cell)
            else:
                self.ShallowCopy(vtk_cell)

    @property
    def type(self) -> CellType:  # numpydoc ignore=RT01
        """Get the cell type from the enum :class:`pyvista.CellType`.

        Returns
        -------
        pyvista.CellType
            Type of cell.

        Examples
        --------
        >>> import pyvista as pv
        >>> mesh = pv.Sphere()
        >>> mesh.get_cell(0).type
        <CellType.TRIANGLE: 5>
        """
        return CellType(self.GetCellType())

    @property
    def is_linear(self) -> bool:  # numpydoc ignore=RT01
        """Return if the cell is linear.

        Returns
        -------
        bool
            If the cell is linear.

        Examples
        --------
        >>> import pyvista as pv
        >>> mesh = pv.Sphere()
        >>> mesh.get_cell(0).is_linear
        True

        """
        return bool(self.IsLinear())

    def plot(self, **kwargs):
        """Plot this cell.

        Parameters
        ----------
        **kwargs : dict, optional
            See :func:`pyvista.plot` for a description of the optional keyword
            arguments.

        Examples
        --------
        >>> from pyvista import examples
        >>> mesh = examples.load_hexbeam()
        >>> cell = mesh.get_cell(0)
        >>> cell.plot()

        """
        self.cast_to_unstructured_grid().plot(**kwargs)

    def cast_to_unstructured_grid(self) -> pyvista.UnstructuredGrid:
        """Cast this cell to an unstructured grid.

        Returns
        -------
        pyvista.UnstructuredGrid
            This cell cast to a :class:`pyvista.UnstructuredGrid`.

        Examples
        --------
        >>> from pyvista import examples
        >>> mesh = examples.load_hexbeam()
        >>> cell = mesh.get_cell(0)
        >>> grid = cell.cast_to_unstructured_grid()
        >>> grid  # doctest: +SKIP
        UnstructuredGrid (0x7f9383619540)
          N Cells:      1
          N Points:     8
          X Bounds:     0.000e+00, 5.000e-01
          Y Bounds:     0.000e+00, 5.000e-01
          Z Bounds:     0.000e+00, 5.000e-01
          N Arrays:     0

        """
        if self.type == CellType.POLYHEDRON:
            # construct from faces
            cell_ids = [self.n_faces]
            for face in self.faces:
                cell_ids.append(len(face.point_ids))
                cell_ids.extend(self.point_ids.index(i) for i in face.point_ids)
            cell_ids.insert(0, len(cell_ids))
        else:
            cell_ids = [len(self.point_ids)] + list(range(len(self.point_ids)))
        return pyvista.UnstructuredGrid(
            cell_ids,
            [int(self.type)],
            self.points.copy(),
        )

    @property
    def dimension(self) -> int:  # numpydoc ignore=RT01
        """Return the cell dimension.

        This returns the dimensionality of the cell. For example, 1 for an edge,
        2 for a triangle, and 3 for a tetrahedron.

        Returns
        -------
        int
            The cell dimension.

        Examples
        --------
        >>> import pyvista as pv
        >>> mesh = pv.Sphere()
        >>> mesh.get_cell(0).dimension
        2
        """
        return self.GetCellDimension()

    @property
    def n_points(self) -> int:  # numpydoc ignore=RT01
        """Get the number of points composing the cell.

        Returns
        -------
        int
            The number of points.

        Examples
        --------
        >>> import pyvista as pv
        >>> mesh = pv.Sphere()
        >>> mesh.get_cell(0).n_points
        3
        """
        return self.GetNumberOfPoints()

    @property
    def n_faces(self) -> int:  # numpydoc ignore=RT01
        """Get the number of faces composing the cell.

        Returns
        -------
        int
            The number of faces.

        Examples
        --------
        >>> from pyvista.examples.cells import Tetrahedron
        >>> mesh = Tetrahedron()
        >>> mesh.get_cell(0).n_faces
        4
        """
        return self.GetNumberOfFaces()

    @property
    def n_edges(self) -> int:  # numpydoc ignore=RT01
        """Get the number of edges composing the cell.

        Returns
        -------
        int
            The number of edges composing the cell.

        Examples
        --------
        >>> import pyvista as pv
        >>> mesh = pv.Sphere()
        >>> mesh.get_cell(0).n_edges
        3
        """
        return self.GetNumberOfEdges()

    @property
    def point_ids(self) -> List[int]:  # numpydoc ignore=RT01
        """Get the point IDs composing the cell.

        Returns
        -------
        List[int]
            The point IDs composing the cell.

        Examples
        --------
        >>> import pyvista as pv
        >>> mesh = pv.Sphere()
        >>> mesh.get_cell(0).point_ids
        [2, 30, 0]
        """
        point_ids = self.GetPointIds()
        return [point_ids.GetId(i) for i in range(point_ids.GetNumberOfIds())]

    @property
    def points(self) -> np.ndarray:  # numpydoc ignore=RT01
        """Get the point coordinates of the cell.

        Returns
        -------
        np.ndarray
            The point coordinates of the cell.

        Examples
        --------
        >>> import pyvista as pv
        >>> mesh = pv.Sphere()
        >>> mesh.get_cell(0).points
        array([[0.05405951, 0.        , 0.49706897],
               [0.05287818, 0.0112396 , 0.49706897],
               [0.        , 0.        , 0.5       ]])
        """
        return _vtk.vtk_to_numpy(self.GetPoints().GetData())

    def get_edge(self, index: int) -> Cell:
        """Get the i-th edge composing the cell.

        Parameters
        ----------
        index : int
            Edge ID.

        Returns
        -------
        pyvista.Cell
            Edge given by ``index``.

        Examples
        --------
        Extract a single edge from a face and output the IDs of the edge
        points.

        >>> import pyvista as pv
        >>> mesh = pv.Sphere()
        >>> cell = mesh.get_cell(0)
        >>> edge = cell.get_edge(0)
        >>> edge.point_ids
        [2, 30]

        """
        if index + 1 > self.n_edges:
            raise IndexError(f'Invalid index {index} for a cell with {self.n_edges} edges.')

        # must deep copy here as multiple sequental calls to GetEdge overwrite
        # the underlying pointer
        return Cell(self.GetEdge(index), deep=True)

    @property
    def edges(self) -> List[Cell]:  # numpydoc ignore=RT01
        """Return a list of edges composing the cell.

        Returns
        -------
        List[Cell]
            A list of edges composing the cell.

        Examples
        --------
        >>> from pyvista.examples.cells import Hexahedron
        >>> mesh = Hexahedron()
        >>> cell = mesh.get_cell(0)
        >>> edges = cell.edges
        >>> len(edges)
        12

        """
        return [self.get_edge(i) for i in range(self.n_edges)]

    @property
    def faces(self) -> List[Cell]:  # numpydoc ignore=RT01
        """Return a list of faces composing the cell.

        Returns
        -------
        List[Cell]
            A list of faces composing the cell.

        Examples
        --------
        >>> from pyvista.examples.cells import Tetrahedron
        >>> mesh = Tetrahedron()
        >>> cell = mesh.get_cell(0)
        >>> faces = cell.faces
        >>> len(faces)
        4

        """
        return [self.get_face(i) for i in range(self.n_faces)]

    def get_face(self, index: int) -> Cell:
        """Get the i-th face composing the cell.

        Parameters
        ----------
        index : int
            Face ID.

        Returns
        -------
        pyvista.Cell
            Face given by ``index``.

        Examples
        --------
        Return the face IDs composing the first face of an example tetrahedron.

        >>> from pyvista.examples.cells import Tetrahedron
        >>> mesh = Tetrahedron()
        >>> cell = mesh.get_cell(0)
        >>> face = cell.get_face(0)
        >>> face.point_ids
        [0, 1, 3]

        """
        # must deep copy here as sequental calls overwrite the underlying pointer
        if index + 1 > self.n_faces:
            raise IndexError(f'Invalid index {index} for a cell with {self.n_faces} faces.')

        # must deep copy here as multiple sequental calls to GetFace overwrite
        # the underlying pointer
        cell = self.GetFace(index)
        return Cell(cell, deep=True, cell_type=cell.GetCellType())

    @property
    def bounds(self) -> Tuple[float, float, float, float, float, float]:  # numpydoc ignore=RT01
        """Get the cell bounds in ``[xmin, xmax, ymin, ymax, zmin, zmax]``.

        Returns
        -------
        Tuple[float, float, float, float, float, float]
            The cell bounds in ``[xmin, xmax, ymin, ymax, zmin, zmax]``.

        Examples
        --------
        >>> import pyvista as pv
        >>> mesh = pv.Sphere()
        >>> mesh.get_cell(0).bounds
        (0.0, 0.05405950918793678, 0.0, 0.011239604093134403, 0.49706897139549255, 0.5)

        """
        return self.GetBounds()

    @property
    def center(self) -> Tuple[float, float, float]:  # numpydoc ignore=RT01
        """Get the center of the cell.

        Uses parametric coordinate center to determine x-y-z center.

        Returns
        -------
        Tuple[float, float, float]
            The center of the cell.

        Examples
        --------
        >>> import pyvista as pv
        >>> mesh = pv.Sphere()
        >>> mesh.get_cell(0).center
        (0.03564589594801267, 0.0037465346977114677, 0.49804598093032837)

        """
        para_center = [0.0, 0.0, 0.0]
        sub_id = self.GetParametricCenter(para_center)
        # EvaluateLocation requires mutable sub_id
        sub_id = _vtk.mutable(sub_id)
        # center and weights are returned from EvaluateLocation
        center = [0.0, 0.0, 0.0]
        weights = [0.0] * self.n_points
        self.EvaluateLocation(sub_id, para_center, center, weights)
        return cast(Tuple[float, float, float], tuple(center))

    def _get_attrs(self):
        """Return the representation methods (internal helper)."""
        attrs = []
        attrs.append(("Type", repr(self.type), "{}" * len(repr(self.type))))
        attrs.append(("Linear", self.is_linear, "{}"))
        attrs.append(("Dimension", self.dimension, "{}"))
        attrs.append(("N Points", self.n_points, "{}"))
        attrs.append(("N Faces", self.n_faces, "{}"))
        attrs.append(("N Edges", self.n_edges, "{}"))
        bds = self.bounds
        fmt = f"{pyvista.FLOAT_FORMAT}, {pyvista.FLOAT_FORMAT}"
        attrs.append(("X Bounds", (bds[0], bds[1]), fmt))
        attrs.append(("Y Bounds", (bds[2], bds[3]), fmt))
        attrs.append(("Z Bounds", (bds[4], bds[5]), fmt))

        return attrs

    def __repr__(self) -> str:
        """Return the object representation."""
        return self.head(display=False, html=False)

    def __str__(self) -> str:
        """Return the object string representation."""
        return self.head(display=False, html=False)

    def copy(self, deep=True) -> Cell:
        """Return a copy of the cell.

        Parameters
        ----------
        deep : bool, optional
            When ``True`` makes a full copy of the cell.  When ``False``,
            performs a shallow copy where the new cell still references the
            original cell.

        Returns
        -------
        pyvista.Cell
            Deep or shallow copy of the cell.

        Examples
        --------
        Create a deep copy of the cell and demonstrate it is deep.

        >>> from pyvista.examples.cells import Tetrahedron
        >>> mesh = Tetrahedron()
        >>> cell = mesh.get_cell(0)
        >>> deep_cell = cell.copy(deep=True)
        >>> deep_cell.points[:] = 0
        >>> cell != deep_cell
        True

        Create a shallow copy of the cell and demonstrate it is shallow.

        >>> shallow_cell = cell.copy(deep=False)
        >>> shallow_cell.points[:] = 0
        >>> cell == shallow_cell
        True

        """
        return type(self)(self, deep=deep)

class CellArray(_vtk.vtkCellArray):
    """PyVista wrapping of vtkCellArray.

    Provides convenience functions to simplify creating a CellArray from
    a numpy array or list.

    Parameters
    ----------
    cells : np.ndarray or list, optional
        Import an array of data with the legacy vtkCellArray layout, e.g.
        ``{ n0, p0_0, p0_1, ..., p0_n, n1, p1_0, p1_1, ..., p1_n, ... }``
        Where n0 is the number of points in cell 0, and pX_Y is the Y'th
        point in cell X.

    n_cells : int, optional
        The number of cells.

    deep : bool, default: False
        Perform a deep copy of the original cell.

    Examples
    --------
    Create a cell array containing two triangles from the traditional interleaved format

    >>> from pyvista.core.cell import CellArray
    >>> cellarr = CellArray([3, 0, 1, 2, 3, 3, 4, 5])

    Create a cell array containing two triangles from separate offsets and connectivity arrays

    >>> from pyvista.core.cell import CellArray
    >>> offsets = [0, 3, 6]
    >>> connectivity = [0, 1, 2, 3, 4, 5]
    >>> cellarr = CellArray.from_arrays(offsets, connectivity)
    """

    def __init__(self, cells=None, n_cells=None, deep=False):
        """Initialize a vtkCellArray."""
        self.__offsets = None
        self.__connectivity = None
        if cells is not None:
            self._set_cells(cells, n_cells, deep)

    def _set_cells(self, cells, n_cells, deep):
        """Set a vtkCellArray."""
        vtk_idarr, cells = numpy_to_idarr(cells, deep=deep, return_ind=True)

        # Get number of cells if None.  This is quite a performance
        # bottleneck and we can consider adding a warning.  Good
        # candidate for Cython or JIT compilation
        if n_cells is None:
            if cells.ndim == 1:
                n_cells = ncells_from_cells(cells)
            else:
                n_cells = cells.shape[0]

        self.SetCells(n_cells, vtk_idarr)
        self.__offsets = self.__connectivity = None

    @property
    def cells(self):  # numpydoc ignore=RT01
        """Return a numpy array of the cells.

        Returns
        -------
        np.ndarray
            A numpy array of the cells.
        """
        return _vtk.vtk_to_numpy(self.GetData()).ravel()

    @property
    def n_cells(self):  # numpydoc ignore=RT01
        """Return the number of cells.

        Returns
        -------
        int
            The number of cells.
        """
        return self.GetNumberOfCells()

    @property
    def connectivity_array(self):  # numpydoc ignore=RT01
        """Return the array with the point ids that define the cells' connectivity.

        Returns
        -------
        np.ndarray
            Array with the point ids that define the cells' connectivity.
        """
        return _get_connectivity_array(self)

    @property
    def offset_array(self):  # numpydoc ignore=RT01
        """Return the array used to store cell offsets.

        Returns
        -------
        np.ndarray
            Array used to store cell offsets.
        """
        return _get_offset_array(self)

    def _set_data(self, offsets, connectivity, deep=False):
        """Set the offsets and connectivity arrays."""
        offsets = numpy_to_idarr(offsets, deep=deep)
        connectivity = numpy_to_idarr(connectivity, deep=deep)
        self.SetData(offsets, connectivity)

        # Because vtkCellArray doesn't take ownership of the arrays, it's possible for them to get
        # garbage collected. Keep a reference to them for safety
        self.__offsets = offsets
        self.__connectivity = connectivity

    @staticmethod
    def from_arrays(offsets, connectivity, deep=False) -> CellArray:
        """Construct a CellArray from offsets and connectivity arrays.

        Parameters
        ----------
        offsets : numpy.ndarray or list[int]
            Offsets array of length `n_cells + 1`.

        connectivity : numpy.ndarray or list[int]
            Connectivity array.

        deep : bool, default: False
            Whether to deep copy the array data into the vtk arrays.

        Returns
        -------
        CellArray
            Constructed CellArray.

        """
        cellarr = CellArray()
        cellarr._set_data(offsets, connectivity, deep=deep)
        return cellarr

    @property
    def regular_cells(self) -> np.ndarray:  # numpydoc ignore=RT01
        """Return an array of shape (n_cells, cell_size) of point indices when all faces have the same size.

        Returns
        -------
        numpy.ndarray
            Array of face indices of shape (n_cells, cell_size).

        Notes
        -----
        This property does not validate that the cells are all
        actually the same size. If they're not, this property may either
        raise a `ValueError` or silently return an incorrect array.
        """
        return _get_regular_cells(self)

    @classmethod
    def from_regular_cells(cls, cells, deep=False):
        """Construct a ``CellArray`` from a (n_cells, cell_size) array of cell indices.

        Parameters
        ----------
        cells : numpy.ndarray or list[list[int]]
            Cell array of shape (n_cells, cell_size) where all cells have the same size `cell_size`.

        deep : bool, default: False
            Whether to deep copy the cell array data into the vtk connectivity array.

        Returns
        -------
        pyvista.CellArray
            Constructed ``CellArray``.
        """
        cells = np.asarray(cells, dtype=pyvista.ID_TYPE)
        n_cells, cell_size = cells.shape
        offsets = cell_size * np.arange(n_cells + 1, dtype=pyvista.ID_TYPE)
        cellarr = cls()
        cellarr._set_data(offsets, cells, deep=deep)
        return cellarr

# The following methods would be much nicer bound to CellArray,
# but then they wouldn't be available on bare vtkCellArrays. In the future,
# consider using vtkCellArray.override decorator, so they're all automatically
# returned as CellArrays

def _get_connectivity_array(cellarr: _vtk.vtkCellArray):
    """Return the array with the point ids that define the cells' connectivity."""
    return _vtk.vtk_to_numpy(cellarr.GetConnectivityArray())

def _get_offset_array(cellarr: _vtk.vtkCellArray):
    """Return the array used to store cell offsets."""
    return _vtk.vtk_to_numpy(cellarr.GetOffsetsArray())

def _get_regular_cells(cellarr: _vtk.vtkCellArray) -> np.ndarray:
    """Return an array of shape (n_cells, cell_size) of point indices when all faces have the same size."""
    cells = _get_connectivity_array(cellarr)
    if len(cells) == 0:
        return cells

    offsets = _get_offset_array(cellarr)
    cell_size = offsets[1] - offsets[0]
    return cells.reshape(-1, cell_size)


from pytest import approx, raises

from datetime import datetime
from igrf_model import IGRFModel

def test_model_v13():
    model = IGRFModel.get(version=13)
    assert isinstance(model, IGRFModel)
    assert len(model._table) == (19 * 120 + 7 * 195 + 1)
    assert model._table[0] == -31543
    assert model._table[250] == -389

def test_caching():
    model1 = IGRFModel.get(version=13)
    model2 = IGRFModel.get(version=13)
    assert model1 is model2

def test_invalid_version():
    with raises(ValueError, match="unsupported model version"):
        IGRFModel.get(version=777777)

def test_evaluation():
    model = IGRFModel.get(version=13)

    # Budapest according to http://www.geomag.bgs.ac.uk/data_service/models_compass/igrf_calc.html,
    # on Dec 22, 2021
    vec = model.evaluate(47.498, 19.04, date=datetime(2021, 12, 22))
    assert vec.declination == approx(5.371, abs=1e-2)
    assert vec.inclination == approx(64.265, abs=1e-2)
    assert vec.total_intensity == approx(48978, abs=1)

    # Genova according to http://www.geomag.bgs.ac.uk/data_service/models_compass/igrf_calc.html,
    # 2000m above MSL, on Jun 30, 2002
    vec = model.evaluate(44.414, 8.942, alt=2000, date=datetime(2002, 6, 30))
    assert vec.declination == approx(0.658, abs=1e-2)
    assert vec.inclination == approx(60.457, abs=1e-2)
    assert vec.total_intensity == approx(46543, abs=1)

    # Tokyo according to http://www.geomag.bgs.ac.uk/data_service/models_compass/igrf_calc.html,
    # 1000m above MSL, on Jan 15, 1996
    vec = model.evaluate(35.652, 139.83, alt=1000, date=datetime(1996, 1, 15))
    assert vec.declination == approx(-6.844, abs=1e-2)
    assert vec.inclination == approx(48.902, abs=1e-2)
    assert vec.total_intensity == approx(46175, abs=1)

    # Buenos Aires according to http://www.geomag.bgs.ac.uk/data_service/models_compass/igrf_calc.html,
    # 1500m above MSL, on Jul 29, 1983
    vec = model.evaluate(-34.603, -58.381, alt=1500, date=datetime(1983, 7, 29))
    assert vec.declination == approx(-3.940, abs=1e-2)
    assert vec.inclination == approx(-34.068, abs=1e-2)
    assert vec.total_intensity == approx(24227, abs=1)

def test_evaluation_invalid_years():
    model = IGRFModel.get(version=13)

    with raises(ValueError, match="year"):
        model.evaluate(47.498, 19.04, date=datetime(1899, 12, 22))
    with raises(ValueError, match="year"):
        model.evaluate(47.498, 19.04, date=2050)

def test_evaluation_works_without_year():
    model = IGRFModel.get(version=13)
    now = datetime.now()
    result1 = model.evaluate(47.498, 19.04)
    result2 = model.evaluate(47.498, 19.04, date=now)
    assert result1 == approx(result2)


from data_crawler import DataCrawler
from tgChatbot import TkinterGUIExample

def main():
    crawler = DataCrawler()
    crawler.main()
    #json_doc = crawler.getJSON_Tree()
    gui_example = TkinterGUIExample()
    gui_example.mainloop()

if __name__ == '__main__':
    main()


#!/usr/bin/env python
"""
Compute nye tensor around dislocation core.
The INPUT should be a LAMMPS dump file.

Usage:
  nye_tensor.py dumpconf
  nye_tensor.py calc INPUT [CONFIG]
  nye_tensor.py plot [options] [CONFIG]

Options:
  -h,--help   Show this message and exit.
  --component COMPONENT
              Specifies a component to be plot. [default: 33]
  -x X        Origin of x. [default: 0.0]
  -y Y        Origin of y. [default: 0.0]
  --width W   Half width in unit of Burgers vector. [default: 10]
  --height H  Half height in unit of Burgers vector. [default: 8]
"""
from __future__ import print_function

import os,sys,math,json
from docopt import docopt
import numpy as np
import numba

from ase.io import read

__author__ = "RYO KOBAYASHI"
__version__ = "160930"

########################################################################
#...parameters to be set to match the system
########################################################################
a0 = 4.045
c_o_a = 1.0
phi_min = 27.
iwindow = 1
xmin = 150.  # in Angstrom
xmax = 200.
ymin = 150.
ymax = 200.
nei_perf = np.zeros((12,3),dtype=float)
nei_perf[:,:] = [
    [ .5,  .5,  0.],
    [ .5, -.5,  0.],
    [-.5,  .5,  0.],
    [-.5, -.5,  0.],
    [ .5,  0.,  .5],
    [ .5,  0., -.5],
    [-.5,  0.,  .5],
    [-.5,  0., -.5],
    [ 0.,  .5,  .5],
    [ 0., -.5,  .5],
    [ 0.,  .5, -.5],
    [ 0., -.5, -.5]
]
#...rotation matrix from reference to deformed system
#...to be normalized in the script
block = np.array([[ 1.,-2., 1.],
                   [-1.,-1.,-1.],
                   [ 1., 0.,-1.]])

#...max number of nearest neighbors
maxnn = 20

def nye_tensor(atoms):
    """
    Compute Nye tensor around z-axis of given structure.
    """
    global block,maxnn,nei_perf,a0,\
        xmin,xmax,ymin,ymax,iwindow,phi_min

    phi_min = math.cos(phi_min*math.pi/180)
    pos = atoms.get_positions()
    cot = [ [i,pos[i,0],pos[i,1],pos[i,2]] for i in range(len(atoms)) ]
    co1 = np.array(cot)
    cell = atoms.get_cell()
    #...assuming that cell[2,2] is z-period
    period = cell[2,2]
    ntot = len(atoms)
    print(' num of atoms = ',ntot)

    xmin0 = np.min(co1[:,1])
    xmax0 = np.max(co1[:,1])
    ymin0 = np.min(co1[:,2])
    ymax0 = np.max(co1[:,2])
    zmin0 = np.min(co1[:,3])
    zmax0 = np.max(co1[:,3])
    zmin = zmin0 - 0.05
    zmax = zmax0 + 0.05

    for mm in range(3):
        block[mm,:] /= np.linalg.norm(block[mm,:])
    block = block.T
    print(' block after modification:')
    for mm in range(3):
        print(' {0:8.2f} {1:8.2f} {2:8.2f}'.format(block[mm,0],
                                                   block[mm,1],
                                                   block[mm,2]))

    nei_perf *= a0
    b = nei_perf[0,:]
    r1 = np.sqrt(np.dot(b,b))
    rc = (r1 +a0)/2
    rc2 = rc*rc
    print(' r1 = ',r1)
    print(' rc,rc2 = ',rc,rc2)

    #...Rotate the lattice vectors to the block system (what is block system?)
    # print(' nei_perf before rotation:')
    # for i in range(len(nei_perf)):
    #     print('   i,nei_perf =',i,nei_perf[i,:])
    for i in range(len(nei_perf)):
        nei_perf[i,:] = np.dot(nei_perf[i,:],block)
    # print(' nei_perf after rotation:')
    # for i in range(len(nei_perf)):
    #     print('   i,nei_perf =',i,nei_perf[i,:])

    #...select atoms within the window
    if iwindow > 0:
        tmp = []
        for i in range(ntot):
            if (xmin < co1[i,1] < xmax) and (ymin < co1[i,2] < ymax) and (zmin < co1[i,3] < zmax):
                tmp.append(co1[i,:])
        nfreew = len(tmp)
        co = np.array(tmp)

    else:
        xmin = xmin0
        xmax = xmax0
        ymin = ymin0
        ymax = ymax0
        zmin = zmax0
        zmax = zmax0
        nfreew = ntot
        co = copy.deepcopy(co1)
    print(' nfreew = ',nfreew)

    print(' >>> make_neighbors...')
    lsnn,lspr,lssft = make_neighbors_fast(co,co1,maxnn,
                                          rc,period)
    #check_neighbors(lsnn,lspr,lssft,co,co1,nei_perf)
    print(' >>> get_lattice_correspondance...')
    emat = get_lattice_correspondance(co,co1,
                                      lsnn,lspr,lssft,
                                      nei_perf,maxnn,
                                      period,r1,phi_min)
    print(' >>> compute_nye...')
    nye,inner = compute_nye(co,co1,lsnn,lspr,lssft,
                            emat,rc,period,
                            xmin,xmax,ymin,ymax,zmin,zmax)

    #...write to file
    f = open('dat.nye','w')
    for jj in range(len(inner)):
        i = inner[jj]
        f.write(' {0:8.3f} {1:8.3f} {2:8.3f}'.format(co[i,1],co[i,2],co[i,3]))
        for mm in range(3):
            f.write(' {0:8.4f} {1:8.4f} {2:8.4f}'.format(nye[jj,mm,0],
                                                        nye[jj,mm,1],
                                                        nye[jj,mm,2]))
        f.write('\n')
    f.close()
    print(' Nye tensor was written to file: dat.nye')
    return None

#@numba.jit
def make_neighbors(co,co1,maxnn,rc2,period):
    """
    Make neighbors of atoms in the window.
    Note that the neighbors can be outside the window.
    """
    #...indentify neighbors within the window
    nfreew = len(co)
    nnmax = 0
    nnmin= 20
    ntemp = np.zeros(maxnn,dtype=int)
    nshift= np.zeros(maxnn,dtype=int)
    lsnn = np.zeros(nfreew,dtype=int)
    lspr = np.zeros((nfreew,maxnn),dtype=int)
    lssft= np.zeros((nfreew,maxnn),dtype=int)
    for i in range(nfreew):
        ri = co[i,1:4]
        nn = 0
        for j in range(len(co1)):
            rj = co1[j,1:4]
            for k in (-1,0,1):
                rij = rj[:] -ri[:]
                rij[2] += period*k
                #r2 = np.dot(rij,rij)
                r2 = rij[0]*rij[0] +rij[1]*rij[1] +rij[2]*rij[2]
                if 0.001 < r2 < rc2:
                    ntemp[nn] = j
                    nshift[nn]= k
                    nn += 1
                    if nn >= maxnn:
                        raise RuntimeError('nn >= maxnn, nn =',nn)

        lsnn[i] = nn
        lspr[i,0:nn] = ntemp[0:nn]
        lssft[i,0:nn] = nshift[0:nn]
        if nn > nnmax:
            nnmax = nn
        if nn < nnmin:
            nnmin = nn
    print(' nnmax = ',nnmax)
    print(' nnmin = ',nnmin)
    return lsnn,lspr,lssft

def make_neighbors_fast(co,co1,maxnn,rc,period):
    """
    Make neighbors of atoms in the window using cell list method,
    which is much faster than Brute-force method.
    Assuming that the PERIOD, which is z-lengh, is short enough
    not to use cell list method.
    Note that the neighbors can be outside the window.
    """
    tiny = 1.e-3
    xmin1 = np.min(co1[:,1])-tiny
    xmax1 = np.max(co1[:,1])+tiny
    ymin1 = np.min(co1[:,2])-tiny
    ymax1 = np.max(co1[:,2])+tiny
    zmin1 = np.min(co1[:,3])-tiny
    zmax1 = np.max(co1[:,3])+tiny
    wx = xmax1 - xmin1
    wy = ymax1 - ymin1
    print(' xmin1,xmax1,wx =',xmin1,xmax1,wx)
    print(' ymin1,ymax1,wy =',ymin1,ymax1,wy)
    lcx = int(wx/rc)
    lcy = int(wy/rc)
    lcxy= lcx*lcy
    print(' lcx,lcy,lcxy = ',lcx,lcy,lcxy)
    rcx = wx /lcx
    rcy = wy /lcy
    rcxi= 1.0 /rcx
    rcyi= 1.0 /rcy
    lscl= np.zeros(len(co1),dtype=int)
    lshd= np.zeros(lcxy,dtype=int)
    lscl[:] = -1
    lshd[:] = -1

    for i in range(len(co1)):
        #...assign a vector cell index
        mx = int((co1[i,1]-xmin1)*rcxi)
        my = int((co1[i,2]-ymin1)*rcyi)
        m = mx*lcy + my
        try:
            lscl[i] = lshd[m]
        except:
            print(' i,mx,my,m =',i,mx,my,m)
            print(' co1 =',co1[i,:])
            raise
        lshd[m] = i

    natm = len(co)
    natm1= len(co1)
    lsnn = np.zeros(natm,dtype=int)
    lspr = np.zeros((natm,maxnn),dtype=int)
    lssft= np.zeros((natm,maxnn),dtype=int)
    lspr[:] = -1

    rc2 = rc*rc
    for ia in range(len(co)):
        ri = co[ia,1:4]
        mx = int((ri[0]-xmin1)*rcxi)
        my = int((ri[1]-ymin1)*rcyi)
        m = mx*lcy + my
        for kuy in (-1,0,1):
            m1y = my + kuy
            if m1y < 0 or m1y >= lcy: continue
            for kux in (-1,0,1):
                m1x = mx + kux
                if m1x < 0 or m1x >= lcx: continue
                m1 = m1x*lcy + m1y
                ja = lshd[m1]
                if ja == -1: continue
                scan_j_in_cell(ia,ri,ja,lscl,rc2,co1,
                               lsnn,lspr,lssft,maxnn,
                               period)

    print(' nnmax = ',np.max(lsnn))
    print(' nnmin = ',np.min(lsnn))
    return lsnn,lspr,lssft

def scan_j_in_cell(ia,ri,ja,lscl,rc2,co1,
                   lsnn,lspr,lssft,maxnn,period):
    if ja == ia: ja = lscl[ja]
    if ja == -1: return 0

    if not ja in lspr[ia]:
        rj= co1[ja,1:4]
        for k in (-1,0,1):
            rij= rj[:] - ri[:]
            rij[2] += period*k
            r2 = rij[0]*rij[0] +rij[1]*rij[1] +rij[2]*rij[2]
            if 0.001 < r2 < rc2:
                n = lsnn[ia]
                lspr[ia,n] = ja
                lssft[ia,n]= k
                lsnn[ia] += 1
                # if lsnn[ia] > 12:
                #     print(' lsnn[ia] > 12, ia =',ia)
                #     print('   lspr = ',lspr[ia,:])
                #     print('   lssft= ',lssft[ia,:])
                if lsnn[ia] >= maxnn:
                    raise RuntimeError(' lsnn >= maxnn,'+
                                       ' ia =',ia)

    ja= lscl[ja]
    scan_j_in_cell(ia,ri,ja,lscl,rc2,co1,
                   lsnn,lspr,lssft,maxnn,period)

def check_neighbors(lsnn,lspr,lssft,co,co1,nei_perf):
    #...check neighbor list and rotated nei_perf
    print(' >>> check_neighbors...')
    idx = lsnn.argmax()
    print(' idx =',idx)
    ri = co[idx,1:4]
    print('Neighbor vectors in deformed system:')
    for jj in range(lsnn[idx]):
        j = lspr[idx,jj]
        rj = co1[j,1:4]
        rij = rj[:] -ri[:]
        rij[2] += period*lssft[idx,jj]
        print('jj,j,rij=',jj,j,rij)

    for j in range(len(nei_perf)):
        print('j,nei_perf =',j,nei_perf[j,:])
    return None

# @numba.jit
def get_lattice_correspondance(co,co1,lsnn,lspr,lssft,nei_perf,
                               maxnn,period,r1,phi_min):
    """
    Compute lattice correspondance between deformed and reference lattices.
    Local strain is also computed in the same loop as well.

    Returns
    --------
    emat : ndarray
           Local correspondance strain matrices for each atom.

    """

    nfreew = len(co)
    iden = np.identity(3)
    isym = 0
    iunique = 0
    iiu = 0
    npr = 0
    rr = np.zeros(maxnn)
    best = np.zeros(maxnn)
    km = [ 0 for i in range(maxnn) ]
    igood = np.zeros((nfreew,maxnn))
    nsym = np.zeros(nfreew)
    best_fit = np.ones(nfreew)
    emat = np.zeros((nfreew,3,3))
    angle = np.zeros(len(nei_perf))
    #...loop for atoms in deformed system
    for i in range(nfreew):
        ri = co[i,1:4]
        b = np.zeros((3,3))
        a = np.zeros((3,3))
        isym1 = isym
        iunique1 = iunique
        #...loop for neighbors of atom-i in deformed system
        for jj in range(lsnn[i]):
            j = lspr[i,jj]
            rj = co1[j,1:4]
            rij = rj[:] - ri[:]
            rij[2] += period*lssft[i,jj]
            drij= np.linalg.norm(rij)
            rr[jj] = abs(drij-r1)
            erij = rij[:]/drij
            #...check angle of bond from reference structure
            for k in range(len(nei_perf)):
                rn = nei_perf[k,0:3]
                ern = rn[:]/r1
                angle[k] = np.dot(erij,ern)
            best[jj] = np.max(angle)
            kmax = [ k for k in range(len(angle)) if abs(angle[k]-best[jj]) < 1.e-5 ]

            if not kmax:
                print('i,jj,j,kmax=',i,jj,j,kmax)
                print('ri,rj=',ri,rj)
                print('angle =',angle)
                raise ValueError('kmax is [] which should not happen.')

            if len(kmax) > 1:
                if isym == 0:
                    print(' problems with symmetry: isym==0, len(kmax)>1')
                    print('     i,jj,j =',i,jj,j)
                isym = isym + 1
                igood[i,jj] = 0
            else:
                igood[i,jj] = 1
                if best[jj] < best_fit[jj]:
                    best_fit[jj] = best[jj]
            if igood[i,jj] == 1: # if the deformed vector unique
                km[jj] = kmax
                repeat = ismember(km[0:jj],km[jj])
                if np.sum(repeat) > 0:
                    try:
                        jjj = km[0:jj].index(km[jj])
                    except:
                        print('kmax = ',kmax)
                        print('km = ',km)
                        raise
                    dr1 = rr[jjj]
                    dr2 = rr[jj]
                    #...choose deformed vector with smaller stretch
                    if dr2 > dr1:
                        iunique = iunique + 1
                        igood[i,jj] = 0
                    elif dr2 < dr1:
                        igood[i,jjj] = 0
                        iunique = iunique + 1
                    else:
                        if iiu == 0:
                            print('Lattice correspondance is not unique.')
                            iiu = 1
                        iunique = iunique + 1
            if igood[i,jj] == 1 and best[jj] < phi_min:
                igood[i,jj] = 0
            if igood[i,jj] == 1:
                p = nei_perf[kmax,:]
                b = b + np.outer(rij,p)
                a = a + np.outer(rij,rij)
        if isym > isym1:
            npr = npr + 1
            nsym[npr] = i
        try:
            ee = np.dot(np.linalg.inv(a),b) # local correspondence strain
        except:
            print('i = ',i)
            print('a  =',a)
            raise
        strn = (iden - np.dot(ee,ee)) /2 # finite local strain
        small= ( (iden - ee) + (iden -ee.T) ) /2 # local small strain
        inv1 = np.trace(small) # 1st invariant of strain
        inv2 = (np.sum(small*small) -inv1*inv1) /2 # 2nd invariant of strain
        rot = ( (iden - ee) - (iden - ee).T) /2 # local spin
        vspin = [ -rot[1,2], rot[0,2], -rot[0,1]] # local angular velocity
        emat[i,:,:] = ee[:,:]

    if npr > 0:
        print(' correspondence is not unique.')
        print(' number of problematic atoms =',npr)
    else:
        print(' no problematic atoms.')

    return emat

@numba.jit()
def compute_nye(co,co1,lsnn,lspr,lssft,emat,rc,period,
                xmin,xmax,ymin,ymax,zmin,zmax):
    """
    Compute Nye tensor as curl of G.

    Returns
    -------
    nye : ndarray

    """
    rcc = 1.1*rc
    # inner = [ i for i in range(len(co)) \
    #     if xmin+rcc < co[i,1] < xmax-rcc and \
    #        ymin+rcc < co[i,2] < ymax-rcc and \
    #        zmin-rcc/1000 < co[i,3] < zmax+rcc/1000 ]
    n=0
    for i in range(len(co)):
        if xmin+rcc < co[i,1] < xmax-rcc and \
           ymin+rcc < co[i,2] < ymax-rcc and \
           zmin-rcc/1000 < co[i,3] < zmax+rcc/1000:
            n += 1
    inner = np.zeros(n,dtype=int)
    n= 0
    for i in range(len(co)):
        if xmin+rcc < co[i,1] < xmax-rcc and \
           ymin+rcc < co[i,2] < ymax-rcc and \
           zmin-rcc/1000 < co[i,3] < zmax+rcc/1000:
            inner[n] = i
            n += 1

    mi = len(inner)
    # co2 = np.zeros((mi,4))
    # for i in range(mi):
    #     co2[i,:] = co[inner[i],0:4]

    grd = np.zeros((mi,3,3,3))
    for i1 in range(3):
        for j1 in range(3):
            for jj in range(mi):
                n = inner[jj]
                r = co[n,1:4]
                a = np.zeros((3,3))
                c = np.zeros((3))
                e0 = emat[n,i1,j1]
                for j in range(lsnn[n]):
                    nb = lspr[n,j]
                    nnb = find_idx_in_co(nb,co)
                    rn = co1[nb,1:4]
                    dr = rn[:] -r[:]
                    dr[2] += period*lssft[n,j]
                    a = a + np.outer(dr,dr)
                    de = emat[nnb,i1,j1] - e0
                    c = c + de*dr
                aa = np.dot(c,np.linalg.inv(a))
                grd[jj,i1,j1,:] = aa[:]

    #...compute curl and get Nye tensor
    nye = np.zeros((mi,3,3))
    for jj in range(mi):
        for mm in range(3):
            nye[jj,0,mm] = -grd[jj,2,mm,1] + grd[jj,1,mm,2]
            nye[jj,1,mm] = -grd[jj,0,mm,2] + grd[jj,2,mm,0]
            nye[jj,2,mm] = -grd[jj,1,mm,0] + grd[jj,0,mm,1]

    return nye,inner

#@numba.jit
def ismember(a,b):
    """
    Mimics ismember function in Matlab.
    Returns an array of the same length as A in which elements are 0 or 1.
    If an element of A exists in the array B, the element of returning array is 1,
    otherwise it is 0.
    """
    arr = np.zeros((len(a)),dtype=int)
    for i in range(len(a)):
        if a[i] in b:
            arr[i] = 1
    return arr

@numba.jit
def find_idx_in_co(idx,co):
    """
    Find the index such that co[index,0]==idx.
    """
    for i in range(len(co)):
        if co[i,0] == idx:
            return i
    return None

def dumpconf():
    global a0,c_o_a,phi_min,iwindow,xmin,xmax,ymin,ymax, \
        nei_perf,block,maxnn

    confname = 'nye_config.json'
    dic = {
        "a0": a0,
        "c_o_a": c_o_a,
        "phi_min": phi_min,
        "iwindow": iwindow,
        "xmin": xmin,
        "xmax": xmax,
        "ymin": ymin,
        "ymax": ymax,
        "nei_perf": nei_perf.tolist(),
        "block": block.tolist(),
        "maxnn":maxnn,
    }
    with open(confname,'w') as f:
        json.dump(dic,f,indent=2,sort_keys=True)
    print(' config file '+confname+' was written.')
    return None

def loadconf(confname):
    global a0,c_o_a,phi_min,iwindow,xmin,xmax,ymin,ymax, \
        nei_perf,block,maxnn

    with open(confname,'r') as f:
        js = json.load(f)
    a0 = js['a0']
    c_o_a = js['c_o_a']
    phi_min = js['phi_min']
    iwindow = js['iwindow']
    xmin = js['xmin']
    xmax = js['xmax']
    ymin = js['ymin']
    ymax = js['ymax']
    nei_perf = np.array(js['nei_perf'])
    block = np.array(js['block'])
    maxnn = js['maxnn']
    return None

def read_dat_nye(fname='dat.nye',):
    with open(fname,'r') as f:
        lines = f.readlines()
        natm = len(lines)
        pos = np.zeros((natm,3),dtype=float)
        nye = np.zeros((natm,3,3),dtype=float)
        for il,l in enumerate(lines):
            ds = l.split()
            pos[il,:] = [ float(ds[i]) for i in range(3) ]
            k = 3
            for i in range(3):
                for j in range(3):
                    nye[il,i,j] = float(ds[k])
                    k += 1
    return pos,nye

if __name__ == "__main__":

    args = docopt(__doc__)
    fname = args['INPUT']
    confname = args['CONFIG']
    print(args)

    exit

    if args['dumpconf']:
        dumpconf()

    elif args['calc']:
        if confname:
            loadconf(confname)
        #...output for checking
        print(' block:')
        for i in range(3):
            print(' {0:8.2f} {1:8.2f} {2:8.2f}'.format(block[i,0],
                                                       block[i,1],
                                                       block[i,2]))
        print(' nei_perf:')
        for i in range(len(nei_perf)):
            print(' {0:4d}:'.format(i)+
                  ' {0:8.2f} {1:8.2f} {2:8.2f}'.format(nei_perf[i,0],
                                                       nei_perf[i,1],
                                                       nei_perf[i,2]))
        atoms = read(fname,format='lammps-dump')
        nye_tensor(atoms)

    elif args['plot']:
        #...See http://matplotlib.org/examples/pylab_examples/griddata_demo.html
        #...for contour plot example.
        from matplotlib.mlab import griddata
        import matplotlib.pyplot as plt
        if confname:
            loadconf(confname)
        comp = args['--component']
        xo = float(args['-x'])
        yo = float(args['-y'])
        w = int(args['--width'])
        h = int(args['--height'])
        if len(comp) != 2:
            raise ValueError('len(comp) != 2')
        cmpnnt = [ int(comp[0])-1, int(comp[1])-1 ]
        pos,nye = read_dat_nye(fname='dat.nye')
        x = pos[:,0] -xo
        y = pos[:,1] -yo
        z = nye[:,cmpnnt[0],cmpnnt[1]]
        nei_perf *= a0
        b = nei_perf[0,:]
        b = np.sqrt(np.dot(b,b))
        print(' b = ',b)
        print(' xmin,xmax = ',x.min(),x.max())
        print(' ymin,ymax = ',y.min(),y.max())
        xi = np.linspace(x.min(),x.max(),100)
        yi = np.linspace(y.min(),y.max(),100)
        zi = griddata(x,y,z,xi,yi,interp='linear')
        cs = plt.contourf(xi,yi,zi, 15, cmap=plt.cm.rainbow,
                          vmax=abs(zi).max(),
                          vmin=-abs(zi).max())
        plt.colorbar(shrink=float(h)/w,aspect=20.*float(h)/w)
        plt.scatter(x,y,marker='o',s=40,zorder=10,
                    facecolors='white',edgecolors='black')
        print(' -w*b,w*b = ',-w*b,w*b)
        print(' -h*b,h*b = ',-h*b,h*b)
        plt.xlim(-w*b,w*b)
        plt.ylim(-h*b,h*b)
        xtics = [ i*b for i in range(-w,w+1,1) ]
        xticss = [ '{0:d}b'.format(i) for i in range(-w,w+1,1) ]
        ytics = [ i*b for i in range(-h,h+1,1) ]
        yticss = [ '{0:d}b'.format(i) for i in range(-h,h+1,1) ]
        plt.xticks( xtics, xticss, fontname='sans-serif',
                   fontsize=16 )
        plt.yticks( ytics, yticss, fontname='sans-serif',
                   fontsize=16 )
        plt.xlabel('[-1 1 0] -->', fontname='sans-serif',
                   fontsize=16)
        plt.ylabel('[ 1 1 1] -->', fontname='sans-serif',
                   fontsize=16)
        plt.title('Nye component '+comp)
        plt.axes().set_aspect(1.0)
        plt.axes().tick_params(axis='x',
                               which='major',
                               pad=10)
        plt.axes().tick_params(axis='y',
                               which='major',
                               pad=10)
        plt.show()


# DontCamp.com Population Logger
# written by: butter@dontcamp.com
# Revision: $Revision: 1.7 $
#
# This program writes a simple CSV formatted file in a directory under your BF2
# root directory specified by the the 'dir' variable below. A new CSV file will
# be made for each round played. The current CSV file will be called
# population_log.in_progress. The rotated CSV files will have the .in_progress
# extention replaced with a UNIX C timestamp and a .csv.
#
# Each line contains the profile ID, playername IP address, C timestamp, and
# whether the line was written on connect or disconnect. This program has many
# flaws that have yet to be resolved. But it is at least a useful tool for
# gathering profile IDs to use in the DontCamp.com Administrative Support
# System.
#
# To install this, simply drop it into the admin/standard_admin directory of
# your BF2 installation. Edit the admin/standard_admin/__init__.py to include
# these two lines:
#
#     import dc_pop_log
#     dc_pop_log.init()
#
# Create a directory somewhere under your BF2 root directory and enter the
# relative path from your BF2 root directory to the directory you just created
# in the 'dir' variable below. For example: if your BF2 server is installed in
# /usr/local/bin/bf2 and you want to keep your population logs in
# /usr/local/bin/bf2/dc_pop_logs then the 'dir' variable should equal
# 'dc_pop_logs'.
#
# NOTE: This program requires that dc_debug.py be installed into the
# admin/standard_admin directory as well.

import bf2
import host
import time
import os
from bf2 import g_debug
from dc_debug import decho

dir = 'dc_pop_logs'

def init():
	decho('dc_pop_log: initializing DontCamp.com Population Logger', 2)
	host.registerHandler('PlayerConnect', onPlayerConnect, 1)
	host.registerHandler('PlayerDisconnect', onPlayerDisconnect, 1)
	host.registerGameStatusHandler(onStatusChange)

def onPlayerConnect(p):
	decho("dc_pop_log: player connected", 5)

	id = p.getProfileId()
	name = p.getName()
	ip = p.getAddress()
	timestamp = time.time()
	state = "connected"
	writeLogFile(id, name, ip, timestamp, state)

def onPlayerDisconnect(p):
	decho("dc_pop_log: player disconnected", 5)

	id = p.getProfileId()
	name = p.getName()
	ip = p.getAddress()
	timestamp = time.time()
	state = "disconnected"
	writeLogFile(id, name, ip, timestamp, state)

def writeLogFile(id, name, ip, timestamp, state):
	decho( "dc_pop_log: writing that %s %s to population_log.in_progress" % (name, state), 3 )

	try:
		fh = open('%s/population_log.in_progress' % dir, 'a')
		fh.write("%d,\"%s\",%s,%d,%s\n" % (id, name, ip, timestamp, state))
		fh.close()
	except:
		decho( 'dc_pop_log: unable to write to %s/population_log.in_progress' % dir, 2 )

def onStatusChange(status):
	decho("dc_pop_log: status handler entered", 5)

	if status == bf2.GameStatus.EndGame:
		decho("dc_pop_log: status == EndGame", 5)
		timestamp = time.time()

		try:
			fh_old = open('%s/population_log.in_progress' % dir, 'r+')
			fh_new = open('%s/population_log.%d.csv' % (dir, timestamp), 'w')

			for line in fh_old:
				fh_new.write(line)

			fh_old.truncate(0)
			fh_old.close()
			fh_new.close()
		except:
			decho( 'dc_pop_log: there was an error trying to "move" the in progress log', 2 )


####### ------------- Imports ---------------######
# Import tkinter module
import tkinter as tk
import tkinter.messagebox as tkMessageBox
from tkinter.filedialog import asksaveasfilename

# Import Matplotlib, math and statitics
import numpy as np  # To use array of numbers instead of list
import matplotlib.pyplot as plt # To plot graphics
from matplotlib.figure import Figure
import random # To generate random numbers
from statistics import mean # To use mean from statistics package
import math # To use log and pi methods.

# To import integration features (between tkinter and matplotlib)
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg # used to integrate tkinter and matplotlib
plt.style.use("ggplot")

# Imports not being used (here as reference)
#import tkinter.filedialog # To use dialogs (like open file, save file)
#import tkinter import filedialog as fd # Different way of calling it

### defs at the begin of the code ### defs are the functions ###
def graph(f,c):
    window_size_N = 5 # Set a initial value
    f.clear()
    # Now lets import .txt file
    # 3 Column, being packet number, RSSI Downlink, PSR (packet success rate)
    file = open("gerencia.txt", mode='r')
    #print(file.read())

    RSSIdl = np.loadtxt("gerencia.txt", delimiter=';', usecols=[1])
    #print(RSSIdl)
    #file.close() #? I am considering that I have all the data already

    val_run = 0
    std_deviation_running = np.array(0)
    #print(type(std_deviation_running))
    # Shows how many dimention the array has, not elements
    # print(std_deviation_running.ndim)
    # std_deviation_running = np.append(std_deviation_running, 10)

    #print(std_deviation_running)
    for val in RSSIdl:
        # val returns <class 'numpy.float64'>
        # To run over all the random values by incrementing 1
        val_run = val_run+1
        # array_partial = initial value up to window size
        # then do it again, but initial value + 1 up to window size + 1
        array_partial = RSSIdl[val_run:window_size_N+val_run]
        # now, I need to add to an array, each value of std deviation
        #print(np.std(array_partial))
        std_deviation_running = np.append(std_deviation_running, np.std(array_partial))
        #print('Standard deviation: ' + str(np.float64(np.std(array_partial))))
        #print(array_partial)
    #print(std_deviation_running)
    #plt.figure(1)
    ax = f.add_subplot()
    ax.plot(std_deviation_running, label='Running statistics')     # plt.plot(std_deviation_running)
    ax.set_xlabel('Time domain') # plt.xlabel('Time domain')
    ax.set_ylabel('Standard deviation') #plt.ylabel('Standard deviation')

    f.subplots_adjust(left=0.05, bottom=0.2, right=0.98, top=0.95, wspace=None, hspace=None)
    canvas.draw() # instead of plt.show()

    file.close()
    window.after(1000, graph,f,c) # Call function again after 1000 mili seconds.

def save_value():
    entry = window_size.get() # Takes string fist
    window_size_N = int(entry) # Then convert str to int
    print(window_size_N)
    if window_size_N <= 1:
        print('Window size cannont be lesser than 2')
    elif window_size_N > 101: #elif = else if
        print('Window size cannont be greater than 101')
    else:
        print('Running statistcs considering window size of: ', window_size_N)

def callback():
    if tkMessageBox.askokcancel("Sair", "Tem certeza que deseja sair?"):
        window.destroy()

def save(ff):
        ftypes = [('.png (PNG)', '*.png')]
        f = asksaveasfilename(filetypes=ftypes, defaultextension=".png")

        print(f)

        if f != '':
            ff.savefig(f)

''' this coments
more than just
one line '''
################################################### CODE ##############################################

#### ------------ Window Creation ---------------- ####

# Initialize the window manager
window = tk.Tk() # blank window with close, maximize, and minimize buttons on the top
# (Optional) Rename the GUI window
window.title("N6 Running Statistics")
# Geometry management
window.geometry("1000x380")
window.resizable(0,0) # User can't resize window
# Let's create a frame
frame = tk.Frame(master = window, borderwidth=1, relief='sunken')
frame.place(x=10,y=10,width=980,height=360)

# Define the label widget
#label = tk.Label(window, text ="Hello World!").pack() # a widget that is used to insert some text into the window

#### -------------- Buttons ------------------- ####

# Create text to assist user
text = tk.Label(frame, text = "Tamanho da janela:")
text.place(x=110,y=318)
# Create box to receive value
window_size = tk.Entry(frame, width=10)
window_size.place(x=230,y=319)
window_size.insert(5, "5")
# Create button to save value to the variable
b_save_value = tk.Button(frame,text="GRAVAR", width=10, command = save_value)
b_save_value.place(x=300, y=315)
b_save_value.config(state="normal")

fig = Figure(figsize=(9.8, 3), facecolor='white')
# Figure: Area to plot the mathplot graph
# figsize=(x,y) in units, facecolor='white' to make background of the figure white
canvas = FigureCanvasTkAgg(fig, master = frame)
canvas.get_tk_widget().grid()
graph(fig,canvas)

b_save_image = tk.Button(frame, text='Salvar Gráfico', command=lambda:save(fig))
b_save_image.place(x=760,y=315)

#### -------------- Mainloop method ------------------ ####
window.protocol("WM_DELETE_WINDOW", callback)
window.mainloop() # method to display the window until you manually close it


import itertools
import os
import re
import shutil
import subprocess

from farmer.data import TAGS

DIR = os.path.split(__file__)[0]
os.chdir(DIR)
TESSERACT_PATH = None

GROUPS = {
    "hr": {
        "font": "Noto Sans CJK SC Regular",
        "words": TAGS.keys()
    },
}

# Command line equivalent:

# text2image --text dicts/hr.txt --font 'Noto Sans CJK SC Regular' --fonts_dir ./fonts/ --outputbase hr.notosans.exp0 --fontconfig_tmpdir ./ --ptsize 25
# tesseract hr.notosans.exp0.tif hr.notosans.exp0 nobatch box.train
# unicharset_extractor ./hr.notosans.exp0.box
# mftraining -F font_properties -U unicharset -O hr.unicharset hr.notosans.exp0.tr
# cntraining ./hr.notosans.exp0.tr
# mv normproto hr.normproto
# mv inttemp hr.inttemp
# mv pffmtable hr.pffmtable
# mv shapetable hr.shapetable
# combine_tessdata hr.

def execute(command: str, *args):
    if TESSERACT_PATH:
        command = os.path.join(TESSERACT_PATH, command)
    result = subprocess.check_output([command, *args])
    return result

def train(name):
    # make text dict
    full_set = set(itertools.chain(*GROUPS[name]["words"]))
    os.makedirs("dicts", exist_ok=True)
    with open(os.path.join("dicts", f"{name}.txt"), "w",
              encoding="utf-8") as file:
        text = "".join(full_set)
        # Workaround for https://github.com/tesseract-ocr/tesseract/issues/1166
        text *= 3
        file.write(text)

    # train
    font = GROUPS[name]["font"]
    execute(
        "text2image", "--text", f"dicts/{name}.txt", "--font", font,
        "--fonts_dir", "./fonts", "--outputbase", f"{name}.a_font.exp0",
        "--fontconfig_tmpdir", DIR)  # , "--ptsize", "22")
    execute("tesseract", "--oem", "1", f"{name}.a_font.exp0.tif",
            f"{name}.a_font.exp0", "nobatch", "box.train")
    execute("unicharset_extractor", f"{name}.a_font.exp0.box")
    execute(
        "mftraining", "-F", "font_properties", "-U", "unicharset",
        "-O", f"{name}.unicharset", f"{name}.a_font.exp0.tr")
    execute("cntraining", f"{name}.a_font.exp0.tr")

    for file in ("normproto", "inttemp", "pffmtable", "shapetable"):
        shutil.move(os.path.join(DIR, file),
                    os.path.join(DIR, f"{name}.{file}"))
    execute("combine_tessdata", f"{name}.")

if __name__ == '__main__':
    train("hr")