# -*- coding: utf-8 -*-
"""QGIS Unit tests for QgsServer WMS GetPrint.

From build dir, run: ctest -R PyQgsServerWMSGetPrint -V

.. note:: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

"""
__author__ = 'Alessandro Pasotti'
__date__ = '25/05/2015'
__copyright__ = 'Copyright 2015, The QGIS Project'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '176c06ceefb5f555205e72b20c962740cc0ec183'

import os

# Needed on Qt 5 so that the serialization of XML is consistent among all executions
os.environ['QT_HASH_SEED'] = '1'

import re
import urllib.request
import urllib.parse
import urllib.error

from qgis.testing import unittest
from qgis.PyQt.QtCore import QSize
from qgis.PyQt.QtGui import QImage, QPainter
from qgis.PyQt.QtSvg import QSvgRenderer, QSvgGenerator

import osgeo.gdal  # NOQA
import tempfile
import base64
import subprocess

from test_qgsserver import QgsServerTestBase
from qgis.core import QgsProject, QgsRenderChecker
from qgis.server import QgsServerRequest
from utilities import getExecutablePath, unitTestDataPath

# Strip path and content length because path may vary
RE_STRIP_UNCHECKABLE = b'MAP=[^"]+|Content-Length: \d+'
RE_ATTRIBUTES = b'[^>\s]+=[^>\s]+'

