""" Finds the domain name from the string """

string = 'From a.n.other@gmail.com Sun 17 Feb 2018 15:34'

# Solution 1
domain_name = string[string.find('@'): string.find(' ', string.find('@'))].strip()
print(f"{'Solution 1 Domain Name:'} {domain_name}")

# Solution 2
start_position = string.find('@')
end_position = string.find(' ', start_position)
domain_name = string[start_position: end_position].strip()
print(f"{'Solution 2 Domain Name:'} {domain_name}")

"""
# NOTE:
In the example above, the first method of resolving the issue is a more
tersely written expression, however since the zen of Python stipulates that
readability counts, then the more Pythonic approach would be the second one.

The .strip() method is not required as there is actually no leading or trailing
spaces, however it has been applied as a belt and braces approach to ensure
there is none.
"""


#
# @lc app=leetcode id=576 lang=python3
#
# [576] Out of Boundary Paths
#

# @lc code=start
class Solution:
    def findPaths(self, m: int, n: int, N: int, i: int, j: int):
        dp = [[[0] * n for _ in range(m)] for _ in range(N + 1)]
        for s in range(1, N + 1):
            for x in range(m):
                for y in range(n):
                    v1 = 1 if x == 0 else dp[s - 1][x - 1][y]
                    v2 = 1 if x == m - 1 else dp[s - 1][x + 1][y]
                    v3 = 1 if y == 0 else dp[s - 1][x][y - 1]
                    v4 = 1 if y == n - 1 else dp[s - 1][x][y + 1]
                    dp[s][x][y] = (v1 + v2 + v3 + v4) % (10**9 + 7)
        return dp[N][i][j]

# @lc code=end


"""Implements the help window."""

# If we are running the unit tests.
if __name__ == '__main__':
    import sys
    sys.path.insert(1, '..')
    resourcePath = '../'
else:
    from resourcePath import resourcePath

import os.path
import wx
from HtmlWindow import HtmlWindow

data = ['Acknowledgments',
        'License',
        'Introduction',
        'Installation',
        'Platform-Specific Information',
        ["User's Guide",
         ['Overview',
          'Quick Start',
          'Model List',
          'Method Editor',
          'Recorder',
          'Launcher',
          'Simulation Output',
          'Species Editor',
          'Reaction Editor',
          'Parameter Editor',
          'Compartment Editor',
          'Tool Bar',
          'Mathematical Expressions']],
        ['Examples',
         ['Birth-Death',
          'Immigration-Death']],
        ['Simulation Methods',
         ['Discrete Stochastic Simulations',
          'Direct Method',
          'First Reaction Method',
          'Next Reaction Method',
          'Tau-Leaping',
          'Direct Method with Time-Dependent Propensities',
          'Hybrid Direct/Tau-Leaping',
          'ODE Integration']],
        ['Performance',
         ['Exact Methods']],
        ["Developer's Guide",
         ['Command Line Solvers',
          'File Formats',
          'Adding New Solvers']],
        ['Cain XML File Format',
         ['Top-Level Elements',
          'Models',
          'Methods',
          'Output',
          'Random Numbers']],
        'FAQ',
        'Links',
        'Bibliography',
        'Known Issues',
        'To Do']

class Help(wx.Frame):
    """The help window."""

    def __init__(self, parent=None, title='Cain help'):
        """Read and render the HTML help file."""
        wx.Frame.__init__(self, parent, -1, title, size=(1100,750))
        splitter = wx.SplitterWindow(self)

        self.contents = wx.TreeCtrl(splitter,
                                    style=wx.TR_HIDE_ROOT|wx.TR_DEFAULT_STYLE)
        root = self.contents.AddRoot('Cain Help')
        self.addTreeNodes(root, data)
        self.Bind(wx.EVT_TREE_SEL_CHANGED, self.onActivated, self.contents)

        self.html = HtmlWindow(splitter)
        if "gtk2" in wx.PlatformInfo:
            self.html.SetStandardFonts()
        # The window title.
        self.html.SetRelatedFrame(self, self.GetTitle() + " -- %s")
        # Status bar.
        self.CreateStatusBar()
        self.html.SetRelatedStatusBar(0)

        splitter.SetMinimumPaneSize(10)
        splitter.SplitVertically(self.contents, self.html, 200)

        self.html.LoadPage(os.path.join(resourcePath, 'gui/help.html'))

    def addTreeNodes(self, parent, items):
        for item in items:
            if type(item) == str:
                self.contents.AppendItem(parent, item)
            else:
                newItem = self.contents.AppendItem(parent, item[0])
                self.addTreeNodes(newItem, item[1])

    def onActivated(self, event):
        label = self.contents.GetItemText(event.GetItem())
        self.html.OnLinkClicked(wx.html.HtmlLinkInfo('#' + label))

def main():
    app = wx.PySimpleApp()
    frame = Help()
    frame.Show()
    app.MainLoop()

if __name__ == '__main__':
    main()


import sys
import cv2
import numpy as np
from collections import deque

#sys.stderr = object     # uncomment to get rid of all errors

cam = cv2.VideoCapture(0)
haar_face_cascade = cv2.CascadeClassifier('/usr/local/bin/opencv/data/haarcascades/haarcascade_frontalface_alt.xml')
haar_eye_cascade = cv2.CascadeClassifier('/usr/local/bin/opencv/data/haarcascades/haarcascade_eye.xml')

def assimilate(q):
    if len(q):
        assim = lambda i,v: v/(len(q)-i)      # change this to change the assimilation function
        norm = sum([assim(i,1) for i in range(len(q))])

        rx,ry,rw,rh = 0,0,0,0
        for i, (x,y,w,h) in enumerate(q):
            rx += assim(i,x)
            ry += assim(i,y)
            rw += assim(i,w)
            rh += assim(i,h)

        return int(rx/norm), int(ry/norm), int(rw/norm), int(rh/norm)

FACE_MEM_LEN = 5
face_mem = deque()

EYE_MEM_LEN = 10
lefteye_mem = deque()
righteye_mem = deque()

