import pytesseract
import time
import os
import pyautogui

from utils import settings, functions, scrape, exporter

import datetime

# Flags (And defaults)
f_export = "xlsx"

try:
	# Focus and maximize the NOX window
	# Somewhat buggy since NOX does not use native Windows forms
	if functions.focusnox() == False:
		print("Could not detect Nox... Aborting!")
		exit(1)
	time.sleep(1)
	functions.click(settings.points['focus'])

	# Confirm we are on the right screen
	print("Checking if we are on the \"Nearby\" screen...")
	if functions.confirmpixels(settings.pixelgroups['nearby']) == False:
		print("Not on correct screen inside Nox... Aborting!")
		exit(1)
	else:
		print("Seems OK, proceeding...")

	# Extract current coordinates
	print("Looking for current GPS coordinates...")
	coords = functions.getGPSCoords()
	if coords == False:
		print("Could not extract GPS location... Aborting!")
		exit(1)
	else:
		print("Found location: {}".format(coords))
		time.sleep(1)

	# Close GPS window
	functions.click(settings.points['close'])
	time.sleep(2)

	# I didn't put my tesseract in my PATH properly, too lazy to fix :)
	# If you one of those people as well, feel free to use this in from your config
	if len(settings.settings['tesseract']) > 0:
		pytesseract.pytesseract.tesseract_cmd = settings.settings['tesseract']

	# Align screen for start
	functions.firstalign()

	# See if we have to unfold user list (> 5 users) and settle out
	scrape.expandLists()
	time.sleep(1)

	# Runtimeeeee!
	raw = scrape.scrapeEntries()

	# Export
	# Should actually make this into a proper jumptable but whatever
	filename = "results/result_{}".format(datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S"))

	# XLSX
	if f_export == "xlsx":
		filename += ".xlsx"
		exporter.exportDistancesXLSX(raw, coords, filename=filename)

	# JSON
	elif f_export == "json":
		filename += ".json"
		exporter.exportDistancesJSON(raw, coords, filename=filename)

# Using the PyAutoGUI failsafe
except pyautogui.FailSafeException:
	print("FAILSAFE TRIGGERED, ABORTING!")
	exit(2)

# Using the PyAutoGUI failsafe
except KeyboardInterrupt:
	print("User interrupt, aborting!")
	exit(1)

# Tests I want to save untill I am ready to use them
exit()

# Countdown and move spoofed GPS to coords
for i in range(3, 0, -1):
	print("{}...".format(i))
	time.sleep(1)

for k in settings.coords.keys():
	functions.setGeo(settings.coords[k])
	time.sleep(1)


def alphabeticShift(inputString):
    asciis = []
    for i in inputString:
        if i == 'z':
            asciis.append(ord('a'))
        else:
            asciis.append(ord(i)+1)
    outStr = ''.join(chr(i) for i in asciis)
    return outStr

print(alphabeticShift("crazy"))


import FetchService
from pathlib import Path

'''
This class enables the download and handle of COVID-19 epidemiological data provides by the german RKI Institut (www.RKI.de)
All data is gathereed into a single csv file, which makes the file very large (> 1.8million columns)

RKI.fetch allows the download of the whole file, saved in a seperated folder (./data/rki)

'''

def fetch():
    url = "https://www.arcgis.com/sharing/rest/content/items/f10774f1c63e40168479a1feb6c7ca74/data"
    directory = Path("./data/rki/")
    print("this will need a while...")
    FetchService.save_csv(directory, url)
    print("Finished!")


from __future__ import annotations

import asyncio
import logging
import os
import pathlib
from collections import defaultdict
from copy import deepcopy
from dataclasses import asdict, dataclass
from datetime import datetime
from functools import cache, cached_property
from types import SimpleNamespace

import watchfiles
from fontTools.designspaceLib import DesignSpaceDocument
from fontTools.misc.transform import DecomposedTransform
from fontTools.pens.recordingPen import RecordingPointPen
from fontTools.ufoLib import UFOReaderWriter
from fontTools.ufoLib.glifLib import GlyphSet

from ..core.changes import applyChange
from ..core.classes import (
    Component,
    GlobalAxis,
    Layer,
    LocalAxis,
    Source,
    StaticGlyph,
    VariableGlyph,
)
from ..core.packedpath import PackedPathPointPen
from .ufo_utils import extractGlyphNameAndUnicodes

logger = logging.getLogger(__name__)

VARIABLE_COMPONENTS_LIB_KEY = "com.black-foundry.variable-components"
GLYPH_DESIGNSPACE_LIB_KEY = "com.black-foundry.glyph-designspace"
SOURCE_NAME_MAPPING_LIB_KEY = "xyz.fontra.source-names"
LAYER_NAME_MAPPING_LIB_KEY = "xyz.fontra.layer-names"

defaultUFOInfoAttrs = {
    "unitsPerEm": 1000,
    "ascender": 750,
    "descender": -250,
    "xHeight": 500,
    "capHeight": 750,
    "familyName": None,
    "copyright": None,
    "year": None,
}

class DesignspaceBackend:
    @classmethod
    def fromPath(cls, path):
        return cls(DesignSpaceDocument.fromfile(path))

    @classmethod
    def createFromPath(cls, path):
        path = pathlib.Path(path)
        ufoDir = path.parent

        # Create default UFO
        makeUniqueFileName = uniqueNameMaker(p.stem for p in ufoDir.glob("*.ufo"))
        familyName = path.stem
        styleName = "Regular"
        ufoFileName = makeUniqueFileName(f"{familyName}_{styleName}")
        ufoFileName = ufoFileName + ".ufo"
        ufoPath = os.fspath(ufoDir / ufoFileName)
        assert not os.path.exists(ufoPath)
        writer = UFOReaderWriter(ufoPath)  # this creates the UFO
        info = UFOFontInfo()
        for infoAttr, value in defaultUFOInfoAttrs.items():
            if value is not None:
                setattr(info, infoAttr, value)
        writer.writeInfo(info)
        _ = writer.getGlyphSet()  # this creates the default layer
        writer.writeLayerContents()
        assert os.path.isdir(ufoPath)

        dsDoc = DesignSpaceDocument()
        dsDoc.addSourceDescriptor(styleName=styleName, path=ufoPath, location={})

        dsDoc.write(path)
        return cls(dsDoc)

    def __init__(self, dsDoc):
        self.dsDoc = dsDoc
        self.ufoManager = UFOManager()
        self.updateAxisInfo()
        self.loadUFOLayers()
        self.buildGlyphFileNameMapping()
        self.glyphMap = getGlyphMapFromGlyphSet(self.defaultDSSource.layer.glyphSet)
        self.savedGlyphModificationTimes = {}

    def updateAxisInfo(self):
        self.dsDoc.findDefault()
        axes = []
        axisPolePositions = {}
        for dsAxis in self.dsDoc.axes:
            axis = GlobalAxis(
                minValue=dsAxis.minimum,
                defaultValue=dsAxis.default,
                maxValue=dsAxis.maximum,
                label=dsAxis.name,
                name=dsAxis.name,
                tag=dsAxis.tag,
                hidden=dsAxis.hidden,
            )
            if dsAxis.map:
                axis.mapping = [[a, b] for a, b in dsAxis.map]
            axes.append(axis)
            axisPolePositions[dsAxis.name] = (
                dsAxis.map_forward(dsAxis.minimum),
                dsAxis.map_forward(dsAxis.default),
                dsAxis.map_forward(dsAxis.maximum),
            )
        self.axes = axes
        self.axisPolePositions = axisPolePositions
        self.defaultLocation = {
            axisName: polePosition[1]
            for axisName, polePosition in axisPolePositions.items()
        }

    def close(self):
        pass

    @property
    def defaultDSSource(self):
        return self.dsSources.findItem(isDefault=True)

    @property
    def defaultUFOLayer(self):
        return self.defaultDSSource.layer

    @property
    def defaultReader(self):
        return self.defaultUFOLayer.reader

    @cached_property
    def defaultFontInfo(self):
        fontInfo = UFOFontInfo()
        self.defaultReader.readInfo(fontInfo)
        return fontInfo

    def loadUFOLayers(self):
        manager = self.ufoManager
        self.dsSources = ItemList()
        self.ufoLayers = ItemList()

        # Using a dict as an order-preserving set:
        ufoPaths = {source.path: None for source in self.dsDoc.sources}
        for ufoPath in ufoPaths:
            reader = manager.getReader(ufoPath)
            for ufoLayerName in reader.getLayerNames():
                self.ufoLayers.append(
                    UFOLayer(manager=manager, path=ufoPath, name=ufoLayerName)
                )

        makeUniqueSourceName = uniqueNameMaker()
        for source in self.dsDoc.sources:
            reader = manager.getReader(source.path)
            defaultLayerName = reader.getDefaultLayerName()
            ufoLayerName = source.layerName or defaultLayerName

            sourceLayer = self.ufoLayers.findItem(path=source.path, name=ufoLayerName)
            sourceStyleName = source.styleName or sourceLayer.fileName
            sourceName = (
                sourceStyleName
                if ufoLayerName == defaultLayerName
                else source.layerName
            )
            sourceName = makeUniqueSourceName(sourceName)

            self.dsSources.append(
                DSSource(
                    name=sourceName,
                    layer=sourceLayer,
                    location={**self.defaultLocation, **source.location},
                    isDefault=source == self.dsDoc.default,
                )
            )

    def buildGlyphFileNameMapping(self):
        glifFileNames = {}
        for glyphSet in self.ufoLayers.iterAttrs("glyphSet"):
            for glyphName, fileName in glyphSet.contents.items():
                glifFileNames[fileName] = glyphName
        self.glifFileNames = glifFileNames

    def updateGlyphSetContents(self, glyphSet):
        glyphSet.writeContents()
        glifFileNames = self.glifFileNames
        for glyphName, fileName in glyphSet.contents.items():
            glifFileNames[fileName] = glyphName

    async def getGlyphMap(self):
        return dict(self.glyphMap)

    async def getGlyph(self, glyphName):
        if glyphName not in self.glyphMap:
            return None

        axes = []
        sources = []
        localSources = []
        layers = {}
        sourceNameMapping = {}
        layerNameMapping = {}

        for ufoLayer in self.ufoLayers:
            if glyphName not in ufoLayer.glyphSet:
                continue

            staticGlyph, ufoGlyph = ufoLayerToStaticGlyph(ufoLayer.glyphSet, glyphName)
            if ufoLayer == self.defaultUFOLayer:
                localDS = ufoGlyph.lib.get(GLYPH_DESIGNSPACE_LIB_KEY)
                if localDS is not None:
                    axes, localSources = self._unpackLocalDesignSpace(
                        localDS, ufoLayer.name
                    )
                sourceNameMapping = ufoGlyph.lib.get(SOURCE_NAME_MAPPING_LIB_KEY, {})
                layerNameMapping = ufoGlyph.lib.get(LAYER_NAME_MAPPING_LIB_KEY, {})
            layers[ufoLayer.fontraLayerName] = Layer(staticGlyph)

        # When a glyph has axes with names that also exist as global axes, we need
        # to make sure our source locations use the *local* default values. We do
        # that with a location dict that only contains local values for such "shadow"
        # axes.
        localDefaultOverride = {
            axis.name: axis.defaultValue
            for axis in axes
            if axis.name in self.defaultLocation
        }

        for dsSource in self.dsSources:
            glyphSet = dsSource.layer.glyphSet
            if glyphName not in glyphSet:
                continue
            sources.append(dsSource.newFontraSource(localDefaultOverride))

        sources.extend(localSources)

        if layerNameMapping:
            for source in sources:
                source.layerName = layerNameMapping.get(
                    source.layerName, source.layerName
                )
            layers = {
                layerNameMapping.get(layerName, layerName): layer
                for layerName, layer in layers.items()
            }

        if sourceNameMapping:
            for source in sources:
                source.name = sourceNameMapping.get(source.name, source.name)

        return VariableGlyph(glyphName, axes=axes, sources=sources, layers=layers)

    def _unpackLocalDesignSpace(self, dsDict, defaultLayerName):
        axes = [
            LocalAxis(
                name=axis["name"],
                minValue=axis["minimum"],
                defaultValue=axis["default"],
                maxValue=axis["maximum"],
            )
            for axis in dsDict["axes"]
        ]
        localAxisNames = {axis.name for axis in axes}

        sources = []
        for source in dsDict.get("sources", ()):
            ufoLayerName = source.get("layername", defaultLayerName)
            sourceName = source.get(
                "name",
                ufoLayerName if ufoLayerName != defaultLayerName else "<default>",
            )

            sourceLocation = {**self.defaultLocation, **source["location"]}
            globalLocation = self._getGlobalPortionOfLocation(
                sourceLocation, localAxisNames
            )
            dsSource = self.dsSources.findItem(
                locationTuple=tuplifyLocation(globalLocation)
            )
            assert dsSource is not None
            ufoPath = dsSource.layer.path

            ufoLayer = self.ufoLayers.findItem(path=ufoPath, name=ufoLayerName)
            assert ufoLayer is not None
            sources.append(
                Source(
                    name=sourceName,
                    location=source["location"],
                    layerName=ufoLayer.fontraLayerName,
                )
            )
        return axes, sources

    async def putGlyph(self, glyphName, glyph, unicodes):
        assert isinstance(unicodes, list)
        assert all(isinstance(cp, int) for cp in unicodes)
        self.glyphMap[glyphName] = unicodes

        defaultLayerGlyph = readGlyphOrCreate(
            self.defaultUFOLayer.glyphSet, glyphName, unicodes
        )
        revLayerNameMapping = reverseSparseDict(
            defaultLayerGlyph.lib.get(LAYER_NAME_MAPPING_LIB_KEY, {})
        )

        localAxes = packLocalAxes(glyph.axes)
        localDefaultLocation = {axis.name: axis.defaultValue for axis in glyph.axes}

        # Prepare UFO source layers and local sources
        sourceNameMapping = {}
        layerNameMapping = {}
        localSources = []
        for source in glyph.sources:
            sourceInfo = self._prepareUFOSourceLayer(
                glyphName, source, localDefaultLocation, revLayerNameMapping
            )
            if sourceInfo.sourceName != source.name:
                sourceNameMapping[sourceInfo.sourceName] = source.name
            if sourceInfo.layerName != source.layerName:
                layerNameMapping[sourceInfo.layerName] = source.layerName
            if sourceInfo.localSourceDict is not None:
                localSources.append(sourceInfo.localSourceDict)

        # Prepare local design space
        localDS = {}
        if localAxes:
            localDS["axes"] = localAxes
        if localSources:
            localDS["sources"] = localSources

        revLayerNameMapping = reverseSparseDict(layerNameMapping)

        # Gather all UFO layers
        usedLayers = set()
        layers = []
        for layerName, layer in glyph.layers.items():
            layerName = revLayerNameMapping.get(layerName, layerName)
            ufoLayer = self.ufoLayers.findItem(fontraLayerName=layerName)

            if ufoLayer is None:
                # This layer is not used by any source and we haven't seen it
                # before. Let's create a new layer in the default UFO.
                ufoLayer = self._newUFOLayer(
                    glyphName, self.defaultUFOLayer.path, layerName
                )
                if ufoLayer.fontraLayerName != layerName:
                    layerNameMapping[ufoLayer.fontraLayerName] = layerName
                layerName = ufoLayer.fontraLayerName
            layers.append((layer, ufoLayer))
            usedLayers.add(layerName)

        # Write all UFO layers
        hasVariableComponents = glyphHasVariableComponents(glyph)
        modTimes = set()
        for layer, ufoLayer in layers:
            glyphSet = ufoLayer.glyphSet
            writeGlyphSetContents = glyphName not in glyphSet

            if glyphSet == self.defaultUFOLayer.glyphSet:
                layerGlyph = defaultLayerGlyph
                storeInLib(layerGlyph, GLYPH_DESIGNSPACE_LIB_KEY, localDS)
                storeInLib(layerGlyph, SOURCE_NAME_MAPPING_LIB_KEY, sourceNameMapping)
                storeInLib(layerGlyph, LAYER_NAME_MAPPING_LIB_KEY, layerNameMapping)
            else:
                layerGlyph = readGlyphOrCreate(glyphSet, glyphName, unicodes)

            drawPointsFunc = populateUFOLayerGlyph(
                layerGlyph, layer.glyph, hasVariableComponents
            )
            glyphSet.writeGlyph(glyphName, layerGlyph, drawPointsFunc=drawPointsFunc)
            if writeGlyphSetContents:
                # FIXME: this is inefficient if we write many glyphs
                self.updateGlyphSetContents(glyphSet)

            modTimes.add(glyphSet.getGLIFModificationTime(glyphName))

        # Prune unused UFO layers
        relevantLayerNames = set(
            layer.fontraLayerName
            for layer in self.ufoLayers
            if glyphName in layer.glyphSet
        )
        layersToDelete = relevantLayerNames - usedLayers
        for layerName in layersToDelete:
            glyphSet = self.ufoLayers.findItem(fontraLayerName=layerName).glyphSet
            glyphSet.deleteGlyph(glyphName)
            # FIXME: this is inefficient if we write many glyphs
            self.updateGlyphSetContents(glyphSet)
            modTimes.add(None)

        self.savedGlyphModificationTimes[glyphName] = modTimes

    def _prepareUFOSourceLayer(
        self, glyphName, source, localDefaultLocation, revLayerNameMapping
    ):
        sparseLocalLocation = {
            name: source.location[name]
            for name, value in localDefaultLocation.items()
            if source.location.get(name, value) != value
        }
        sourceLocation = {**self.defaultLocation, **source.location}
        globalLocation = self._getGlobalPortionOfLocation(
            sourceLocation, localDefaultLocation
        )

        dsSource = self.dsSources.findItem(
            locationTuple=tuplifyLocation(globalLocation)
        )
        if dsSource is None:
            dsSource = self._createDSSource(glyphName, source, globalLocation)

        if sparseLocalLocation:
            ufoLayer = self.ufoLayers.findItem(
                fontraLayerName=revLayerNameMapping.get(
                    source.layerName, source.layerName
                )
            )

            if ufoLayer is None:
                ufoPath = dsSource.layer.path
                ufoLayer = self._newUFOLayer(glyphName, ufoPath, source.layerName)
                ufoLayerName = ufoLayer.name
            else:
                ufoLayerName = ufoLayer.name
            normalizedSourceName = source.name
            normalizedLayerName = f"{ufoLayer.fileName}/{ufoLayerName}"
            defaultUFOLayerName = ufoLayer.reader.getDefaultLayerName()

            localSourceDict = {"name": source.name}
            if ufoLayerName != defaultUFOLayerName:
                localSourceDict["layername"] = ufoLayerName
            localSourceDict["location"] = source.location
        else:
            normalizedSourceName = dsSource.name
            normalizedLayerName = dsSource.layer.fontraLayerName
            localSourceDict = None

        return SimpleNamespace(
            sourceName=normalizedSourceName,
            layerName=normalizedLayerName,
            localSourceDict=localSourceDict,
        )

    def _createDSSource(self, glyphName, source, globalLocation):
        manager = self.ufoManager
        atPole, notAtPole = splitLocationByPolePosition(
            globalLocation, self.axisPolePositions
        )
        if not notAtPole:
            # Create a whole new UFO
            ufoDir = pathlib.Path(self.defaultUFOLayer.path).parent
            makeUniqueFileName = uniqueNameMaker(p.stem for p in ufoDir.glob("*.ufo"))
            dsFileName = pathlib.Path(self.dsDoc.path).stem
            ufoFileName = makeUniqueFileName(f"{dsFileName}_{source.name}")
            ufoFileName = ufoFileName + ".ufo"
            ufoPath = os.fspath(ufoDir / ufoFileName)
            assert not os.path.exists(ufoPath)
            reader = manager.getReader(ufoPath)  # this creates the UFO
            info = UFOFontInfo()
            for infoAttr in defaultUFOInfoAttrs:
                value = getattr(self.defaultFontInfo, infoAttr, None)
                if value is not None:
                    setattr(info, infoAttr, value)
            _ = reader.getGlyphSet()  # this creates the default layer
            reader.writeLayerContents()
            ufoLayerName = reader.getDefaultLayerName()
            assert os.path.isdir(ufoPath)

            ufoLayer = UFOLayer(
                manager=manager,
                path=ufoPath,
                name=ufoLayerName,
            )
            self.ufoLayers.append(ufoLayer)
        else:
            # Create a new layer in the appropriate existing UFO
            atPole = {**self.defaultLocation, **atPole}
            poleDSSource = self.dsSources.findItem(
                locationTuple=tuplifyLocation(atPole)
            )
            if poleDSSource is None:
                poleDSSource = self.defaultDSSource
            assert poleDSSource is not None
            ufoPath = poleDSSource.layer.path
            ufoLayer = self._newUFOLayer(
                glyphName, poleDSSource.layer.path, source.layerName
            )
            ufoLayerName = ufoLayer.name

        self.dsDoc.addSourceDescriptor(
            styleName=source.name,
            location=globalLocation,
            path=ufoPath,
            layerName=ufoLayerName,
        )
        self.dsDoc.write(self.dsDoc.path)

        dsSource = DSSource(
            name=source.name,
            layer=ufoLayer,
            location=globalLocation,
        )
        self.dsSources.append(dsSource)

        return dsSource

    def _newUFOLayer(self, glyphName, ufoPath, suggestedLayerName):
        reader = self.ufoManager.getReader(ufoPath)
        existingLayerNames = set(reader.getLayerNames())
        ufoLayerName = suggestedLayerName
        count = 0
        # getGlyphSet() will create the layer if it doesn't already exist
        while glyphName in self.ufoManager.getGlyphSet(ufoPath, ufoLayerName):
            # The glyph already exists in the layer, which means there is
            # a conflict. Let's make up a layer name in which the glyph
            # does not exist.
            count += 1
            ufoLayerName = f"{suggestedLayerName}#{count}"

        if ufoLayerName not in existingLayerNames:
            reader.writeLayerContents()

        ufoLayer = UFOLayer(
            manager=self.ufoManager,
            path=ufoPath,
            name=ufoLayerName,
        )
        self.ufoLayers.append(ufoLayer)

        return ufoLayer

    def _getGlobalPortionOfLocation(self, location, localAxisNames):
        globalLocation = {
            name: value
            for name, value in location.items()
            if name not in localAxisNames
        }
        return {**self.defaultLocation, **globalLocation}

    async def deleteGlyph(self, glyphName):
        if glyphName not in self.glyphMap:
            raise KeyError(f"Glyph '{glyphName}' does not exist")
        for glyphSet in self.ufoLayers.iterAttrs("glyphSet"):
            if glyphName in glyphSet:
                glyphSet.deleteGlyph(glyphName)
                glyphSet.writeContents()
        del self.glyphMap[glyphName]
        self.savedGlyphModificationTimes[glyphName] = None

    async def getGlobalAxes(self):
        return self.axes

    async def putGlobalAxes(self, axes):
        self.dsDoc.axes = []
        for axis in axes:
            self.dsDoc.addAxisDescriptor(
                name=axis.name,
                tag=axis.tag,
                minimum=axis.minValue,
                default=axis.defaultValue,
                maximum=axis.maxValue,
                map=deepcopy(axis.mapping) if axis.mapping else None,
            )
        self.dsDoc.write(self.dsDoc.path)
        self.updateAxisInfo()
        self.loadUFOLayers()

    async def getUnitsPerEm(self):
        return self.defaultFontInfo.unitsPerEm

    async def getFontLib(self):
        return self.dsDoc.lib

    async def watchExternalChanges(self):
        ufoPaths = sorted(set(self.ufoLayers.iterAttrs("path")))
        async for changes in watchfiles.awatch(*ufoPaths):
            changes = cleanupWatchFilesChanges(changes)
            changedItems = await self._analyzeExternalChanges(changes)

            glyphMapUpdates = {}

            # TODO: update glyphMap for changed non-new glyphs

            for glyphName in changedItems.newGlyphs:
                try:
                    glifData = self.defaultDSSource.layer.glyphSet.getGLIF(glyphName)
                except KeyError:
                    logger.info(f"new glyph '{glyphName}' not found in default source")
                    continue
                gn, unicodes = extractGlyphNameAndUnicodes(glifData)
                glyphMapUpdates[glyphName] = unicodes

            for glyphName in changedItems.deletedGlyphs:
                if glyphName in self.glyphMap:
                    glyphMapUpdates[glyphName] = None

            externalChange = makeGlyphMapChange(glyphMapUpdates)

            reloadPattern = (
                {"glyphs": dict.fromkeys(changedItems.changedGlyphs)}
                if changedItems.changedGlyphs
                else None
            )

            if externalChange:
                rootObject = {"glyphMap": self.glyphMap}
                applyChange(rootObject, externalChange)

            if externalChange or reloadPattern:
                yield externalChange, reloadPattern

    async def _analyzeExternalChanges(self, changes):
        changedItems = SimpleNamespace(
            changedGlyphs=set(),
            newGlyphs=set(),
            deletedGlyphs=set(),
            rebuildGlyphSetContents=False,
        )
        for change, path in changes:
            _, fileSuffix = os.path.splitext(path)

            if fileSuffix == ".glif":
                self._analyzeExternalGlyphChanges(change, path, changedItems)

        if changedItems.rebuildGlyphSetContents:
            #
            # In some cases we're responding to a changed glyph while the
            # contents.plist hasn't finished writing yet. Let's pause a little
            # bit and hope for the best.
            #
            # This is obviously not a solid solution, and I'm not sure there is
            # one, given we don't know whether new .glif files written before or
            # after the corresponding contents.plist file. And even if we do know,
            # the amount of time between the two events can be arbitrarily long,
            # at least in theory, when many new glyphs are written at once.
            #
            # TODO: come up with a better solution.
            #
            await asyncio.sleep(0.15)
            for glyphSet in self.ufoLayers.iterAttrs("glyphSet"):
                glyphSet.rebuildContents()

        return changedItems

    def _analyzeExternalGlyphChanges(self, change, path, changedItems):
        fileName = os.path.basename(path)
        glyphName = self.glifFileNames.get(fileName)

        if change == watchfiles.Change.deleted:
            # Deleted glyph
            changedItems.rebuildGlyphSetContents = True
            if path.startswith(os.path.join(self.dsDoc.default.path, "glyphs/")):
                # The glyph was deleted from the default source,
                # do a full delete
                del self.glifFileNames[fileName]
                changedItems.deletedGlyphs.add(glyphName)
            # else:
            # The glyph was deleted from a non-default source,
            # just reload.
        elif change == watchfiles.Change.added:
            # New glyph
            changedItems.rebuildGlyphSetContents = True
            if glyphName is None:
                with open(path, "rb") as f:
                    glyphName, _ = extractGlyphNameAndUnicodes(f.read())
                self.glifFileNames[fileName] = glyphName
                changedItems.newGlyphs.add(glyphName)
                return
        else:
            # Changed glyph
            assert change == watchfiles.Change.modified

        if glyphName is None:
            return

        if os.path.exists(path):
            mtime = os.stat(path).st_mtime
            # Round-trip through datetime, as that's effectively what is happening
            # in getGLIFModificationTime, deep down in the fs package. It makes sure
            # we're comparing timestamps that are actually comparable, as they're
            # rounded somewhat, compared to the raw st_mtime timestamp.
            mtime = datetime.fromtimestamp(mtime).timestamp()
        else:
            mtime = None
        savedMTimes = self.savedGlyphModificationTimes.get(glyphName, ())
        if savedMTimes is not None and mtime not in savedMTimes:
            logger.info(f"external change '{glyphName}'")
            changedItems.changedGlyphs.add(glyphName)

def makeGlyphMapChange(glyphMapUpdates):
    if not glyphMapUpdates:
        return None
    changes = [
        {"f": "=", "a": [glyphName, unicodes]}
        for glyphName, unicodes in glyphMapUpdates.items()
        if unicodes is not None
    ] + [
        {"f": "d", "a": [glyphName]}
        for glyphName, unicodes in glyphMapUpdates.items()
        if unicodes is None
    ]
    glyphMapChange = {"p": ["glyphMap"]}
    if len(changes) == 1:
        glyphMapChange.update(changes[0])
    else:
        glyphMapChange["c"] = changes
    return glyphMapChange

class UFOBackend:
    @classmethod
    def fromPath(cls, path):
        dsDoc = DesignSpaceDocument()
        dsDoc.addSourceDescriptor(path=os.fspath(path), styleName="default")
        return DesignspaceBackend(dsDoc)

    @classmethod
    def createFromPath(cls, path):
        raise NotImplementedError()

class UFOGlyph:
    unicodes = ()
    width = 0

class UFOFontInfo:
    unitsPerEm = 1000

class UFOManager:
    @cache
    def getReader(self, path):
        return UFOReaderWriter(path)

    @cache
    def getGlyphSet(self, path, layerName):
        return self.getReader(path).getGlyphSet(layerName, defaultLayer=False)

@dataclass(kw_only=True, frozen=True)
class DSSource:
    name: str
    layer: UFOLayer
    location: dict[str, float]
    isDefault: bool = False

    @cached_property
    def locationTuple(self):
        return tuplifyLocation(self.location)

    def newFontraSource(self, localDefaultOverride=None):
        if localDefaultOverride is None:
            localDefaultOverride = {}
        return Source(
            name=self.name,
            location={**self.location, **localDefaultOverride},
            layerName=self.layer.fontraLayerName,
        )

@dataclass(kw_only=True, frozen=True)
class UFOLayer:
    manager: UFOManager
    path: str
    name: str

    @cached_property
    def fileName(self):
        return os.path.splitext(os.path.basename(self.path))[0]

    @cached_property
    def fontraLayerName(self):
        return f"{self.fileName}/{self.name}"

    @cached_property
    def reader(self):
        return self.manager.getReader(self.path)

    @cached_property
    def glyphSet(self):
        return self.manager.getGlyphSet(self.path, self.name)

class ItemList:
    def __init__(self):
        self.items = []
        self.invalidateCache()

    def __iter__(self):
        return iter(self.items)

    def append(self, item):
        self.items.append(item)
        self.invalidateCache()

    def invalidateCache(self):
        self._mappings = {}

    def findItem(self, **kwargs):
        items = self.findItems(**kwargs)
        return items[0] if items else None

    def findItems(self, **kwargs):
        attrTuple = tuple(kwargs.keys())
        valueTuple = tuple(kwargs.values())
        keyMapping = self._mappings.get(attrTuple)
        if keyMapping is None:
            keyMapping = defaultdict(list)
            for item in self.items:
                itemValueTuple = tuple(
                    getattr(item, attrName) for attrName in attrTuple
                )
                keyMapping[itemValueTuple].append(item)
            self._mappings[attrTuple] = dict(keyMapping)
        return keyMapping.get(valueTuple)

    def iterAttrs(self, attrName):
        for item in self:
            yield getattr(item, attrName)

def ufoLayerToStaticGlyph(glyphSet, glyphName):
    glyph = UFOGlyph()
    glyph.lib = {}
    pen = PackedPathPointPen()
    glyphSet.readGlyph(glyphName, glyph, pen, validate=False)
    components = [*pen.components] + unpackVariableComponents(glyph.lib)
    staticGlyph = StaticGlyph(
        path=pen.getPath(), components=components, xAdvance=glyph.width
    )
    # TODO: anchors
    # TODO: yAdvance, verticalOrigin
    return staticGlyph, glyph

def unpackVariableComponents(lib):
    components = []
    for componentDict in lib.get(VARIABLE_COMPONENTS_LIB_KEY, ()):
        glyphName = componentDict["base"]
        transformationDict = componentDict.get("transformation", {})
        transformation = DecomposedTransform(**transformationDict)
        location = componentDict.get("location", {})
        components.append(Component(glyphName, transformation, location))
    return components

def readGlyphOrCreate(
    glyphSet: GlyphSet,
    glyphName: str,
    unicodes: list[int],
):
    layerGlyph = UFOGlyph()
    layerGlyph.lib = {}
    if glyphName in glyphSet:
        # We read the existing glyph so we don't lose any data that
        # Fontra doesn't understand
        glyphSet.readGlyph(glyphName, layerGlyph, validate=False)
    layerGlyph.unicodes = unicodes
    return layerGlyph

def populateUFOLayerGlyph(
    layerGlyph: UFOGlyph,
    staticGlyph: StaticGlyph,
    forceVariableComponents: bool = False,
) -> None:
    pen = RecordingPointPen()
    layerGlyph.width = staticGlyph.xAdvance
    layerGlyph.height = staticGlyph.yAdvance
    staticGlyph.path.drawPoints(pen)
    variableComponents = []
    for component in staticGlyph.components:
        if component.location or forceVariableComponents:
            # Store as a variable component
            varCoDict = {"base": component.name, "location": component.location}
            if component.transformation != DecomposedTransform():
                varCoDict["transformation"] = asdict(component.transformation)
            variableComponents.append(varCoDict)
        else:
            # Store as a regular component
            pen.addComponent(
                component.name,
                cleanupTransform(component.transformation.toTransform()),
            )

    storeInLib(layerGlyph, VARIABLE_COMPONENTS_LIB_KEY, variableComponents)

    return pen.replay

def getGlyphMapFromGlyphSet(glyphSet):
    glyphMap = {}
    for glyphName in glyphSet.keys():
        glifData = glyphSet.getGLIF(glyphName)
        gn, unicodes = extractGlyphNameAndUnicodes(glifData)
        assert gn == glyphName, (gn, glyphName)
        glyphMap[glyphName] = unicodes
    return glyphMap

def uniqueNameMaker(existingNames=()):
    usedNames = set(existingNames)

    def makeUniqueName(name):
        count = 0
        uniqueName = name
        while uniqueName in usedNames:
            count += 1
            uniqueName = f"{name}#{count}"
        usedNames.add(uniqueName)
        return uniqueName

    return makeUniqueName

def cleanupTransform(t):
    """Convert any integer float values into ints. This is to prevent glifLib
    from writing float values that can be integers."""
    return tuple(int(v) if int(v) == v else v for v in t)

def cleanupWatchFilesChanges(changes):
    # If a path is mentioned with more than one event type, we pick the most
    # appropriate one among them:
    # - if there is a delete event and the path does not exist: delete it is
    # - else: keep the lowest sorted event (order: added, modified, deleted)
    perPath = {}
    for change, path in sorted(changes):
        if path in perPath:
            if change == watchfiles.Change.deleted and not os.path.exists(path):
                # File doesn't exist, event to "deleted"
                perPath[path] = watchfiles.Change.deleted
            # else: keep the first event
        else:
            perPath[path] = change
    return [(change, path) for path, change in perPath.items()]

def tuplifyLocation(loc):
    # TODO: find good place to share this (duplicated from opentype.py)
    return tuple(sorted(loc.items()))

def splitLocationByPolePosition(location, poles):
    atPole = {}
    notAtPole = {}
    for name, value in location.items():
        if value in poles.get(name, ()):
            atPole[name] = value
        else:
            notAtPole[name] = value
    return atPole, notAtPole

def packLocalAxes(axes):
    return [
        dict(
            name=axis.name,
            minimum=axis.minValue,
            default=axis.defaultValue,
            maximum=axis.maxValue,
        )
        for axis in axes
    ]

def reverseSparseDict(d):
    return {v: k for k, v in d.items() if k != v}

def storeInLib(layerGlyph, key, value):
    if value:
        layerGlyph.lib[key] = value
    else:
        layerGlyph.lib.pop(key, None)

def glyphHasVariableComponents(glyph):
    return any(
        compo.location or compo.transformation.tCenterX or compo.transformation.tCenterY
        for layer in glyph.layers.values()
        for compo in layer.glyph.components
    )


from lxml import html
import requests
import pyfiglet
from prettytable import PrettyTable

try:
    f = pyfiglet.Figlet(font='larry3d')

    page = requests.get("https://www.theguardian.com/football/premierleague/table")
    tree = html.fromstring(page.content)

    clubs = tree.xpath("//a[@class='team-name__long']/text()")
    points = tree.xpath("//tr/td[10]/b[1]/text()")
    goal_difference = tree.xpath("//td[9]/text()")
    goals_for = tree.xpath("//td[7]/text()")
    goals_against = tree.xpath("//td[8]/text()")

    x = PrettyTable()

    column_names = ["Club", "Points", "Goal Difference", "Goals for", "Goals against"]

    x.add_column(column_names[0], clubs)
    x.add_column(column_names[1], points)
    x.add_column(column_names[2], goal_difference)
    x.add_column(column_names[3], goals_for)
    x.add_column(column_names[4], goals_against)

    print(f.renderText('Premier league'))

    print(x)
    print("")
    print(
        "The data provided is gathered from the Guardian website, https://www.theguardian.com/football/premierleague/table")
except:
    print("An error occured")


from django.urls import path
from Accounts import views
app_name= 'accounts'

urlpatterns = [
    path('user_login/',views.userLogin,name='userLogin'),
    path('user_logout/',views.userLogout,name="userLogout"),
    path('user_profile/',views.userProfile,name="userProfile"),
    path('register/',views.RegisterUser,name='registerUser'),
    path('user_update/<pk>/',views.UserUpdate,name='updateProfile'),
]


from django.shortcuts import render, redirect
from accounts.models import *
from .forms import OrderForm, CustomerForm, ProductForm
# Create your views here.
from django.http import HttpResponse

def home(request):
    orders = Order.objects.all()
    customers = Customer.objects.all()
    total_orders = orders.count()
    order_delivered = orders.filter(status='Delivered').count()
    order_pending = orders.filter(status='Pending').count()
    context = {'orders': orders, 'customers': customers, 'total_orders': total_orders,
               'order_delivered': order_delivered, 'order_pending': order_pending}
    return render(request, 'accounts/dashboard.html', context)

def products(request):
    products = Product.objects.all()
    return render(request, 'accounts/products.html', {'products': products})

def customer(request, pk):
    customer = Customer.objects.get(id=pk)
    orders = customer.order_set.all()
    total_order = orders.count()
    context = {'customer': customer, 'orders': orders, 'total_order': total_order}
    return render(request, 'accounts/customer.html', context)

def createOrder(request):
    form = OrderForm()
    if request.method == 'POST':
        form = OrderForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('/')
    context = {'form': form}
    return render(request, 'accounts/order_form.html', context)

def updateOrder(request, pk):
    order = Order.objects.get(id=pk)
    form = OrderForm(instance=order)
    context = {'form': form}
    if request.method == 'POST':
        form = OrderForm(request.POST, instance=order)
        if form.is_valid():
            form.save()
            return redirect('/')
    return render(request, 'accounts/order_form.html', context)

def deleteOrder(request, pk):
    order = Order.objects.get(id=pk)
    if request.method == 'POST':
        order.delete()
        return redirect('/')
    context = {'item': order}
    return render(request, 'accounts/delete.html', context)

def createCustomer(request):
    form = CustomerForm()
    if request.method == 'POST':
        form = CustomerForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('/')
    context = {'form': form}
    return render(request, 'accounts/customer_form.html', context)

def createProduct(request):
    form = ProductForm()
    if request.method == 'POST':
        form = ProductForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('/')
    context = {'form': form}
    return render(request, 'accounts/product_form.html', context)


from __future__ import annotations

import os
import matplotlib.pyplot as plt
import numpy as np
import torch
import torch.nn as nn
from torch import optim
from tqdm import tqdm

import gymnasium as gym

class A2C(nn.Module):
    """
    (Synchronous) Advantage Actor-Critic (A2C) agent class.
    """

    def __init__(self,
                 n_features: int,
                 n_actions: int,
                 device: torch.device,
                 critic_lr: float,
                 actor_lr: float,
                 n_envs: int) -> None:
        """Initialize the actor and critic networks and their optimizers.
        ### Parameters
        - `n_features`: int, number of features in the state
        - `n_actions`: int, number of actions
        - `device`: torch.device, device to use for computation
        - `critic_lr`: float, learning rate for the critic
        - `actor_lr`: float, learning rate for the actor
        - `n_envs`: int, number of parallel environments to use"""
        super().__init__()
        self.device = device
        self.n_envs = n_envs

        critic_layers = [
            nn.Linear(n_features, 32),
            nn.ReLU(),
            nn.Linear(32,32),
            nn.ReLU(),
            nn.Linear(32, 1), # estimate V(s)
        ]

        actor_layers = [
            nn.Linear(n_features, 32),
            nn.ReLU(),
            nn.Linear(32, 32),
            nn.ReLU(),
            nn.Linear(
                32, n_actions
            ),  # estimate action logits (will be fed into a softmax later)
        ]
        # define actor and critic networks
        self.critic:nn.Sequential = nn.Sequential(*critic_layers).to(self.device)
        self.actor:nn.Sequential = nn.Sequential(*actor_layers).to(self.device)

        # define optimizer for actor and critic
        self.critic_optim = optim.RMSprop(self.critic.parameters(), lr=critic_lr)
        self.actor_optim = optim.RMSprop(self.actor.parameters(), lr=actor_lr)

    def forward(self, x:np.ndarray) -> tuple[torch.Tensor, torch.Tensor]:
        """Forward pass of the actor and critic networks.

        ### Parameters
        - `x`: A batched vector of states, [n_env, state_dim]

        ### Return
        - `state_values`: torch.Tensor, estimated state values, with shape [n_env, ]
        - `action_logits_vec`: torch.Tensor, estimated action logits, with shape [n_env, n_actions]
        """
        x = torch.Tensor(x).to(self.device)
        state_values = self.critic(x)
        action_logits_vec = self.actor(x)
        return (state_values, action_logits_vec)

    def select_action(self, x: np.ndarray) -> tuple[torch.tensor, torch.tensor, torch.tensor, torch.tensor]:
        """
        Return a tuple the chosen actions and the log-probs of the actions.

        ### Return
         - a tuple: (actions, action_log_probs, state_values, entropy)
         Four torch.Tensor objects with shape [n_env, ]
        """
        state_values, action_logits_vec = self.forward(x)
        action_pd = torch.distributions.Categorical(logits=action_logits_vec)
        actions = action_pd.sample()
        action_log_probs = action_pd.log_prob(actions)
        entropy = action_pd.entropy()
        return (actions, action_log_probs, state_values, entropy)

    def get_losses(self,
                   rewards:torch.Tensor,
                   action_log_probs: torch.Tensor,
                   value_preds: torch.Tensor,
                   entropy: torch.Tensor,
                   masks: torch.Tensor,
                   gamma: float,
                   lam: float,
                   ent_coeft: float,
                   device: torch.device
                   )-> tuple[torch.Tensor, torch.Tensor]:
        """
        ### Parameters
        - `rewards`: torch.Tensor, with the rewards for each time step in the episode, with shape `[n_steps_per_update, n_env]`
        - `action_log_probs`: torch.Tensor, with the log-probabilities of the actions taken, with shape `[n_steps_per_update, n_env]`
        - `value_preds`: torch.Tensor, with the state values prediction for each time step in the episode, with shape `[n_steps_per_update, n_env]`
        - `masks`: torch.Tensor
        - `gamma`: float, discount factor
        - `lam`: float, GAE hyperparameter

        ### Return
        - A tuple, (critic_loss, actor_loss)
        - critic_loss: torch.Tensor, with shape [1, ]
        - actor_loss: torch.Tensor, with shape [1, ]
        """
        T = len(rewards) # the n_steps_per_update
        advantages = torch.zeros_like(T, self.n_envs, device=device)
        # []
        # compute the advanteges using GAE
        gae = 0.0
        for t in reversed(range(T-1)):
            td_error = (-value_preds[t] + rewards[t] + gamma * masks[t]* value_preds[t+1])
            gae = td_error + gamma * lam * masks[t] * gae
            advantages[t] = gae

        # calculate the loss of the minibatch for actor and critic
        critic_loss = advantages.pow(2).mean()

        # give a bonus for higher entropy, to encourage exploration
        actor_loss = -(advantages.detach() * action_log_probs).mean() - ent_coeft * entropy.mean()
        return (critic_loss, actor_loss)

    def update_parameters(self,
                          critic_loss: torch.Tensor,
                          actor_loss: torch.Tensor)->None:
        self.critic_optim.zero_grad()
        critic_loss.backward()
        self.critic_optim.step()

        self.actor_optim.zero_grad()
        actor_loss.backward()
        self.actor_optim.step()

n_envs = 3
n_updates = 1000
n_steps_per_update = 128
randomize_domain = False

# agent hyperparams
gamma = 0.999
lam = 0.95
ent_coeft = 0.01
actor_lr = 0.001
critic_lr = 0.005

if __name__ == "__main__":
    # envs = gym.vector.make("LunarLander-v2", num_envs=3, max_episode_steps=600)
   if randomize_domain:
    envs = gym.vector.AsyncVectorEnv(
        [
            lambda: gym.make(
                "LunarLander-v2",
                gravity=np.clip(
                    np.random.normal(loc=-10.0, scale=1.0), a_min=-11.99, a_max=-0.01
                ),
                enable_wind=np.random.choice([True, False]),
                wind_power=np.clip(
                    np.random.normal(loc=15.0, scale=1.0), a_min=0.01, a_max=19.99
                ),
                turbulence_power=np.clip(
                    np.random.normal(loc=1.5, scale=0.5), a_min=0.01, a_max=1.99
                ),
                max_episode_steps=600,
            )
            for i in range(n_envs)
        ]
        )
   else:
    envs = gym.vector.make("LunarLander-v2", num_envs=n_envs, max_episode_steps=600)

    obs_shape = envs.single_action_space.shape[0]
    action_shape = envs.single_action_space.n

    use_cuda = False
    if use_cuda:
       device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    else:
       device = torch.device("cpu")

    # init the agent
    agent = A2C(obs_shape, action_shape, device, critic_lr, actor_lr, n_envs)


lista = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
lista2 = []
listzapas = []
for x in lista:
    if x > 5 :
        lista2.append(x)
    else:
        #stworzone przez irytacje z przeskakującymi wartości removie.
        listzapas.append(x)
lista = listzapas
print(lista2)
print(lista)
#Zadanie7
listzapas = [0] + listzapas + lista2
print(listzapas)


import logging
import regex

from logrec.dataprep.model.chars import MultilineCommentStart, MultilineCommentEnd, OneLineCommentStart, \
    NewLine, Backslash, Quote
from logrec.dataprep.model.containers import MultilineComment, OneLineComment, StringLiteral, \
    ProcessableTokenContainer
from logrec.dataprep.model.numeric import Number, D, F, L, DecimalPoint, HexStart, E
from logrec.dataprep.model.placeholders import placeholders
from logrec.dataprep.model.word import ParseableToken

logger = logging.getLogger(__name__)

START_MULTILINE_COMMENT = MultilineCommentStart()
END_MULTILINE_COMMENT = MultilineCommentEnd()

START_ONE_LINE_COMMENT = OneLineCommentStart()
NEW_LINE = NewLine()

QUOTE = Quote()
BACKSLASH = Backslash()

tabs = ["\t" + str(i) for i in range(11)]

multiline_comments_tokens = ["/*", "*/"]

two_character_tokens = [
    "==",
    "!=",
    "**",
    "//",
    "++",
    "--",
    "+=",
    "-=",
    "/=",
    "*=",
    "%=",
    "<=",
    ">=",
    "^=",
    "&=",
    "|=",
    ">>",
    "<<",
    "&&",
    "||"
]

one_character_tokens = [
    "+",
    "*",
    "!",
    "/",
    ">",
    "<",
    "="
]

two_char_verbose = [
    "\t", "\n"
]

newlines_and_tabs_reprs = [
    '\\t', '\\n'
]

one_char_verbose = [
    "{", "}", "[", "]", ",", ".", "-", "?", ":", "(", ")", ";", '"', "&",
    "|", "\\", "@", "#", "$", "'", "~", "%", "^", "\\"
]

delimiters_to_drop = "[\[\] ,.\-?:\n\t(){};\"&|_#\\\@$]"
delimiters_to_drop_verbose = " " #TODO according to the new philosophy we shoulnt drop anything

special_tokens = tabs + multiline_comments_tokens + two_character_tokens + one_character_tokens + two_char_verbose + one_char_verbose + newlines_and_tabs_reprs

key_words = [
"abstract",
"continue",
"for",
"new",
"switch",
"assert",
"default",
"package",
"synchronized",
"boolean",
"do",
"if",
"private",
"this",
"break",
"double",
"implements",
"protected",
"throw",
"byte",
"else",
"import",
"public",
"throws",
"case",
"enum",
"instanceof",
"return",
"transient",
"catch",
"extends",
"int",
"short",
"try",
"char",
"final",
"interface",
"static",
"void",
"class",
"finally",
"long",
"strictfp",
"volatile",
"float",
"native",
"super",
"while",
"true",
"false",
"null"
]

NUMBER_REGEX = '-?(?:0x[0-9a-fA-F]+[lL]?|[0-9]+[lL]?|(?:[0-9]*\.[0-9]+|[0-9]+(?:\.[0-9]*)?)(?:[eE][-+]?[0-9]+)?[fFdD]?)'

def is_number(s):
    return regex.fullmatch(NUMBER_REGEX, s)

def find_all_comment_string_literal_symbols(token_list):
    res = []
    for ind in range(len(token_list)):
        if token_list[ind] == QUOTE:
            i = ind - 1
            while i >= 0 and token_list[i] == BACKSLASH:
                i -= 1
            if (ind - i) % 2 == 1 and (ind == 0 or token_list[ind-1] != "'" or ind +1 >= len(token_list) or token_list[ind+1] != "'"):
                res.append((ind, token_list[ind]))
        elif token_list[ind] in [START_MULTILINE_COMMENT, END_MULTILINE_COMMENT, START_ONE_LINE_COMMENT, NEW_LINE]:
            res.append((ind, token_list[ind]))
    return res

def replace_segments(token_list, segments_to_remove):
    new_token_list = []
    curr_ind = 0
    for begin, end, clazz in segments_to_remove:
        new_token_list.extend(token_list[curr_ind:begin])
        new_token_list.append(clazz(token_list[begin+1:end]))
        curr_ind = end if clazz == OneLineComment else end + 1
    if curr_ind < len(token_list):
        new_token_list.extend(token_list[curr_ind:])
    return new_token_list

def process_comments_and_str_literals(token_list, context):
    comment_string_literal_symbols_locations = find_all_comment_string_literal_symbols(token_list)
    active_symbol, active_symbol_index = None, -1
    segments_to_remove = []

    for index, symbol in comment_string_literal_symbols_locations:
        if active_symbol is None:
            if symbol == END_MULTILINE_COMMENT:
                logger.warning(
                    f"{repr(' '.join(list(map(lambda t: str(t),token_list[index-100:index+1]))))}, index: {index}")
                return token_list
            elif symbol == NEW_LINE:
                pass
            else:
                active_symbol, active_symbol_index = symbol, index
        elif active_symbol == QUOTE:
            if symbol == NEW_LINE:
                logger.warning(
                    f"{repr(' '.join(list(map(lambda t: str(t),token_list[index-100:index+1]))))}, index: {index}")
                return token_list
            elif symbol == QUOTE:
                segments_to_remove.append((active_symbol_index, index, StringLiteral))
                active_symbol, active_symbol_index = None, -1
        elif active_symbol == START_ONE_LINE_COMMENT:
            if symbol == NEW_LINE:
                segments_to_remove.append((active_symbol_index, index, OneLineComment))
                active_symbol, active_symbol_index = None, -1
        elif active_symbol == START_MULTILINE_COMMENT:
            if symbol == END_MULTILINE_COMMENT:
                segments_to_remove.append((active_symbol_index, index, MultilineComment))
                active_symbol, active_symbol_index = None, -1
        else:
            raise AssertionError(f"Unknown symbol: {active_symbol}")
    token_list = replace_segments(token_list, segments_to_remove)
    return token_list

def replace(token_list, start, end, new_symbol):
    len_before_replacement = len(token_list)
    string_literal_content = token_list[start+1:end]
    del (token_list[start: end if new_symbol == OneLineComment else end+1])
    token_list.insert(start, new_symbol(string_literal_content))
    return len_before_replacement - len(token_list)

def strip_off_identifiers(token_list, context):
    identifiers_to_ignore = context['identifiers_to_ignore']
    non_identifiers = set(
        key_words + multiline_comments_tokens + two_character_tokens + one_character_tokens + one_char_verbose + two_char_verbose + \
        list(placeholders.values()) + tabs + identifiers_to_ignore)

    result = []
    for token in token_list:
        if not is_number(token) and token not in non_identifiers:
            result.append(placeholders['identifier'])
        else:
            result.append(token)
    return result

def process_number_literal(possible_number):
    if is_number(possible_number) and possible_number not in tabs:
        parts_of_number = []
        if possible_number.startswith('-'):
            parts_of_number.append('-')
            possible_number = possible_number[1:]
        if possible_number.startswith("0x"):
            parts_of_number.append(HexStart())
            possible_number = possible_number[2:]
            hex = True
        else:
            hex = False
        for ch in possible_number:
            if ch == '.':
                parts_of_number.append(DecimalPoint())
            elif ch == 'l' or ch == 'L':
                parts_of_number.append(L())
            elif (ch == 'f' or ch == 'F') and not hex:
                parts_of_number.append(F())
            elif (ch == 'd' or ch == 'D') and not hex:
                parts_of_number.append(D())
            elif (ch == 'e' or ch == 'E') and not hex:
                parts_of_number.append(E())
            else:
                parts_of_number.append(ch)
        return Number(parts_of_number)
    else:
        return ParseableToken(possible_number)

def process_numeric_literals(token_list, context):
    res = []
    for token in token_list:
        if isinstance(token, ParseableToken):
            numbers_separated = list(
                filter(None, regex.split(
                    f'(?:^|(?<=[^[:lower:][:upper:][:digit:]_]))({NUMBER_REGEX})(?![[:lower:][:upper:][:digit:]_.]|$)',
                    str(token))))
            for possible_number in numbers_separated:
               res.append(process_number_literal(possible_number))
        elif isinstance(token, ProcessableTokenContainer):
            for subtoken in token.get_subtokens():
                res.extend(process_numeric_literals(subtoken))
        else:
            res.append(token)
    return res


from nonebot import on_command, CommandSession
from nonebot import on_natural_language, NLPSession, IntentCommand

from .data_source import get_self_info

@on_command('who', aliases=('你是', '你是谁', '你妈妈是谁'))
async def who(session: CommandSession):
    info = await get_self_info()
    await session.send(info)

# on_natural_language 装饰器将函数声明为一个自然语言处理器
# keywords 表示需要响应的关键词，类型为任意可迭代对象，元素类型为 str
# 如果不传入 keywords，则响应所有没有被当作命令处理的消息
@on_natural_language(keywords={'谁', '爸爸'})
async def _(session: NLPSession):
    stripped_msg = session.msg_text.strip()
    return IntentCommand(69.0, 'who')


import numpy as np

def sigmoid_prime(x):
    return np.exp(-x) / ((np.exp(-x) + 1) ** 2)

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

class Network:
    # all list parameters are list of matrices
    b = []  # biases
    syn = []  # synapses
    LEARN_RATE = 1

    def __init__(self, num_of_neurons: list):  # to create NN you need to give a list how many neurons will be in layers
        np.random.seed(1)

        for i in range(len(num_of_neurons) - 1):
            self.syn.append(2 * np.random.random((num_of_neurons[i], num_of_neurons[i+1])) - 1)

        # biases for respective layers
        for i in range(1, len(num_of_neurons)):
            self.b.append(2 * np.random.random((1, num_of_neurons[i])) - 1)

    def epoch(self, images, y, num_of_iter):  # images : list of batches (batch is a matrix of many inputs)
        # y : list of matrix of desired outputs,  num of iter : numer of backprop for one batch

        for i, batch in list(enumerate(images)):
            X = np.array(batch)

            print("======================= BATCH {} =======================".format(i))

            for j in range(num_of_iter):
                l = []  # layers
                l.append(X)

                for k in range(len(self.b)):
                    l.append(sigmoid(np.dot(l[k], self.syn[k]) + self.b[k]))  # (mozna to bd zmienic)

                matrix_error = (y[i] - l[-1])

                if j % 20 == 0:
                    error = np.mean(np.abs(matrix_error))
                    print(("[%d] error: " % j) + str(error))

                delta = []
                delta.append(matrix_error * sigmoid_prime(l[-1]))

                # backpropagation
                for k in range(len(self.b)-1, 0, -1):
                    error = delta[-1].dot(self.syn[k].T)
                    delta.append(error * sigmoid_prime(l[k]))

                # grandient descent
                for k in range(len(self.b)):
                    descent = delta.pop()
                    self.syn[k] += l[k].T.dot(descent)
                    self.b[k] += descent.mean(axis=0)

    def run(self, data):
        l = []
        l.append([data])

        for k in range(len(self.b)):
            l.append(sigmoid(np.dot(l[k], self.syn[k]) + self.b[k]))

        return np.argmax(l[-1])


import os
import openai

from langchain.schema import SystemMessage, HumanMessage
from langchain.prompts import ChatPromptTemplate, HumanMessagePromptTemplate
from langchain.chat_models import ChatOpenAI
from langchain.chains import LLMChain, SequentialChain

from traceloop.sdk import Traceloop

openai.api_key = os.getenv("OPENAI_API_KEY")
Traceloop.init(app_name="langchain_example")

def langchain_app():
    chat = ChatOpenAI(temperature=0)

    first_prompt_messages = [
        SystemMessage(content="You are a funny sarcastic nerd."),
        HumanMessage(content="Tell me a joke about OpenTelemetry."),
    ]
    first_prompt_template = ChatPromptTemplate.from_messages(first_prompt_messages)
    first_chain = LLMChain(llm=chat, prompt=first_prompt_template, output_key="joke")

    second_prompt_messages = [
        SystemMessage(content="You are an Elf."),
        HumanMessagePromptTemplate.from_template(
            "Translate the joke below into Sindarin language:\n {joke}"
        ),
    ]
    second_prompt_template = ChatPromptTemplate.from_messages(second_prompt_messages)
    second_chain = LLMChain(llm=chat, prompt=second_prompt_template)

    workflow = SequentialChain(chains=[first_chain, second_chain], input_variables=[])
    workflow({})

langchain_app()


import cv2
import numpy as np
#img1 = cv2.imread('vlcsnap-2014-01-20-18h51m28s254.PNG')
cap = cv2.VideoCapture(0)

ret, frame = cap.read()

cv2.imshow('image',frame)

cap.release()

cv2.waitKey(0)
cv2.destroyAllWindows()


from django.shortcuts import render
from enroll.models import Student,Teacher,Contractor

# Create your views here.

def home(request):
	student_data = Student.objects.all()
	teacher_data = Teacher.objects.all()
	contractor = Contractor.objects.all()

	context = {'student':student_data,'teacher':teacher_data,'contractor':contractor}

	return render(request,'enroll/home.html',context = context)


#!/usr/bin/env python3

"""Radio scheduling program.

Usage:
  album_times.py [--host=HOST] PORT

Options:
  --host=HOST  Hostname of MPD [default: localhost]
  -h --help    Show this text

Prints out the last scheduling time of every album.
"""

from datetime import datetime
from docopt import docopt
from mpd import MPDClient

def album_sticker_get(client, album, sticker):
    """Gets a sticker associated with an album."""

    # I am pretty sure that MPD only implements stickers for songs, so
    # the sticker gets attached to the first song in the album.
    tracks = client.find("album", album)
    if len(tracks) == 0:
        return

    return client.sticker_get("song", tracks[0]["file"], "album_" + sticker)

def list_albums(client):
    """Lists albums sorted by last play timestamp."""

    # Get all albums
    albums = client.list("album")
    all_albums = list(
        filter(lambda a: a not in ["", "Lainchan Radio Transitions"], albums)
    )

    # Group albums by when they were last scheduled
    albums_by_last_scheduled = {}
    last_scheduled_times = []
    for album in all_albums:
        # Get the last scheduled time, defaulting to 0
        try:
            last_scheduled = int(album_sticker_get(client, album, "last_scheduled"))
        except ValueError:
            last_scheduled = 0

        # Put the album into the appropriate bucket
        if last_scheduled in albums_by_last_scheduled:
            albums_by_last_scheduled[last_scheduled].append(album)
        else:
            albums_by_last_scheduled[last_scheduled] = [album]
            last_scheduled_times.append(last_scheduled)

    # Pick the 10 oldest times
    last_scheduled_times.sort()
    for last_scheduled in last_scheduled_times:
        dt = datetime.utcfromtimestamp(last_scheduled)
        albums = albums_by_last_scheduled[last_scheduled]
        print("{}: {}".format(dt.strftime("%Y-%m-%d %H:%M:%S"), albums))

if __name__ == "__main__":
    args = docopt(__doc__)

    try:
        args["PORT"] = int(args["PORT"])
    except ValueError:
        print("PORT must be an integer")
        exit(1)

    try:
        client = MPDClient()
        client.connect(args["--host"], args["PORT"])
    except Exception as e:
        print(f"could not connect to MPD: {e.args[0]}")
        exit(2)

    list_albums(client)


import scipy.io
import numpy as np
from pylgmath.so3.operations import hat
import os
import pickle
from thesis.experiments.utils import StereoLocalizationProblem
import thesis.solvers.local_solver as local_solver
from thesis.solvers.iterative_sdp import iterative_sdp_solution
from thesis.simulation.sim import Camera
import thesis.visualization.plotting as plotting
import thesis.simulation.sim as sim
from typing import List
from datetime import datetime
from copy import deepcopy

RECORD_HISTORY = False

def read_dataset(path: str):
    dataset3 = scipy.io.loadmat(path)

    # F_i: inertial frame
    # F_v: vehicle frame
    # F_c: camera frame

    theta_vk_i = dataset3["theta_vk_i"] # a 3xK matrix
    r_i_vk_i = dataset3["r_i_vk_i"] # a 3xK matrix where the kth column is the groundtruth position of the camera at timestep k

    y_k_j = dataset3["y_k_j"] # 4 x K x 20 array of observations. All components of y_k_j(:, k, j) will be -1 if the observation is invalid
    y_var = dataset3["y_var"] # 4 x 1 matrix of computed variances based on ground truth stereo measurements
    rho_i_pj_i = dataset3["rho_i_pj_i"] # a 3x20 matrix where the jth column is the poisition of feature j

    # camera to vehicle
    C_c_v = dataset3["C_c_v"] # 3 x 3 matrix giving rotation from vehicle frame to camera frame
    rho_v_c_v = dataset3["rho_v_c_v"]

    # intrinsics
    fu = dataset3["fu"]
    fv = dataset3["fv"]
    cu = dataset3["cu"]
    cv = dataset3["cv"]
    b = dataset3["b"]
    print(fu, fv, cu, cv, b)

    cam = Camera(fu, fv, cu, cv, b, R = 0 * np.eye(4), fov_phi_range=(0, 0), fov_depth_range=(0, 0)) # is this noise correct?
    M = np.array(cam.M(), dtype=np.float64)

    T_c_v = np.eye(4)
    T_c_v[:3, :3] = C_c_v
    T_c_v[:3, -1:] = -C_c_v @ rho_v_c_v

    problems = []

    p_max = -np.inf * np.ones((3, 1))
    W = np.array(np.linalg.inv(np.diag(y_var.reshape(-1))), dtype=np.float64)
    #W = np.ones((4, 4), dtype=np.float64)

    for k, psi in enumerate(theta_vk_i.T):

        p_w = rho_i_pj_i.T[:, :, None]
        p_w = np.concatenate((p_w, np.ones_like(p_w[:, 0:1, :])), axis = 1)
        ys_with_invalid = y_k_j[:, k, :].T[:, :, None]
        mask = ~((ys_with_invalid.squeeze(-1) == -1).all(axis = 1))
        p_w = np.array(p_w[mask] , dtype=np.float64)

        if p_w.shape[0] < 3: # reject problems with less than 3 landmark points in the image
            continue

        y = np.array(ys_with_invalid[mask], dtype=np.float64)

        psi = psi.reshape(3, 1)
        psi_mag = np.linalg.norm(psi)
        C_vk_i = np.cos(psi_mag) * np.eye(3) + ( 1 - np.cos(psi_mag) ) * (psi / psi_mag) @ (psi / psi_mag).T - np.sin(psi_mag) * hat(psi / psi_mag)
        T_vk_i = np.eye(4)
        T_vk_i[:3, :3] = C_vk_i
        T_vk_i[:3, -1] = - C_vk_i @ r_i_vk_i[:, k]
        T_ck_i = T_c_v @ T_vk_i

        T_w_ck = np.array(np.linalg.inv(T_ck_i), dtype = np.float64)
        problems.append(
            StereoLocalizationProblem(
                T_wc = T_w_ck,
                p_w = p_w,
                M = M,
                y = y,
                W = W,
            )
        )
        p_max = np.maximum(p_max, T_w_ck[:3, -1:])

    p_wc_extent = p_max

    return problems, p_wc_extent, np.diag(y_var)

def metrics_fcn(problem, num_tries = 100):
    mosek_params = {}
    datum = {}
    local_solution = local_solver.stereo_localization_gauss_newton(problem, log = False, max_iters = 100, num_tries = num_tries, record_history=RECORD_HISTORY)
    iter_sdp_soln = iterative_sdp_solution(problem, problem.T_init, max_iters = 10, min_update_norm = 0.02, return_X = False, mosek_params=mosek_params, max_num_tries = num_tries, record_history=RECORD_HISTORY)
    datum["local_solution"] = local_solution
    datum["iterative_sdp_solution"] = iter_sdp_soln

    return datum

def run_experiment(problems: List[StereoLocalizationProblem], num_local_solve_tries: int, p_wc_extent: np.array):

    exp_time = datetime.today().strftime('%Y-%m-%d-%H:%M:%S')
    dir_path = os.path.dirname(os.path.realpath(__file__))
    exp_dir = os.path.join(dir_path, f"outputs/{exp_time}")
    if not os.path.isdir(exp_dir):
        os.mkdir(exp_dir)

    metrics = []

    for ind, problem in enumerate(problems):
        print(f"Problem {ind+1}/{len(problems)}")
        for _ in range(num_local_solve_tries):
            T_op = sim.generate_random_T(p_wc_extent)
            problem.T_init = T_op
            metrics.append(metrics_fcn(problem))
            metrics[-1]["problem"] = deepcopy(problem)
            metrics[-1]['scene_ind'] = ind
            metrics[-1]['noise_var'] = 'natural'

    with open(os.path.join(exp_dir, "metrics.pkl"), "wb") as f:
        pickle.dump(metrics, f)
    return metrics, exp_dir

def main():
    num_local_solve_tries = 20

    problems, p_wc_extent, y_var = read_dataset('dataset3/dataset3.mat')
    metrics, exp_dir = run_experiment(problems, num_local_solve_tries, p_wc_extent)
    plotting.plot_percent_succ_vs_noise(metrics, os.path.join(exp_dir, "local_vs_iterative_bar.png"))

if __name__ == "__main__":
    main()


class Stacks:
    def __init__(self):
        self.size = 10
        self.tos = -1
        self.array = [0] * self.size

    def __init__(self, size):
        self.size = size
        self.tos = -1
        self.array = [0] * size

    def push(self, value):
        if self.tos == self.size - 1:
            print("Stack is full")
        else:
            self.tos += 1
            self.array[self.tos] = value

    def pop(self):
        if self.tos == -1:
            print("Stack is empty")
        else:
            self.tos -= 1

    def traverse(self):
        temp = self.tos - 1

        if self.tos == -1:
            print("Stack is empty")
        else:
            print("Top of stack is : " + str(self.array[self.tos]))

            if temp > -1:
                print("Other :", end = " ")

            while temp > -1:
                print(self.array[temp], end = " ")
                temp -= 1

            print()

st = Stacks(5)

for i in range(0, 6):
    st.push(i)

st.traverse()

for i in range(0, 6):
    st.pop()

'''
    Output

    Stack is full
    Top of stack is : 4
    Other : 3 2 1 0
    Stack is empty
'''


"""
Given a 2D board and a word, find if the word exists in the grid.

The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.

Example:

board =
[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]

Given word = "ABCCED", return true.
Given word = "SEE", return true.
Given word = "ABCB", return false.
"""

import numpy as np
class Solution(object):
    temp = list();
    def recur(self,board,i,j,word):
        print(i,j,board[i][j],word)
        self.temp[i][j] = 1
        if word == "":
            return True;
        t1 = False
        t2 = False
        t3 = False
        t4 = False
        if j-1>=0 and board[i][j-1] == word[0] and self.temp[i][j-1]!=1:
            t3 = self.recur(board,i,j-1,word.replace(board[i][j-1],"",1))
        if j+1<len(board[0]) and board[i][j+1] == word[0] and self.temp[i][j+1]!=1:
            t4 = self.recur(board,i,j+1,word.replace(board[i][j+1],"",1))
        if i-1>=0 and board[i-1][j] == word[0] and self.temp[i-1][j]!=1:
            t1 = self.recur(board,i-1,j,word.replace(board[i-1][j],"",1))
        if i+1<len(board) and board[i+1][j] ==word[0] and self.temp[i+1][j]!=1:
            t2 = self.recur(board,i+1,j,word.replace(board[i+1][j],"",1))
        if t1==t2==t3==t4==False:
            self.temp[i][j]=0
        return t1 or t2 or t3 or t4
    def exist(self, board, word):
        """
        :type board: List[List[str]]
        :type word: str
        :rtype: bool
        """
        for i in range(len(board)):
            for j in range(len(board[0])):
                if board[i][j] == word[0]:
                    self.temp = np.zeros((len(board), len(board[0])))
                    if self.recur(board,i,j,word.replace(board[i][j],"",1)):
                        return True
        return False


import numpy as np
import pandas as pd
import tensorflow as tf
import os
from scipy.io import arff
from sklearn.preprocessing import MinMaxScaler

def load_data(path='/content/microarray-data/data/', shuffle=False):
  """
  Funkcja działa analogicznie do load_data zbioru MNIST.
  Zwraca (X_train, y_train), (X_test, y_test) o wymiarach:
  (900, 32, 32)
  (900,)
  (157, 32, 32)
  (157,)

  Dla potrzeb wizualizacji każdy gen przyjmuje wymiary kwadratu 32 x 32.
  """
  microarrays = []

  # Załadowanie danych
  for filename in os.listdir(path):
    full_path = os.path.join(path, filename)

    if os.path.isfile(full_path):
      if filename[-5:] == '.arff':
        microarray, _ = arff.loadarff(full_path)
        microarrays.append(microarray)

  # Konkatenacja danych z plików do jednej listy o długości 1057
  data = [*microarrays[0], *microarrays[1], *microarrays[2], *microarrays[3],
          *microarrays[4], *microarrays[5], *microarrays[6], *microarrays[7]]

  # 1057 pacjentów
  patients = len(data)
  # 1000 genów i 1 etykieta na pacjenta
  genes = len(data[0]) - 1

  # Zamiana listy data na macierze numpy
  X_flatten = np.zeros((patients, genes))
  X_reshaped = np.zeros((patients, 32, 32))
  y = np.zeros(patients)

  for i in range(patients):
    for j in range(genes):
      X_flatten[i][j] = data[i][j]

    # Normalizacja w przedziale <0, 1> w obrębie pojedynczego genu
    df = pd.DataFrame(X_flatten[i])
    x = df.select_dtypes(include=[np.number])
    scaler = MinMaxScaler(feature_range=(0, 1))
    x = scaler.fit_transform(x)

    # Dostawienie zer, aby długość genomu była równa 1024
    # I zmiana wymiaru x z (1000, 1) na 1000
    x = np.concatenate((np.reshape(x, 1000), np.zeros(24)))

    # Zmiana kształtu genu na 32 x 32
    X_reshaped[i] = np.reshape(x, (32, 32))

    # Zastąpienie etykiet wartościami logicznymi
    if str(data[i][1000]) == "b'yes'":
      y[i] = 1
    elif str(data[i][1000]) == "b'no'":
      y[i] = 0

  # Przetasowanie elementów
  if shuffle:
    indices = np.arange(patients)
    X = tf.gather(X_reshaped, indices)
    y = tf.gather(y, indices)
  else:
    X = X_reshaped

  # Podział na zbiór treningowy i testowy
  X_train = X[:900]
  X_test = X[-157:]
  y_train = y[:900]
  y_test = y[-157:]

  return (X_train, y_train), (X_test, y_test)

# Do użycia podczas trenowania GANów i sieci niewymagających etykiet
def load_data_by_label(label, path='/content/microarray-data/data/', shuffle=False):
  """
  Zwraca (X_train, X_test) o wymiarach:
  (n, 32, 32)
  (n, 32, 32)
  Gdzie n jest liczbą przypadków oznaczonych daną etykietą.
  """
  (X_train, y_train), (X_test, y_test) = load_data(path=path, shuffle=shuffle)

  assert X_train.shape[0] == y_train.shape[0]
  assert X_test.shape[0] == y_test.shape[0]
  assert label == 0 or label == 1

  X_pos_train = []
  for i in range(X_train.shape[0]):
    if y_train[i] == label:
      X_pos_train.append(X_train[i])

  X_pos_test = []
  for i in range(X_test.shape[0]):
    if y_test[i] == label:
      X_pos_test.append(X_test[i])

  X_pos_train = np.array(X_pos_train)
  X_pos_test = np.array(X_pos_test)

  return X_pos_train, X_pos_test

def convert_to_arff(images, labels, filename_r, filename_w, precision=3):
  """
  Konwersja obrazów z powrotem na plik .arff
  Funkcja przyjmuje argumenty:
  images o wymiarach (n, 32, 32)
  labels o wymiarach (n,)
  filename_r - nazwa pliku .arff, z którego pochodzą dane obrazów i etykiet
  filename_w - nazwa pliku .arff, do którego zostaną zapisane dane z obrazów np. po augmentacji
  precision - liczba cyfr po przecinku w danych, domyślnie 3

  n jest liczbą pacjentów (wierszy) we wczytanym pliku .arff !!
  """
  assert images.shape[1] == images.shape[2] == 32
  assert images.shape[0] == labels.shape[0]

  data_length = images.shape[0]
  genes = 1000

  file_r = open(filename_r, 'r')
  file_w = open(filename_w, 'w')

  # Przepisanie pierwszej linijki do nowego pliku
  lines = file_r.readlines()
  file_w.write(lines[0] + '\n')

  # Przepisanie artybutów
  for line in lines:
    if '@attribute' in line:
      file_w.write(line)

  file_w.write('\n@data \n')

  for i in range(data_length):
    img = np.array(images[i]).reshape(1024)[:1000]

    for j in range(genes):
      file_w.write(str(round(img[j], precision)) + ',')

    if labels[i] == 1:
      file_w.write("'yes' \n")
    elif labels[i] == 0:
      file_w.write("'no' \n")

  file_r.close()
  file_w.close()
  return file_w


# Day 3 - Part 1

def get_vals(lines):
    gamma = ""
    epsilion = ""

    for index in range(len(lines[0])):
        bit0 = 0
        bit1 = 0
        for line in lines:
            if line[index] == "0":
                bit0 += 1
            elif line[index] == "1":
                bit1 += 1
        if bit0 > bit1:
            gamma += "0"
            epsilion += "1"
        else:
            gamma += "1"
            epsilion += "0"

    return  (gamma , epsilion)

if __name__ == "__main__":
    lines = [x.strip() for x in open('input-d3.txt', 'r').readlines()]
    gamma , epsilion = get_vals(lines)
    print(f"GAMMA - BINARY: {int(gamma)}")
    print(f"GAMMA DECIMAL: {int(gamma,2)}")
    print(f"EPSILION - BINARY: {int(epsilion)}")
    print(f"EPSILION DECIMAL: {int(epsilion,2)}")
    print(f"POWER CONSUMPTION: {(int(gamma,2)) * (int(epsilion,2)) }")


import os
import tempfile
from typing import Generator, List

import pytest

from runexpy.utils import DefaultParamsT

@pytest.fixture()
def script() -> List[str]:
    command = """import sys
print("stdout")
print("stderr", file=sys.stderr)
with open("out.txt", "w") as f:
    f.write("file\\n")
"""
    script = ["python3", "-c", f"{command}"]
    return script

@pytest.fixture()
def default_params() -> DefaultParamsT:
    return {
        "p1": "x",
        "p2": 3,
        "p3": None,
    }

@pytest.fixture()
def campaign_dir() -> Generator[str, None, None]:
    with tempfile.TemporaryDirectory() as tempdir:
        yield os.path.join(tempdir, "temp_campaign")


import argparse
import os
import sys
from datetime import datetime

import numpy as np
import torch
import yaml
from tqdm import tqdm

from models.mdrnn import MDRNN
from models.vae import VAE

# checking if the saved_models directory exists or create it
if not os.path.isdir("../saved_models"):
    os.makedirs("../saved_models")

# we want to use GPU if available
device = "cuda" if torch.cuda.is_available() else "cpu"
print("device used:", device)

# import data from the moving mnist dataset
data = np.load("../data/bouncing_mnist_test.npy")
data = data / 255  # normalize the data to be between 0 and 1

def count_parameters(net):
    # return the number of parameters of the model
    return sum(p.numel() for p in net.parameters() if p.requires_grad)

def main(params_path, model_path, model_vae_path):
    # we do not allow the training if there is not a training VAE model
    if model_vae_path is None:
        raise ValueError("no VAE model path given, please train a VAE model first.")
    else:
        print("loading VAE model saved in", model_vae_path)

        vae_params_path_recovery = model_vae_path[:-3] + ".params.yml"
        with open(vae_params_path_recovery) as file:
            vae_parameters = yaml.load(file, Loader=yaml.FullLoader)
        print("using VAE parameters from " + vae_params_path_recovery)

        vae_model = VAE(
            img_channels=vae_parameters["img_channels_vae"],
            latent_dim=vae_parameters["latent_dim_vae"],
            beta=vae_parameters["beta_vae"],
        )
        vae_model.load_state_dict(torch.load(model_vae_path))
        vae_model.to(device)
        print("number of parameters in vae :", count_parameters(vae_model))

    # now we create the MDRNN model
    if model_path is None:
        print("no model path given, training from scratch using default parameters.")
        with open(params_path) as file:
            parameters = yaml.load(file, Loader=yaml.FullLoader)
        model = MDRNN(
            latent_dim=parameters["latent_dim_mdrnn"],
            action_dim=parameters["action_dim_mdrnn"],
            hidden_dim=parameters["hidden_dim_mdrnn"],
            gaussians_nb=parameters["gaussians_nb_mdrnn"],
        )
    else:
        print("loading model saved in", model_path)
        try:
            params_path_recovery = model_path[:-3] + ".params.yml"
            with open(params_path_recovery) as file:
                parameters = yaml.load(file, Loader=yaml.FullLoader)
            print("using parameters from " + params_path_recovery)
        except:
            print("model parameters not found, trying to use default parameters.")
            with open(params_path) as file:
                parameters = yaml.load(file, Loader=yaml.FullLoader)
        model = MDRNN(
            latent_dim=parameters["latent_dim_mdrnn"],
            action_dim=parameters["action_dim_mdrnn"],
            hidden_dim=parameters["hidden_dim_mdrnn"],
            gaussians_nb=parameters["gaussians_nb_mdrnn"],
        )
        model.load_state_dict(torch.load(model_path))

    # even if we load a model, we are going to save a new version of it to not risk any overwriting
    model_name = "model_mdrnn_" + datetime.today().strftime("%Y-%m-%d")

    # we save the corresponding parameters
    with open(
        "../saved_models/vae-mdrnn/" + model_name + ".params.yml", "w"
    ) as outfile:
        yaml.dump(parameters, outfile, default_flow_style=False)

    model = model.to(device)
    batch_size = parameters["batch_size_mdrnn"]
    train_loader = torch.utils.data.DataLoader(
        dataset=data, batch_size=batch_size, shuffle=True
    )

    optimizer = torch.optim.Adam(
        model.parameters(), lr=parameters["learning_rate_mdrnn"]
    )
    print("number of parameters :", count_parameters(model))

    nb_epochs = parameters["nb_epochs_mdrnn"]
    for epoch in range(nb_epochs):
        pbar = tqdm(train_loader)
        pbar.set_description("epoch %s/ loss=? " % str(epoch + 1))
        for x in pbar:
            x = torch.reshape(x, (-1, 1, 64, 64)).float().to(device)
            latents = vae_model.encoder(x)[0]
            # x = torch.transpose(torch.reshape(x,(-1,20,64,64)),0,1).float().to(device)
            latents = torch.transpose(torch.reshape(latents, (-1, 20, 32)), 0, 1)
            seq_len, batch_size, _ = latents.shape

            if model.memory == "rnn":
                hidden = torch.zeros(batch_size, model.hidden_dim).to(device)
            else:
                hidden = (
                    torch.zeros(batch_size, model.hidden_dim).to(device),
                    torch.zeros(batch_size, model.hidden_dim).to(device),
                )
            action = torch.zeros(batch_size, model.action_dim).to(device)

            optimizer.zero_grad()
            episode_loss = []
            for t in range(seq_len - 1):
                latent = latents[t, :, :]
                latent_next_obs = latents[t + 1, :, :]

                if model.memory == "rnn":
                    mus, sigmas, logpi, next_hidden = model(action, latent, hidden)
                    hidden = next_hidden[1].squeeze(0)
                else:
                    mus, sigmas, logpi, next_hidden = model(action, latent, hidden)
                    hidden = next_hidden

                loss = model.loss_function(mus, sigmas, logpi, latent_next_obs)
                episode_loss.append(loss)

            episode_loss = torch.stack(episode_loss).sum()
            episode_loss.backward()
            optimizer.step()

            pbar.set_description(
                "epoch "
                + str(epoch + 1)
                + "/"
                + str(nb_epochs)
                + "  loss= "
                + str(loss.cpu().detach().numpy())
            )

        if (epoch + 1) % 10 == 0:
            torch.save(
                model.state_dict(), "../saved_models/vae-mdrnn/" + model_name + ".pt"
            )

    torch.save(model.state_dict(), "../saved_models/vae-mdrnn/" + model_name + ".pt")
    print(
        "end of training, model saved at",
        "saved_models/vae-mdrnn/" + model_name + ".pt",
    )

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Command line options")
    parser.add_argument(
        "--params_path", type=str, dest="params_path", default="default_parameters.yaml"
    )
    parser.add_argument("--model_path", type=str, dest="model_path", default=None)
    parser.add_argument(
        "--model_vae_path", type=str, dest="model_vae_path", default=None
    )
    args = parser.parse_args(sys.argv[1:])
    main(**{k: v for (k, v) in vars(args).items()})


from typing import Optional, Tuple
from retry import retry

import apimoex
import requests

class MoexAPI:
    @staticmethod
    @retry(tries=3, delay=2, backoff=2)
    def get_ticker_info(session, ticker):
        url = f'https://iss.moex.com/iss/securities/{ticker}.json'
        table = 'boards'
        query = apimoex.requests._make_query(table=table, columns=None)
        data = apimoex.requests._get_short_data(session, url, table, query)
        for info in data:
            if info['secid'] == ticker:
                return info

        raise Exception("No such ticker on MOEX!")

    @staticmethod
    @retry(tries=3, delay=2, backoff=2)
    def get_board_history(
        session: requests.Session,
        security: str,
        start: Optional[str] = None,
        end: Optional[str] = None,
        columns: Optional[Tuple[str, ...]] = (
            "BOARDID",
            "TRADEDATE",
            "CLOSE",
            "VOLUME",
            "VALUE",
        ),
        board: str = "TQBR",
        market: str = "shares",
        engine: str = "stock",
    ):
        return apimoex.get_board_history(session, security, start, end, columns, board, market, engine)


import cherrypy
import urllib
import json
import tumblpy

class OAuthApp:

    def read_config( self ):
        fh = open( "tumblr_config.json")
        tumblr_config = json.load( fh )
        fh.close()
        return tumblr_config

    @cherrypy.expose
    def index( self ):

        callback_url = cherrypy.url("oauth_callback")

        tumblr_config = self.read_config()

        t = tumblpy.Tumblpy( app_key = tumblr_config[ "consumer_key" ],
            app_secret = tumblr_config[ "consumer_secret" ],
            callback_url = callback_url )

        auth_props = t.get_authentication_tokens()
        auth_url = auth_props['auth_url']

        # get token for this session from auth_props
        oauth_token = auth_props['oauth_token']
        oauth_token_secret = auth_props['oauth_token_secret']

        # write token for this session to temp file
        fh = open( "tumblr_authsession_token", "w")
        out = "%s\n%s" % (oauth_token,oauth_token_secret)
        fh.write( out )
        fh.close()

        raise cherrypy.HTTPRedirect( auth_url )

    @cherrypy.expose
    def oauth_callback( self, oauth_token=None, oauth_verifier=None ):
        if oauth_verifier is not None:

            # read session token from temp file
            fh = open( "tumblr_authsession_token")
            token_lines = fh.readlines()
            # oauth_token = token_lines[0]
            oauth_token_secret = token_lines[1]
            fh.close()

            tumblr_config = self.read_config()

            t = tumblpy.Tumblpy( app_key = tumblr_config[ "consumer_key" ],
                app_secret = tumblr_config[ "consumer_secret" ],
                oauth_token=oauth_token,
                oauth_token_secret=oauth_token_secret )

            # get oauth token
            authorized_tokens = t.get_authorized_tokens(oauth_verifier)
            final_oauth_token = authorized_tokens['oauth_token']
            final_oauth_token_secret = authorized_tokens['oauth_token_secret']

            # read exisitng config json
            fh = open( "tumblr_config.json")
            tumblr_config = json.load( fh )
            fh.close()

            # add oauth token
            tumblr_config[ "oauth_token" ] = final_oauth_token
            tumblr_config[ "oauth_secret" ] = final_oauth_token_secret

            # write back out again
            fh = open( "tumblr_config.json", "w" )
            json.dump( tumblr_config, fh )
            fh.close()

        else:
            return "Auth callback didn't get a verifier :("

if __name__ == "__main__":
    cherrypy.config.update( {'server.socket_host':"0.0.0.0", 'server.socket_port':1413 } )
    cherrypy.quickstart( OAuthApp() )


"""empty message

Revision ID: 26c949a8de36
Revises: 20f51de281fe
Create Date: 2022-12-02 12:13:27.533902

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '26c949a8de36'
down_revision = '20f51de281fe'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    with op.batch_alter_table('patients', schema=None) as batch_op:
        batch_op.add_column(sa.Column('patientid', sa.Integer(), nullable=False))
        batch_op.drop_column('id')

    with op.batch_alter_table('user', schema=None) as batch_op:
        batch_op.drop_column('hiredate')

    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    with op.batch_alter_table('user', schema=None) as batch_op:
        batch_op.add_column(sa.Column('hiredate', sa.DATE(), nullable=True))

    with op.batch_alter_table('patients', schema=None) as batch_op:
        batch_op.add_column(sa.Column('id', sa.INTEGER(), nullable=False))
        batch_op.drop_column('patientid')

    # ### end Alembic commands ###


# -*- coding: utf-8 -*-
from flask import (
    Blueprint,
    current_app,
    flash,
    redirect,
    render_template,
    request,
    url_for,
    abort,
    jsonify,
    current_app,
    g
)
import requests

from eternity_backend_server.extensions import csrf_protect
from eternity_backend_server.blueprints.datamin.datamin import bishijieclient
from eternity_backend_server.extensions import db
from eternity_backend_server.blueprints.datamin.models import DATAMINFLAG, DATAMIN
from eternity_backend_server.blueprints.datamin.etherscanclient import etherscanclient
from eternity_backend_server.extensions import db
from eternity_backend_server.settings import ETHERSCAN_APIKEY, ETHERSCAN_TOKEN

datamin_bp = Blueprint("datamin", __name__)

@csrf_protect.exempt
@datamin_bp.route("/news/get", methods=["GET"])
def get_view():
    """获取新闻时讯的数据内容

       @@@
       ### description
       > finished
       ### args
       None

       ### return
       status code: **200**
       ```json

        [
          {
            "content": "A新闻的内容",
            "look_count_flase": "看空12",
            "look_count_true": "看多23",
            "title": "A新闻的标题"
          },
          {
            "content": "B新闻的内容",
            "look_count_flase": "看空25",
            "look_count_true": "看多12",
            "title": "B新闻的标题"
          },
          {
            "content": "C新闻的内容",
            "look_count_flase": "看空33",
            "look_count_true": "看多12",
            "title": "C新闻的标题"
          },
        ]
       ```
       @@@
       """
    datamin = DATAMIN.query.filter().first()
    return jsonify(datamin.datalist)

@csrf_protect.exempt
@datamin_bp.route("/news/send_heartbeat", methods=["GET"])
def send_heartbeat():
    """更新新闻时讯数据库信息

       @@@
       ### description
       > finished
       ### args
       None

       ### return
       status code: **200**
       已经更新过了
       ```json
        {
            "result": "is update",
            "message": [
              {
                "content": "A新闻的内容",
                "look_count_flase": "看空12",
                "look_count_true": "看多23",
                "title": "A新闻的标题"
              },
              {
                "content": "B新闻的内容",
                "look_count_flase": "看空25",
                "look_count_true": "看多12",
                "title": "B新闻的标题"
              },
              {
                "content": "C新闻的内容",
                "look_count_flase": "看空33",
                "look_count_true": "看多12",
                "title": "C新闻的标题"
              },
            ],
            "flag": 1
        }

       status code: **200**
       现在更新成功。
       ```json
        {
            "result": "is update",
            "message": [
              {
                "content": "A新闻的内容",
                "look_count_flase": "看空12",
                "look_count_true": "看多23",
                "title": "A新闻的标题"
              },
              {
                "content": "B新闻的内容",
                "look_count_flase": "看空25",
                "look_count_true": "看多12",
                "title": "B新闻的标题"
              },
              {
                "content": "C新闻的内容",
                "look_count_flase": "看空33",
                "look_count_true": "看多12",
                "title": "C新闻的标题"
              },
            ],
            "flag": 1
        }

       ```
       @@@
       """
    dataminflag = DATAMINFLAG.query.filter(DATAMINFLAG.id==1).first()
    if dataminflag.flag == 1:
        datamin = DATAMIN.query.filter(DATAMIN.id==1).first()
        return jsonify({
            "result": "is update",
            "message": datamin.datalist,
            "flag": dataminflag.flag
        })
    dataminflag.flag = 1
    result = bishijieclient()
    datamin = DATAMIN.query.filter(DATAMIN.id==1).first()
    datamin.type = result.get("info")
    datamin.datalist = result.get("info_list")
    db.session.commit()
    return jsonify({
        "result": "success update",
        "message": datamin.datalist,
        "flag": dataminflag.flag
    })

@csrf_protect.exempt
@datamin_bp.route("/eth/contractaddress", methods=["GET"])
def contract_address():
    """获取合约状态

       @@@
       ### description
       > finished
       ### args
       None

       ### return
       status code: **200**
       ```json
       {
          "message": "OK",
          "result": "0",
          "status": "1"
        }
       ```
       @@@
    """
    ethclient = etherscanclient(ETHERSCAN_TOKEN, ETHERSCAN_APIKEY)
    result = ethclient.contractaddress()
    return jsonify(result)

@csrf_protect.exempt
@datamin_bp.route("/eth/tokencontractaddress", methods=["GET"])
def token_contract_address():
    """获取tokenbalance状态

       @@@
       ### description
       > finished
       ### args
       None

       ### return
       status code: **200**
       ```json
       {
          "message": "OK",
          "result": "0",
          "status": "1"
        }
       ```
       @@@
    """
    ethclient = etherscanclient(ETHERSCAN_TOKEN, ETHERSCAN_APIKEY)
    result = ethclient.tokencontractaddress()
    return jsonify(result)

@csrf_protect.exempt
@datamin_bp.route("/eth/token_info", methods=["GET"])
def token_info():
    """获取token合约的信息

       @@@
       ### description
       > finished
       ### args
       None

       ### return
       status code: **200**
       ```json
        {
          "info_list": [
            {
              "name": "Price",
              "value": "$0.0772 @ 0.000036 Eth (-1.41%)"
            },
            {
              "name": "Fully_Diluted_Market_Cap",
              "value": "$77,244,000.00"
            },
            {
              "name": "Max_Total_Supply",
              "value": "1,000,000,000"
            },
            {
              "name": "Holders",
              "value": "5,098 ( -0.059%)"
            },
            {
              "name": "Volume_24H",
              "value": "$1,794,841.00"
            },
            {
              "name": "Market_Capitalization",
              "value": "$5,299,380.00"
            },
            {
              "name": "Circulating_Supply",
              "value": "68,605,322.00 ARES"
            }
          ],
          "info_name": "basic information",
          "status": true
        }
       ```
       @@@
    """
    ethclient = etherscanclient(ETHERSCAN_TOKEN, ETHERSCAN_APIKEY)
    result = ethclient.token_info()
    return jsonify(result)

@csrf_protect.exempt
@datamin_bp.route("/eth/token_transfers", methods=["GET"])
def token_transfers():
    """获取tokenbalance状态

       @@@
       ### description
       > error api, todo
       ### args
       None

       ### return
       status code: **200**
       ```json
        {}
       ```
       @@@
    """
    ethclient = etherscanclient(ETHERSCAN_TOKEN, ETHERSCAN_APIKEY)
    result = ethclient.token_transfers()
    return jsonify(result)


from math import pi
def g(): return [*map(int, input().split())]

t = int(input()) / (2 * pi)
ans = 0
nums = sorted(g()[::-1] for _ in range(int(input())))
for s, d in nums:
    if t > s * d:
        ans += d
        t -= s * d
    else:
        ans += t // s
        break
print(int(ans))