class TestQgsServerWMSGetPrint(QgsServerTestBase):

    def _pdf_to_png(self, pdf_file_path, rendered_file_path, page, dpi=96):

        # PDF-to-image utility
        # look for Poppler w/ Cairo, then muPDF
        # * Poppler w/ Cairo renders correctly
        # * Poppler w/o Cairo does not always correctly render vectors in PDF to image
        # * muPDF renders correctly, but slightly shifts colors
        for util in [
            'pdftocairo',
            # 'mudraw',
        ]:
            PDFUTIL = getExecutablePath(util)
            if PDFUTIL:
                break

        # noinspection PyUnboundLocalVariable
        if not PDFUTIL:
            assert False, ('PDF-to-image utility not found on PATH: '
                           'install Poppler (with Cairo)')

        if PDFUTIL.strip().endswith('pdftocairo'):
            filebase = os.path.join(
                os.path.dirname(rendered_file_path),
                os.path.splitext(os.path.basename(rendered_file_path))[0]
            )
            call = [
                PDFUTIL, '-png', '-singlefile', '-r', str(dpi),
                '-x', '0', '-y', '0', '-f', str(page), '-l', str(page),
                pdf_file_path, filebase
            ]
        elif PDFUTIL.strip().endswith('mudraw'):
            call = [
                PDFUTIL, '-c', 'rgba',
                '-r', str(dpi), '-f', str(page), '-l', str(page),
                # '-b', '8',
                '-o', rendered_file_path, pdf_file_path
            ]
        else:
            return False, ''

        print("exportToPdf call: {0}".format(' '.join(call)))
        try:
            subprocess.check_call(call)
        except subprocess.CalledProcessError as e:
            assert False, ("exportToPdf failed!\n"
                           "cmd: {0}\n"
                           "returncode: {1}\n"
                           "message: {2}".format(e.cmd, e.returncode, e.message))

    def _pdf_diff(self, pdf, control_image, max_diff, max_size_diff=QSize(), dpi=96):

        temp_pdf = os.path.join(tempfile.gettempdir(), "%s_result.pdf" % control_image)

        with open(temp_pdf, "wb") as f:
            f.write(pdf)

        temp_image = os.path.join(tempfile.gettempdir(), "%s_result.png" % control_image)
        self._pdf_to_png(temp_pdf, temp_image, dpi=dpi, page=1)

        control = QgsRenderChecker()
        control.setControlPathPrefix("qgis_server")
        control.setControlName(control_image)
        control.setRenderedImage(temp_image)
        if max_size_diff.isValid():
            control.setSizeTolerance(max_size_diff.width(), max_size_diff.height())
        return control.compareImages(control_image, max_diff), control.report()

    def _pdf_diff_error(self, response, headers, image, max_diff=100, max_size_diff=QSize(), unittest_data_path='control_images', dpi=96):

        reference_path = unitTestDataPath(unittest_data_path) + '/qgis_server/' + image + '/' + image + '.pdf'
        self.store_reference(reference_path, response)

        self.assertEqual(
            headers.get("Content-Type"), 'application/pdf',
            "Content type is wrong: %s instead of %s\n%s" % (headers.get("Content-Type"), 'application/pdf', response))

        test, report = self._pdf_diff(response, image, max_diff, max_size_diff, dpi)

        with open(os.path.join(tempfile.gettempdir(), image + "_result.pdf"), "rb") as rendered_file:
            if not os.environ.get('ENCODED_OUTPUT'):
                message = "PDF is wrong\: rendered file %s/%s_result.%s" % (tempfile.gettempdir(), image, 'pdf')
            else:
                encoded_rendered_file = base64.b64encode(rendered_file.read())
                message = "PDF is wrong\n%s\File:\necho '%s' | base64 -d >%s/%s_result.%s" % (
                    report, encoded_rendered_file.strip().decode('utf8'), tempfile.gettempdir(), image, 'pdf'
                )

        with open(os.path.join(tempfile.gettempdir(), image + "_result.png"), "rb") as rendered_file:
            if not os.environ.get('ENCODED_OUTPUT'):
                message = "Image is wrong\: rendered file %s/%s_result.%s" % (tempfile.gettempdir(), image, 'png')
            else:
                encoded_rendered_file = base64.b64encode(rendered_file.read())
                message = "Image is wrong\n%s\nImage:\necho '%s' | base64 -d >%s/%s_result.%s" % (
                    report, encoded_rendered_file.strip().decode('utf8'), tempfile.gettempdir(), image, 'png'
                )

        # If the failure is in image sizes the diff file will not exists.
        if os.path.exists(os.path.join(tempfile.gettempdir(), image + "_result_diff.png")):
            with open(os.path.join(tempfile.gettempdir(), image + "_result_diff.png"), "rb") as diff_file:
                if not os.environ.get('ENCODED_OUTPUT'):
                    message = "Image is wrong\: diff file %s/%s_result_diff.%s" % (tempfile.gettempdir(), image, 'png')
                else:
                    encoded_diff_file = base64.b64encode(diff_file.read())
                    message += "\nDiff:\necho '%s' | base64 -d > %s/%s_result_diff.%s" % (
                        encoded_diff_file.strip().decode('utf8'), tempfile.gettempdir(), image, 'png'
                    )

        self.assertTrue(test, message)

    def _svg_to_png(svg_file_path, rendered_file_path, width):
        svgr = QSvgRenderer(svg_file_path)

        height = width / svgr.viewBoxF().width() * svgr.viewBoxF().height()

        image = QImage(width, height, QImage.Format_ARGB32)
        image.fill(Qt.transparent)

        p = QPainter(image)
        p.setRenderHint(QPainter.Antialiasing, False)
        svgr.render(p)
        p.end()

        res = image.save(rendered_file_path, 'png')
        if not res:
            os.unlink(rendered_file_path)

    """QGIS Server WMS Tests for GetPrint request"""

    def test_wms_getprint_basic(self):
        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetPrint",
            "TEMPLATE": "layoutA4",
            "map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
            "map0:LAYERS": "Country,Hello",
            "CRS": "EPSG:3857"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetPrint_Basic")

        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetPrint",
            "TEMPLATE": "layoutA4",
            "FORMAT": "png",
            "map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
            "LAYERS": "Country,Hello",
            "CRS": "EPSG:3857"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetPrint_Basic")

        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetPrint",
            "TEMPLATE": "layoutA4",
            "FORMAT": "png",
            "map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
            "map0:LAYERS": "Country,Hello",
            "LAYERS": "Country,Hello",
            "CRS": "EPSG:3857"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetPrint_Basic")

        # Output JPEG
        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetPrint",
            "TEMPLATE": "layoutA4",
            "FORMAT": "jpeg",
            "map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
            "LAYERS": "Country,Hello",
            "CRS": "EPSG:3857"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetPrint_Basic", outputJpg=True)

        # Output PDF
        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetPrint",
            "TEMPLATE": "layoutA4",
            "FORMAT": "pdf",
            "map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
            "LAYERS": "Country,Hello",
            "CRS": "EPSG:3857"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        self._pdf_diff_error(r, h, "WMS_GetPrint_Basic_Pdf", dpi=300)

    def test_wms_getprint_style(self):
        # default style
        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetPrint",
            "TEMPLATE": "layoutA4",
            "FORMAT": "png",
            "map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
            "map0:LAYERS": "Country_Labels",
            "CRS": "EPSG:3857"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        assert h.get("Content-Type").startswith('image'), r
        self._img_diff_error(r, h, "WMS_GetPrint_StyleDefault")

        # custom style
        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetPrint",
            "TEMPLATE": "layoutA4",
            "FORMAT": "png",
            "map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
            "map0:LAYERS": "Country_Labels",
            "map0:STYLES": "custom",
            "CRS": "EPSG:3857"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetPrint_StyleCustom")

        # default style
        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetPrint",
            "TEMPLATE": "layoutA4",
            "FORMAT": "png",
            "map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
            "LAYERS": "Country_Labels",
            "CRS": "EPSG:3857"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetPrint_StyleDefault")

        # custom style
        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetPrint",
            "TEMPLATE": "layoutA4",
            "FORMAT": "png",
            "map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
            "LAYERS": "Country_Labels",
            "STYLES": "custom",
            "CRS": "EPSG:3857"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetPrint_StyleCustom")

        # default style
        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetPrint",
            "TEMPLATE": "layoutA4",
            "FORMAT": "png",
            "map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
            "map0:LAYERS": "Country_Labels",
            "LAYERS": "Country_Labels",
            "CRS": "EPSG:3857"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetPrint_StyleDefault")

        # custom style
        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetPrint",
            "TEMPLATE": "layoutA4",
            "FORMAT": "png",
            "map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
            "map0:LAYERS": "Country_Labels",
            "map0:STYLES": "custom",
            "LAYERS": "Country_Labels",
            "CRS": "EPSG:3857"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetPrint_StyleCustom")

    def test_wms_getprint_legend(self):
        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetPrint",
            "TEMPLATE": "layoutA4copy",
            "FORMAT": "png",
            "map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
            "map0:LAYERS": "Country,Hello",
            "CRS": "EPSG:3857"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetPrint_Legend")

    def test_wms_getprint_srs(self):
        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetPrint",
            "TEMPLATE": "layoutA4",
            "FORMAT": "png",
            "map0:EXTENT": "-309.015,-133.011,312.179,133.949",
            "map0:LAYERS": "Country,Hello",
            "CRS": "EPSG:4326"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetPrint_SRS")

    def test_wms_getprint_scale(self):
        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetPrint",
            "TEMPLATE": "layoutA4",
            "FORMAT": "png",
            "map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
            "map0:LAYERS": "Country,Hello",
            "map0:SCALE": "36293562",
            "CRS": "EPSG:3857"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetPrint_Scale")

    def test_wms_getprint_grid(self):
        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetPrint",
            "TEMPLATE": "layoutA4",
            "FORMAT": "png",
            "map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
            "map0:LAYERS": "Country,Hello",
            "map0:GRID_INTERVAL_X": "1000000",
            "map0:GRID_INTERVAL_Y": "2000000",
            "CRS": "EPSG:3857"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetPrint_Grid")

    def test_wms_getprint_rotation(self):
        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetPrint",
            "TEMPLATE": "layoutA4",
            "FORMAT": "png",
            "map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
            "map0:LAYERS": "Country,Hello",
            "map0:ROTATION": "45",
            "CRS": "EPSG:3857"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetPrint_Rotation")

    def test_wms_getprint_selection(self):
        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetPrint",
            "TEMPLATE": "layoutA4",
            "FORMAT": "png",
            "LAYERS": "Country,Hello",
            "map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
            "map0:LAYERS": "Country,Hello",
            "CRS": "EPSG:3857",
            "SELECTION": "Country: 4"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetPrint_Selection")

        # Output PDF
        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetPrint",
            "TEMPLATE": "layoutA4",
            "FORMAT": "pdf",
            "LAYERS": "Country,Hello",
            "map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
            "map0:LAYERS": "Country,Hello",
            "CRS": "EPSG:3857",
            "SELECTION": "Country: 4"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        self._pdf_diff_error(r, h, "WMS_GetPrint_Selection_Pdf", dpi=300)

    def test_wms_getprint_opacity(self):
        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetPrint",
            "TEMPLATE": "layoutA4",
            "FORMAT": "png",
            "map0%3AEXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
            "map0:LAYERS": "Country,Hello",
            "CRS": "EPSG:3857",
            "SELECTION": "Country: 4",
            "LAYERS": "Country,Hello",
            "OPACITIES": "125,125"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetPrint_Opacity")

    def test_wms_getprint_opacity_post(self):
        qs = "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetPrint",
            "TEMPLATE": "layoutA4",
            "FORMAT": "png",
            "map0%3AEXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
            "map0:LAYERS": "Country,Hello",
            "CRS": "EPSG:3857",
            "SELECTION": "Country: 4",
            "LAYERS": "Country,Hello",
            "OPACITIES": "125%2C125"
        }.items())])

        r, h = self._result(self._execute_request('', QgsServerRequest.PostMethod, data=qs.encode('utf-8')))
        self._img_diff_error(r, h, "WMS_GetPrint_Opacity")

    def test_wms_getprint_highlight(self):
        # default style
        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetPrint",
            "TEMPLATE": "layoutA4",
            "FORMAT": "png",
            "map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
            "map0:LAYERS": "Country_Labels",
            "map0:HIGHLIGHT_GEOM": "POLYGON((-15000000 10000000, -15000000 6110620, 2500000 6110620, 2500000 10000000, -15000000 10000000))",
            "map0:HIGHLIGHT_SYMBOL": "<StyledLayerDescriptor><UserStyle><Name>Highlight</Name><FeatureTypeStyle><Rule><Name>Symbol</Name><LineSymbolizer><Stroke><SvgParameter name=\"stroke\">%23ea1173</SvgParameter><SvgParameter name=\"stroke-opacity\">1</SvgParameter><SvgParameter name=\"stroke-width\">1.6</SvgParameter></Stroke></LineSymbolizer></Rule></FeatureTypeStyle></UserStyle></StyledLayerDescriptor>",
            "map0:HIGHLIGHT_LABELSTRING": "Highlight Layer!",
            "map0:HIGHLIGHT_LABELSIZE": "16",
            "map0:HIGHLIGHT_LABELCOLOR": "%2300FF0000",
            "map0:HIGHLIGHT_LABELBUFFERCOLOR": "%232300FF00",
            "map0:HIGHLIGHT_LABELBUFFERSIZE": "1.5",
            "CRS": "EPSG:3857"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        assert h.get("Content-Type").startswith('image'), r
        self._img_diff_error(r, h, "WMS_GetPrint_Highlight")

    def test_wms_getprint_label(self):
        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetPrint",
            "TEMPLATE": "layoutA4",
            "FORMAT": "png",
            "map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
            "map0:LAYERS": "Country,Hello",
            "CRS": "EPSG:3857",
            "IDTEXTBOX": "Updated QGIS composer label"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetPrint_LabelUpdated")

        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetPrint",
            "TEMPLATE": "layoutA4",
            "FORMAT": "png",
            "map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
            "map0:LAYERS": "Country,Hello",
            "CRS": "EPSG:3857",
            "IDTEXTBOX": ""
        }.items())])

        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetPrint_LabelRemoved")

    def test_wms_getprint_two_maps(self):
        """Test map0 and map1 apply to the correct maps"""
        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetPrint",
            "TEMPLATE": "layoutA4twoMaps",
            "FORMAT": "png",
            "map0:EXTENT": "11863620.20301065221428871,-5848927.97872077487409115,19375243.89574331790208817,138857.97204941",
            "map0:LAYERS": "Country",
            "map1:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
            "map1:LAYERS": "Country,Hello",
            "CRS": "EPSG:3857",
            "IDTEXTBOX": "",
        }.items())])

        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetPrint_TwoMaps")

    def test_wms_getprint_atlas(self):
        qs = "?" + "&".join(["%s=%s" % i for i in list({
             "MAP": urllib.parse.quote(self.projectPath),
             "SERVICE": "WMS",
             "VERSION": "1.3.0",
             "REQUEST": "GetPrint",
             "TEMPLATE": "layoutA4",
             "FORMAT": "png",
             "CRS": "EPSG:3857",
             "ATLAS_PK": "3",
             "map0:LAYERS": "Country,Hello",
        }.items())])
        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetPrint_Atlas")

    def test_wms_getprint_atlas_getProjectSettings(self):
        qs = "?" + "&".join(["%s=%s" % i for i in list({
             "MAP": urllib.parse.quote(self.projectPath),
             "SERVICE": "WMS",
             "VERSION": "1.3.0",
             "REQUEST": "GetProjectSettings",
        }.items())])
        r, h = self._result(self._execute_request(qs))
        self.assertTrue('atlasEnabled="1"' in str(r))
        self.assertTrue('<PrimaryKeyAttribute>' in str(r))

    @unittest.skipIf(os.environ.get('TRAVIS', '') == 'true', 'Can\'t rely on external resources for continuous integration')
    def test_wms_getprint_external(self):
        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetPrint",
            "TEMPLATE": "layoutA4",
            "map0:EXTENT": "-90,-180,90,180",
            "map0:LAYERS": "EXTERNAL_WMS:landsat",
            "landsat:layers": "GEBCO_LATEST",
            "landsat:dpiMode": "7",
            "landsat:url": "https://www.gebco.net/data_and_products/gebco_web_services/web_map_service/mapserv",
            "landsat:crs": "EPSG:4326",
            "landsat:styles": "default",
            "landsat:format": "image/jpeg",
            "landsat:bbox": "-90,-180,90,180",
            "landsat:version": "1.3.0",
            "CRS": "EPSG:4326"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetPrint_External")