while cv2.waitKey(1000//30) == -1:

    ret, frame = cam.read()
    draw = frame.copy()

    if ret:
        gray_img = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        faces = haar_face_cascade.detectMultiScale(gray_img, scaleFactor=1.1, minNeighbors=5)

        if len(faces) == 0:
            face_box = assimilate(face_mem)
            if face_box:
                x,y,w,h = face_box
            else:
                face_mem.popleft()
                cv2.imshow("Full", frame)
                continue
        elif len(faces) > 1:
            # use the face closest to avg of prev faces
            face_box = assimilate(face_mem)
            min_diff, min_i = sys.maxsize, 0
            if face_box:
                px,py,pw,ph = face_box
                for i, (tx,ty,tw,th) in enumerate(faces):
                    diff = (px-tx)**2+(py-ty)**2+(px+pw-tx-tw)**2+(py+ph-ty-th)**2
                    if diff < min_diff:
                        min_diff = diff
                        min_i = i
            x,y,w,h = faces[min_i]
            face_mem.append((x,y,w,h))
        else:
            x,y,w,h = faces[0]
            face_mem.append((x,y,w,h))
        if len(face_mem) > FACE_MEM_LEN:
            face_mem.popleft()
        face = frame[y:y+h, x:x+w]
        cv2.rectangle(frame, (x,y), (x+w,y+h), (255,0,0), 4)
        cv2.line(frame, (x,y+h//2), (x+w,y+h//2), (255,0,0), 2)
        cv2.line(frame, (x+w//2,y), (x+w//2,y+h), (255,0,0), 2)

        gray_face = gray_img[y:y+h, x:x+w]
        eyes = haar_eye_cascade.detectMultiScale(gray_face, scaleFactor=1.1,
                                                minNeighbors=5)

        right_eyes = [(ex,ey,ew,eh) for (ex,ey,ew,eh) in eyes if ey+eh//2 < h//2
                                                            and ex+ew//2 < w//2]
        if len(right_eyes) == 0:
            reye_box = assimilate(righteye_mem)
            if reye_box:
                ex,ey,ew,eh = reye_box
            else:
                righteye_mem.popleft()
                continue
        elif len(right_eyes) > 1:
            # use the face closest to avg of prev faces
            reye_box = assimilate(righteye_mem)

            min_diff, min_i = sys.maxsize, 0
            if reye_box:
                px,py,pw,ph = reye_box
                for i, (tx,ty,tw,th) in enumerate(right_eyes):
                    diff = (px-tx)**2+(py-ty)**2+(px+pw-tx-tw)**2+(py+ph-ty-th)**2
                    if diff < min_diff:
                        min_diff = diff
                        min_i = i
            ex,ey,ew,eh = right_eyes[min_i]
            righteye_mem.append((ex,ey,ew,eh))
        else:
            ex,ey,ew,eh = right_eyes[0]
            righteye_mem.append((ex,ey,ew,eh))
        if len(righteye_mem) > EYE_MEM_LEN:
            righteye_mem.popleft()
        cv2.rectangle(frame, (x+ex,y+ey), (x+ex+ew,y+ey+eh), (0,0,255), 2)
        cv2.line(frame, (x+ex,y+ey+eh//2), (x+ex+ew,y+ey+eh//2), (0,0,255), 1)
        cv2.line(frame, (x+ex+ew//2,y+ey), (x+ex+ew//2,y+ey+eh), (0,0,255), 1)

        left_eyes = [(ex,ey,ew,eh) for (ex,ey,ew,eh) in eyes if ey+eh//2 < h//2
                                                            and ex+ew//2 >= w//2]
        if len(left_eyes) == 0:
            leye_box = assimilate(lefteye_mem)
            if leye_box:
                ex,ey,ew,eh = leye_box
            else:
                lefteye_mem.popleft()
                continue
        elif len(left_eyes) > 1:
            # use the face closest to avg of prev faces
            leye_box = assimilate(lefteye_mem)

            min_diff, min_i = sys.maxsize, 0
            if leye_box:
                px,py,pw,ph = leye_box
                for i, (tx,ty,tw,th) in enumerate(left_eyes):
                    diff = (px-tx)**2+(py-ty)**2+(px+pw-tx-tw)**2+(py+ph-ty-th)**2
                    if diff < min_diff:
                        min_diff = diff
                        min_i = i
            ex,ey,ew,eh = left_eyes[min_i]
            lefteye_mem.append((ex,ey,ew,eh))
        else:
            ex,ey,ew,eh = left_eyes[0]
            lefteye_mem.append((ex,ey,ew,eh))
        if len(lefteye_mem) > EYE_MEM_LEN:
            lefteye_mem.popleft()
        cv2.rectangle(frame, (x+ex,y+ey), (x+ex+ew,y+ey+eh), (0,0,255), 2)
        cv2.line(frame, (x+ex,y+ey+eh//2), (x+ex+ew,y+ey+eh//2), (0,0,255), 1)
        cv2.line(frame, (x+ex+ew//2,y+ey), (x+ex+ew//2,y+ey+eh), (0,0,255), 1)

        cv2.imshow("Full", frame)

    else:
        break


from rest_framework import serializers
from authapp.models import User
from books.models import Book, BookImage

from .models import Bookcase, Shelf, DisplayedBook

class DisplayedBookSerializer(serializers.ModelSerializer):
    book = serializers.PrimaryKeyRelatedField(queryset=Book.objects.all())
    book_isbn = serializers.SerializerMethodField()
    book_title = serializers.SerializerMethodField()
    book_url = serializers.SerializerMethodField()
    book_stock = serializers.SerializerMethodField()
    book_thickness = serializers.SerializerMethodField()
    book_width = serializers.SerializerMethodField()
    display_order = serializers.IntegerField(required=False, write_only=True)
    shelf = serializers.PrimaryKeyRelatedField(queryset=Shelf.objects.all(), required=False, write_only=True)

    def get_book_isbn(self, instance):
        return instance.book.isbn_13

    def get_book_title(self, instance):
        return instance.book.title

    def get_book_url(self, instance):
        return BookImage.objects.get(book=instance.book).image_url

    def get_book_stock(self, instance):
        return instance.book.stock

    def get_book_thickness(self, instance):
        return instance.book.thickness

    def get_book_width(self, instance):
        return instance.book.width

    class Meta:
        model = DisplayedBook
        fields = ['book', 'display_mode', 'display_count', 'display_order', 'shelf','book_isbn', 'book_title', 'book_url', 'book_stock', 'book_thickness', 'book_width']
        read_only_fields = ['book_isbn', 'book_title', 'book_url', 'book_stock', 'book_thickness', 'book_width']

class ShelfSerializer(serializers.ModelSerializer):
    displayed_books = DisplayedBookSerializer(many=True)
    shelf_order = serializers.IntegerField(required=False, write_only=True)
    bookcase = serializers.PrimaryKeyRelatedField(queryset=Bookcase.objects.all(), required=False, write_only=True)

    class Meta:
        model = Shelf
        fields = ['displayed_books', 'shelf_order', 'bookcase']

    def create(self, data):
        books = data.pop('displayed_books')
        shelf = Shelf.objects.create(**data)
        self.create_display_books(books, shelf)
        return shelf

    def create_display_books(self, books, shelf):
        self.preprocess_display_books(books, shelf)
        serializer = DisplayedBookSerializer(data=books, many=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()

    def preprocess_display_books(self, books, shelf):
        for idx, book in enumerate(books):
            book['book'] = book['book'].id
            book['shelf'] = shelf.id
            book['display_order'] = idx

class BookcaseSerializer(serializers.ModelSerializer):
    shelves = ShelfSerializer(many=True)
    creator = serializers.PrimaryKeyRelatedField(queryset=User.objects.all(), write_only=True, required=False)
    last_editor = serializers.PrimaryKeyRelatedField(queryset=User.objects.all(), write_only=True)
    creator_username = serializers.SerializerMethodField()
    last_editor_username = serializers.SerializerMethodField()

    class Meta:
        model = Bookcase
        fields = ['id', 'name', 'width', 'shelves', 'last_edit_date',
                  'creator', 'creator_username', 'last_editor', 'last_editor_username']
        read_only_fields = ['id', 'creator_username', 'last_editor_username']

    def get_creator_username(self, instance):
        return instance.creator.username

    def get_last_editor_username(self, instance):
        return instance.last_editor.username

    def create(self, data):
        shelves = data.pop('shelves')
        bookcase = Bookcase.objects.create(**data)
        self.create_shelves(shelves, bookcase)
        return bookcase

    # The update method deletes/recreates all shelves for the bookcase,
    # and updates the top level fields
    def update(self, instance, validated_data):
        self.delete_old_shelves(instance)
        new_shelves = validated_data['shelves']
        self.create_shelves(new_shelves, instance)
        self.update_non_nested_fields(instance, validated_data)
        instance.save()
        return instance

    def update_non_nested_fields(self, instance, validated_data):
        instance.name = validated_data['name']
        instance.width = validated_data['width']
        instance.last_editor = validated_data['last_editor']

    def delete_old_shelves(self, bookcase):
        shelves = Shelf.objects.filter(bookcase_id=bookcase.id)
        for shelf in shelves:
            shelf.delete()

    def create_shelves(self, shelves, bookcase):
        self.preprocess_shelves(shelves, bookcase)
        serializer = ShelfSerializer(data=shelves, many=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()

    def preprocess_shelves(self, shelves, bookcase):
        for idx, shelf in enumerate(shelves):
            shelf['bookcase'] = bookcase.id
            shelf['shelf_order'] = idx
            for idx, book in enumerate(shelf['displayed_books']):
                book['book'] = book['book'].id


from django.core.exceptions import ValidationError
from django.test import TestCase
from ..service import InvoiceService, PaymentService
from organisations.models import Organisation
from ..models import Invoice, Payment
from ...orders.models import Vendor, OrderProduct, Order
from ...products.models import Product, Category
from utils.exceptionhandler import CustomException

class PaymentServiceTest(TestCase):
    def setUp(self):
        organisation = Organisation.objects.create(
            name="Ideas2it", description="Ideas2it Organisation"
        )

        self.organisation_uid = organisation.organisation_uid
        self.invoice_service = InvoiceService()
        self.payment_service = PaymentService()

        self.category = Category.objects.create(
            name="Electronics",
            description="Electronic products",
            organisation_id=self.organisation_uid,
        )

        self.product = Product.objects.create(
            name="Lenovo Thinkpad",
            description="Thinkpad mod_001 i3 8GB RAM GRP",
            category_id=self.category.category_uid,
            organisation_id=self.organisation_uid,
        )

        self.vendor = Vendor.objects.create(
            name="Lenovo Vendors Sample",
            address="Chennai",
            email="lenovovensam@lenovo.com",
            phone_number=8789878981,
            organisation_id=self.organisation_uid,
        )

        self.order = Order.objects.create(
            delivery_date="2022-06-03",
            vendors_id=self.vendor.vendor_uid,
            organisation_id=self.organisation_uid,
        )

        self.order_exc = Order.objects.create(
            delivery_date="2022-06-03",
            vendors_id=self.vendor.vendor_uid,
            organisation_id=self.organisation_uid,
        )

        self.order_product_exc = OrderProduct.objects.create(
            product=self.product, order=self.order_exc, quantity=10
        )

        self.order_product = OrderProduct.objects.create(
            product=self.product, order=self.order, quantity=10
        )

        self.invoice = Invoice.objects.create(
            amount=0, order=self.order, organisation_id=self.organisation_uid,
        )

        self.invoice_exc = Invoice.objects.create(
            amount=0, order=self.order_exc, organisation_id=self.organisation_uid,
        )

    def test_create_invoice(self):
        str_order = str(self.order.order_uid)
        self.invoice.is_active = False
        self.invoice.save()
        payload = {"order": str_order, "payment_deadline": "2022-06-03"}
        exception_payload = {"payment_deadline": "2022-06"}

        new_invoice = self.invoice_service.create(
            payload, str_order, self.organisation_uid
        )
        self.assertTrue(isinstance(new_invoice, Invoice))

        with self.assertRaises(CustomException):
            self.invoice_service.create(
                exception_payload, "str_order", self.organisation_uid
            )

    def test_update_invoice(self):

        updated_invoice = self.invoice_service.update_invoice(self.invoice)
        self.assertEqual(updated_invoice["message"], "Invoice Status Updated")

    def test_invoice_retrieve(self):
        str_invoice = str(self.invoice.invoice_uid)
        retrieved_invoice = self.invoice_service.retrieve(
            str_invoice, self.organisation_uid
        )
        self.assertEqual(retrieved_invoice.order, self.order)

    def test_create_payment(self):
        str_invoice = str(self.invoice.invoice_uid)
        str_invoice_exc = str(self.invoice_exc.invoice_uid)
        payload = {
            "payee_name": "Sasikumar",
            "email": "sasikumar@samsung.com",
            "phone": 8987898789,
            "payment_type": 2,
            "amount": 0,
        }

        name_exception_payload = {
            "payee_name": "1Sasikumar",
            "email": "sasikumar@samsung.com",
            "phone": 8987898789,
            "payment_type": 2,
            "amount": 0,
        }

        phone_exception_payload = {
            "payee_name": "Sasikumar",
            "email": "sasikumar@samsung.com",
            "phone": 1987898789,
            "payment_type": 2,
            "amount": 0,
        }

        payment_name_exc = self.payment_service.create(
                name_exception_payload, str_invoice_exc, self.organisation_uid
            )
        self.assertRaises(ValidationError, payment_name_exc.full_clean)

        new_payment = self.payment_service.create(
            payload, str_invoice, self.organisation_uid
        )

        self.assertEqual(new_payment.invoice.id, self.invoice.id)


class MYcompny:
    slary=5

gaurav=MYcompny()
print(gaurav.slary)
saurav=MYcompny
saurav.addras="gali dore wali "
print(saurav.slary)
print(saurav.addras)

class student:
    company = "Google"
    def getSalary(gaurb):
        print("my salary is 900000")
saurv= student()
saurav.getSalary()


import Backend
import Gui
import socket
import struct
import sys
import threading
import time

class Controller(object):

    def __init__(self, configPath):
        self.__backend = Backend.Backend(configPath)
        self.__gui = Gui.Gui(self)
        self.__gui.setStatus(Controller.ping(self.__getAddressTuple()))
        self.__gui.start()

    def toggleServerState(self, widget, data=None):
        if Controller.ping(self.__getAddressTuple()) == True:
            self.__shutdownServer()
            self.exitProgam()
        else:
            thread = self.WakeupWaitingThread(self.__gui, int(self.__backend.getRetries()), self.__getAddressTuple(), self.__backend.getMac())
            thread.start()
            #thread.join()

    def exitProgam(self):
        sys.exit(0)

    @staticmethod
    def ping(addressTuple):
        try:
            s = socket.create_connection(addressTuple, 1)
            s.close()
            available = True
        except socket.error:
            available = False
        return available

    def getFreeSpace(self):
        space = None
        try:
            s = self.__getConnection()
            s.send(str(2) + "\n")
            space = s.recv(128)
            s.close()
        except socket.error:
            space = None
        return space

    def __shutdownServer(self):
        try:
            s = self.__getConnection()
            s.send(str(1)+ "\n")
            s.close()
        except socket.error:
            pass

    def __getConnection(self):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect(self.__getAddressTuple())
        return s

    def __getAddressTuple(self):
        return self.__backend.getAddress(), int(self.__backend.getPort())

    class WakeupWaitingThread(threading.Thread):

        def __init__(self, gui, retries, addressTuple, mac):
            threading.Thread.__init__(self)
            self.__gui = gui
            self.__retries = retries
            self.__addressTuple = addressTuple
            self.__mac = mac

        def run(self):
            self.__wakeup()

        def __wakeup(self):
            available = False
            self.__gui.enableButton(False)
            self.__wakeOnLan()
            while (self.__retries > 0) and (available == False):
                available = Controller.ping(self.__addressTuple)
                self.__retries = self.__retries - 1
                self.__gui.setStatusWhileWakingUp(self.__retries)
                time.sleep(1)
            if available == False:
                self.__gui.setStatusWakeupFailed()
            else:
                self.__gui.setStatus(True)
            self.__gui.enableButton(True)

        # Wake-On-LAN
        #
        # Copyright (C) 2002 by Micro Systems Marc Balmer
        # Written by Marc Balmer, marc@msys.ch, http://www.msys.ch/
        # This code is free software under the GPL
        def __wakeOnLan(self):

            # Construct a six-byte hardware address

            addr_byte = self.__mac.split(':')
            hw_addr = struct.pack('BBBBBB',
            int(addr_byte[0], 16),
            int(addr_byte[1], 16),
            int(addr_byte[2], 16),
            int(addr_byte[3], 16),
            int(addr_byte[4], 16),
            int(addr_byte[5], 16))

            # Build the Wake-On-LAN "Magic Packet"...

            msg = '\xff' * 6 + hw_addr * 16

            # ...and send it to the broadcast address using UDP

            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
            s.sendto(msg, ('<broadcast>', 9))
            s.close()

if __name__ == "__main__":
    if len(sys.argv) < 2 or sys.argv[1].__contains__("--config=") == False:
        print("need --config=[path to config]")
    else:
        configPath = sys.argv[1].strip("--config=")
        if configPath is None or len(configPath) == 0:
            print("you need to add the configfile path")
        else:
            Controller(configPath)


'tldextract helpers for testing and fetching remote resources.'

import re
import socket

from urllib.parse import scheme_chars

IP_RE = re.compile(
    r'^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$')  # pylint: disable=line-too-long

SCHEME_RE = re.compile(r'^([' + scheme_chars + ']+:)?//')

def looks_like_ip(maybe_ip):
    """Does the given str look like an IP address?"""
    if not maybe_ip[0].isdigit():
        return False

    try:
        socket.inet_aton(maybe_ip)
        return True
    except (AttributeError, UnicodeError):
        if IP_RE.match(maybe_ip):
            return True
    except socket.error:
        return False


import cv2
import numpy as np

image = cv2.imread('testImg.png')
cv2.imshow("Original", image)

AvgBlur = cv2.blur(image, (5,5))
cv2.imshow("Averaged blur", AvgBlur)

GausBlur = cv2.GaussianBlur(image, (5,5), 0)
cv2.imshow("Gaussian Blur", GausBlur)

cv2.waitKey(0)
cv2.destroyAllWindows()


import os, sys, inspect
import numpy as np
from copy import deepcopy
from ..mfbase import MFDataException

def clean_name(name):
    # remove bad characters
    clean_string = name.replace(' ', '_')
    clean_string = clean_string.replace('-', '_')
    # remove anything after a parenthesis
    index = clean_string.find('(')
    if index != -1:
        clean_string = clean_string[0:index]

    return clean_string

def find_keyword(arr_line, keyword_dict):
    # convert to lower case
    arr_line_lower = []
    for word in arr_line:
        # integers and floats are not keywords
        if not DatumUtil.is_int(word) and not DatumUtil.is_float(word):
            arr_line_lower.append(word.lower())
    # look for constants in order of most words to least words
    key = ''
    for num_words in range(len(arr_line_lower), -1, -1):
        key = tuple(arr_line_lower[0:num_words])
        if len(key) > 0 and key in keyword_dict:
            return key
    return None

def max_tuple_abs_size(some_tuple):
    max_size = 0
    for item in some_tuple:
        item_abs = abs(item)
        if item_abs > max_size:
            max_size = item_abs
    return max_size

class TemplateGenerator(object):
    """
    Abstract base class for building a data template for different data types.
    This is a generic class that is initialized with a path that identifies
    the data to be built.

    Parameters
    ----------
    path : string
        tuple containing path of data is described in dfn files
        (<model>,<package>,<block>,<data name>)
    """
    def __init__(self, path):
        self.path = path

    def _get_data_dimensions(self, model):
        from ..data import mfstructure
        from ..coordinates import modeldimensions

        # get structure info
        sim_struct = mfstructure.MFStructure().sim_struct
        package_struct = sim_struct.get_data_structure(self.path[0:-2])

        # get dimension info
        data_struct = sim_struct.get_data_structure(self.path)
        package_dim = modeldimensions.PackageDimensions([model.dimensions],
                                                        package_struct,
                                                        self.path[0:-1])
        return data_struct, modeldimensions.DataDimensions(package_dim,
                                                           data_struct)

    def build_type_header(self, type, data=None):
        from ..data.mfdata import DataStorageType

        if type == DataStorageType.internal_array:
            if isinstance(self, ArrayTemplateGenerator):
                return {'factor':1.0, 'iprn':1, 'data':data}
            else:
                return None
        elif type == DataStorageType.internal_constant:
            return data
        elif type == DataStorageType.external_file:
            return {'filename':'', 'factor':1.0, 'iprn':1}
        return None

class ArrayTemplateGenerator(TemplateGenerator):
    """
    Class that builds a data template for MFArrays.  This is a generic class
    that is initialized with a path that identifies the data to be built.

    Parameters
    ----------
    path : string
        tuple containing path of data is described in dfn files
        (<model>,<package>,<block>,<data name>)

    Methods
    -------
    empty: (model: MFModel, layered: boolean, data_storage_type_list: boolean,
            default_value: int/float) : variable
        Builds a template for the data you need to specify for a specific data
        type (ie. "hk") in a specific model.  The data type and dimensions
        is determined by "path" during initialization of this class and the
        model is passed in to this method as the "model" parameter.  If the
        data is transient a dictionary containing a single stress period
        will be returned.  If "layered" is set to true, data will be returned
        as a list ndarrays, one for each layer.  data_storage_type_list is a
        list of DataStorageType, one type for each layer.  If "default_value"
        is specified the data template will be populated with that value,
        otherwise each ndarray in the data template will be populated with
        np.empty (0 or 0.0 if the DataStorageType is a constant).
    """
    def __init__(self, path):
        super(ArrayTemplateGenerator, self).__init__(path)

    def empty(self, model=None, layered=False, data_storage_type_list=None,
              default_value=None):
        from ..data import mfdata, mfstructure
        from ..data.mfdata import DataStorageType

        # get the expected dimensions of the data
        data_struct, data_dimensions = self._get_data_dimensions(model)
        datum_type = data_struct.get_datum_type()
        data_type = data_struct.get_datatype()
        # build a temporary data storge object
        data_storage = mfdata.DataStorage(
                model.simulation_data, data_dimensions, None,
                mfdata.DataStorageType.internal_array,
                mfdata.DataStructureType.recarray)
        dimension_list = data_storage.get_data_dimensions(None)

        # if layered data
        if layered and dimension_list[0] > 1:
            if data_storage_type_list is not None and \
                    len(data_storage_type_list) != dimension_list[0]:
                comment = 'data_storage_type_list specified with the ' \
                          'wrong size.  Size {} but expected to be ' \
                          'the same as the number of layers, ' \
                          '{}.'.format(len(data_storage_type_list),
                                       dimension_list[0])
                type_, value_, traceback_ = sys.exc_info()

                raise MFDataException(data_struct.get_model(),
                                      data_struct.get_package(),
                                      data_struct.path,
                                      'generating array template',
                                      data_struct.name,
                                      inspect.stack()[0][3],
                                      type_, value_, traceback_, comment,
                                      model.simulation_data.debug)
            # build each layer
            data_with_header = []
            for layer in range(0, dimension_list[0]):
                # determine storage type
                if data_storage_type_list is None:
                    data_storage_type = DataStorageType.internal_array
                else:
                    data_storage_type = data_storage_type_list[layer]
                # build data type header
                data_with_header.append(self._build_layer(datum_type,
                                                          data_storage_type,
                                                          default_value,
                                                          dimension_list))
        else:
            if data_storage_type_list is None or \
                    data_storage_type_list[0] == \
                            DataStorageType.internal_array:
                data_storage_type = DataStorageType.internal_array
            else:
                data_storage_type = data_storage_type_list[0]
            # build data type header
            data_with_header = self._build_layer(datum_type,
                                                 data_storage_type,
                                                 default_value,
                                                 dimension_list, True)

        # if transient/multiple list
        if data_type == mfstructure.DataType.array_transient:
            # Return as dictionary
            return {0:data_with_header}
        else:
            return data_with_header

    def _build_layer(self, data_type, data_storage_type, default_value,
                     dimension_list, all_layers=False):
        from ..data.mfdata import DataStorageType

        # build data
        if data_storage_type == DataStorageType.internal_array:
            if default_value is None:
                if all_layers:
                    data = np.empty(dimension_list, data_type)
                else:
                    data = np.empty(dimension_list[1:], data_type)
            else:
                if all_layers:
                    data = np.full(dimension_list, default_value, data_type)
                else:
                    data = np.full(dimension_list[1:], default_value,
                                   data_type)
        elif data_storage_type == DataStorageType.internal_constant:
            if default_value is None:
                if data_type == np.int:
                    data = 0
                else:
                    data = 0.0
            else:
                data = default_value
        else:
            data = None
        # build data type header
        return self.build_type_header(data_storage_type, data)

class ListTemplateGenerator(TemplateGenerator):
    """
    Class that builds a data template for MFLists.  This is a generic class
    that is initialized with a path that identifies the data to be built.

    Parameters
    ----------
    path : string
        tuple containing path of data is described in dfn files
        (<model>,<package>,<block>,<data name>)

    Methods
    -------
    empty: (maxbound: int, aux_vars: list, boundnames: boolean, nseg: int) :
            dictionary
        Builds a template for the data you need to specify for a specific data
        type (ie. "stress_period_data") in a specific model.  The data type is
        determined by "path" during initialization of this class.  If the data
        is transient a dictionary containing a single stress period will be
        returned.  The number of entries in the recarray are determined by
        the "maxbound" parameter.  The "aux_vars" parameter is a list of aux
        var names to be used in this data list.  If boundnames is set to
        true and boundname field will be included in the recarray.  nseg is
        only used on list data that contains segments.  If timeseries is true,
        a template that is compatible with time series data is returned.
    """
    def __init__(self, path):
        super(ListTemplateGenerator, self).__init__(path)

    def _build_template_data(self, type_list):
        template_data = []
        for type in type_list:
            if type[1] == int:
                template_data.append(0)
            elif type[1] == float:
                template_data.append(np.nan)
            else:
                template_data.append(None)
        return tuple(template_data)

    def empty(self, model, maxbound=None, aux_vars=None, boundnames=False,
              nseg=None, timeseries=False, stress_periods=None):
        from ..data import mfdata, mfstructure

        data_struct, data_dimensions = self._get_data_dimensions(model)
        data_type = data_struct.get_datatype()
        # build a temporary data storge object
        data_storage = mfdata.DataStorage(
                model.simulation_data, data_dimensions, None,
                mfdata.DataStorageType.internal_array,
                mfdata.DataStructureType.recarray)

        # build type list
        type_list = data_storage.build_type_list(nseg=nseg)
        if aux_vars is not None:
            if len(aux_vars) > 0 and (isinstance(aux_vars[0], list) or
                    isinstance(aux_vars[0], tuple)):
                aux_vars = aux_vars[0]
            for aux_var in aux_vars:
                type_list.append((aux_var, object))
        if boundnames:
            type_list.append(('boundnames', object))

        if timeseries:
            # fix type list to make all types objects
            for index in range(0, len(type_list)):
                type_list[index] = (type_list[index][0], object)

        # build rec array
        template_data = self._build_template_data(type_list)
        rec_array_data = []
        if maxbound is not None:
            for index in range(0, maxbound):
                rec_array_data.append(template_data)
        else:
            rec_array_data.append(template_data)
        rec_array = np.rec.array(rec_array_data, type_list)

        # if transient/multiple list
        if data_type == mfstructure.DataType.list_transient or \
                data_type == mfstructure.DataType.list_multiple:
            # Return as dictionary
            if stress_periods is None:
                return {0:rec_array}
            else:
                template = {}
                for stress_period in stress_periods:
                    template[stress_period] = deepcopy(rec_array)
                return template
        else:
            return rec_array

class DatumUtil(object):
    @ staticmethod
    def is_int(str):
        try:
            int(str)
            return True
        except TypeError:
            return False
        except ValueError:
            return False

    @ staticmethod
    def is_float(str):
        try:
            float(str)
            return True
        except TypeError:
            return False
        except ValueError:
            return False

class ArrayUtil(object):
    """
    Class contains miscellaneous methods to work with and compare arrays

    Parameters
    ----------
    path : string
        file path to read/write to
    max_error : float
        maximum acceptable error when doing a compare of floating point numbers

    Methods
    -------
    is_empty_list : (current_list : list) : boolean
        determines if an n-dimensional list is empty
    con_convert : (data : string, data_type : type that has conversion
                   operation) : boolean
        returns true if data can be converted into data_type
    max_multi_dim_list_size : (current_list : list) : boolean
        determines the max number of items in a multi-dimensional list
        'current_list'
    first_item : (current_list : list) : variable
        returns the first item in the list 'current_list'
    next_item : (current_list : list) : variable
        returns the next item in the list 'current_list'
    array_comp : (first_array : list, second_array : list) : boolean
        compares two lists, returns true if they are identical (with max_error)
    spilt_data_line : (line : string) : list
        splits a string apart (using split) and then cleans up the results
        dealing with various MODFLOW input file releated delimiters.  returns
        the delimiter type used.
    clean_numeric : (text : string) : string
        returns a cleaned up version of 'text' with only numeric characters
    save_array_diff : (first_array : list, second_array : list,
                       first_array_name : string, second_array_name : string)
        saves lists 'first_array' and 'second_array' to files first_array_name
        and second_array_name and then saves the difference of the two
        arrays to 'debug_array_diff.txt'
    save_array(filename : string, multi_array : list)
        saves 'multi_array' to the file 'filename'
    """
    numeric_chars = {'0': 0, '1': 0, '2': 0, '3': 0, '4': 0, '5': 0,
                     '6': 0, '7': 0, '8': 0, '9': 0, '.': 0, '-': 0}
    quote_list = {"'", '"'}
    delimiter_list = {',': 0, '\t': 0, ' ': 0}
    delimiter_used = None
    line_num = 0
    consistent_delim = False

    def __init__(self, path=None, max_error=0.01):
        self.max_error = max_error
        if path:
            self.path = path
        else:
            self.path = os.getcwd()

    @staticmethod
    def has_one_item(current_list):
        if not isinstance(current_list, list) and not isinstance(current_list,
                                                                 np.ndarray):
            return True
        if len(current_list) != 1:
            return False
        if (isinstance(current_list[0], list) or
                isinstance(current_list, np.ndarray)) and \
                len(current_list[0] != 0):
            return False
        return True

    @staticmethod
    def is_empty_list(current_list):
        if not isinstance(current_list, list):
            return not current_list

        for item in current_list:
            if isinstance(item, list):
                # still in a list of lists, recurse
                if not ArrayUtil.is_empty_list(item):
                    return False
            else:
                return False

        return True

    @staticmethod
    def max_multi_dim_list_size(current_list):
        max_length = -1
        for item in current_list:
            if len(item) > max_length:
                max_length = len(item)
        return max_length

    @staticmethod
    def first_item(current_list):
        if not isinstance(current_list, list):
            return current_list

        for item in current_list:
            if isinstance(item, list):
                # still in a list of lists, recurse
                return ArrayUtil.first_item(item)
            else:
                return item

    @staticmethod
    def next_item(current_list, new_list=True, nesting_change=0,
                  end_of_list=True):
        # returns the next item in a nested list along with other information:
        # (<next item>, <end of list>, <entering new list>,
        #  <change in nesting level>
        if not isinstance(current_list, list) and \
                not isinstance(current_list, np.ndarray):
            yield (current_list, end_of_list, new_list, nesting_change)
        else:
            list_size = 1
            for item in current_list:
                if isinstance(item, list) or isinstance(current_list,
                                                        np.ndarray):
                    # still in a list of lists, recurse
                    for item in ArrayUtil.next_item(item, list_size == 1,
                                                    nesting_change + 1,
                                                    list_size ==
                                                    len(current_list)):
                        yield item
                    nesting_change = -(nesting_change + 1)
                else:
                    yield (item, list_size == len(current_list),
                           list_size == 1, nesting_change)
                    nesting_change = 0
                list_size += 1

    @staticmethod
    def next_list(current_list):
        if not isinstance(current_list[0], list):
            yield current_list
        else:
            for lst in current_list:
                if isinstance(lst[0], list):
                    for lst in ArrayUtil.next_list(lst):
                        yield lst
                else:
                    yield lst

    def array_comp(self, first_array, second_array):
        diff = first_array - second_array
        max = np.max(np.abs(diff))
        if max > self.max_error:
            return False
        return True

    @staticmethod
    def reset_delimiter_used():
        ArrayUtil.delimiter_used = None
        ArrayUtil.line_num = 0
        ArrayUtil.consistent_delim = True

    @staticmethod
    def split_data_line(line, external_file=False, delimiter_conf_length=15):
        if ArrayUtil.line_num > delimiter_conf_length and \
                ArrayUtil.consistent_delim:
            # consistent delimiter has been found.  continue using that
            # delimiter without doing further checks
            if ArrayUtil.delimiter_used == None:
                clean_line = line.strip().split()
            else:
                clean_line = line.strip().split(ArrayUtil.delimiter_used)
        else:
            clean_line = line.strip().split()
            if external_file:
                # try lots of different delimitiers for external files and use the
                # one the breaks the data apart the most
                max_split_size = len(clean_line)
                max_split_type = None
                for delimiter in ArrayUtil.delimiter_list:
                    alt_split = line.strip().split(delimiter)
                    if len(alt_split) > max_split_size:
                        max_split_size = len(alt_split)
                        max_split_type = delimiter
                if max_split_type is not None:
                    clean_line = line.strip().split(max_split_type)
                    if ArrayUtil.line_num == 0:
                        ArrayUtil.delimiter_used = max_split_type
                    elif ArrayUtil.delimiter_used != max_split_type:
                        ArrayUtil.consistent_delim = False
        ArrayUtil.line_num += 1

        arr_fixed_line = []
        index = 0
        # loop through line to fix quotes and delimiters
        while index < len(clean_line):
            item = clean_line[index]
            if item and item not in ArrayUtil.delimiter_list:
                if item and item[0] in ArrayUtil.quote_list:
                    # starts with a quote, handle quoted text
                    if item[-1] in ArrayUtil.quote_list:
                        arr_fixed_line.append(item[1:-1])
                    else:
                        arr_fixed_line.append(item[1:])
                        # loop until trailing quote found
                        while index < len(clean_line):
                            index += 1
                            if index < len(clean_line):
                                item = clean_line[index]
                                if item[-1] in ArrayUtil.quote_list:
                                    arr_fixed_line[-1] = \
                                        '{} {}'.format(arr_fixed_line[-1],
                                                       item[:-1])
                                    break
                                else:
                                    arr_fixed_line[-1] = \
                                        '{} {}'.format(arr_fixed_line[-1],
                                                       item)
                else:
                    # no quote, just append
                    arr_fixed_line.append(item)
            index += 1

        return arr_fixed_line

    @staticmethod
    def clean_numeric(text):
        if isinstance(text, str):
            # remove all non-numeric text from leading and trailing positions
            # of text
            if text:
                while text and (text[0] not in ArrayUtil.numeric_chars or text[-1]
                                not in ArrayUtil.numeric_chars):
                    if text[0] not in ArrayUtil.numeric_chars:
                        text = text[1:]
                    if text and text[-1] not in ArrayUtil.numeric_chars:
                        text = text[:-1]
        return text

    def save_array_diff(self, first_array, second_array, first_array_name,
                        second_array_name):
        try:
            diff = first_array - second_array
            self.save_array(first_array_name, first_array)
            self.save_array(second_array_name, second_array)
            self.save_array('debug_array_diff.txt', diff)
        except:
            print("An error occurred while outputting array differences.")
            return False
        return True

    # Saves an array with up to three dimensions
    def save_array(self, filename, multi_array):
        file_path = os.path.join(self.path, filename)
        with open(file_path, 'w') as outfile:
            outfile.write('{}\n'.format(str(multi_array.shape)))
            if len(multi_array.shape) == 4:
                for slice in multi_array:
                    for second_slice in slice:
                        for third_slice in second_slice:
                            for item in third_slice:
                                outfile.write(' {:10.3e}'.format(item))
                            outfile.write('\n')
                        outfile.write('\n')
                    outfile.write('\n')
            elif len(multi_array.shape) == 3:
                for slice in multi_array:
                    np.savetxt(outfile, slice, fmt='%10.3e')
                    outfile.write('\n')
            else:
                np.savetxt(outfile, multi_array, fmt='%10.3e')

class MultiList():
    """
    Class for storing objects in an n-dimensional list which can be iterated
    through as a single list.

    Parameters
    ----------
    mdlist : list
        multi-dimensional list to initialize the multi-list.  either mdlist
        or both shape and callback must be specified
    shape : tuple
        shape of the multi-list
    callback : method
        callback method that takes a location in the multi-list (tuple) and
        returns an object to be stored at that location in the multi-list

    Methods
    -------
    increment_dimension : (dimension, callback)
        increments the size of one of the two dimensions of the multi-list
    build_list : (callback)
        builds a multi-list of shape self.list_shape, constructing objects
        for the list using the supplied callback method
    first_item : () : object
        gets the first entry in the multi-list
    get_total_size : () : int
        returns the total number of entries in the multi-list
    in_shape : (indexes) : boolean
        returns whether a tuple of indexes are valid indexes for the shape of
        the multi-list
    inc_shape_idx : (indexes) : tuple
        given a tuple of indexes pointing to an entry in the multi-list,
        returns a tuple of indexes pointing to the next entry in the multi-list
    first_index : () : tuple
        returns a tuple of indexes pointing to the first entry in the
        multi-list
    indexes : (start_indexes=None, end_indexes=None) : iter(tuple)
        returns an iterator that iterates from the location in the
        multi-list defined by start_indexes to the location in the
        multi-list defined by end_indexes
    elements : () : iter(object)
        returns an iterator that iterates over each object stored in the
        multi-list
    """
    def __init__(self, mdlist=None, shape=None, callback=None):
        if mdlist is not None:
            self.multi_dim_list = mdlist
            self.list_shape = MultiList._calc_shape(mdlist)
        elif shape is not None:
            self.list_shape = shape
            self.multi_dim_list = []
            if callback is not None:
                self.build_list(callback)
        else:
            raise Exception('MultiList requires either a mdlist or a shape '
                            'at initialization.')

    def __getitem__(self, k):
        if isinstance(k, list) or isinstance(k, tuple):
            item_ptr = self.multi_dim_list
            for index in k:
                item_ptr = item_ptr[index]
            return item_ptr
        else:
            return self.multi_dim_list[k]

    @staticmethod
    def _calc_shape(current_list):
        shape = []
        if isinstance(current_list, list):
            shape.append(len(current_list))
            sub_list = current_list[0]
            if isinstance(sub_list, list):
                shape += MultiList._calc_shape(sub_list)
        elif isinstance(current_list, np.ndarray):
            shape.append(current_list.shape[0])
        else:
            return 1
        return tuple(shape)

    def increment_dimension(self, dimension, callback):
        # ONLY SUPPORTS 1 OR 2 DIMENSIONAL MULTI-LISTS
        # TODO: REWRITE TO SUPPORT N-DIMENSIONAL MULTI-LISTS
        if len(self.list_shape) > 2:
            raise Exception('Increment_dimension currently only supports 1 '
                            'or 2 dimensional multi-lists')
        if len(self.list_shape) == 1:
            self.multi_dim_list.append(callback(len(self.list_shape)))
            self.list_shape = (self.list_shape[0] + 1,)
        else:
            if dimension == 1:
                new_row_idx = len(self.multi_dim_list)
                self.multi_dim_list.append([])
                for index in range(0, self.list_shape[1]):
                    self.multi_dim_list[-1].append(callback((new_row_idx,
                                                             index)))
                self.list_shape = (self.list_shape[0] + 1, self.list_shape[1])
            elif dimension == 2:
                new_col_idx = len(self.multi_dim_list[0])
                for index in range(0, self.list_shape[0]):
                    self.multi_dim_list[index].append(callback((index,
                                                                new_col_idx)))
                self.list_shape = (self.list_shape[0], self.list_shape[1] + 1)
            else:
                raise Exception('For two dimensional lists "dimension" must '
                                'be 1 or 2.')

    def build_list(self, callback):
        entry_points = [(self.multi_dim_list, self.first_index())]
        shape_len = len(self.list_shape)
        # loop through each dimension
        for index, shape_size in enumerate(self.list_shape):
            new_entry_points = []
            # loop through locations to add to the list
            for entry_point in entry_points:
                # loop through the size of current dimension
                for val in range(0, shape_size):
                    if index < (shape_len - 1):
                        # this is a multi-dimensional multi-list, build out
                        # first dimension
                        entry_point[0].append([])
                        if entry_point[1] is None:
                            new_location = (len(entry_point) - 1,)
                        else:
                            new_location = ((len(entry_point[0]) - 1), val)
                        new_entry_points.append((entry_point[0][-1],
                                                 new_location))
                    else:
                        entry_point[0].append(callback(entry_point[1]))
            entry_points = new_entry_points

    def first_item(self):
        return ArrayUtil.first_item(self.multi_dim_list)

    def get_total_size(self):
        shape_size = 1
        for item in self.list_shape:
            if item is None:
                return 0
            else:
                shape_size *= item
        return shape_size

    def in_shape(self, indexes):
        for index, item in zip(indexes, self.list_shape):
            if index > item:
                return False
        return True

    def inc_shape_idx(self, indexes):
        new_indexes = []
        incremented = False
        for index, item in zip(indexes, self.list_shape):
            if index == item:
                new_indexes.append(0)
            elif incremented:
                new_indexes.append(index)
            else:
                incremented = True
                new_indexes.append(index+1)
        if not incremented:
            new_indexes[-1] += 1
        return tuple(new_indexes)

    def first_index(self):
        first_index = []
        for index in self.list_shape:
            first_index.append(0)
        return tuple(first_index)

    def nth_index(self, n):
        index = None
        aii = ArrayIndexIter(self.list_shape, True)
        index_num = 0
        while index_num <= n:
            index = aii.next()
            index_num += 1
        return index

    def indexes(self, start_indexes=None, end_indexes=None):
        aii = ArrayIndexIter(self.list_shape, True)
        if start_indexes is not None:
            aii.current_location = list(start_indexes)
            aii.current_index = len(aii.current_location) - 1
        if end_indexes is not None:
            aii.end_location = list(end_indexes)
        return aii

    def elements(self):
        return MultiListIter(self.multi_dim_list, False)

class ArrayIndexIter(object):
    def __init__(self, array_shape, index_as_tuple=False):
        self.array_shape = array_shape
        self.current_location = []
        self.end_location = []
        self.first_item = True
        self.index_as_tuple = index_as_tuple
        for item in array_shape:
            self.current_location.append(0)
            self.end_location.append(item)
        self.current_index = len(self.current_location) - 1

    def __iter__(self):
        return self

    def __next__(self):
        if self.first_item:
            self.first_item = False
            if self.current_location[self.current_index] < \
                    self.end_location[self.current_index]:
                if len(self.current_location) > 1 or self.index_as_tuple:
                    return tuple(self.current_location)
                else:
                    return self.current_location[0]
        while self.current_index >= 0:
            location = self.current_location[self.current_index]
            if location < self.end_location[self.current_index] - 1:
                self.current_location[self.current_index] += 1
                self.current_index = len(self.current_location) - 1
                if len(self.current_location) > 1 or self.index_as_tuple:
                    return tuple(self.current_location)
                else:
                    return self.current_location[0]
            else:
                self.current_location[self.current_index] = 0
                self.current_index -= 1
        raise StopIteration()

    next = __next__  # Python 2 support

class MultiListIter(object):
    def __init__(self, multi_list, detailed_info=False, iter_leaf_lists=False):
        self.multi_list = multi_list
        self.detailed_info = detailed_info
        if iter_leaf_lists:
            self.val_iter = ArrayUtil.next_list(self.multi_list)
        else:
            self.val_iter = ArrayUtil.next_item(self.multi_list)

    def __iter__(self):
        return self

    def __next__(self):
        next_val = next(self.val_iter)
        if self.detailed_info:
            return next_val
        else:
            return next_val[0]

    next = __next__  # Python 2 support

class ConstIter(object):
    def __init__(self, value):
        self.value = value

    def __iter__(self):
        return self

    def __next__(self):
        return self.value

    next = __next__  # Python 2 support

class FileIter(object):
    def __init__(self, file_path):
        self.eof = False
        try:
            self._fd = open(file_path, 'r')
        except:
            self.eof = True
        self._current_data = None
        self._data_index = 0
        self._next_line()

    def __iter__(self):
        return self

    def __next__(self):
        if self.eof:
            raise StopIteration()
        else:
            while self._current_data is not None and \
                  self._data_index >= len(self._current_data):
                self._next_line()
                self._data_index = 0
                if self.eof:
                    raise StopIteration()
            self._data_index += 1
            return self._current_data[self._data_index-1]

    def close(self):
        self._fd.close()

    def _next_line(self):
        if self.eof:
            return
        data_line = self._fd.readline()
        if data_line is None:
            self.eof = True
            return
        self._current_data = ArrayUtil.split_data_line(data_line)

    next = __next__  # Python 2 support

class NameIter(object):
    def __init__(self, name, first_not_numbered=True):
        self.name = name
        self.iter_num = -1
        self.first_not_numbered = first_not_numbered

    def __iter__(self):
        return self

    def __next__(self):
        self.iter_num += 1
        if self.iter_num == 0 and self.first_not_numbered:
            return self.name
        else:
            return '{}_{}'.format(self.name, self.iter_num)

    next = __next__  # Python 2 support

class PathIter(object):
    def __init__(self, path, first_not_numbered=True):
        self.path = path
        self.name_iter = NameIter(path[-1], first_not_numbered)

    def __iter__(self):
        return self

    def __next__(self):
        return self.path[0:-1] + (self.name_iter.__next__(),)

    next = __next__  # Python 2 support

class MFDocString(object):
    """
    Helps build a python class doc string

    Parameters
    ----------
    description : string
        description of the class

    Attributes
    ----------
    indent: string
        indent to use in doc string
    description : string
        description of the class
    parameter_header : string
        header for parameter section of doc string
    parameters : list
        list of docstrings for class parameters

    Methods
    -------
    add_parameter : (param_descr : string, beginning_of_list : bool)
        adds doc string for a parameter with description 'param_descr' to the
        end of the list unless beginning_of_list is True
    get_doc_string : () : string
        builds and returns the docstring for the class
    """
    def __init__(self, description):
        self.indent = '    '
        self.description = description
        self.parameter_header = '{}Parameters\n{}' \
                                '----------'.format(self.indent, self.indent)
        self.parameters = []
        self.model_parameters = []

    def add_parameter(self, param_descr, beginning_of_list=False,
                      model_parameter=False):
        if beginning_of_list:
            self.parameters.insert(0, param_descr)
            if model_parameter:
                self.model_parameters.insert(0, param_descr)
        else:
            self.parameters.append(param_descr)
            if model_parameter:
                self.model_parameters.append(param_descr)

    def get_doc_string(self, model_doc_string=False):
        doc_string = '{}"""\n{}{}\n\n{}\n'.format(self.indent, self.indent,
                                                  self.description,
                                                  self.parameter_header)
        if model_doc_string:
            param_list = self.model_parameters
            doc_string = '{}    modelname : string\n        name of the ' \
                         'model\n    model_nam_file : string\n' \
                         '        relative path to the model name file from ' \
                         'model working folder\n    version : string\n' \
                         '        version of modflow\n    exe_name : string\n'\
                         '        model executable name\n' \
                         '    model_ws : string\n' \
                         '        model working folder path' \
                         '\n'.format(doc_string)
        else:
            param_list = self.parameters
        for parameter in param_list:
            doc_string += '{}\n'.format(parameter)
        if not model_doc_string:
            doc_string += '\n{}"""'.format(self.indent)
        return doc_string


import os
import glob
import numpy as np
from skimage import io
from sklearn.utils import Bunch
from skimage.feature import hog

W = 75
H = 100
COLOR_BYTE = 3
CATEGORY_NUM = 3

def load_handimage(path):
    files = glob.glob(os.path.join(path, '*/*.jpg'))

    hogs = np.ndarray((len(files), 39600), dtype = float)

    images = np.ndarray((len(files), H, W, COLOR_BYTE), dtype = np.uint8)
    labels = np.ndarray(len(files), dtype = int)

    for idx, file in enumerate(files):
        #image = io.imread(file)
        image = io.imread(file, as_gray=True)
        h = hog(image, orientations=9, pixels_per_cell=(5,5), cells_per_block=(5,5))
        #images[idx] = image
        hogs[idx] = h

        label = os.path.split(os.path.dirname(file))[-1]
        labels[idx] = label

    #flat_data = images.reshape((-1, IMAGE_SIZE * IMAGE_SIZE * COLOR_BYTE))
    #images= flat_data.view()
    return Bunch(data = hogs,
                     target = labels.astype(int),
                     target_names = np.arange(3),
                     #image =images,
                     DESCR = None)

from sklearn import svm, tree, ensemble,  metrics

train = load_handimage('C:\\Users\\wkn_4\\Pictures\\Rock-Paper-Scissors\\tot_train')
test = load_handimage('C:\\Users\\wkn_4\\Pictures\\Rock-Paper-Scissors\\tot_test')

clf = svm.LinearSVC()

clf.fit(train.data, train.target)

predicted = clf.predict(test.data)
print("准确率:{}".format(metrics.accuracy_score(test.target, predicted)))


import hashlib

def md5sum_file(path):
    '''
    Generating md5 for a file
    '''
    md5 = hashlib.md5()
    with open(path,'rb') as f:
        for chunk in iter(lambda: f.read(128*md5.block_size), b''):
            md5.update(chunk)
    return md5.hexdigest()

def md5sum_str(str):
    '''
    Generating md5sum for a string
    '''
    md5 = hashlib.md5()
    md5.update(str.encode("utf-8"))
    return md5.hexdigest()


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

# In[6]:

from tkinter import*

# In[7]:

root = Tk()
root.geometry('500x500')
root.title("Registration Form")

# In[8]:

label_0 = Label(root, text="Registration form",width=20,font=("bold", 20))
label_0.place(x=90,y=53)
label_1 = Label(root, text="FullName",width=20,font=("bold", 10))
label_1.place(x=80,y=130)
entry_1 = Entry(root)
entry_1.place(x=240,y=130)
label_2 = Label(root, text="Email",width=20,font=("bold", 10))
label_2.place(x=68,y=180)
entry_2 = Entry(root)
entry_2.place(x=240,y=180)
label_3 = Label(root, text="Phone",width=20,font=("bold", 10))
label_3.place(x=70,y=230)
entry_3 = Entry(root)
entry_3.place(x=240,y=230)
label_4 = Label(root, text="Description",width=20,font=("bold", 10))
label_4.place(x=70,y=280)
entry_4 = Entry(root)
entry_4.place(x=240,y=280)

# In[9]:

Button(root, text='Submit',width=20,bg='brown',fg='white').place(x=180,y=380)
root.mainloop()

# In[ ]:


from typing import List, Type, Union

from rsocket.extensions.authentication_content import AuthenticationContent
from rsocket.extensions.composite_metadata_item import CompositeMetadataItem
from rsocket.extensions.mimetypes import WellKnownMimeTypes, ensure_encoding_name
from rsocket.extensions.routing import RoutingMetadata
from rsocket.extensions.stream_data_mimetype import StreamDataMimetype
from rsocket.extensions.stream_data_mimetype import StreamDataMimetypes
from rsocket.frame_helpers import (pack_24bit_length, unpack_24bit)
from rsocket.helpers import parse_well_known_encoding, serialize_well_known_encoding

_default = object()

def default_or_value(value, default=None):
    if value is _default:
        return default
    return value

def metadata_item_factory(metadata_encoding: bytes) -> Type[CompositeMetadataItem]:
    metadata_item_factory_by_type = {
        WellKnownMimeTypes.MESSAGE_RSOCKET_ROUTING.value.name: RoutingMetadata,
        WellKnownMimeTypes.MESSAGE_RSOCKET_MIMETYPE.value.name: StreamDataMimetype,
        WellKnownMimeTypes.MESSAGE_RSOCKET_ACCEPT_MIMETYPES.value.name: StreamDataMimetypes,
        WellKnownMimeTypes.MESSAGE_RSOCKET_AUTHENTICATION.value.name: AuthenticationContent
    }

    return metadata_item_factory_by_type.get(metadata_encoding, CompositeMetadataItem)

class CompositeMetadata:
    __slots__ = 'items'

    def __init__(self, items: List[CompositeMetadataItem] = _default):

        self.items: List[CompositeMetadataItem] = default_or_value(items, [])

    def append(self, item: CompositeMetadataItem) -> 'CompositeMetadata':
        self.items.append(item)
        return self

    def find_by_mimetype(self, mimetype: Union[WellKnownMimeTypes, str, bytes]) -> List[CompositeMetadataItem]:
        mimetype_name = ensure_encoding_name(mimetype)
        return [item for item in self.items if ensure_encoding_name(item.encoding) == mimetype_name]

    def extend(self, *items: CompositeMetadataItem) -> 'CompositeMetadata':
        self.items.extend(items)
        return self

    def parse(self, metadata: bytes) -> 'CompositeMetadata':
        composite_length = len(metadata)
        offset = 0

        while offset < composite_length:
            metadata_encoding, relative_offset = parse_well_known_encoding(metadata[offset:],
                                                                           WellKnownMimeTypes.require_by_id)
            offset += relative_offset

            length = unpack_24bit(metadata, offset)
            offset += 3

            item = metadata_item_factory(metadata_encoding)()
            item.encoding = metadata_encoding

            item_metadata = metadata[offset:offset + length]
            metadata_length = len(item_metadata)
            item.parse(item_metadata)

            self.append(item)
            offset += metadata_length

        return self

    def serialize(self) -> bytes:
        serialized = b''

        for item in self.items:
            metadata_header = serialize_well_known_encoding(item.encoding, WellKnownMimeTypes.get_by_name)
            item_metadata = item.serialize()

            item_serialized = b''
            item_serialized += metadata_header
            item_serialized += pack_24bit_length(item_metadata)
            item_serialized += item_metadata

            serialized += item_serialized

        return serialized


class Color(str):

    """
    This object represents a color. This object is immutable.

    The initial argument can be either a color string as defined in the UFO
    specification or a sequence of (red, green, blue, alpha) components.

    By calling str(colorObject) you will get a UFO compatible color string.
    You can also iterate over the object to create a sequence::

        colorTuple = tuple(colorObject)
    """

    def __new__(self, value):
        # convert from string
        if isinstance(value, str):
            value = _stringToSequence(value)
        r, g, b, a = value
        # validate the values
        color = (("r", r), ("g", g), ("b", b), ("a", a))
        for component, v in color:
            if v < 0 or v > 1:
                raise ValueError("The color for %s (%s) is not between 0 and 1." % (component, str(v)))
        # convert back to a normalized string
        r = _stringify(r)
        g = _stringify(g)
        b = _stringify(b)
        a = _stringify(a)
        s = ",".join((r, g, b, a))
        # call the super
        return super(Color, self).__new__(Color, s)

    def __iter__(self):
        value = _stringToSequence(self)
        return iter(value)

    def _get_r(self):
        return _stringToSequence(self)[0]

    r = property(_get_r, "The red component.")

    def _get_g(self):
        return _stringToSequence(self)[1]

    g = property(_get_g, "The green component.")

    def _get_b(self):
        return _stringToSequence(self)[2]

    b = property(_get_b, "The blue component.")

    def _get_a(self):
        return _stringToSequence(self)[3]

    a = property(_get_a, "The alpha component.")

def _stringToSequence(value):
    r, g, b, a = [i.strip() for i in value.split(",")]
    value = []
    for component in (r, g, b, a):
        try:
            v = int(component)
            value.append(v)
            continue
        except ValueError:
            pass
        v = float(component)
        value.append(v)
    return value

def _stringify(v):
    """
    >>> _stringify(1)
    '1'
    >>> _stringify(.1)
    '0.1'
    >>> _stringify(.01)
    '0.01'
    >>> _stringify(.001)
    '0.001'
    >>> _stringify(.0001)
    '0.0001'
    >>> _stringify(.00001)
    '0.00001'
    >>> _stringify(.000001)
    '0'
    >>> _stringify(.000005)
    '0.00001'
    """
    # it's an int
    i = int(v)
    if v == i:
        return str(i)
    # it's a float
    else:
        # find the shortest possible float
        for i in range(1, 6):
            s = "%%.%df" % i
            s = s % v
            if float(s) == v:
                break
        # see if the result can be converted to an int
        f = float(s)
        i = int(f)
        if f == i:
            return str(i)
        # otherwise return the float
        return s

if __name__ == "__main__":
    import doctest
    doctest.testmod()


# -*- coding: utf-8 -*-
"""
Created on Fri Nov 27 19:26:17 2020

@author: Ankit Parashar
"""
#! largestPalindProduct.py

def largestPalindProduct():
    largest = 0
    # i = 999
    # j = 999
    # while i >= 100:
    #     while j >= 100:
    #         product = i * j
    #         if ((isPalindromeNumber(product)) & (product > largest)):
    #             largest = product
    #             if largest != 0:
    #                 break
    #         j = j - 1
    #     i = i - 1

    for i in range(100, 1000):
        for j in range(100, 1000):
            product = i * j
            if ((isPalindromeNumber(product)) & (product > largest)):
                largest = product
    return largest

def isPalindromeNumber(n):
    strNumber = str(n)
    numFirstPart = ""
    size = len(strNumber)
    if size > 2:
        if size % 2 == 0:
            mid = int((size / 2) - 1)
        else:
            if size == 3:
                if strNumber[0] == strNumber[-1]:
                    return True
            mid = int((size // 2) - 1)
        k = mid
        while k >= 0:
            numFirstPart = numFirstPart + strNumber[k]
            k = k - 1
        if size % 2 == 0:
            if numFirstPart == strNumber[mid+1:]:
                return True
        else:
            if numFirstPart == strNumber[mid+2:]:
                return True
    else:
        return True
    return False

print(largestPalindProduct())


import pyaudio

# 創建PyAudio對象
p = pyaudio.PyAudio()

# 獲取可用的音頻設備數據
info = p.get_host_api_info_by_index(0)
numdevices = info.get('deviceCount')

# 列出可用的麥克風設備
for i in range(0, numdevices):
    if (p.get_device_info_by_host_api_device_index(0, i).get('maxInputChannels')) > 0:
        print("麥克風ID {0}: {1}".format(i, p.get_device_info_by_host_api_device_index(0, i).get('name')))

# 關閉PyAudio對象
p.terminate()


"""bottlecaps URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/3.1/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from rest_framework.authtoken.views import obtain_auth_token

from bottlecaps import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/', obtain_auth_token, name='login'),
    path('signup/', views.CreateUserView.as_view(), name='sign_up'),
    path('categories/', views.CategoryList.as_view(), name='categories'),
    path('titles/', views.TitleList.as_view(), name='titles'),
    path('titles-filter/', views.TitleFilteredList.as_view(), name='titles_filter'),
    path('title/<int:key>/', views.TitleView.as_view(), name='title'),
    path('reviews/', views.ReviewList.as_view(), name='reviews'),
    path('review/<int:key>/', views.ReviewView.as_view(), name='review'),
]


from aiogram import types
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.builtin import CommandStart
from keyboards.default.button import but, but2
from loader import dp, bot
from states.holat import Murojaatlar

@dp.message_handler(CommandStart())
async def bot_start(message: types.Message):
    await message.answer(f"Salom, {message.from_user.full_name}! \n \nUshbu bot orqali siz Oliy ta'lim, fan va innovatsiyalar vazirligi farg‘ona viloyati boshqarmasi uchun ariza yoki shikoyatingizni kiritishingiz mumkin.", reply_markup=but)

@dp.message_handler(text="Ariza kiritish ✍")
async def bot_start(message: types.Message):
    await message.answer(text="Ismingizni kiriting:")
    await Murojaatlar.ism_uchun.set()

@dp.message_handler(state=Murojaatlar.ism_uchun)
async def bot_start(message: types.Message, state=FSMContext):
    ismi = message.text
    await state.update_data({"ism":ismi})
    await message.answer(text="Familyangizni kiriting:")
    await Murojaatlar.fam_uchun.set()

@dp.message_handler(state=Murojaatlar.fam_uchun)
async def bot_start(message: types.Message, state=FSMContext):
    fami = message.text
    await state.update_data({"fam":fami})
    await message.answer(text="Yoshingizni kiriting:")
    await Murojaatlar.yosh_uchun.set()

@dp.message_handler(state=Murojaatlar.yosh_uchun)
async def bot_start(message: types.Message, state=FSMContext):
    yoshi = message.text
    await state.update_data({"yosh":yoshi})
    await message.answer(text="Telefon raqamingizni kiriting:")
    await Murojaatlar.tel_uchun.set()

@dp.message_handler(state=Murojaatlar.tel_uchun)
async def bot_start(message: types.Message, state=FSMContext):
    teli = message.text
    await state.update_data({"tel":teli})
    await message.answer(text="Manzilingizni kiriting:")
    await Murojaatlar.manzil_uchun.set()

@dp.message_handler(state=Murojaatlar.manzil_uchun)
async def bot_start(message: types.Message, state=FSMContext):
    manzili = message.text
    await state.update_data({"manzil":manzili})
    await message.answer(text="Murojaatingiz mazmunini kiriting:")
    await Murojaatlar.murojaat_uchun.set()

@dp.message_handler(state=Murojaatlar.murojaat_uchun)
async def bot_echo(message: types.Message, state=FSMContext):
    murojaati = message.text
    await state.update_data({"murojaat":murojaati})

    info = await state.get_data()

    name = info.get("ism")
    last_name = info.get("fam")
    old = info.get("yosh")
    phone = info.get("tel")
    locat = info.get("manzil")
    text = info.get("murojaat")

    send = f"Ismingiz: {name}; \n" \
           f"Familyangiz: {last_name}; \n" \
           f"Yoshingiz: {old}; \n" \
           f"Telefon raqamingiz: {phone}; \n" \
           f"Manzilingiz: {locat}; \n" \
           f"Murojaatingiz mazmuni: {text}; \n"

    user_id = message.from_user.id
    await bot.send_message(chat_id=user_id, text=send, reply_markup=but2)
    await Murojaatlar.tasdqilash.set()

@dp.message_handler(state=Murojaatlar.tasdqilash, text="Tasdiqlash 👌")
async def bot_echo(message: types.Message, state=FSMContext):

    info = await state.get_data()

    name = info.get("ism")
    last_name = info.get("fam")
    old = info.get("yosh")
    phone = info.get("tel")
    locat = info.get("manzil")
    text = info.get("murojaat")

    send = f"Ismingiz: {name}; \n" \
           f"Familyangiz: {last_name}; \n" \
           f"Yoshingiz: {old}; \n" \
           f"Telefon raqamingiz: {phone}; \n" \
           f"Manzilingiz: {locat}; \n" \
           f"Murojaatingiz mazmuni: {text}; \n"

    user_id = message.from_user.id
    await bot.send_message(chat_id='@jghyrt', text=send)
    await bot.send_message(chat_id=user_id, text="Ariza yuborildi")
    await state.finish()


# 풀이 1
# import sys
# from collections import deque

# input = sys.stdin.readline
# n = int(input())
# matrix = [list(map(int, input().split())) for _ in range(n)]
# max_mark = 0
# for i in range(n):
#     for j in range(n):
#         max_mark = max(matrix[i][j], max_mark)

# deq6 = deque([])
# visited6 = [[0] * n for _ in range(n)]

# dy = (-1, 0, 0, 1)
# dx = (0, -1, 1, 0)
# def bfs(start_row, start_col, mark, deq, visited):
#     deq.append([start_row, start_col])
#     visited[start_row][start_col] = 1

#     while deq:
#         y, x = deq.popleft()
#         for i in range(4):
#             ny = y + dy[i]
#             nx = x + dx[i]
#             if ny < 0 or nx < 0 or ny >= n or nx >= n:
#                 continue
#             if matrix[ny][nx] <= mark or visited[ny][nx]:
#                 continue
#             deq.append([ny, nx])
#             visited[ny][nx] = 1

# result = 0
# for mark in range(0, max_mark + 1):
#     deq = deque([])
#     visited = [[0] * n for _ in range(n)]
#     count = 0
#     for i in range(n):
#         for j in range(n):
#             if matrix[i][j] > mark and not visited[i][j]:
#                 count += 1
#                 bfs(i, j, mark, deq, visited)
#     result = max(result, count)
# print(result)

# 풀이 2
from collections import deque

n = int(input())
graph = []
maxNum = 0

for i in range(n):
    graph.append(list(map(int, input().split())))
    for j in range(n):
        if graph[i][j] > maxNum:
            maxNum = graph[i][j]

dx = [0 ,0, 1, -1]
dy = [1, -1, 0 ,0]
def bfs(a, b, value, visited):
    q = deque()
    q.append((a, b))
    visited[a][b] = 1

    while q:
        x, y = q.popleft()

        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            if 0 <= nx < n and 0 <= ny < n:
                if graph[nx][ny] > value and visited[nx][ny] == 0:
                    visited[nx][ny] = 1
                    q.append((nx, ny))

result = 0
for i in range(maxNum):
    visited = [[0] * n for i in range(n)]
    cnt = 0
    for j in range(n):
        for k in range(n):
            if graph[j][k] > i and visited[j][k] == 0:
                bfs(j, k, i, visited)
                cnt += 1
    if result < cnt:
        result = cnt

print(result)


global favorite3
global e1
global e2
global e3
global e4
global e5
global e6
global episode_totals

episode_totals = []

favorite3 = []

def pick_3():
    global favorite3
    global e1
    global e2
    global e3
    global e4
    global e5
    global e6
    global episode_totals
    print("to select a character, input the number of that character on the list")
    print("pick your 3 favroite characters")

    selection = int(input("enter your FAVORITE The Office! character -> "))
    favorite3.append(selection)

    selection = int(input("enter your SECOND FAVORITE The Office! character -> "))
    favorite3.append(selection)

    selection = int(input("enter your THIRD FAVORITE The Office! character -> "))
    favorite3.append(selection)

def character_select():
    print("[1] Michael Scott")
    print("[2] Pam Beesly")
    print("[3] Jim Halpert")
    print("[4] Dwight Schrute")
    print("[5] Ryan Howard")
    print("[6] Phyllis vance")
    print("[7] Angela Martin")
    print("[8] Kevin Malone")
    print("[9] Toby Flenderson")
    print("[10] Meredith Palmer")
    print("[11] Stanley Hudson")
    print("[12] Oscar Martinez")
    print("[13] Creed Bratton")
    print("[14] Darryl Phlibin")
    print("[15] Roy Anderson")

def episodes():
    global favorite3
    global e1
    global e2
    global e3
    global e4
    global e5
    global e6
    global episode_totals

    e1 = [8, 6, 10, 6, 4, 2, 1, 1, 0, 2, 4, 3, 0, 0, 3]
    e2 = [9, 4, 6, 7, 3, 1, 2, 3, 2, 1, 5, 4, 0, 0, 0]
    e3 = [9, 6, 9, 9, 0, 0, 2, 4, 0, 0, 2, 1, 0, 0, 0]
    e4 = [10, 8, 9, 8, 1, 5, 6, 1, 3, 4, 4, 7, 0, 0, 0]
    e5 = [9, 8, 8, 8, 5, 3, 0, 4, 0, 0, 0, 4, 0, 6, 7]
    e6 = [10, 7, 8, 8, 3, 0, 3, 0, 2, 0, 4, 0, 0, 0, 5]

def point_assignment():

    global favorite3
    global e1
    global e2
    global e3
    global e4
    global e5
    global e6
    global episode_totals

    firstpick = favorite3[0]
    secondpick = favorite3[1]
    thirdpick = favorite3[2]

    a = firstpick - 1
    b = secondpick - 1
    c = thirdpick - 1

    e1[a] = e1[a] * 4
    e1[b] = e1[b] * 3
    e1[c] = e1[c] * 2

    e2[a] = e2[a] * 4
    e2[b] = e2[b] * 3
    e2[c] = e2[c] * 2

    e3[a] = e3[a] * 4
    e3[b] = e3[b] * 3
    e3[c] = e3[c] * 2

    e4[a] = e4[a] * 4
    e4[b] = e4[b] * 3
    e4[c] = e4[c] * 2

    e5[a] = e5[a] * 4
    e5[b] = e5[b] * 3
    e5[c] = e5[c] * 2

    e6[a] = e6[a] * 4
    e6[b] = e6[b] * 3
    e6[c] = e6[c] * 2

def episode_ranks():

    global favorite3
    global e1
    global e2
    global e3
    global e4
    global e5
    global e6
    global episode_totals

    e1sum = sum(e1)
    e2sum = sum(e2)
    e3sum = sum(e3)
    e4sum = sum(e4)
    e5sum = sum(e5)
    e6sum = sum(e6)

    episode_totals.append(e1sum)
    episode_totals.append(e2sum)
    episode_totals.append(e3sum)
    episode_totals.append(e4sum)
    episode_totals.append(e5sum)
    episode_totals.append(e6sum)

    winner = max(episode_totals)
    first = episode_totals.index(winner)
    episode_totals[first] = 0
    print("Best episode:", (first + 1))

    winner = max(episode_totals)
    second = episode_totals.index(winner)
    episode_totals[second] = 0
    print("Second best episode:", second + 1)

    winner = max(episode_totals)
    third = episode_totals.index(winner)
    episode_totals[third] = 0
    print("Third best episode:", (third + 1))

    winner = max(episode_totals)
    fourth = episode_totals.index(winner)
    episode_totals[fourth] = 0
    print("Fourth best episode:", (fourth + 1))

    winner = max(episode_totals)
    fifth = episode_totals.index(winner)
    episode_totals[fifth] = 0
    print("Fifth best episode:", (fifth + 1))

    winner = max(episode_totals)
    last = episode_totals.index(winner)
    episode_totals[last] = 0
    print("Worst episode:", (last + 1))

def main():
    character_select()
    pick_3()
    episodes()
    point_assignment()
    print(e1)
    print(e2)
    print(e3)
    print(e4)
    print(e5)
    print(e6)
    episode_ranks()
    print(episode_totals)

main()


import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, RadioButtons
import gpr

### toy data
toy_data_1 = np.array([ [-2, -.5, .8, 2, 2.3, 4, 5.5],
                    [1.5, -1, 4, 1.1, 1, .5, 2.5] ])

toy_func = np.sinc
sample_x = np.random.uniform(-2, 8, 20)
noise_y = np.random.normal( 0, .15, [len(sample_x)] ).T
toy_data_2 = np.array([ sample_x, toy_func(sample_x) + noise_y ])

data = toy_data_1

### fit data
gp = gpr.GP()
gp.fit(data[0], data[1])

### widget start
n_grid_x = 201
n_samples = 15

### build window and graphs
data_view = [
        min(data[0]) - 1, max(data[0]) + 1,
        min(data[1]) - 1, max(data[1]) + 1 ]

#fig = plt.figure()
main_axis = plt.subplot2grid((3,3), (0,0), colspan=3, rowspan=2)

text_mse = main_axis.text(.85, .05, '',
                verticalalignment='bottom', transform=main_axis.transAxes)

plt.axis(data_view)

### create placeholders for later plot
plt.scatter(data[0], data[1], c='b')    # main data plot

grid_x = np.linspace(data_view[0], data_view[1], num=n_grid_x)
dummy_init = grid_x*0

#XXX
#plt.plot(grid_x, toy_func(grid_x))

curve, = plt.plot(grid_x, dummy_init, c='r', lw=1, label='mean')
curve_area = plt.fill_between(grid_x, dummy_init, dummy_init)

curve_samples = [plt.plot(grid_x, dummy_init, lw=1, alpha=.4, c='k')[0] \
                for i in range(n_samples)]

### set legend
from matplotlib.patches import Patch
curve_legend = Patch(color='b', alpha=.4, label='std')
plt.legend(handles=[curve,curve_legend], loc=1)

### create kernel window
rbf_axis = plt.subplot2grid((3,3), (2,2))
rbf_axis.set_title('RBF kernel', fontsize=8)
rbf_plot_x = np.linspace(-1.3, 1.3, 25)**3      # finer plot around 0
rbf_plot, = plt.plot(rbf_plot_x, rbf_plot_x*0 )
plt.xlabel(r'$s_0*\exp(-\frac{s_1}{2}|x_i-x_j|^{s_2})$')

plt.tight_layout()

# main update for graph, redraw
def update(val):

    # get slider values
    bi = np.round(np.exp(slider[0].val), 3)
    s0 = np.round(np.exp(slider[1].val), 2)
    s1 = np.round(np.exp(slider[2].val), 2)
    s2 = np.round(slider[3].val, 1)
    slider[0].valtext.set_text(bi)
    slider[1].valtext.set_text(s0)
    slider[2].valtext.set_text(s1)
    slider[3].valtext.set_text(s2)

    # calculate new regression with updated kernel
    post_m, post_s = gp.update(grid_x, bi, s0, s1, s2)
    post_std = np.sqrt( np.diagonal(post_s) )

    # main view
    if view_button.value_selected == 'mean':

        curve.set_ydata(post_m)     # update mean curve
        text_mse.set_text('rmse: ' + str(np.round(gp.rmse(), 2)))

        # curve_area is deleted and recreated, since moving all
        # poly-shapes is impractical
        global curve_area
        curve_area.remove()
        curve_area = main_axis.fill_between(
                                grid_x, post_m+post_std, post_m-post_std,
                                color='b', alpha=.3, label='std')
        curve_area.set_edgecolor('none')

    else:       # sample from calculated distribution
        for c in curve_samples:
            c.set_ydata(np.random.multivariate_normal(post_m, post_s))

    # adjust kernel graph
    rbf_y = gp.kernel_matrix([0], rbf_plot_x)
    rbf_plot.set_ydata(rbf_y)
    rbf_axis.set_ylim(0, max(rbf_y)+1)

    plt.draw()

### create slider widgets
slider_ax = [
        plt.axes([.26, .31, .36, .03]),
        plt.axes([.26, .24, .36, .03]),
        plt.axes([.26, .19, .36, .03]),
        plt.axes([.26, .14, .36, .03]) ]
slider = [
        Slider(slider_ax[0], r'precision: $\beta^{-1}$',
                                    -7.7, 1.38, valinit=-7, valstep=.1),
        Slider(slider_ax[1], r'$s_0$', -2.3, 2.31, valinit=0, valstep=.1),
        Slider(slider_ax[2], r'$s_1$', -1.6, 2.8, valinit=0, valstep=.1),
        Slider(slider_ax[3], r'$s_2$', 0.5, 2, valinit=2, valstep=.1) ]

for s in slider:
    s.on_changed(update)

### create radio button
button_ax = plt.axes([.07, .14, .12, .13])
view_button = RadioButtons(button_ax, ('mean','sample'), active=0)

# is called when radiobutton is clicked
def toggle_vis(state):

    # update graph
    update(0)

    # toggle view and legend
    if state == 'sample':
        main_axis.get_legend().set_visible(False)
        text_mse.set_visible(False)
        curve.set_linestyle('')
        curve_area.set_facecolor('none')
        for c in curve_samples:
            c.set_linestyle('-')
    else:
        main_axis.get_legend().set_visible(True)
        text_mse.set_visible(True)
        curve.set_linestyle('-')
        curve_area.set_facecolor('b')
        for c in curve_samples:
            c.set_linestyle('')

view_button.on_clicked(toggle_vis)

toggle_vis('mean')
plt.show()


# https://www.python-lernen.de/while-schleife.htm
# https://www.python-lernen.de/uebung-zahlenraten.htm

"""schleife in Epoche einfügen mit 'soll ich weiter machen?'
   -> muss nicht mit Epoche sein, hauptsache input drin"""

"""mit
durchgang = 0
aktiv = True
while aktiv:
    print(durchgang)
    durchgang = durchgang + 1
    if (durchgang == 3):
        aktiv = False
print("nach der Schleife")"""

def epochen():
    Jahr = int(input("Bitte Jahr eingeben \n"))

    if Jahr < 0:
        print("vor Christus")

    elif 0 < Jahr <= 500:
        print("mit Christus")

    elif 500 < Jahr <= 750:
        print("frühes Mittelalter")

    elif 750 < Jahr <= 1250:
        print("hohes Mittelalter")

    elif 1250 < Jahr <= 1500:
        print("spätes Mittelalter")

    elif 1500 < Jahr <= 1600:
        print("Neuzeit")

    else:
        print("Bitte eine Zahl zwischen 0 und 1600 eingeben!")

def schleife():
    aktiv = True
    while aktiv:
        epochen()
        weitermachen = input("soll ich weitermachen? Ja/Nein \n")
        if weitermachen == "Ja" or weitermachen == "ja":
            print("")
        else:
            aktiv = False
            print("ok, tschüss")

schleife()

#Zahlenratespiel


import io
from datetime import datetime
from uuid import UUID

from sqlalchemy import select
from PIL import Image as pilImage

from config.settings import settings
from db.deps import get_db_session
from web_app.models import Image

async def save_image(
    uuid,
    upload_date,
    extension_type
):
    async with get_db_session() as session:
        image = Image(
            uuid=uuid,
            upload_date=upload_date,
            extension_type=extension_type
        )
        session.add(image)
        await session.commit()

async def search_image_by_token(
    token
) -> UUID:
    async with get_db_session() as session:
        stmt = select(Image.uuid).where(Image.uuid == token)
        token = await session.scalar(stmt)
        return token

async def get_image_by_token(
    token: str
) -> Image:
    async with get_db_session() as session:
        stmt = select(Image).where(Image.uuid == token)
        image = await session.scalar(stmt)
        return image

async def set_finished_date(
    token,
    date
):
    async with get_db_session() as session:
        image = await session.scalar(
            select(
                Image
            ).where(Image.uuid == token)
        )
        image.finished_date = date
        await session.commit()

async def change_last_upload_time(
    token,
    date
):
    async with get_db_session() as session:
        image = await session.scalar(
            select(
                Image
            ).where(Image.uuid == token)
        )
        image.last_upload_date = date
        await session.commit()

def get_full_name(token, extension_type, resized=False):
    return "{}-resized.{}".format(token, extension_type) \
        if resized else "{}.{}".format(token, extension_type)

async def save_images(
    token: str,
    extension_type: str,
    image,
    width: int,
    height: int
):
    img = pilImage.open(io.BytesIO(image))
    img.save(settings.MEDIA_PATH / get_full_name(token, extension_type))

    new_image = img.resize((width, height))
    new_image.save(settings.MEDIA_PATH / get_full_name(token, extension_type, resized=True))
    await set_finished_date(token, datetime.now())


#return에 대해서 더 알아보자
#return 밑으로는 어느 함수도 실행되지 않는다.
def r_plus(a, b):
    return a + b
    print("djfekjfiedjfdjkfdkjf jfiekjfiooje fef", True)

r_result = r_plus(2, 4)

print(r_result)
    #>>>6
    #왜 밑에 print함수는 실행되지 않았을까?
        #파이썬에선 하나의 함수에 하나의 결과 값만 출력받는다.
        #즉, 6이라는 하나의 결과값을 return했으니 그 이상의 일은 하지 않는 것.