if __name__ == '__main__':
    unittest.main()


import os, sys
import traceback
from threading import Thread
from functools import partial
try:
    from importlib import reload
except:
    pass
from kivy.lang import Builder
from kivy.clock import mainthread
from kivy.resources import resource_add_path, resource_remove_path
# from kivystudio.components.emulator_area import emulator_area
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.behaviors import ToggleButtonBehavior
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.properties import ObjectProperty, StringProperty
from kivy.clock import Clock
import os
# __all__ = ('get_emulator',)
# filepath = os.path.dirname(__file__)
# Builder.load_file(os.path.join(filepath, 'emulator.kv'))

# class EmulatorArea(BoxLayout):
#     screen_display = ObjectProperty(None)
#     emulation_file = StringProperty('')
#
#     def __init__(self, **kwargs):
#         super(EmulatorArea, self).__init__(**kwargs)
#         self.screen_manager = EmulatorScreens()
#         self.add_widget(self.screen_manager)
#         # self.screen_display = ScreenDisplay()
#         self.screen_manager.add_widget(self.screen_display)
#
#     def add_widget(self, widget):
#         super(EmulatorArea, self).add_widget(widget)

    # def toggle_orientation(self):
    #     if self.screen_display.screen.orientation == 'portrait':
    #         self.screen_display.screen.orientation = 'landscape'
    #     else:
    #         self.screen_display.screen.orientation = 'portrait'

    # def open_screen_drop(self, widget):
    #     ScreenDrop().open(widget, self.screen_display)

#
# instance = []
#
#
# def emulator_area():
#     if instance:
#         return instance[0]
#     else:
#         emulator_area = EmulatorArea(size_hint_x=.45)
#         instance.append(emulator_area)
#         return emulator_area

def emulate_file(filename, threaded=False):
    root = None
    if not os.path.exists(filename):
        return

    dirname = os.path.dirname(filename)
    sys.path.append(dirname)
    os.chdir(dirname)
    resource_add_path(dirname)

    emulator_area().screen_display.screen.clear_widgets()

    if threaded:
        Thread(target=partial(start_emulation, filename, threaded=threaded)).start()
    else:
        start_emulation(filename, threaded=threaded)

def start_emulation(filename, threaded=False):
    root = None
    if os.path.splitext(filename)[1] == '.kv':  # load the kivy file directly
        try:  # cahching error with kivy files
            Builder.unload_file(filename)
            root = Builder.load_file(filename)
        except:
            traceback.print_exc()
            print("You kivy file has a problem")

    elif os.path.splitext(filename)[1] == '.py':
        load_defualt_kv(filename)

        try:  # cahching error with python files
            root = load_py_file(filename)
        except:
            traceback.print_exc()
            print("You python file has a problem")

    if root:
        if threaded:
            emulation_done(root, filename)
        else:
            emulator_area().screen_display.screen.add_widget(root)

    dirname = os.path.dirname(filename)
    sys.path.pop()
    resource_remove_path(dirname)

@mainthread
def emulation_done(root, filename):
    if root:
        emulator_area().screen_display.screen.add_widget(root)

def load_defualt_kv(filename):
    app_cls_name = get_app_cls_name(filename)
    if app_cls_name is None:
        return

    kv_name = app_cls_name.lower()
    if app_cls_name.endswith('App'):
        kv_name = app_cls_name[:len(app_cls_name) - 3].lower()

    if app_cls_name:
        file_dir = os.path.dirname(filename)
        kv_filename = os.path.join(file_dir, kv_name + '.kv')

        if os.path.exists(kv_filename):
            try:  # cahching error with kivy files
                Builder.unload_file(kv_filename)
                root = Builder.load_file(kv_filename)
            except:
                traceback.print_exc()
                print("You kivy file has a problem")

def get_app_cls_name(filename):
    with open(filename) as fn:
        text = fn.read()

    lines = text.splitlines()
    app_cls = get_import_as('from kivy.app import App', lines)

    def check_app_cls(line):
        line = line.strip()
        return line.startswith('class') and line.endswith('(%s):' % app_cls)

    found = list(filter(check_app_cls, lines))

    if found:
        line = found[0]
        cls_name = line.split('(')[0].split(' ')[1]
        return cls_name

def get_root_from_runTouch():
    with open(filename) as fn:
        text = fn.read()

    lines = text.splitlines()
    run_touch = get_import_as('from kivy.base import runTouchApp', lines)

    def check_run_touch(line):
        line = line.strip()
        return line.startswith('%s(' % run_touch)

    found = list(filter(check_run_touch, lines))

    if found:
        line = found[0]
        root_name = line.strip().split('(')[1].split(')')[0]

        root_file = import_from_dir(filename)
        root = getattr(reload(root_file), root_name)

        return root

def load_py_file(filename):
    app_cls_name = get_app_cls_name(filename)
    if app_cls_name:
        root_file = import_from_dir(filename)
        app_cls = getattr(reload(root_file), app_cls_name)
        root = app_cls().build()

        return root

    run_root = get_root_from_runTouch(filename)
    if run_root:
        return run_root

def import_from_dir(filename):
    ''' force python to import this file
    from the project_ dir'''

    dirname, file = os.path.split(filename)
    sys.path = [dirname] + sys.path

    import_word = os.path.splitext(file)[0]
    imported = __import__(import_word)
    return imported

def get_import_as(start, lines):
    line = list(filter(lambda line: line.strip().startswith(start), lines))
    if line:
        words = line[0].split(' ')
        import_word = words[len(words) - 1]
        return import_word
    else:
        return


from torch import nn
from torch.nn import functional as F
import torch

class Generator(nn.Module):
    def __init__(self, gen,dim_g,dim_z):
        super(Generator, self).__init__()
        self.m = gen(dim_g,dim_z)
        self.dim_z = dim_z

    def forward(self, x):
        return self.m(x)

class Discriminator(nn.Module):
    def __init__(self, dis, dim_z):
        super(Discriminator, self).__init__()
        self.m = dis(dim_z)
        self.dim_z=dim_z

    def forward(self, x):
        return self.m(x)

class LWG(nn.Module):
    def __init__(self,dim_g, dim_z):
        super(LWG, self).__init__()

        self.dim_z = dim_z
        self.dim_g = dim_g

        self.m = nn.Sequential(
            nn.Linear(self.dim_g,128),
            nn.BatchNorm1d(128),
            nn.ReLU(),

	        nn.Linear(128, 128),
	        nn.BatchNorm1d(128),
	        nn.ReLU(),

	        nn.Linear(128, 128),
	        nn.BatchNorm1d(128),
	        nn.ReLU(),

	        nn.Linear(128,self.dim_z),
	        # nn.BatchNorm1d(100),
        )

    def forward(self, x):
        x = self.m(x)
        return x

class LWD(nn.Module):
    def __init__(self, dim_z):
        super(LWD, self).__init__()

        self.dim_z = dim_z

        self.m = nn.Sequential(
            nn.Linear(self.dim_z,128),
            nn.BatchNorm1d(128),
            nn.LeakyReLU(1e-1,inplace=True),

	        nn.Linear(128,128),
	        nn.BatchNorm1d(128),
	        nn.LeakyReLU(1e-1,inplace=True),
            #512*1*1

	        nn.Linear(128,128),
	        nn.BatchNorm1d(128),
	        nn.LeakyReLU(1e-1,inplace=True),

	        nn.Linear(128,1),
	        # nn.BatchNorm1d(1),
        )

    def forward(self, x):
        x = self.m(x)
        return x

_CONFIG_MAP = {
    'lwgan':(LWG,LWD),
}

def load_config(name):
    """Load a particular configuration
    Returns:
    (encoder, transition, decoder) A tuple containing class constructors
    """
    if name not in _CONFIG_MAP.keys():
        raise ValueError("Unknown config: %s", name)
    return _CONFIG_MAP[name]

__all__ = ['load_config']


import os
import numpy as np
import re

#1 Ignore warnings
import warnings
warnings.filterwarnings("ignore")

#2 Define different filepaths
global_filepath = 'C:/Users/lir58/Desktop/Jierui/Dataset'
otb50_filepath = 'C:/Users/lir58/Desktop/Jierui/Dataset/OTB50'
#os.chdir(global_filepath)

#3 Build the datasets
"""
#There are 100 datasets, and each dataset will be imported seperately
#The images in each folder are the input datasets
#The groundtruth values (each line) in the text files are the output datasets
"""
#3.1 Build the X datasets
import glob
import cv2
from PIL import Image
import matplotlib.pyplot as plt
def X_dataset(datasetpath, read_foldername):   #grab the images and put into the input dataset
    X_eachfolder = []
    folderpath = datasetpath + '/' + read_foldername + '/img'
    file_name = glob.glob(folderpath + "/*.jpg")
    for i in range(len(os.listdir(folderpath))):
        img = cv2.imread(file_name[i])
        X_eachfolder.append(img)
    return X_eachfolder
"""
#Now different input datasets could be imported, for example:
import matplotlib.pyplot as plt
David_X = X_dataset('David')
img = David_X[0]; plt.figure(); plt.imshow(img); plt.show()
"""
#3.2 Build the output dataset
def line_to_array(line):
    new_line1 = []
    new_line2 = line.replace('\n', '')

    if ',' in new_line2:
        for i in new_line2.split(','):
           new_line1.append(int(i))

    if '\t' in new_line2:
        for i in new_line2.split('\t'):
            new_line1.append(int(i))

    new_line = np.array(new_line1)
    return new_line
def y_dataset(datasetpath, read_foldername):
    y_eachline = []
    fileloc = datasetpath + '/' + read_foldername + '/groundtruth_rect.txt'
    text = open(fileloc)
    for line in text.readlines():
        new_line = line_to_array(line)
        y_eachline.append(new_line)
    return y_eachline

#Now different output datasets could be imported, for example:
#David_y = y_dataset('David')
#print(David_y[0])


import ipaddress
import csv
import argparse
from argparse import RawTextHelpFormatter
from cidrize import cidrize

parser = argparse.ArgumentParser(description='IP Subnet Checker',formatter_class=RawTextHelpFormatter)
parser.add_argument('-s', '--subnet', dest='subnet',  type=str, required=False, help='A subnet to check against.\n\n', metavar='<subnet>')
parser.add_argument('-S', '--subnets_file', dest='subnets_file',  type=str, required=False, help='CSV file containing a list of subnets to check against.\n\nFormat - IPAddress, Name\n\n', metavar='<filename>')
parser.add_argument('-i', '--ip_address', dest='ip_address',  type=str, required=False, help='IP address to check in subnet.\n\n', metavar='<ip address>')
parser.add_argument('-I', '--ip_file', dest='ip_file',  type=str, required=False, help='CSV file containing IP addresses to check in subnet.\n\nFormat - Subnet, Name\n\n', metavar='<filename>')
parser.add_argument('-o', '--output_file', dest='output_file',  type=str, required=False, help='Specify a CSV output_file file.\n\n', metavar='<filename>')

args = parser.parse_args()
subnet = args.subnet
subnets_file = args.subnets_file
ip_addr = args.ip_address
ip_file = args.ip_file
output_file = args.output_file

def range_to_ips(iprange):
    list_of_ips = []
    if iprange:
        try:
            ipaddr = ipaddress.ip_address(iprange)
            list_of_ips.append(ipaddr)
        except:
            try:
                ipaddrs = ipaddress.ip_network(iprange)
                for ipaddr in ipaddrs:
                    list_of_ips.append(ipaddr)
            except:
                try:
                    ipaddrs = ipaddress.ip_network(iprange,strict=False)
                    msg = 'Address %s is not valid CIDR syntax, using recommended CIDR: %s' % (iprange, ipaddrs)
                    print(msg)
                    for ipaddr in ipaddrs:
                        list_of_ips.append(ipaddr)
                except:
                    try:
                        cidrip = cidrize(iprange)
                        for cidr in cidrip:
                            ipaddrs = ipaddress.ip_network(cidr)
                            for ipaddr in ipaddrs:
                                list_of_ips.append(ipaddr)
                    except:
                        msg = 'Address %s is not valid CIDR syntax, cannot process!' % (iprange)
                        print(msg)
    return list_of_ips

def validate_subnet(subnet):
    if subnet:
        try:
            ip = ipaddress.ip_address(subnet)
            subbed = ipaddress.ip_network(ip)
            return subbed
        except:
            try:
                subbed = ipaddress.ip_network(subnet)
                return subbed
            except:
                try:
                    subbed = ipaddress.ip_network(subnet,strict=False)
                    msg = 'Address %s is not valid CIDR syntax, using recommended CIDR: %s' % (subnet, subbed)
                    print(msg)
                    return subbed
                except:
                    try:
                        cidrip = cidrize(subnet)
                        subbed = ipaddress.ip_network(cidrip)
                        return subbed
                    except:
                        msg = 'Subnet %s is not valid CIDR syntax, cannot process!' % (subnet)
                        print(msg)

def output(ip,ip_name,valid_subnet,subnet,sub_name):
    if valid_subnet:
        if ip in valid_subnet:
            values = [str(ip),ip_name,str(valid_subnet),sub_name,True,ip_addr,subnet]
            msg = ("IP Address",values[0],"found in",values[2],"( Inputted Address:",values[5],"Inputted Subnet:",values[6],")")
        else:
            values = [str(ip),ip_name,str(valid_subnet),sub_name,False,ip_addr,subnet]
            msg = ("IP Address",values[0],"NOT in",values[2],"( Inputted Address:",values[5],"Inputted Subnet:",values[6],")")
        if output_file:
            mapped.append(values)
        else:
            print(' '.join(str(s) for s in msg))
            mapped.append(values)
    return mapped

def checkIPs(ip_addr,ip_name=None):
    count = 0
    ip_list = range_to_ips(ip_addr)
    for ip in ip_list:
        count += 1
        if subnet:
            validated = validate_subnet(subnet)
            mapped = output(ip,ip_name,validated,subnet,None)
        elif subnets_file:
            with open(subnets_file) as file:
                reader = csv.reader(file)
                for line in reader:
                    subnet_ip = line[0]
                    sub_name = line[1]
                    validated = validate_subnet(subnet_ip)
                    mapped = output(ip,ip_name,validated,subnet_ip,sub_name)
    mapped.sort( key = lambda k: ipaddress.ip_address(k[0]) )
    return mapped

mapped = []

if ip_addr:
    mapped = checkIPs(ip_addr)
    mapped.insert(0, [ "IP Address", "IP Name", "Subnet", "Subnet Name", "In Subnet", "Inputted Address", "Inputted Subnet" ])
elif ip_file:
    with open(ip_file) as file:
        reader = csv.reader(file)
        count = 0
        for line in reader:
            ip_addr = line[0]
            ip_name = line[1]
            mapped = checkIPs(ip_addr,ip_name)
        mapped.insert(0, [ "IP Address", "IP Name", "Subnet", "Subnet Name", "In Subnet", "Inputted Address", "Inputted Subnet" ])

print (len(mapped)-1,"IP addresses processed.\n")

if output_file:
    with open(output_file, 'w', newline='') as file:
        writer = csv.writer(file)
        writer.writerows(mapped)
    print("Results saved to",output_file,"\n")


import pickle
from pathlib import Path
import streamlit_authenticator as stauth
import streamlit as st
import pandas as pd
import numpy as np
import plotly.express as px

st.set_page_config(page_title="Area Sales 2023",
                   page_icon="bar_chart:",
                   layout="wide")

df = pd.read_excel("dfstoreTotal.xlsx")

##---------------Sidebar------------------

st.sidebar.header('Welcome to the Sales Report by Area:')

Week = st.sidebar.selectbox(
    "Select the Week:",
    options=df["Week"].unique())

Area = st.sidebar.selectbox(
 "Select the Area:",
  options=df["AREA"].unique(),)

##Store = st.sidebar.multiselect(
  ##"Select the Store:",
  ##options=df["Stores"])

st.markdown("##")

##Week1 = st.sidebar._selectbox(
  ##"Select the Store:",
    ##options=df1["Week"].unique())

df_selection = df.query("Week == @Week & AREA == @Area")
##df_selection1 = df2.query("Week == @Week1")

st.title(":bar_chart: Sales Report by Area 2023")
st.markdown("##")

total_sales = int(df_selection["Sales Report"].sum())
total_units = int(df_selection["LY"].sum())

left_column,right_column = st.columns(2)

with left_column:
 st.subheader("Total Sales:")
 st.subheader(f"EU € {total_sales:,}")

with right_column :
 st.subheader("Last Year Sales 2022:")
 st.subheader(f"EU € {total_units:,}")

st.markdown("---")

dfchart = px.bar(df_selection,
                 x = "Stores", y="Sales Report", text_auto=',',
                 title="Sales by Area", height=600,
                color_discrete_sequence=["#fa6e0a"] * len(df_selection),
    template="simple_white",)
dfchart.update_traces(textfont_size=15, textangle=0, textposition="outside", cliponaxis=False)

##st.plotly_chart(dfchart)
##st.dataframe(df_selection)
st.write(':loudspeaker: From Week 29 *Area Manager Changed!* :heavy_exclamation_mark:')

st.plotly_chart(dfchart, use_container_width=True)

st.markdown("---")

st.write(':loudspeaker: From Week 29 *Area Manager Changed!* :heavy_exclamation_mark:')
df_selection

st.markdown("---")

##fig_sales = px.bar(df,
  ##x="Sales Report",
   ## y="Stores",
##title="Sales",
  ##   color_discrete_sequence=["#0085B8"],
    ##  template="simple_white",)

##Sales = (
 ##df_selection.groupby(by=["ItemGroup"]).sum()[["SALES"]].sort_values(by="SALES"))

##fig_sales = px.bar(sales_by_Category,
  ##    x="SALES",
    ##  y=sales_by_Category.index,
     ## title="Sales by Category",
     ## color_discrete_sequence=["#0085B8"] *len (sales_by_Category),
      ##template="simple_white",)

##sales_by_SubCategory = (
 ##df_selection.groupby(by=["ItemSubGrp_Id"]).sum()[["SALES"]].sort_values(by="SALES")
##)

#fig_Subsales = px.bar(sales_by_SubCategory,
 ##     x="SALES",
   ##   y=sales_by_SubCategory.index,
     ## title="Sales by SubCategory",
     ## color_discrete_sequence=["#0095B8"] *len (sales_by_SubCategory),
     ## template="simple_white",)


from django.shortcuts import render, get_object_or_404
from front.forms import BusinessForm
from front.models import Business, Category, County, Area, CustomBusinessGroup
from django.http import HttpResponseRedirect
from django.contrib.auth.decorators import login_required

def index(request):
    with open('featured.txt') as f:
        featured =  map(int, f)

    featured_businesses = Business.objects.filter(pk__in=featured)

    return render(request, 'front/index.html',
            {
                'featured_businesses': featured_businesses,
            }
        )

def category(request, slug):
    category = get_object_or_404(Category, slug=slug)
    businesses = Business.objects.all().filter(category=category)
    return render(request, 'front/businesses.html',
        {
            'category': category,
            'businesses': businesses,
        }
    )

def business(request, slug):
    business = get_object_or_404(Business, slug=slug)
    category = Category.objects.get(name=business.category)
    county = County.objects.get(name=business.county)
    related_businesses = business.tags.similar_objects()[:5]
    return render(request, 'front/business.html',
        {
            'business': business,
            'category': category,
            'county': county,
            'related_businesses': related_businesses,
        }
    )

def county(request, slug):
    county = get_object_or_404(County, slug=slug)
    businesses = Business.objects.all().filter(county=county)
    return render(request, 'front/businesses.html',
        {
            'businesses': businesses,
            'county': county,
        }
    )

def area(request, county, area):
    county = get_object_or_404(County, slug=county)
    area = get_object_or_404(Area, slug=area)
    businesses = Business.objects.all().filter(county=county, area=area)
    return render(request, 'front/businesses.html',
        {
            'businesses': businesses,
            'area': area,
            'county': county,
        }
    )

def custom_business_group(request, slug):
    custom_business_group = get_object_or_404(CustomBusinessGroup, slug=slug)
    custom_business_group_tags = custom_business_group.tags.names()
    businesses = Business.objects.filter(tags__name__in=custom_business_group_tags).distinct()
    return render(request, 'front/businesses.html',
        {
            'custom_business_group': custom_business_group,
            'businesses': businesses,
        }
    )

def custom_business_groups(request):
    custom_business_groups = CustomBusinessGroup.objects.all()
    return render(request, 'front/custom_business_groups.html',
        {
            'custom_business_groups': custom_business_groups,
        }
    )

@login_required(login_url='/login/')
def add_business(request):
    if request.method == "POST":
        form = BusinessForm(request.POST, request.FILES)
        if form.is_valid():
            business = form.save(commit=False)
            cd = form.cleaned_data
            business.user = request.user
            business.name = cd['name']
            business.category = cd['category']
            business.county = cd['county']
            business.area = cd['area']
            business.street_address = cd['street_address']
            business.website = cd['website']
            business.email = cd['email']
            business.image = cd['image']
            tags = cd['tags']
            business.phone_number = cd['phone_number']
            business.description = cd['description']
            business.save()

            business.tags.add(*tags)
            return HttpResponseRedirect('/' + business.slug)
    else:
        form = BusinessForm()
    return render(request, 'front/post.html', {
        "form": form
        })


import matplotlib.pyplot as plt
import networkx as nx
import os
os.environ["PATH"] += os.pathsep + 'C:/Program Files/Graphviz/bin/'

# change this for the graphs of different sizes
N = 15

def partitions(n):
    a = [0 for i in range(n + 1)]
    k = 1
    y = n - 1
    while k != 0:
        x = a[k - 1] + 1
        k -= 1
        while 2 * x <= y:
            a[k] = x
            y -= x
            k += 1
        l = k + 1
        while x <= y:
            a[k] = x
            a[l] = y
            yield a[:k + 2]
            x += 1
            y -= 1
        a[k] = x + y
        y = x + y - 1
        yield a[:k + 1]

def next_state(state):
    state = list(filter(lambda x: x != 0, [*map(lambda y: y - 1, state)])) + [len(state)]
    return sorted(state)

def main():

    G = nx.DiGraph()

    G.add_nodes_from([tuple(partition) for partition in partitions(N)])
    for node in G.nodes:
        G.add_edge(node, tuple(next_state(list(node))))
    # change figure size to account for different N size
    plt.figure(figsize=(48,36))

    pos = nx.nx_pydot.graphviz_layout(G,prog='dot')
    nx.draw_networkx(G, pos=pos, node_color = '#ff00ff',font_size = 6, with_labels=True, verticalalignment='baseline')
    plt.savefig('size_.png')

if __name__ == "__main__":
    main()


import pandas as pd
import torch
from torch import nn
import os
from global_variables import *
from dataloader import BinaryClass
from model import Simple, Medium, AgeAlexNet
from torch.utils.data import DataLoader
import numpy as np
import torchvision
import sys
from sklearn.model_selection import train_test_split
import prepare_data_training
from global_variables import *

if __name__ == '__main__':

    net = Simple()
    model_conv = torchvision.models.resnet18(pretrained=False)
    num_ftrs = model_conv.fc.in_features

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

    model_conv.fc = nn.Sequential(nn.Linear(num_ftrs, 512),
                                  nn.ReLU(),
                                  nn.Dropout(0.2),
                                  nn.Linear(512, 2))

    # To read the data directory from the argument given
    PATH_TO_PRETRAINED_MODEL = 'alex/models/123.pth'

    # Check all the models and the accuracy they produce:

    if file_exists(PATH_TO_PRETRAINED_MODEL):
        states = torch.load(PATH_TO_PRETRAINED_MODEL)
    else:
        print(
            "Please check the file directory or the parameter name you provided for the pretrained-model and try again..")
        exit(0)

    model_conv.load_state_dict(states)

    net = model_conv

    train, valid, weights = prepare_data_training.get_the_df(os.path.split(os.getcwd())[0] + '/files/train.txt',
                                                             class_2=True)
    classes = [0, 1]
    correct_pred = {classname: 0 for classname in classes}
    total_pred = {classname: 0 for classname in classes}

    val_dataset = BinaryClass(valid, PATH_TO_IMAGES, train=False)
    val_dataset = torch.utils.data.DataLoader(val_dataset, batch_size=100)

    # again no gradients needed
    with torch.no_grad():
        for i, data in enumerate(val_dataset):
            images, labels = data
            outputs = net(images)
            _, predictions = torch.max(outputs, 1)
            # collect the correct predictions for each class
            for label, prediction in zip(labels, predictions):
                if label == prediction:
                    correct_pred[classes[label]] += 1
                total_pred[classes[label]] += 1
                if i % 10 == 9:
                    print('correct------->' + str(correct_pred))
                    print('overall------->' + str(total_pred))

    # print accuracy for each class
    for classname, correct_count in correct_pred.items():
        accuracy = 100 * float(correct_count) / total_pred[classname]
        print(accuracy)


import unittest
import numpy as np
import pyscf
import cupy
from pyscf import lib
from pyscf.dft import Grids
from pyscf.dft.numint import NumInt as pyscf_numint
from gpu4pyscf.dft.numint import NumInt
from gpu4pyscf import dft

mol = pyscf.M(
    atom='''
C  -0.65830719,  0.61123287, -0.00800148
C   0.73685281,  0.61123287, -0.00800148
''',
    basis='ccpvtz',
    spin=None,
)
mol.verbose=1
np.random.seed(2)
nao = mol.nao
dm = np.random.random((2,nao,nao))
dm1 = dm + dm.transpose(0,2,1)
mo_coeff = np.random.rand(nao, nao)
mo_occ = (np.random.rand(nao) > .5).astype(np.double)
dm0 = (mo_coeff*mo_occ).dot(mo_coeff.T)

grids_cpu = Grids(mol)
grids_cpu.level = 5
grids_cpu.build()

grids_gpu = Grids(mol)
grids_gpu.level = 5
grids_gpu.build()

grids_gpu.weights = cupy.asarray(grids_gpu.weights)
grids_gpu.coords = cupy.asarray(grids_gpu.coords)

LDA = 'LDA_C_VWN'
GGA_PBE = 'GGA_C_PBE'
MGGA_M06 = 'MGGA_C_M06'

def tearDownModule():
    global mol
    del mol

class KnownValues(unittest.TestCase):

    def _check_vxc(self, method, xc):
        ni = NumInt(xc=xc)
        fn = getattr(ni, method)
        n, e, v = fn(mol, grids_gpu, xc, dm0, hermi=1)
        v = [i.get() for i in v]

        ni_pyscf = pyscf_numint()
        fn = getattr(ni_pyscf, method)
        nref, eref, vref = fn(mol, grids_cpu, xc, dm0, hermi=1)

        cupy.allclose(e, eref)
        cupy.allclose(n, nref)
        cupy.allclose(v, vref)

    def _check_rks_fxc(self, xc, hermi=1):
        if hermi == 1:
            t1 = dm1
        else:
            t1 = dm
        spin = 0
        ni_pyscf = pyscf_numint()
        rho, vxc, fxc = ni_pyscf.cache_xc_kernel(mol, grids_cpu, xc, mo_coeff, mo_occ, spin)
        vref = ni_pyscf.nr_rks_fxc(
            mol, grids_cpu, xc, dm0=dm0, dms=t1, rho0=rho, vxc=vxc, fxc=fxc, hermi=hermi)

        rho0 = rho.copy()
        vxc0 = vxc.copy()
        fxc0 = fxc.copy()
        ni = NumInt()
        rho, vxc, fxc = ni.cache_xc_kernel(mol, grids_gpu, xc, cupy.asarray(mo_coeff), cupy.asarray(mo_occ), spin)
        v = ni.nr_rks_fxc(mol, grids_gpu, xc, dms=t1, fxc=fxc, hermi=hermi)
        if xc == MGGA_M06:
            assert cupy.allclose(rho[[0,1,2,3,5]], rho0[[0,1,2,3,5]])
        else:
            assert cupy.allclose(rho, rho0)

        assert cupy.linalg.norm(vxc - cupy.asarray(vxc0)) < 1e-6 * cupy.linalg.norm(vxc)
        assert cupy.linalg.norm(fxc - cupy.asarray(fxc0)) < 1e-6 * cupy.linalg.norm(fxc)
        assert cupy.allclose(v, vref)

    def _check_rks_fxc_st(self, xc, fpref):
        ni = NumInt()
        spin = 1
        rho, vxc, fxc = ni.cache_xc_kernel(
            mol, grids_gpu, xc, [mo_coeff]*2, [mo_occ*.5]*2, spin)
        v = ni.nr_rks_fxc_st(mol, grids_gpu, xc, dms_alpha=dm, fxc=fxc)
        self.assertAlmostEqual(lib.fp(v), fpref, 12)

        ni_pyscf = pyscf_numint()
        rho, vxc, fxc = ni_pyscf.cache_xc_kernel(
            mol, grids_cpu, xc, [mo_coeff]*2, [mo_occ*.5]*2, spin)
        vref = ni_pyscf.nr_rks_fxc_st(
            mol, grids_cpu, xc, dm0=dm0, dms_alpha=dm, rho0=rho, vxc=vxc, fxc=fxc)
        self.assertAlmostEqual(abs(v - vref).max(), 0, 12)

    def _check_uks_fxc(self, xc, fpref, hermi=1):
        if hermi == 1:
            t1 = dm1
        else:
            t1 = dm
        ni = NumInt()
        spin = 1
        rho, vxc, fxc = ni.cache_xc_kernel(
            mol, grids_gpu, xc, [mo_coeff]*2, [mo_occ, 1-mo_occ], spin)
        v = ni.nr_uks_fxc(mol, grids_gpu, xc, dms=t1, fxc=fxc, hermi=hermi)
        self.assertAlmostEqual(lib.fp(v), fpref, 12)

        ni = ni.to_cpu()
        dm0 = mo_coeff.dot(mo_coeff.T)
        rho, vxc, fxc = ni.cache_xc_kernel(
            mol, grids_cpu, xc, [mo_coeff]*2, [mo_occ, 1-mo_occ], spin)
        vref = ni.nr_uks_fxc(
            mol, grids_cpu, xc, dm0=dm0, dms=t1, rho0=rho, vxc=vxc, fxc=fxc, hermi=hermi)
        self.assertAlmostEqual(abs(v - vref).max(), 0, 12)

    def test_rks_lda(self):
        self._check_vxc('nr_rks', LDA)

    def test_rks_gga(self):
        self._check_vxc('nr_rks', GGA_PBE)

    def test_rks_mgga(self):
        self._check_vxc('nr_rks', MGGA_M06)

    # Not implemented yet
    '''
    def test_uks_lda(self):
        self._check_vxc('nr_uks', 'lda', -6.362059440515177)

    def test_uks_gga(self):
        self._check_vxc('nr_uks', 'pbe', -6.732546841646528)

    def test_uks_mgga(self):
        self._check_vxc('nr_uks', 'm06', 83.5606316500255)
    '''

    def test_rks_fxc_lda(self):
        self._check_rks_fxc(LDA, hermi=1)

    def test_rks_fxc_gga(self):
        self._check_rks_fxc(GGA_PBE, hermi=1)

    def test_rks_fxc_mgga(self):
        self._check_rks_fxc(MGGA_M06, hermi=1)

    '''
    def test_uks_fxc_lda(self):
        self._check_uks_fxc('lda', -0.1125902447294953, hermi=1)
        self._check_uks_fxc('lda', -0.05629512236474782, hermi=0)

    def test_uks_fxc_gga(self):
        self._check_uks_fxc('pbe', -0.0752237471800169, hermi=1)
        self._check_uks_fxc('pbe', -0.03761187359000853, hermi=0)

    def test_uks_fxc_mgga(self):
        self._check_uks_fxc('m06', 0.7005336565753997, hermi=1)
        self._check_uks_fxc('m06', 0.35026682828770006, hermi=0)

    def test_rks_fxc_st_lda(self):
        self._check_rks_fxc_st('lda', -0.06358425564270553)

    def test_rks_fxc_st_gga(self):
        self._check_rks_fxc_st('pbe', -0.006650911990898234)

    def test_rks_fxc_st_mgga(self):
        self._check_rks_fxc_st('m06', 1.2456987899337242)
    '''

    def test_vv10(self):
        np.random.seed(10)
        rho = np.random.random((4,20))
        coords = (np.random.random((20,3))-.5)*3
        vvrho = np.random.random((4,60))
        vvweight = np.random.random(60)
        vvcoords = (np.random.random((60,3))-.5)*3
        nlc_pars = .8, .3

        rho = cupy.asarray(rho)
        coords = cupy.asarray(coords)
        vvrho = cupy.asarray(vvrho)
        vvweight = cupy.asarray(vvweight)
        vvcoords = cupy.asarray(vvcoords)

        v = dft.numint._vv10nlc(rho, coords, vvrho, vvweight, vvcoords, nlc_pars)
        self.assertAlmostEqual(lib.fp(v[0].get()), 0.15894647203764295, 8)
        self.assertAlmostEqual(lib.fp(v[1].get()), 0.20500922537924576, 8)
        return

if __name__ == "__main__":
    print("Full Tests for dft numint")
    unittest.main()


from transformers import GPT2Tokenizer, GPT2Model, GPT2LMHeadModel
import torch
import torch.nn as nn
from torch.utils.data import Dataset, DataLoader
import pandas as pd
import logging
import time
import os
from transformers import get_scheduler
import random

class Args:
    def __init__(self, train_path, valid_path, batch_size, num_workers, epochs, lr, shuffle, gpu_num, vocab_rev):
        self.train_path = train_path
        self.valid_path = valid_path
        self.batch_size = batch_size
        self.num_workers = num_workers
        self.shuffle = shuffle
        self.device = torch.device(f'cuda:{gpu_num}' if torch.cuda.is_available() else 'cpu')
        self.epochs = epochs
        self.lr = lr
        self.vocab_rev = vocab_rev

class NewsDataset(Dataset):
    def __init__(self, data_path, tokenizer, max_length=1024, use_title=False):
        super().__init__()

        ### preprocessing
        data = pd.read_csv(data_path, index_col=0)[['content']]
        safe_len = data['content'].apply(lambda x: len(x.split(' ')) < 350)
        clean = []
        for line in data['content']:
            if len(line.split(' ')) > 350:
                truncated_line = ' '.join(line.split(' ')[:350])
                clean.append(truncated_line.lower())
        clean = pd.DataFrame(clean, columns=['content'])
        self.data = pd.concat([data[safe_len], clean], axis=0)
        ### ### ### ### ###
        self.tokenizer = tokenizer
        self.use_title = use_title
    def __getitem__(self, index):
        if self.use_title and random.random() < 0.01:
            text = self.data['title'].iloc[index]
        text = self.data['content'].iloc[index]
        # truncation 하면 전처리 대체 가능?
        inputs = self.tokenizer(f'<|endoftext|>{text}<|endoftext|>', return_tensors='pt')
        # inputs['labels'] = inputs['input_ids'][index]
        ids_len, mask_len = inputs['input_ids'].size(1), inputs['attention_mask'].size(1)
        return inputs, ids_len, mask_len
    def __len__(self):
        return len(self.data)

def NewsCollate(batch):
    batch, ids_len, mask_len = zip(*batch)
    max_ids, max_mask = max(ids_len), max(mask_len)
    ids_res, mask_res, label_res = [], [], []
    for i, sample in enumerate(batch):
        ids_pad = max_ids - ids_len[i]
        mask_pad = max_mask - mask_len[i]

        ids_tensor = torch.cat([sample['input_ids'], torch.LongTensor([[tokenizer.get_vocab()['<|endoftext|>']] * ids_pad])], dim=1)
        if want_to_change_vocab:
            ids_tensor = torch.cat([sample['input_ids'], torch.LongTensor([[tokenizer.get_vocab()['[PAD]']] * ids_pad])], dim=1)
        mask_tensor = torch.cat([sample['attention_mask'], torch.LongTensor([[0] * mask_pad])], dim=1)
        ids_res.append(ids_tensor)
        mask_res.append(mask_tensor)
        # label_res.append(sample['labels'].reshape(-1))
    ids_batch = torch.cat(ids_res, dim=0)
    mask_batch = torch.cat(mask_res, dim=0)
    return {'input_ids':ids_batch, 'attention_mask':mask_batch}

def get_logger(name: str, file_path: str, stream=False):
    logger = logging.getLogger(name)
    logger.setLevel(logging.INFO)

    # 시간, 로거 이름, 로깅 레벨, 메세지
    formatter = logging.Formatter('%(asctime)s | %(name)s | %(levelname)s | %(message)s')
    # console에 출력하도록 설정
    stream_handler = logging.StreamHandler()
    # 현재 디렉토리에 파일로 로깅하도록 설정
    file_handler = logging.FileHandler(file_path)

    stream_handler.setFormatter(formatter)
    file_handler.setFormatter(formatter)

    if stream:
        logger.addHandler(stream_handler)
    # 현재 디렉토리에 로깅 저장
    logger.addHandler(file_handler)

    return logger

def save(filename, model, optimizer, logger):
    state = {
        'model': model.state_dict(),
        'optimizer': optimizer.state_dict()
    }
    torch.save(state, filename)
    logger.info('Model saved')

def load(filename, model, optimizer, logger):
    # state = torch.load(filename)
    state = torch.load(filename, map_location=torch.device('cpu'))
    model.load_state_dict(state['model'])
    if 'optimizer' in state and optimizer:
        optimizer.load_state_dict(state['optimizer'])
    logger.info('Model loaded : {}'.format(filename))

def train(model, tokenizer, dataloader, optimizer,
          lr_scheduler, epoch, train_begin, device):
    begin = epoch_begin = time.time()
    print_batch = 100

    total_num, total_batch_size = 0, len(dataloader)
    losses, batch_cnt = 0, 0
    print('train start...')
    for batch in dataloader:
        batch = {k:v.to(device) for k, v in batch.items()}
        outputs = model(**batch, labels=batch['input_ids'])
        loss = outputs[0]
        loss.backward()

        losses += loss.item()
        total_num += 1

        optimizer.step()
        lr_scheduler.step()
        optimizer.zero_grad()

        if batch_cnt % print_batch == 0:
            current = time.time()
            elapsed = current - begin
            epoch_elapsed = (current - epoch_begin) / 60.0
            train_elapsed = (current - train_begin) / 3600.0
            print('epoch: {:4d}, batch: {:5d}/{:5d}, lr: {:.16f},\nloss: {:.8f}, elapsed: {:6.2f}s {:6.2f}m {:6.2f}h'.format(
                epoch, batch_cnt, total_batch_size,
                optimizer.param_groups[0]['lr'],
                losses / total_num,
                elapsed, epoch_elapsed, train_elapsed))
            begin = time.time()

        batch_cnt += 1
    print('train completed...')
    return losses / total_batch_size

def evaluate(model, tokenizer, dataloader, epoch, device):
    model.eval()
    losses, batch_cnt = 0, 0
    print('evaluate start...')
    with torch.no_grad():
        for batch in dataloader:
            if batch_cnt % 500 == 0:
                batch = {k:v.to(device) for k, v in batch.items()}
                outputs = model(**batch, labels=batch['input_ids'])
                loss = outputs[0]
                print(f"loss {loss}")
                losses = loss.item()
            batch_cnt += 1
    print('train completed...')
    return losses / len(dataloader)

if __name__=='__main__':
    args = Args('/content/drive/MyDrive/Data/archive/articles1.csv',
            '/content/drive/MyDrive/Data/archive/articles2.csv',
            2,
            0,
            30,
            7e-4,
            True,
            0,
            False)

    ##### model load #####
    tokenizer = GPT2Tokenizer.from_pretrained('gpt2')
    # model = GPT2Model.from_pretrained('gpt2')
    want_to_change_vocab = args.vocab_rev
    pad_id = 50267 if want_to_change_vocab else tokenizer.eos_token_id
    # lm_head.weight 	 torch.Size([50257, 768]) 추가
    # loss func.이 내재되어 있음
    model = GPT2LMHeadModel.from_pretrained('gpt2', pad_token_id=pad_id)
    model.to(args.device)
    # 애초에 attn mask가 있기 때문에 안해도 무방
    # 그러나 open-end generation을 피하는 한 가지 방법
    # '<|endoftext|>': 50256
    # 마구 추가하면 pretrain 방식과 다르기 때문에 성능을 저하시킬 수 있다
    if want_to_change_vocab:
        special_tokens =  {'pad_token': '[PAD]'}
                      # 'bos_token': '<|endoftext|>',
                      # 'additional_special_tokens': ['[SP1]', '[SP2]']}
        tokenizer.add_special_tokens(special_tokens)
        vocab = tokenizer.get_vocab()
        # print(vocab)
        model.resize_token_embeddings(len(vocab))

    ##### dataset #####
    dataset = NewsDataset(args.train_path, tokenizer)
    dataloader = DataLoader(dataset,
                          batch_size=args.batch_size,
                          num_workers=args.num_workers,
                          collate_fn=NewsCollate,
                          shuffle=args.shuffle)
    valid_dataset = NewsDataset(args.valid_path, tokenizer)
    valid_dataloader = DataLoader(dataset,
                          batch_size=args.batch_size,
                          num_workers=args.num_workers,
                          collate_fn=NewsCollate)

    optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)

    num_training_steps = args.epochs * len(dataloader)

    lr_scheduler = get_scheduler(
    "linear",
    optimizer=optimizer,
    num_warmup_steps=8000,
    num_training_steps=num_training_steps
    )

    logger = get_logger(name='train',
                    file_path=os.path.join('.', 'train_log.log'),
                    stream=True)

    #### START #####
    n_epoch = 0
    train_begin = time.time()
    for epoch in range(args.epochs):
        train_loss = train(model, tokenizer, dataloader, optimizer, lr_scheduler, epoch, train_begin, args.device)
        logger.info('Epoch %d (Training) Loss %0.8f' % (epoch, train_loss))

        valid_loss = evaluate(model, tokenizer, valid_dataloader, epoch, args.device)

        model.eval()
        input_1 = tokenizer.encode('''How serious is the presence of the Covid virus in deer for humans?"''', return_tensors='pt')
        input_2 = tokenizer.encode('''Joe Biden is the best president to ever ''', return_tensors='pt')
        input_3 = tokenizer.encode('''Donald trump and his polices ''', return_tensors='pt')
        input_4 = tokenizer.encode('''Seldom has such an amateur armchair diagnosis been so easy as when ex-President Donald Trump and the Fox News switchboard reconnected on Wednesday for a conversation about Trump's tax returns.''', return_tensors='pt')

        logger.info(f"{epoch} epc Output:\n" + 55 * '-')
        for sample in [input_1, input_2, input_3, input_4]:
            sample_inputs = model.generate(
                        sample.to(args.device),
                        do_sample=True,
                        top_k=50,
                        max_length = 120,
                        top_p=0.90,
                        num_return_sequences=3)
            for sample_output in sample_inputs:
                texts = tokenizer.decode(sample_output, skip_special_tokens=True)

                logger.info('Epoch %d (Prompt-Generation) | %s' % (epoch, texts))

        # make_directory('checkpoint')
        save(os.path.join('checkpoint', f"model_{epoch:03d}.pt"), model, optimizer, logger)

        epoch_end_time = time.time()
        n_epoch += 1
        print(f'For {(epoch_end_time - epoch_start_time)/60:6.2f}, {n_epoch} Epoch Finished')


# -*- coding: utf-8 -*-
"""
Created on Fri May 17 21:03:14 2019

@author: shane
"""

import gym
import numpy as np

np.set_printoptions(precision=3, linewidth=120)

# Setup GPU TF stability
import tensorflow as tf
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.8)
sess = tf.Session(config=tf.ConfigProto(
  allow_soft_placement=True, log_device_placement=True))

import gc
gc.enable()

"""
# Create an environment and set random seed
"""
selectedEnvironment = 8
env = 0
envName = 0

# Toy Text - Discrete state and action space
if selectedEnvironment == 0:
    envName = 'Taxi-v2'

# Classic Control - Continuous State and Discrete Action Spaces
elif selectedEnvironment == 1:
    envName = 'MountainCar-v0' # needs Discretized or better
elif selectedEnvironment == 2:
    envName = 'Acrobot-v1'     # needs Discretized, Tile Encoding or better
elif selectedEnvironment == 3:
    envName = 'CartPole-v1'    # needs Deep Q Learning to do well?

# Box 2D - Continuous State, Discrete Actions
elif selectedEnvironment == 4:
    envName = 'LunarLander-v2' # discrete actions, continuous state

# Classic Control - Continuous State and Action Spaces
elif selectedEnvironment == 5:
    envName = 'Pendulum-v0' # continuous only
elif selectedEnvironment == 6:
    envName = 'MountainCarContinuous-v0' # continuous only

# Box 2D - Continuous State and Action Spaces
elif selectedEnvironment == 7:
    envName = 'LunarLanderContinuous-v2' # continuous only
elif selectedEnvironment == 8:
    envName = 'BipedalWalker-v2'  # continuous only

# Box 2D - Image State and Continuous Action Spaces
elif selectedEnvironment == 9:
    envName = 'CarRacing-v0'      #  image input, actions [steer, gas, brake]

# Initialize the environment
env = gym.make(envName)
env.reset()

# Set output file paths based on environment
from visuals import examine_environment, examine_environment_MountainCar_discretized, examine_environment_Acrobat_tiled
#examine_environment(env)

from datetime import datetime
FORMAT = '%Y%m%d%H%M%S'
file_output_train = envName + '_train.txt'       # file name for saved results
file_output_test = envName + '_test.txt'       # file name for saved results
file_output_train = datetime.now().strftime(FORMAT) + file_output_train

print('-----------------------------------------------------------')
print('New Experiment, training output file name: ', file_output_train)

"""
# Create Agent
"""
agent = 0
selectedAgent = 2
if selectedAgent == 0:
    # create the agent discretized state space Q Learning
    state_size = env.observation_space.shape[0]
    action_size = env.action_space.n
    print("env.observation_space.shape[0]", state_size)
    print("env.action_space", action_size)
    from agents import QLearningAgentDiscretized as qlad
    agent = qlad.QLearningAgent(env)
#    examine_environment_MountainCar_discretized(env)

if selectedAgent == 1:
    # create the agent for tiled state space Q Learning
    state_size = env.observation_space.shape[0]
    action_size = env.action_space.n
    print("env.observation_space.shape[0]", state_size)
    print("env.action_space", action_size)
    from agents import QLearningAgentDiscretizedTiles as qlat
    agent = qlat.QLearningAgentDisTiles(env)
#    examine_environment_Acrobat_tiled(env, n_bins)

if selectedAgent == 2:
    # Create DDPG network agent
    obsSpace = env.observation_space.shape
    print("env.observation_space: ", obsSpace)
    from agents.DDPG import DDPG
    agent = DDPG(env, "continousStateAction")  # continousStateAction imageStateContinuousAction

if selectedAgent == 3:
    # Create DDPG network agent
    obsSpace = env.observation_space.shape
    print("env.observation_space: ", obsSpace)
    from agents.DDPG import DDPG
    agent = DDPG(env, "imageStateContinuousAction")  # continousStateAction imageStateContinuousAction

"""
# run the simulation
"""
import interact as sim
num_episodes=500
sim.interact(agent, env, num_episodes, mode='train', file_output=file_output_train, renderSkip=100)

"""
# Plot training scores obtained per episode
"""
from visuals import plot_q_table, plot_score_from_file
plot_score_from_file(file_output_train, -300, 300, 1)
if selectedAgent == 0 or selectedAgent == 1:
    plot_q_table(agent.q_table)

"""
# save model and architecture to single file
# https://machinelearningmastery.com/save-load-keras-deep-learning-models/
"""
if selectedAgent == 2 or selectedAgent == 3:
    import sys
    sys.setrecursionlimit(1000000) # need to be big enough to handle whole weight list
    agent.actor_local.model.save(file_output_train+"actor_local.h5")
    agent.actor_target.model.save(file_output_train+"actor_target.h5")
    agent.critic_local.model.save(file_output_train+"critic_local.h5")
    agent.critic_target.model.save(file_output_train+"critic_target.h5")
    print("Saved model to disk")

"""
# Run in test mode and analyze scores obtained
"""
print("[TEST] Training Done, now running tests...")
test_scores = sim.interact(agent, env, num_episodes=3, mode='test', file_output=file_output_test)
plot_score_from_file(file_output_test, -300, 300, 1)

"""
# Watch Agent
"""
state = env.reset()
score = 0
for t in range(5000):
    # get action from agent
    action = agent.act(state, mode='test')

    # show environment and step it forward
    env.render()
    state, reward, done, _ = env.step(action)
    score += reward
    if done:
        break
print('Final score:', score)

"""
# Exit Environment
"""
#if 0:
env.close()


import pytest, testinfra

def define_server_test(server, app_env):

    def _function():
        host = testinfra.get_host("paramiko://root@" + server, ssh_config="/root/.ssh/config")
        app_id_path = '/etc/app.id'
        assert host.file(app_id_path).exists
        assert host.file(app_id_path).content_string.strip() == f"CIC_WEBAPP:{app_env}:{server}"

    return _function

servers = {'dev-app1': 'DEV', 'dev-app2' : 'DEV', 'prod-app1' : 'PROD', 'prod-app2' : 'PROD'}

for server, app_env in servers.items():

    exec(f"test_{server.replace('-','_')}_server = define_server_test('{server}', '{app_env}')")


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models

class Migration(migrations.Migration):

    dependencies = [
        ('authentication', '0004_auto_20151030_1838'),
    ]

    operations = [
        migrations.AlterField(
            model_name='userimage',
            name='image',
            field=models.ImageField(max_length=300, upload_to=b'static/media/images'),
        ),
    ]


import copy
import itertools

global temp
temp = []
dx = [-1,1,0,0] # 왼쪽 오른쪽 위 아래
dy = [0,0,-1,1]

N, M = map(int, input().split())
my_map = [[0 for i in range(M)] for i in range(N)]

safe_area_list = []

for i in range(N):
    my_map[i] = list(map(int, input().split()))

def dfs(x , y):  # 탐색하기
    global temp

    for i in range(4):
        nx = x + dx[i]
        ny = y + dy[i]

        if nx >= 0 and ny >= 0 and nx < M and ny <N and temp[ny][nx] == 0:
            temp[ny][nx] = 2
            dfs(nx, ny)

def find_virus(my_map):                                      # 바이러스 위치 찾기

    result = []
    for i in range(N):
        for j in range(M):
            if my_map[i][j] == 2:
                result.append([i,j])
    return result

def find_combination(index_list):
    result = list(itertools.combinations((index_list),3))    # 조합 생성하기
    return result

def find_index(my_map):                     # 비어있는 곳의 인덱스 찾기 (벽을 어디에 세울지 알기 위해서)
    index_list = []
    for i in range(N):
        for j in range(M):
            if my_map[i][j] == 0:
                index_list.append([i,j])

    return index_list

def build_wall(my_map, combination_list):    # 벽 세워서 점검하기
    global temp
    result = find_virus(my_map)

    for i in range(len(combination_list)):
        temp = copy_map(my_map)

        wall_1st = combination_list[i][0]
        wall_2nd = combination_list[i][1]
        wall_3rd = combination_list[i][2]

        temp[wall_1st[0]][wall_1st[1]] = 1
        temp[wall_2nd[0]][wall_2nd[1]] = 1
        temp[wall_3rd[0]][wall_3rd[1]] = 1

        for i in range(len(result)):
            x = result[i][1]
            y = result[i][0]
            dfs(x,y)

        safe_area = count_safe_area(temp)
        safe_area_list.append(safe_area)

def count_safe_area(my_map):    # 안전 영역 세기

    result = 0
    for i in range(N):
        result = result + my_map[i].count(0)
    return result

def copy_map(my_map):
    temp = copy.deepcopy(my_map)    # my_map copy
    return temp

index_list = find_index(my_map)   # 비어있는 곳의 i, j 인덱스 찾기
combination_list = find_combination(index_list)      # 찾은 index로 조합 생성하기
build_wall(my_map, combination_list)
print(max(safe_area_list))


#! /usr/bin/env python3

import numpy as np
from scipy import signal
import matplotlib.pyplot as plt

import sys
sys.path.append('../Signal')
import Signal

if __name__ == "__main__":
    width = 3
    time_array = np.linspace(-np.pi*width, np.pi*width, 128*width)
    wave1 = Signal.Signal(time_array, 2, 5, 0)
    wave1.calculateSineWave()
    window = signal.hamming(len(wave1.getSineWave))

    conv = signal.convolve(wave1.getSineWave, window)
    conv_len = len(conv)

    print("Len Wave1 {}".format(len(wave1.getSineWave)))
    print("Len Conv {}".format(len(conv)))

    plt.figure(1)

    plt.subplot(311)
    plt.grid(True)
    plt.plot(time_array, wave1.getSineWave)

    plt.subplot(312)
    plt.grid(True)
    plt.plot(time_array, window)

    plt.subplot(313)
    plt.grid(True)
    plt.plot(time_array, conv[0:(conv_len/2)+1])

    plt.show()