import logging
import os

import pytest
import yaml

from cekit.config import Config
from cekit.descriptor import Image, Overrides
from cekit.descriptor.resource import create_resource
from cekit.errors import CekitError

try:
    from unittest.mock import call
except ImportError:
    from mock import call

config = Config()

def setup_function(function):
    config.cfg["common"] = {"work_dir": "/tmp"}

    if os.path.exists("file"):
        os.remove("file")

def test_repository_dir_is_constructed_properly(mocker):
    mocker.patch("subprocess.run")
    mocker.patch("os.path.isdir", ret="True")
    mocker.patch("cekit.descriptor.resource.Chdir", autospec=True)

    res = create_resource(
        {"git": {"url": "http://host.com/url/repo.git", "ref": "ref"}}
    )

    assert res.copy("dir") == "dir/repo"

def test_repository_dir_uses_name_if_defined(mocker):
    mocker.patch("subprocess.run")
    mocker.patch("os.path.isdir", ret="True")
    mocker.patch("cekit.descriptor.resource.Chdir", autospec=True)

    res = create_resource(
        {
            "name": "some-id",
            "git": {"url": "http://host.com/url/repo.git", "ref": "ref"},
        }
    )
    assert res.copy("dir") == "dir/some-id"

def test_repository_dir_uses_target_if_defined(mocker):
    mocker.patch("subprocess.run")
    mocker.patch("os.path.isdir", ret="True")
    mocker.patch("cekit.descriptor.resource.Chdir", autospec=True)

    res = create_resource(
        {
            "target": "some-name",
            "git": {"url": "http://host.com/url/repo.git", "ref": "ref"},
        }
    )
    assert res.copy("dir") == "dir/some-name"

def test_git_clone(mocker):
    mock = mocker.patch("subprocess.run")
    mocker.patch("os.path.isdir", ret="True")
    mocker.patch("cekit.descriptor.resource.Chdir", autospec=True)

    res = create_resource(
        {"git": {"url": "http://host.com/url/path.git", "ref": "ref"}}
    )
    res.copy("dir")
    mock.assert_has_calls(
        [
            call(
                ["git", "clone", "http://host.com/url/path.git", "dir/path"],
                stdout=None,
                stderr=None,
                check=True,
                universal_newlines=True,
            ),
            call(
                ["git", "checkout", "ref"],
                stdout=None,
                stderr=None,
                check=True,
                universal_newlines=True,
            ),
        ],
        any_order=True,
    )

def get_res(mocker):
    res = mocker.Mock()
    res.status_code = 200
    res.iter_content = lambda chunk_size: [b"test"]
    return res

def get_ctx(mocker):
    ctx = mocker.Mock()
    ctx.check_hostname = True
    ctx.verify_mode = 1
    return ctx

def get_mock_urlopen(mocker):
    return mocker.patch("cekit.tools.urlopen", return_value=get_res(mocker))

def get_mock_ssl(mocker, ctx):
    return mocker.patch("cekit.tools.ssl.create_default_context", return_value=ctx)

def test_fetching_with_ssl_verify(mocker):
    config.cfg["common"]["ssl_verify"] = True
    ctx = get_ctx(mocker)
    get_mock_ssl(mocker, ctx)
    mock_urlopen = get_mock_urlopen(mocker)

    res = create_resource({"name": "file", "url": "https:///dummy"})

    try:
        res.copy()
    except Exception:
        pass

    mock_urlopen.assert_called_with("https:///dummy", context=ctx)
    assert ctx.check_hostname is True
    assert ctx.verify_mode == 1

def test_fetching_disable_ssl_verify(mocker):
    config.cfg["common"]["ssl_verify"] = False

    mock_urlopen = get_mock_urlopen(mocker)
    ctx = get_ctx(mocker)
    get_mock_ssl(mocker, ctx)

    res = create_resource({"name": "file", "url": "https:///dummy"})

    try:
        res.copy()
    except Exception:
        pass

    mock_urlopen.assert_called_with("https:///dummy", context=ctx)

    assert ctx.check_hostname is False
    assert ctx.verify_mode == 0

def test_fetching_bad_status_code():
    res = create_resource({"name": "file", "url": "http:///dummy"})
    with pytest.raises(CekitError):
        res.copy()

def test_fetching_file_exists_but_used_as_is(mocker):
    """
    It should not download the file, because we didn't
    specify any hash algorithm, so integrity checking is
    implicitly disabled here.
    """
    with open("file", "w") as f:  # noqa: F841
        pass
    mock_urlopen = get_mock_urlopen(mocker)
    res = create_resource(
        {
            "name": "file",
            "url": "http:///dummy",
            "md5": "d41d8cd98f00b204e9800998ecf8427e",
        }
    )
    res.copy()
    mock_urlopen.assert_not_called()

def test_fetching_file_exists_fetched_again(mocker):
    """
    It should download the file again, because available
    file locally doesn't match checksum.
    """
    mock_urlopen = get_mock_urlopen(mocker)
    ctx = get_ctx(mocker)
    get_mock_ssl(mocker, ctx)

    with open("file", "w") as f:  # noqa: F841
        pass
    res = create_resource({"name": "file", "url": "http:///dummy", "md5": "123456"})
    with pytest.raises(CekitError):
        # Checksum will fail, because the "downloaded" file
        # will not have md5 equal to 123456. We need investigate
        # mocking of requests get calls to do it properly
        res.copy()
    mock_urlopen.assert_called_with("http:///dummy", context=ctx)

def test_fetching_file_exists_no_hash_fetched_again(mocker):
    """
    It should download the file again, because available
    file locally doesn't match checksum.
    """
    mock_urlopen = get_mock_urlopen(mocker)
    ctx = get_ctx(mocker)
    get_mock_ssl(mocker, ctx)

    with open("file", "w") as f:  # noqa: F841
        pass

    res = create_resource({"name": "file", "url": "http:///dummy"})

    with pytest.raises(CekitError):
        # url is not valid so we get error, but we are not interested
        # in it. We just need to check that we attempted to downlad.
        res.copy()
    mock_urlopen.assert_called_with("http:///dummy", context=ctx)

def test_generated_url_without_cacher():
    res = create_resource({"url": "url"})
    assert res._Resource__substitute_cache_url("url") == "url"

def test_resource_verify(mocker):
    mock = mocker.patch("cekit.descriptor.resource.check_sum")
    res = create_resource({"url": "dummy", "sha256": "justamocksum"})
    res._Resource__verify("dummy")
    mock.assert_called_with("dummy", "sha256", "justamocksum")

def test_generated_url_with_cacher():
    config.cfg["common"]["cache_url"] = "#filename#,#algorithm#,#hash#"
    res = create_resource({"url": "dummy", "sha256": "justamocksum"})
    res.name = "file"
    assert res._Resource__substitute_cache_url("file") == "file,sha256,justamocksum"

def test_path_resource_absolute():
    res = create_resource({"name": "foo", "path": "/bar"}, directory="/foo")
    assert res.path == "/bar"

def test_path_resource_relative():
    res = create_resource({"name": "foo", "path": "bar"}, directory="/foo")
    assert res.path == "/foo/bar"

def test_path_local_existing_resource_no_cacher_use(mocker):
    config.cfg["common"]["cache_url"] = "#filename#,#algorithm#,#hash#"
    mocker.patch("os.path.exists", return_value=True)
    shutil_mock = mocker.patch("shutil.copy2")

    res = create_resource({"name": "foo", "path": "bar"}, directory="/foo")

    mocker.spy(res, "_download_file")

    res.guarded_copy("target")

    shutil_mock.assert_called_with("/foo/bar", "target")
    assert res._download_file.call_count == 0

def test_path_local_non_existing_resource_with_cacher_use(mocker):
    config.cfg["common"]["cache_url"] = "#filename#,#algorithm#,#hash#"
    mocker.patch("os.path.exists", return_value=False)
    mocker.patch("os.makedirs")

    res = create_resource({"name": "foo", "path": "bar"}, directory="/foo")

    mocker.spy(res, "_download_file")
    download_file_mock = mocker.patch.object(res, "_download_file")

    res.guarded_copy("target")

    download_file_mock.assert_called_with("/foo/bar", "target")

def test_url_resource_download_cleanup_after_failure(mocker, tmpdir, caplog):
    caplog.set_level(logging.DEBUG, logger="cekit")

    mocker.patch("os.path.exists", return_value=False)
    mocker.patch("os.makedirs")
    os_remove_mock = mocker.patch("os.remove")

    urlopen_class_mock = mocker.patch("cekit.tools.urlopen")
    urlopen_mock = urlopen_class_mock.return_value
    urlopen_mock.getcode.return_value = 200
    urlopen_mock.read.side_effect = Exception

    res = create_resource({"url": "http://server.org/dummy", "sha256": "justamocksum"})

    targetfile = os.path.join(str(tmpdir), "targetfile")

    with pytest.raises(CekitError) as excinfo:
        res.guarded_copy(targetfile)

    assert "Error copying resource: 'dummy'. See logs for more info" in str(
        excinfo.value
    )
    assert (
        "Removing incompletely downloaded '{}' file".format(targetfile) in caplog.text
    )

    urlopen_class_mock.assert_called_with("http://server.org/dummy", context=mocker.ANY)
    os_remove_mock.assert_called_with(targetfile)

def test_copy_plain_resource_with_cacher(mocker, tmpdir):
    config.cfg["common"]["cache_url"] = "#filename#,#algorithm#,#hash#"
    config.cfg["common"]["work_dir"] = str(tmpdir)

    urlopen_class_mock = mocker.patch("cekit.tools.urlopen")
    mock_urlopen = urlopen_class_mock.return_value
    mock_urlopen.getcode.return_value = 200
    mock_urlopen.read.side_effect = [b"one", b"two", None]

    ctx = get_ctx(mocker)
    get_mock_ssl(mocker, ctx)

    with open("file", "w") as f:  # noqa: F841
        pass

    res = create_resource({"name": "foo", "md5": "5b9164ad6f496d9dee12ec7634ce253f"})

    substitute_cache_url_mock = mocker.patch.object(
        res, "_Resource__substitute_cache_url", return_value="http://cache/abc"
    )

    res.copy(str(tmpdir))

    substitute_cache_url_mock.assert_called_once_with(None)
    urlopen_class_mock.assert_called_with("http://cache/abc", context=ctx)

def test_copy_plain_resource_from_brew(mocker, tmpdir):
    config.cfg["common"]["work_dir"] = str(tmpdir)
    config.cfg["common"]["redhat"] = True

    urlopen_class_mock = mocker.patch("cekit.tools.urlopen")
    mock_urlopen = urlopen_class_mock.return_value
    mock_urlopen.getcode.return_value = 200
    mock_urlopen.read.side_effect = [b"one", b"two", None]

    ctx = get_ctx(mocker)
    get_mock_ssl(mocker, ctx)

    with open("file", "w") as f:  # noqa: F841
        pass

    res = create_resource({"name": "foo", "md5": "5b9164ad6f496d9dee12ec7634ce253f"})

    mocker.spy(res, "_Resource__substitute_cache_url")

    mock_get_brew_url = mocker.patch(
        "cekit.descriptor.resource.get_brew_url", return_value="http://cache/abc"
    )

    res.copy(str(tmpdir))

    mock_get_brew_url.assert_called_once_with("5b9164ad6f496d9dee12ec7634ce253f")
    assert res._Resource__substitute_cache_url.call_count == 0
    urlopen_class_mock.assert_called_with("http://cache/abc", context=ctx)

def test_override_resource_remove_chksum():
    image = Image(
        yaml.safe_load(
            """
    from: foo
    name: test/foo
    version: 1.9
    artifacts:
      - name: abs
        path: /tmp/abs
        md5: 'foo'
        sha1: 'foo'
        sha256: 'foo'
        sha512: 'foo'
    """
        ),
        "foo",
    )
    overrides = Overrides(
        yaml.safe_load(
            """
    artifacts:
      - name: abs
        path: /tmp/over
"""
        ),
        "foo",
    )
    overrides.merge(image)

    assert overrides["from"] == "foo"
    assert overrides["artifacts"][0]["path"] == "/tmp/over"
    assert "md5" not in overrides["artifacts"][0]
    assert "sha1" not in overrides["artifacts"][0]
    assert "sha256" not in overrides["artifacts"][0]
    assert "sha512" not in overrides["artifacts"][0]


import tkinter as tk
from tkinter import ttk
import pyautogui
import pygetwindow

# The app was developed by Tom Girshovksi.
class CenterWindowGUI:
    def __init__(self, master):
        self.master = master
        master.title("Center Window")

        # Create the frame
        self.frame = ttk.Frame(master, padding=20)
        self.frame.pack()

        # Configure columns to have equal weight
        self.frame.columnconfigure(0, weight=1)
        self.frame.columnconfigure(1, weight=1)
        self.frame.columnconfigure(2, weight=1)

        # Create the label
        self.label = ttk.Label(self.frame, text="Choose a window to center:")
        self.label.grid(row=0, column=0, columnspan=3, pady=10)

        # Create the listbox to display the windows
        self.listbox = tk.Listbox(self.frame, width=50, height=10, selectmode=tk.SINGLE)
        self.listbox.grid(row=1, column=0, columnspan=3, padx=10, pady=10)
        self.update_windows()

        # Center Button
        self.center_button = ttk.Button(self.frame, text="Center Window", command=self.center_window)
        self.center_button.grid(row=2, column=0, pady=10)

        # Scale Function Button
        self.scale_button = ttk.Button(self.frame, text="Scale Window", command=self.scale_window)
        self.scale_button.grid(row=2, column=1, pady=10)

        # Update List Button
        self.update_button = ttk.Button(self.frame, text="Update List", command=self.update_windows)
        self.update_button.grid(row=2, column=2, pady=10)

    def center_window(self):
        # Get the index of the selected item in the list box
        index = self.listbox.curselection()[0]
        # Get the selected window
        window = self.windows[index]
        # Get the size of the screen
        screen_width, screen_height = pyautogui.size()
        # Get the size of the window
        window_width, window_height = window.size
        # Calculate the new position to center the window
        new_left = (screen_width - window_width) // 2
        new_top = (screen_height - window_height) // 2
        # Move the window to the new position
        window.moveTo(new_left, new_top)

    def update_windows(self):
        # Clear the list box
        self.listbox.delete(0, tk.END)
        # Get a list of all windows that are currently open
        self.windows = pyautogui.getAllWindows()
        # Add the window titles to the list box
        for window in self.windows:
            self.listbox.insert(tk.END, window.title)

    def scale_window(self):
        # Get the index of the selected item in the list box
        index = self.listbox.curselection()[0]
        # Get the selected window
        window = self.windows[index]
        # Get the size of the screen
        screen_width, screen_height = pyautogui.size()
        # Get the size of the window
        window_width, window_height = window.size

        if window_width == screen_width and window_height == screen_height:
            # If the window is already full screen, center it instead
            self.center_window()
        else:
            # Resize the window to full screen
            window.resizeTo(screen_width // 2 + 500, screen_height // 2 +300)

# Create the root window
root = tk.Tk()
root.resizable(False, False)
# Set the style of the GUI
style = ttk.Style(root)
gui = CenterWindowGUI(root)

root.mainloop()


import os
from flask import Flask, request, abort, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS
import random
from sqlalchemy import func
from models import setup_db, Question, Category

QUESTIONS_PER_PAGE = 10

# Create APP and settings cors headers
def create_app(test_config=None):
    app = Flask(__name__)
    setup_db(app)
    cors = CORS(app, resources={r"/api/*": {"origins": "*"}})

    @app.after_request
    def after_request(response):
        response.headers.add('Access-Control-Allow-Headers',
                             'Content-Type,Authorization,true')
        response.headers.add('Access-Control-Allow-Methods',
                             'GET,PATCH,POST,DELETE,OPTIONS')
        return response

    # Paginate method
    def paginate_questions(request, questions):
        page = request.args.get('page', 1, type=int)
        start = (page - 1) * QUESTIONS_PER_PAGE
        end = start + QUESTIONS_PER_PAGE

        questions = [question.format() for question in questions]
        paginated_questions = questions[start:end]

        return paginated_questions

    # Questions API with pagination

    @app.route('/api/questions', methods=['GET'])
    def get_questions_with_pagination():
        error_code = 422
        try:
            categories = Category.query.all()
            questions = Question.query.all()

            formatted_questions = paginate_questions(request, questions)
            formatted_categories = [category.format()
                                    for category in categories]

            if len(formatted_categories) == 0 or len(formatted_questions) == 0:
                error_code = 404
                abort(error_code)

            current_categories = []
            for question in formatted_questions:
                category = question['category']
                if not (category in current_categories):
                    current_categories.append(category)

            return jsonify({
                'success': True,
                'questions': formatted_questions,
                'total_questions': len(questions),
                'current_category': current_categories,
                'categories': formatted_categories
            })
        except:
            abort(error_code)

    # Categories API

    @app.route('/api/categories', methods=['GET'])
    def get_categories():
        try:
            categories = Category.query.all()
            formatted_categories = [category.format()
                                    for category in categories]
            if len(formatted_categories) == 0:
                abort(404)

            return jsonify({
                'success': True,
                'categories': formatted_categories,
                'total_categories': len(formatted_categories)
            })
        except:
            abort(422)

    # Delete Question API

    @app.route('/api/questions/<int:question_id>', methods=['DELETE'])
    def delete_question(question_id):
        question = Question.query.filter_by(id=question_id).first()
        if question is None:
            abort(404)
        try:
            question.delete()

            return jsonify({
                'success': True,
                'question': question_id
            })
        except:
            abort(405)

    # Create Question API

    @app.route('/api/questions/create', methods=['POST'])
    def new_question():
        try:
            body = request.get_json()

            new_question = body.get('question', None)
            new_answer = body.get('answer', None)
            new_category = body.get('category', None)
            new_difficulty = body.get('difficulty', None)

            question = Question(
                question=new_question,
                answer=new_answer,
                category=new_category,
                difficulty=new_difficulty)
            question.insert()

            return jsonify({
                'success': True,
                'created': question.id
            })

        except:
            abort(422)

    # Get Questions by Category API

    @app.route(
        '/api/category/<int:question_category>/questions',
        methods=['GET']
        )
    def get_questions_by_categories(question_category):
        error_code = 422
        try:
            questions = Question.query.filter(
                question_category == Question.category).all()
            formatted_questions = paginate_questions(request, questions)

            if len(formatted_questions) == 0:
                error_code = 404
                abort(error_code)

            current_categories = []
            for question in formatted_questions:
                category = question['category']
                if not (category in current_categories):
                    current_categories.append(category)

            return jsonify({
                'success': True,
                'questions': formatted_questions,
                'total_questions': len(formatted_questions),
                'current_categories': current_categories,
            })
        except:
            abort(error_code)

    # Get Question by Search Term  API

    @app.route('/api/questions/search', methods=['POST'])
    def search_questions():
        body = request.get_json()
        search_term = body.get('searchTerm', None)
        search = "%{}%".format(search_term.replace(" ", "\ "))
        data = Question.query.filter(Question.question.ilike(search)).all()
        formatted_questions = [question.format() for question in data]

        if len(formatted_questions) == 0:
            abort(404)
        try:
            current_categories = []
            for question in formatted_questions:
                category = question['category']
                if not (category in current_categories):
                    current_categories.append(category)

            return jsonify({
                'success': True,
                'questions': formatted_questions,
                'totalQuestions': len(formatted_questions),
                'current_categories': current_categories,
                'search': search_term
            })
        except:
            abort(422)

    # Get Question to Play Quiz API

    @app.route('/api/quizzes', methods=['POST'])
    def post_quiz_questions():
        code = 422
        try:
            request_quiz = request.get_json()

            previous_questions = request_quiz.get('previous_questions')
            quiz_category = request_quiz.get('quiz_category')

            question = Question.query
            question = question.filter(~Question.id.in_(previous_questions))

            if quiz_category != 0:
                question = question.filter(Question.category == quiz_category)

            questions_random = question.order_by(func.random()).first()

            if not questions_random:
                return(jsonify({
                    'success': True,
                    'previous_question': len(previous_questions)
                    }))

            return jsonify({
                'success': True,
                'question': questions_random.format(),
                'previous_question': previous_questions
            })
        except:
            abort(code)

    @app.errorhandler(404)
    def not_found(error):
        return jsonify({
            "success": False,
            "error": 404,
            "message": "resource not found"
        }), 404

    @app.errorhandler(422)
    def unprocessable(error):
        return jsonify({
            "success": False,
            "error": 422,
            "message": "unprocessable"
        }), 422

    @app.errorhandler(400)
    def bad_request(error):
        return jsonify({
            "success": False,
            "error": 400,
            "message": "bad request"
        }), 400

    @app.errorhandler(405)
    def method_not_allowed(error):
        return jsonify({
            "success": False,
            "error": 405,
            "message": "Method Not Allowed"
        }), 405

    return app


'''
Given a list accounts, each element accounts[i] is a list of strings, where the first element accounts[i][0] is a name, and the rest of the elements are emails representing emails of the account.

Now, we would like to merge these accounts. Two accounts definitely belong to the same person if there is some email that is common to both accounts. Note that even if two accounts have the same name, they may belong to different people as people could have the same name. A person can have any number of accounts initially, but all of their accounts definitely have the same name.

After merging the accounts, return the accounts in the following format: the first element of each account is the name, and the rest of the elements are emails in sorted order. The accounts themselves can be returned in any order.

Example 1:
Input:
accounts = [["John", "johnsmith@mail.com", "john00@mail.com"], ["John", "johnnybravo@mail.com"], ["John", "johnsmith@mail.com", "john_newyork@mail.com"], ["Mary", "mary@mail.com"]]
Output: [["John", 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com'],  ["John", "johnnybravo@mail.com"], ["Mary", "mary@mail.com"]]
Explanation:
The first and third John's are the same person as they have the common email "johnsmith@mail.com".
The second John and Mary are different people as none of their email addresses are used by other accounts.
We could return these lists in any order, for example the answer [['Mary', 'mary@mail.com'], ['John', 'johnnybravo@mail.com'],
['John', 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com']] would still be accepted.
Note:

The length of accounts will be in the range [1, 1000].
The length of accounts[i] will be in the range [1, 10].
The length of accounts[i][j] will be in the range [1, 30].
'''

from collections import defaultdict

class Solution:
    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:
        email_to_name = {}
        graph = defaultdict(set)
        for account in accounts:
            name = account[0]
            first_email = account[1]
            email_to_name[first_email] = name
            for email in account[1:]:
                graph[first_email].add(email)
                graph[email].add(first_email)
                email_to_name[email] = name

        seen = set()
        ans = []
        for email in graph:
            if email not in seen:
                seen.add(email)
                stack = [email]
                component = []
                while stack:
                    node = stack.pop()
                    component.append(node)
                    for nei in graph[node]:
                        if nei not in seen:
                            seen.add(nei)
                            stack.append(nei)
                ans.append([email_to_name[email]] + sorted(component))

        return ans


#PYTHON CAMERA MODEL
import cv2
import numpy as np
i=0

def capturing(event,x,y,flags,param):
    global i
    if event==cv2.EVENT_LBUTTONUP:
        name="photo_"+str(i)+".png"
        wname="CAPTURED IMAGE"
        cv2.imwrite(name,frame)
        h=cv2.imread(name)
        cv2.namedWindow(wname)
        cv2.imshow(wname,h)
        cv2.moveWindow(wname,700,50)
        i+=1
        cv2.waitKey(1000)
        cv2.destroyWindow(wname)

cap=cv2.VideoCapture(0)
while True:
    ret,frame = cap.read()
    win="CAPTURE"
    cv2.imshow("CAMERA",frame)
    cv2.moveWindow("CAMERA",50,50)
    cv2.namedWindow(win)
    img=np.zeros((150,150,3))
    cv2.putText(img,"CLICK",(35,65),cv2.FONT_HERSHEY_SIMPLEX,0.85,(255,255,255),2,cv2.LINE_AA)
    cv2.putText(img,"HERE",(35,90),cv2.FONT_HERSHEY_SIMPLEX,0.85,(255,255,255),2,cv2.LINE_AA)
    cv2.imshow(win,img)
    cv2.moveWindow(win,250,560)
    cv2.setMouseCallback(win,capturing)
    if cv2.waitKey(1)==13:
        break
cap.release()
cv2.destroyAllWindows()


import nltk
from collections import Counter

nltk.download('vader_lexicon')

from nltk.sentiment import SentimentIntensityAnalyzer

#Зчитуємо файл який дали в завданні
filename = "data.csv"
with open(filename, 'r') as f:
    reviews = f.readlines()

# ініціалізуємо SentimentIntensityAnalyzer (бібліотека для визначення настроїв)
sia = SentimentIntensityAnalyzer()

# рахуємо загальний настрій відгуків
compound_scores = [sia.polarity_scores(review)['compound'] for review in reviews]
overall_sentiment = sum(compound_scores) / len(compound_scores)

# класифікуємо відгуки на позитивні, негативні та нейтральні (рахує всі відгуки пропускаючи ті де немає числового значення в колонці "Stars"
positive_reviews = [review for review in reviews if sia.polarity_scores(review)['compound'] > 0]
negative_reviews = [review for review in reviews if sia.polarity_scores(review)['compound'] < 0]
neutral_reviews = [review for review in reviews if sia.polarity_scores(review)['compound'] == 0]

#positive_reviews = [review for review in reviews if review.strip() and int(review.split('Stars \n')[0]) >= 4]
#negative_reviews = [review for review in reviews if review.strip() and int(review.split('Stars \n')[0]) <= 2]
#neutral_reviews = [review for review in reviews if review.strip() and int(review.split('Stars \n')[0]) == 3]

# рахуємо кількість повторюваних слів
word_count = Counter(word for review in reviews for word in review.split())
most_common_words = word_count.most_common(5)

num_positive = len(positive_reviews)
num_negative = len(negative_reviews)
num_neutral = len(neutral_reviews)

with open('report.txt', 'w') as file:
    file.write('\n Аналіз відгуків:\n')
    file.write(f"Загальний настрій відгуків: ({overall_sentiment}):\n")
    file.write(f"Позитивні: ({len(positive_reviews)}):\n")
    file.write(f"Негативні: ({len(negative_reviews)}):\n")
    file.write(f"Нейтральні: ({len(neutral_reviews)}):\n")

with open('repeating words.txt', 'w') as file:
    file.write("\n П'ять найбільш вживаних слів: \n")
    for word, count in most_common_words:
        file.write(f"{word}: {count}\n")

    file.write("Кількість повторюваних слів: \n")
    for word, count in word_count.items():
        file.write(f"{word}: {count}\n")

# Для перевірки
print("Аналіз настроїв:")
print("Загальний настрій відгуків: {:.2f}".format(overall_sentiment))
print("")

print("Аналіз негативних, позитивних і природних відгуків:")
print("Кількість позитивних відгуків: {}".format(num_positive))
print("Кількість негативних відгуків: {}".format(num_negative))
print("Кількість нейтральних відгуків: {}".format(num_neutral))
print("")


import random
import numpy as np
from scipy.optimize import fsolve

# velocity upper bound from Wu et al (https://flow-project.github.io/papers/wu17a.pdf )
# This is an approximation

def v_eq_max_function(v, *args):
    """Return the error between the desired and actual equivalent gap."""
    num_vehicles, length = args

    # maximum gap in the presence of one rl vehicle
    s_eq_max = (length - num_vehicles * 5) / (num_vehicles - 1)

    v0 = 30
    s0 = 2
    tau = 1
    gamma = 4

    error = s_eq_max - (s0 + v * tau) * (1 - (v / v0) ** gamma) ** -0.5

    return error

def get_velocity_upper_bound(num_vehicles, length):
    """Return the velocity upper bound for the given number of vehicles."""
    v_guess = 4
    return fsolve(v_eq_max_function, np.array(v_guess), args=(num_vehicles, length))[0]

def get_desired_velocity(num_vehicles, length, method_name = None):
    """
    Desired velocity is gotten as the uniform flow equillibrium velocity
    Only some controllers require this
    """

    # some known values are hard coded:
    if length == 220:
        # reduce to 2.7 for FS
        if method_name == "fs":
            return 2.7
        else:
            return 3.0

    elif length == 230:
        return 3.45

    elif length == 260:
        # From hit and trial, for
        return 4.82 # Value from LORR paper, other sources

    elif length == 270:
        return 5.2

    else:
        scaler = 0.93 # 93% of the upper bound may be desired?
        print("Scaler: ", scaler)
        return get_velocity_upper_bound(num_vehicles, length) * scaler

# Shock
# Define shock models

def get_shock_model(identifier, length = None, network_scaler=1, bidirectional=False, high_speed = False):
    # Network scaler 6 used in the bottleneck
    # Accel/ Decel value, duration, frequency (in the interval between shock start and shock end)
    # Duration: In seconds, for which each shock is applied
    # Frequency: In the interval, how many shocks are applied
    # if identifier == 1:
    #     return (-1.4, 2, 10)

    if identifier == 2:
        # Thiese ranges are obtained form data
        # sample frequency
        frequency = network_scaler*np.random.randint(5, 20) # value of 10 means once shock every 3000/10 = 300 steps, 5 = 600 steps, 15 = 200 steps

        intensity_collect = []
        duration_collect = []
        if high_speed:
            intensity_abs_min = 1.5
            intensity_abs_max = 4.0
        else:
            intensity_abs_min = 1
            intensity_abs_max = 3.0
        print("Frequency:", frequency)

        for i in range(frequency):
            if bidirectional:
                # between (-abs_max to -abs_min) and (abs_min to abs_max) but not between (-abs_min to abs_min)
                intensity = random.uniform(-intensity_abs_max, intensity_abs_max)
                while intensity > -intensity_abs_min and intensity < intensity_abs_min:
                    intensity = random.uniform(-intensity_abs_max, intensity_abs_max)

            else:
                intensity = random.uniform(-intensity_abs_max, -intensity_abs_min)

            print("Intensity:", intensity)

            durations = np.linspace(0.1, 2.5, 20) # In seconds
            abs_intensity = abs(intensity)
            intensity_bucket = np.linspace(intensity_abs_min, intensity_abs_max,len(durations))
            loc = np.searchsorted(intensity_bucket, abs_intensity)

            left = loc
            right = len(durations) - loc
            probabilities_left = np.linspace(0.0, 10, left)
            # print("Probabilities left:", probabilities_left, probabilities_left.sum())

            probabilities_right = np.linspace(10, 0.0, right)
            # print("Probabilities right:", probabilities_right, probabilities_right.sum())

            probabilities = np.concatenate((probabilities_left, probabilities_right))
            probabilities /= probabilities.sum()
            #print("Probabilities:", probabilities, probabilities.sum())

            duration = round(np.random.choice(durations, 1, p=probabilities)[0], 1)
            print("Duration:", duration)

            intensity_collect.append(intensity)
            duration_collect.append(duration)

        # return intensity, durations (second), frequency
        return (np.asarray(intensity_collect), np.asarray(duration_collect), frequency)

    # Stability test
    elif identifier == -1:
        # velocity, duration, frequency
        # Stability tests have velocity manipulation, so the first param here is speed at the velocity dip
        # Duration and frequency are also used
        # Just apply once is enough
        if length ==220:
            vel_set = 2.0
            duration = 1

        elif length == 270:
            vel_set = 3.0
            duration = 2

        elif length == 260:
            vel_set = 3.0
            duration = 2

        else:
            vel_set = 5.0
            duration = 2
        print("\n\nVelocity set: ", vel_set)
        return (vel_set, duration, 1)
        #return (2, 10, 10)

    else:
        raise ValueError("Shock model identifier not recognized")

## Shock utils
def get_time_steps_stability(duration, frequency, shock_start_time, shock_end_time):
        # Convert duration to env steps
        duration = duration*10

        # Based on this frequency, get the time steps at which the shock is applied
        start_times = np.linspace(shock_start_time, shock_end_time - duration, frequency, dtype=int)
        end_times = np.linspace(shock_start_time + duration, shock_end_time, frequency, dtype=int)
        shock_time_steps = np.stack((start_times, end_times), axis=1)

        print("Start times: ", start_times)
        print("End times: ", end_times)
        print("Shock times: \n", shock_time_steps)

        # TODO: Perform overlap tests and warn if there is overlap
        # if start_times[1] < end_times[0]:
        #     import sys
        #     sys.exit()

        return shock_time_steps

def get_time_steps(durations, frequency, shock_start_time, shock_end_time):
        # Convert duration to env steps
        durations = durations*10
        print("Durations: ", durations)

        # Based on this frequency, get the time steps at which the shock is applied
        start_times = np.linspace(shock_start_time, shock_end_time - durations[-1], frequency, dtype=int)
        end_times = []

        for i in range(frequency):
            end_times.append(start_times[i] + durations[i])
        shock_time_steps = np.stack((start_times, end_times), axis=1)

        print("Start times: ", start_times)
        print("End times: ", end_times)
        print("Shock times: \n", shock_time_steps)

        # TODO: Perform overlap tests and warn if there is overlap
        # if start_times[1] < end_times[0]:
        #     import sys
        #     sys.exit()

        return shock_time_steps

# use
# sm = shock_model(2)
# get_time_steps(durations, frequency, 8000, 10000)
#print(sm[0][1])


# File: utils.py
# Name: Sergio Ley Languren

"""Utility for wordle program"""

from WordleDictionary import FIVE_LETTER_WORDS
from WordleGraphics import CORRECT_COLOR, PRESENT_COLOR, MISSING_COLOR, UNKNOWN_COLOR, N_COLS, N_ROWS, WordleGWindow
from random import choice
from typing import Type, Union, Optional
from copy import deepcopy
from tempfile import NamedTemporaryFile
from os import getcwd, unlink

__all__ = [
    "choose_word",
    "validate_responce",
    "ScoreFileParser"
]

# CONSTANT
MINUS_COL = 5

t = None

# Functions
def choose_word() -> str:
    """Chooses the answer from a list of words of five characters"""
    a = choice(FIVE_LETTER_WORDS)
    return a

# -----------------------------------------------

def _set_key_color_or_not(gw, key_colored, k, c, override_check=False):
    if not key_colored or override_check:
        gw.set_key_color(k.capitalize(), c)

def _add_color(gw, column, keycolored, character, color, ac, oc: Optional[bool] = None):
    gw.set_square_color(gw.get_current_row(), column, color)
    if oc:
        _set_key_color_or_not(gw, keycolored, character, color, oc)
    else:
        _set_key_color_or_not(gw, keycolored, character, color)
    a_copy = ac.replace(character, "", 1)
    return a_copy

def add_tempfile() -> NamedTemporaryFile:
    """creates score file"""
    global t
    if not t:
        t = NamedTemporaryFile("w+", encoding="utf-8", prefix="wordle_", dir=getcwd(), delete=False)
    return t

def validate_responce(gw: Type[WordleGWindow], res: str, a: str) -> Union[bool, bool, NamedTemporaryFile]:
    """Validates user response
    :param gw: Main Wordle window class
    :param res: User responce
    :param a: answer to the wordle

    Returns:
        validity | word-validation | score tempfile
    """
    global MINUS_COL
    a_copy = deepcopy(a)
    correct_counter = 0

    temp = add_tempfile()
    # checks if word is not in the word list
    if res not in FIVE_LETTER_WORDS:
        gw.show_message(f"{res} is not a word!!!")
        return False, True, temp

    for c in a:
        col = N_COLS - MINUS_COL
        ch = gw.get_square_letter(gw.get_current_row(), col).lower()
        key_colored = gw.get_key_color(c.capitalize()) != UNKNOWN_COLOR
        if ch == c:
            a_copy = _add_color(gw, col, key_colored, ch, CORRECT_COLOR, a_copy, True)
            correct_counter += 1
        elif ch in a_copy:
            a_copy = _add_color(gw, col, key_colored, ch, PRESENT_COLOR, a_copy)
        else:
            a_copy = _add_color(gw, col, key_colored, ch, MISSING_COLOR, a_copy)
        MINUS_COL -= 1

    line = f"{gw.get_current_row()}|{correct_counter}\n"
    temp.write(line)
    temp.flush()

    MINUS_COL = 5

    if correct_counter == 5:
        return True, False, temp
    return False, False, temp

class ScoreFileParser:
    """
    Parses and adds score to wordle grid based on the scorefile
    """
    cleared = False

    def __init__(self, gw: Type[WordleGWindow], tmp: Type[NamedTemporaryFile]):
        self.gw = gw
        self.tmpfile = tmp

    def parse(self):
        """Main function to parse the score file"""
        self.tmpfile.seek(0)
        lines = self.tmpfile.readlines()
        if not self.cleared:
            self.clear_grid()
            self.parse()
        for l in lines:
            row = l.split("|")[0]
            correct_points = l.split("|")[1].replace("\n", "")
            self.gw.set_square_letter(int(row), 0, str(int(row) + 1))
            self.gw.set_square_letter(int(row), 4, correct_points)
            self.gw.set_square_color(int(row), 0, PRESENT_COLOR)
            if int(correct_points) == 5:
                self.gw.set_square_color(int(row), 4, CORRECT_COLOR)
            else:
                self.gw.set_square_color(int(row), 4, MISSING_COLOR)
        self.gw.show_message("rows                           points", "limegreen")

    def clear_grid(self):
        """Clear wordle grid"""
        for i in range(N_ROWS):
            self.gw.set_current_row(i)
            for j in range(N_COLS):
                self.gw.set_square_letter(i, j, "")
        self.cleared = True

    def close(self):
        """closes the score file"""
        self.tmpfile.close()
        path = self.tmpfile.name
        print(path)
        unlink(path)


from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import ui
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from collections import defaultdict
import time
import datetime
import csv
import unicodedata
import re
import hashlib
import os
from selenium.common.exceptions import ElementNotVisibleException

options = webdriver.ChromeOptions()
options.add_argument("--start-maximized")
driver = webdriver.Chrome(chrome_options=options)
actions = ActionChains(driver)
today =datetime.date.today()
def check_exists_by_xpath(xpath):
    try:
        while (driver.find_element_by_xpath("%s"%(xpath,))) :
        	driver.find_element_by_xpath("%s"%(xpath,)).click()
        	time.sleep(5)
    except ElementNotVisibleException:
        print ("element not found")

wait = ui.WebDriverWait(driver, 10)
driver.get('http://www.cwtv.com/shows/')
print(driver.current_url)
time.sleep(8)
(driver.page_source).encode('ascii','ignore')
shows_count =driver.find_elements_by_xpath(".//*[@id='cw-main-footer-1']/div[1]/ul/li/a")
print ("Shows count :[%s]"%(len(shows_count)),)
launch_id =[]
service_videos = {}
href =[]
release_year=0
multiples =1
for s in range (len(shows_count)):
	href.append(shows_count[s].get_attribute('href'))
print (href)
for h in range (len(href)):
	try:
		print (h)
		driver.get (href[h])
		episodes=driver.find_elements_by_xpath(".//*[@id='list_1']/div//li//a")
		multiples= len(episodes)/5
		print (multiples)
		for m in range (multiples) :
			for e in range (len(episodes)):
				print (len(episodes), e+1, m+1)
				if e+1==(5*(m+1)) :
					driver.find_element_by_xpath(".//*[contains(@id,'touchcarousel_1')]/button[2]").click()
					time.sleep  (3)
				epi_href =episodes[e].get_attribute('href')
				video_id =epi_href.split("=")[-1].encode('ascii', 'ignore')
				epi_details =driver.find_element_by_xpath("(.//*[@id='list_1']/div//li//a//div[contains(@class,'videodetails')]/p[1])[%s]"%(e+1)).text.encode('ascii', 'ignore')
				epi_title =epi_details.split("Ep.")[0].split("(")[0].strip()
				epi_sea_num =epi_details.split("Ep.")[1].split(")")[0]
				print (epi_details, epi_title, epi_sea_num)
				if (len (epi_sea_num) == 3) :
					epi_num=epi_details.split("Ep.")[1].split(")")[0][-2:]
					season_num =epi_details.split("Ep.")[1].split(")")[0][0]
				elif (len (epi_sea_num) == 4) :
					epi_num=epi_details.split("Ep.")[1].split(")")[0][-2:]
					season_num =epi_details.split("Ep.")[1].split(")")[0][0:2]
				series_title =driver.find_element_by_xpath(".//*[@id='show-logo']/a").get_attribute('title').encode('ascii', 'ignore')
				launch_id.append(video_id)
				service_videos ["cwtv"] =launch_id

				res=[today, "CWTV Shows", series_title, season_num, epi_num, epi_title, service_videos]
				print (res)
				with open(os.getcwd()+'/'+"cwtv_shows_output"+ '.csv', 'ab+') as mycsvfile:
					thedatawriter =csv.writer(mycsvfile)
					thedatawriter.writerow(res)
					launch_id =[]
					service_videos = {}
	except Exception as e:
		print(e)
		continue


import os
from bson.json_util import dumps
from dotenv import load_dotenv
# from flask import jsonify
import pymongo

load_dotenv()  # use dotenv to hide sensitive credential as environment variables
DATABASE_URL = f'mongodb+srv://{os.environ.get("user")}:{os.environ.get("passwort")}' \
               '@flask-mongodb-atlas.wicsm.mongodb.net/' \
               'flaura?retryWrites=true&w=majority'  # get connection url from environment

client = pymongo.MongoClient(DATABASE_URL)  # establish connection with database

# plants.config['MONGO_DBNAME'] = 'restdb'
# plants.config['MONGO_URI'] = 'mongodb://localhost:27017/restdb'
# mongo = PyMongo(plants)

mydb = client.flaura
mycol = mydb.plants

def getPlantsByName(name):
    cursor = mycol.find({"name": {"$regex": '.*'+name+'.*', "$options": 'i'}})
    list_cur = list(cursor)
    plants = dumps(list_cur)
    return plants

def getAllPlants():
    cursor = mycol.find()
    list_cur = list(cursor)
    plantList = dumps(list_cur)
    return plantList

def setNewPlant(name, waterAmount, critMoist, sleepTime):
    newPlant = {"name": name, "waterAmountML": waterAmount, "criticalMoisture": critMoist, "sleepTime": sleepTime}
    mycol.insert_one(newPlant)

# function Get List of Plants that contain <name>
# function Get All Plants??
# function Add new Plant to DB


import os
import re
from typing import Tuple

from transformers import pipeline  # type: ignore

MODEL_PATH = os.environ.get("MODEL_PATH", "./distilbert-base-cased-distilled-squad")

class CardSourceGeneratorMock:
    def __call__(self, text: str, question: str) -> Tuple[int, int]:
        return 0, len(text) // 2

class CardSourceGenerator:
    def __init__(self) -> None:
        self._qa_model = pipeline(
            "question-answering", model=MODEL_PATH, tokenizer=MODEL_PATH
        )

    def __call__(self, text: str, question: str) -> Tuple[int, int]:
        answer = self._qa_model(question=question, context=text)  # type: ignore

        start, end = self._find_sentence_indices(text, answer["start"], answer["end"])
        return start, end

    def _find_sentence_indices(
        self, text: str, substring_start: int, substring_end: int
    ) -> Tuple[int, int]:
        """
        Finds the starting and ending indices of the sentence that contains the substring.
        """
        sentences = re.split(r"\n|(?<=[.!?])\s+", text)
        substring = text[substring_start:substring_end]

        for sentence in sentences:
            index = sentence.lower().find(substring.lower())
            if index != -1:
                start = text.index(sentence)
                end = start + len(sentence)
                return start, end

        return substring_start, substring_end


import mne
import numpy as np
import pandas as pd
from mne.beamformer import make_lcmv, apply_lcmv, apply_lcmv_cov
from scipy.stats import pearsonr

import config
from config import fname, lcmv_settings
from time_series import simulate_raw, create_epochs

# Don't be verbose
mne.set_log_level(False)

fn_stc_signal = fname.stc_signal(vertex=config.vertex)
fn_simulated_raw = fname.simulated_raw(vertex=config.vertex)
fn_simulated_epochs = fname.simulated_epochs(vertex=config.vertex)

# fn_report_h5 = fname.report(vertex=config.vertex)
fn_report_h5 = None  # Don't produce a report

###############################################################################
# Simulate raw data and create epochs
###############################################################################

print('simulate data')
info = mne.io.read_info(fname.sample_raw)
info = mne.pick_info(info, mne.pick_types(info, meg=True, eeg=False))
fwd_disc_true = mne.read_forward_solution(fname.fwd_discrete_true)
fwd_disc_true = mne.pick_types_forward(fwd_disc_true, meg=True, eeg=False)
er_raw = mne.io.read_raw_fif(fname.ernoise, preload=True)

raw, stc_signal = simulate_raw(info=info, fwd_disc_true=fwd_disc_true, signal_vertex=config.vertex,
                               signal_freq=config.signal_freq, n_trials=config.n_trials,
                               noise_multiplier=config.noise, random_state=config.random,
                               n_noise_dipoles=config.n_noise_dipoles_vol, er_raw=er_raw)

true_ori = fwd_disc_true['src'][0]['nn'][config.vertex]

# del info, fwd_disc_true, er_raw

epochs = create_epochs(raw)

###############################################################################
# Sensor-level analysis
###############################################################################

epochs_grad = epochs.copy().pick_types(meg='grad')
epochs_mag = epochs.copy().pick_types(meg='mag')
epochs_joint = epochs.copy().pick_types(meg=True)

# Make cov matrices
cov = mne.compute_covariance(epochs, tmin=-1, tmax=1, method='empirical')
signal_cov = mne.compute_covariance(epochs, tmin=0, tmax=1, method='empirical')
noise_cov = mne.compute_covariance(epochs, tmin=-1, tmax=0, method='empirical')

# Compute evokeds
evoked_grad = epochs_grad.average()
evoked_mag = epochs_mag.average()
evoked_joint = epochs_joint.average()

###############################################################################
# Compute LCMV beamformer results
###############################################################################

# Read in forward solution
fwd_disc_man = mne.read_forward_solution(fname.fwd_discrete_man)

dists = []
focs = []
corrs = []
ori_errors = []
for setting in lcmv_settings:
    reg, sensor_type, pick_ori, inversion, weight_norm, normalize_fwd, use_noise_cov, reduce_rank, project_pca = setting
    try:
        if sensor_type == 'grad':
            evoked = evoked_grad
        elif sensor_type == 'mag':
            evoked = evoked_mag
        elif sensor_type == 'joint':
            evoked = evoked_joint
        else:
            raise ValueError('Invalid sensor type: %s', sensor_type)

        if project_pca and pick_ori != 'vector':
            raise NotImplementedError('project_pca=True only makes sense when pick_ori="vector"')

        filters = make_lcmv(evoked.info, fwd_disc_man,
                            cov if use_noise_cov else signal_cov,
                            reg=reg,
                            pick_ori=pick_ori, weight_norm=weight_norm,
                            inversion=inversion,
                            depth=1. if normalize_fwd else None,
                            noise_cov=noise_cov if use_noise_cov else None,
                            reduce_rank=reduce_rank)

        stc_est = apply_lcmv(evoked, filters).crop(0.001, 1)

        if pick_ori == 'vector':
            # Combine vector time source
            if project_pca:
                stc_proj, _ = stc_est.project('pca', fwd_disc_man['src'])
            else:
                stc_proj = stc_est.magnitude()
            stc_est_power = (stc_proj ** 2).sum()
            peak_vertex, peak_time = stc_est_power.get_peak(vert_as_index=True, time_as_index=True)
            estimated_time_course = np.abs(stc_proj.data[peak_vertex])
        else:
            stc_est_power = (stc_est ** 2).sum()
            peak_vertex, peak_time = stc_est_power.get_peak(vert_as_index=True, time_as_index=True)
            estimated_time_course = np.abs(stc_est.data[peak_vertex])

        # Compute distance between true and estimated source locations
        pos_est = fwd_disc_man['source_rr'][peak_vertex]
        pos_true = fwd_disc_man['source_rr'][config.vertex]
        dist = np.linalg.norm(pos_est - pos_true)

        # Ratio between estimated peak activity and all estimated activity.
        focality_score = stc_est_power.data[peak_vertex, 0] / stc_est_power.data.sum()

        # Correlation between true and reconstructed timecourse
        true_time_course = stc_signal.copy().crop(0, 1).data[0]
        corr = pearsonr(np.abs(true_time_course), estimated_time_course)[0]

        # Angle between estimated and true source orientation
        if pick_ori == 'max-power':
            estimated_ori = filters['max_power_ori'][config.vertex]
            ori_error = np.rad2deg(np.arccos(estimated_ori @ true_ori))
            if ori_error > 90:
                ori_error = 180 - ori_error
        elif pick_ori == 'vector':
            estimated_ori = stc_est.data[peak_vertex, :, peak_time]
            estimated_ori /= np.linalg.norm(estimated_ori)
            ori_error = np.rad2deg(np.arccos(estimated_ori @ true_ori))
            if ori_error > 90:
                ori_error = 180 - ori_error
        else:
            ori_error = np.nan
    except Exception as e:
        print(e)
        dist = np.nan
        focality_score = np.nan
        corr = np.nan
        ori_error = np.nan
    print(setting, dist, focality_score, corr, ori_error)

    dists.append(dist)
    focs.append(focality_score)
    corrs.append(corr)
    ori_errors.append(ori_error)

###############################################################################
# Save everything to a pandas dataframe
###############################################################################

df = pd.DataFrame(lcmv_settings,
                  columns=['reg', 'sensor_type', 'pick_ori', 'inversion',
                           'weight_norm', 'normalize_fwd', 'use_noise_cov',
                           'reduce_rank', 'project_pca'])
df['dist'] = dists
df['focality'] = focs
df['corr'] = corrs
df['ori_error'] = ori_errors

df.to_csv(fname.lcmv_results(vertex=config.vertex, noise=config.noise))
print('OK!')


"""
Main script: Autonomous Driving on Udacity Simulator
@author : nelsoonc

Undergraduate Thesis
Nelson Changgraini - Bandung Institute of Technology, Indonesia
"""

# Throttle 0 - 1 will produce speed 0 - 30 mph
# Steering -1 - 1 will produce angle -25 - 25 degrees

import os
import numpy as np
import socketio
import eventlet
from flask import Flask
import tensorflow as tf
from tensorflow.keras.models import load_model
import base64
from io import BytesIO
from PIL import Image
from train import rmse, get_lr_metric
from utils import preprocess
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'

# DIRECTORY PATH
MODEL_PATH = 'models/simulation_model.h5'

# VARIABLE
MAX_SPEED = 25

# FOR REAL TIME COMMUNICATION BETWEEN CLIENT AND SERVER
sio = socketio.Server()
# FLASK IS A MICRO WEB FRAMEWORK WRITTEN IN PYTHON
app = Flask(__name__)  # '__main__'

# Executing in graph mode
@tf.function
def predict(input_tensor, model):
    return model(input_tensor)

@sio.on('telemetry')
def telemetry(sid, data):
    speed = float(data['speed'])
    image = Image.open(BytesIO(base64.b64decode(data['image'])))
    image = np.asarray(image)
    image = preprocess(image)
    image = np.array([image])
    steering = float(predict(image, model))

    throttle = 1.0 - abs(steering) - speed / MAX_SPEED
    print('{}, {}, {}'.format(steering, throttle, speed))
    sendControl(steering, throttle)

@sio.on('connect')
def connect(sid, environ):
    print('Connected', sid)
    sendControl(0, 0)

@sio.on('disconnect')
def disconnect(sid):
    print('Disconnect', sid)

def sendControl(steering, throttle):
    sio.emit('steer', data={
        'steering_angle': steering.__str__(),
        'throttle': throttle.__str__()
    }, skip_sid=True)

if __name__ == '__main__':
    print('Setting up..')
    model = load_model(MODEL_PATH, custom_objects={'rmse': rmse, 'lr': get_lr_metric})
    if model:
        print('Model loaded')
    app = socketio.Middleware(sio, app)
    # LISTEN TO PORT 4567
    eventlet.wsgi.server(eventlet.listen(('', 4567)), app)


from pathlib import Path
from promtail_ops_manager import PromtailOpsManager

# The promtail release file.
resource = "./promtail.zip"

manager = PromtailOpsManager()
# manager.install(resource)

# Setup for local tests such that installation of binaries etc.
# will not mess up your local client.
manager.promtail_home = Path('/tmp/promtail')
manager.promtail = Path('/tmp/promtail/promtail-linux-amd64')
manager.promtail_cfg = manager.promtail_home.joinpath('promtail-local-config.yaml')
manager.promtail_unitfile = Path('/tmp/promtail.service')

# Run tests.
manager._prepareOS()
manager._install_from_resource(resource)
manager._install_config()
manager._install_systemd_unitfile()
if manager.verify_config():
    print("Config OK")
else:
    print("Config is error")

print("Version:", manager.promtail_version() )
# manager._purge()


import json
import os
from googleapiclient.discovery import build

class Channel:
    """Класс для ютуб-канала"""

    def __init__(self, channel_id: str) -> None:
        """Экземпляр инициализируется id канала. Дальше все данные будут подтягиваться по API."""
        self.__channel_id = channel_id

        api_key: str = os.getenv('API_KEY')
        youtube = build('youtube', 'v3', developerKey=api_key)
        channel = youtube.channels().list(id=self.__channel_id, part='snippet,statistics').execute()

        self.title = channel['items'][0]['snippet']['title']
        self.description = channel['items'][0]['snippet']['description']
        self.url = 'https://www.youtube.com/channel/' + self.__channel_id
        self.subscribers = channel['items'][0]['statistics']['subscriberCount']
        self.video_count = channel['items'][0]['statistics']['videoCount']
        self.views = channel['items'][0]['statistics']['viewCount']

    def __str__(self):
        return f"{self.title} ({self.url})"

    def __add__(self, other):
        """ Метод для операции сложения"""
        return int(self.subscribers) + int(other.subscribers)

    def __sub__(self, other):
        """ Метод для операции вычитания"""
        return int(self.subscribers) - int(other.subscribers)

    def __lt__(self, other):
        """ Метод для операции сравнения «меньше»"""
        if int(self.subscribers) < int(other.subscribers):
            return True
        else:
            return False

    def __le__(self, other):
        """ Метод для операции сравнения «меньше или равно»"""
        if int(self.subscribers) <= int(other.subscribers):
            return True
        else:
            return False

    def __gt__(self, other):
        """ Метод для операции сравнения «больше»"""
        if int(self.subscribers) > int(other.subscribers):
            return True
        else:
            return False

    def __ge__(self, other):
        """  Метод для операции сравнения «больше или равно»"""
        if int(self.subscribers) >= int(other.subscribers):
            return True
        else:
            return False

    def __eq__(self, other):
        """ Поведение оператора равенства"""
        if int(self.subscribers) == int(other.subscribers):
            return True
        else:
            return False

    @property
    def channel_id(self):
        return self.__channel_id

    def print_info(self) -> None:
        """Выводит в консоль информацию о канале."""
        api_key: str = os.getenv('API_KEY')
        youtube = build('youtube', 'v3', developerKey=api_key)
        channel = youtube.channels().list(id=self.__channel_id, part='snippet,statistics').execute()
        print(json.dumps(channel, indent=2, ensure_ascii=False))

    @classmethod
    def get_service(cls):
        """
        Возвращает объект для работы с YouTube API
        """
        api_key: str = os.getenv('API_KEY')
        youtube = build('youtube', 'v3', developerKey=api_key)
        return youtube

    def to_json(self, name_json):
        """
        Сохраняет в файл значения атрибутов экземпляра Channel
        """
        attribute_dict = {'channel_id': self.__channel_id,
                          'title': self.title,
                          'description': self.description,
                          'url': self.url,
                          'subscribers': self.subscribers,
                          'video_count': self.video_count,
                          'views': self.views,
                          }

        with open(name_json, "w", encoding="utf-8") as file:
            file.write(json.dumps(attribute_dict))


import time
import pyrealsense2 as rs
import numpy as np
import cv2
import os
import open3d as o3d

intrinsics = np.array([
            [605.7855224609375, 0., 324.2651672363281, 0.0],
            [0., 605.4981689453125, 238.91090393066406, 0.0],
            [0., 0., 1., 0.0],
            [0., 0., 0., 1.],])

ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

def launch_realsense(pixel_width, pixel_high, fps, found_rgb=False):
    pipeline = rs.pipeline()
    # Create a config and configure the pipeline to stream
    config = rs.config()
    pipeline_wrapper = rs.pipeline_wrapper(pipeline)
    pipeline_profile = config.resolve(pipeline_wrapper)
    device = pipeline_profile.get_device()

    for s in device.sensors:
        if s.get_info(rs.camera_info.name) == 'RGB Camera':
            found_rgb = True
            break
    if not found_rgb:
        print("Can't launch rgb camera")
        exit(0)

    config.enable_stream(rs.stream.depth, pixel_width, pixel_high, rs.format.z16, fps)
    config.enable_stream(rs.stream.color, pixel_width, pixel_high, rs.format.bgr8, fps)

    align_to = rs.stream.color
    alignedFs = rs.align(align_to)
    # Start streaming
    pipeline.start(config)

    # Create folders by date
    save_path = os.path.join(os.getcwd(), "out_data",
                             time.strftime("%Y_%m_%d_%H_%M_%S",
                                           time.localtime()))
    os.makedirs(save_path)
    os.makedirs(os.path.join(save_path, "rgb"))
    os.makedirs(os.path.join(save_path, "depth"))
    os.makedirs(os.path.join(save_path, "depth_colormap"))

    # cv2.namedWindow("camera in real time", cv2.WINDOW_AUTOSIZE)
    # saved_color_image = None
    # saved_depth_mapped_image = None
    try:
        flag = 0
        while True:
            if flag == 0:
                time.sleep(2)
                flag = 1
                continue
            # Wait for a coherent pair of frames: rgb and depth
            frames = pipeline.wait_for_frames()
            align_frames = alignedFs.process(frames)
            depth_frame = align_frames.get_depth_frame()
            color_frame = align_frames.get_color_frame()
            if not depth_frame or not color_frame:
                continue

            color_profile = color_frame.get_profile()
            cvsprofile = rs.video_stream_profile(color_profile)
            color_intrin = cvsprofile.get_intrinsics()
            color_intrin_part = [color_intrin.ppx, color_intrin.ppy,
                                 color_intrin.fx, color_intrin.fy]
            print('**color_intrin_part**:',color_intrin_part)
            # Convert images to numpy arrays
            depth_image = np.asanyarray(depth_frame.get_data())
            color_image = np.asanyarray(color_frame.get_data())

            depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(depth_image, alpha=0.1), cv2.COLORMAP_JET)

            # depth_colormap_dim = depth_colormap.shape
            # color_colormap_dim = color_image.shape
            #
            # if depth_colormap_dim != color_colormap_dim:
            #     resized_color_image = cv2.resize(color_image, dsize=(depth_colormap_dim[1], depth_colormap_dim[0]),
            #                                      interpolation=cv2.INTER_AREA)
            #     images = np.hstack((resized_color_image, depth_colormap))
            # else:
            #     images = np.hstack((color_image, depth_colormap))

            # # Show images
            # cv2.imshow("camera in real time", images)
            # key = cv2.waitKey(1)

            # Save the image
            # if key & 0xFF == ord('s'):
            saved_count = 0
            for filename in os.listdir(os.path.join((save_path), "rgb")):
                if filename.endswith('.png'):
                    saved_count += 1
            print('save data:',saved_count)
            saved_color_image = color_image
            saved_depth_image = depth_image
            saved_depth_mapped_image = depth_colormap
            # save rgb png
            cv2.imwrite(os.path.join((save_path), "rgb",
                                     "rgb_{}.png".format(saved_count)),saved_color_image)
            # save depth_colormap png
            cv2.imwrite(os.path.join((save_path), "depth_colormap",
                                     "depth_colormap_{}.png".format(saved_count)),
                        saved_depth_mapped_image)
            # save depth png
            cv2.imwrite(os.path.join((save_path), "depth",
                                     "depth_{}.png".format(saved_count)),
                        saved_depth_image)
            # save depth npy
            np.save(os.path.join((save_path), "depth",
                                 "depth_{}.npy".format(saved_count)), saved_depth_image)

            depth_path = os.path.join((save_path), "depth", "depth_{}.npy".format(saved_count))
            color_path = os.path.join((save_path), "rgb", "rgb_{}.png".format(saved_count))
            return depth_path, color_path

    finally:
        # Stop streaming
        pipeline.stop()

def loadRGB(color_file):
    return cv2.cvtColor(cv2.imread(color_file), cv2.COLOR_BGR2RGB)

def loadDepth(depth_file):
    return cv2.imread(depth_file, cv2.IMREAD_UNCHANGED)

def save_points(depth_path, color_path):

    colors = loadRGB(color_path).astype(np.float32) / 255.0
    depths = np.load(depth_path) # loadDepth(depth_path)

    # convert RGB-D to point cloud
    fx, fy = intrinsics[0, 0], intrinsics[1, 1]
    cx, cy = intrinsics[0, 2], intrinsics[1, 2]
    # depth factor
    s = 1000.0
    xmap, ymap = np.arange(colors.shape[1]), np.arange(colors.shape[0])
    xmap, ymap = np.meshgrid(xmap, ymap)
    points_z = depths / s
    points_x = (xmap - cx) / fx * points_z
    points_y = (ymap - cy) / fy * points_z
    points = np.stack([points_x, points_y, points_z], axis=-1)
    points = points.reshape((-1, 3))
    colors = colors.reshape((-1, 3))

    mask = np.where(points[:, 2] < 1)
    points = points[mask]
    colors = colors[mask]

    cloud = o3d.geometry.PointCloud()
    cloud.points = o3d.utility.Vector3dVector(points)
    cloud.colors = o3d.utility.Vector3dVector(colors)

    coord = o3d.geometry.TriangleMesh.create_coordinate_frame(size=0.1, origin=[0, 0, 0])
    o3d.visualization.draw_geometries([cloud, coord])

    base_dir = os.path.dirname(os.path.dirname(color_path))
    points_file = os.path.join(base_dir, 'points.npy')
    colors_file = os.path.join(base_dir, 'colors.npy')
    np.save(points_file, points)
    np.save(colors_file, colors)
    return points_file, colors_file

if __name__ == '__main__':
    depth_path, color_path = launch_realsense(pixel_width=640, pixel_high=480, fps=30)
    save_points(depth_path, color_path)


import customtkinter as ctk
from PIL import Image
root = ctk.CTk()
root.title("IRIS")
root.geometry("1080x720")
root._set_appearance_mode("dark")

frame = ctk.CTkFrame(master=root)
frame.pack(pady=20)

logo = ctk.CTkImage(Image.open(
    "/home/nabendu/Documents/MCA/projects/python-speechRecongition-desktop-AI-project/main/img/walle.png"), size=(200, 180))
label = ctk.CTkLabel(frame, image=logo, text="")
label.grid(row=0, column=0, pady=0, padx=0)

aiTextBox = ctk.CTkTextbox(master=frame, height=100, width=500)
aiTextBox.grid(row=0, column=1, pady=10, padx=50)

frame2 = ctk.CTkFrame(master=root)
frame2.pack(pady=10)

userTextBox = ctk.CTkTextbox(master=frame2, height=50, width=500)
userTextBox.grid(row=0, column=0, padx=30, pady=10)

command = ctk.CTkButton(master=frame2, text="Enter Command",
                        height=50)
command.grid(row=0, column=1, padx=50, pady=10)

root.mainloop()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed May 23 12:34:08 2018

@author: michal
"""

import networkx as nx
from networkx.algorithms.isomorphism import GraphMatcher
from networkx.readwrite.json_graph import node_link_data
from os.path import isdir, join, isfile
from os import mkdir
import json
from glob import glob
import shutil

class anionMatcher(GraphMatcher):
    def semantic_feasibility(self, G1_node, G2_node):
        if "charged" in self.G1.node[G1_node]:
            if self.G1.node[G1_node]["charged"] != self.G2.node[G2_node]["charged"]:
                return False
        elif self.G2.node[G2_node]["charged"]:
            return False

        if self.G2.node[G2_node]["terminating"]:
            if len(list(self.G2.neighbors(G2_node))) != len(list(self.G1.neighbors(G1_node))):
                return False

        if ( self.G2.node[G2_node]["element"] == "X" or "X" in self.G2.node[G2_node]["aliases"] ) and  not self.G1.node[G1_node]["element"] in self.G2.node[G2_node]["notAliases"] :
            return True

        return self.G1.node[G1_node]["element"] == self.G2.node[G2_node]["element"] or self.G1.node[G1_node]["element"] in self.G2.node[G2_node]["aliases"]

def addAtribute( graph, nodes, key ):
    if isinstance(nodes, list):
        for nodeId in nodes:
            graph.node[nodeId][key] = True

    else:
        graph.node[nodes][key] = True

def saveAnion( atoms, bonds, charged, name, priority , terminating = [], aliases = {},
              notAliases = {}, geometry = {}, fullIsomorphism = False, nameMapping = {} , nonUniqueCharge = [] ,
              properties2measure = [] ):
    graph = nx.Graph()
    nonUniqueCharge = set(nonUniqueCharge)

    for i, el in enumerate(atoms):
        graph.add_node(i, element = el, terminating = False, bonded = False, aliases = [], charged = False )

    graph.add_edges_from(bonds)

    addAtribute( graph, terminating, "terminating")

    for nodeId in aliases:
        graph.node[nodeId]["aliases"] = aliases[nodeId]

    for nodeId in notAliases:
        graph.node[nodeId]["notAliases"] = notAliases[nodeId]

    if not geometry:
        graph.graph["geometry"]= "no restrictions"
    else:
        graph.graph["geometry"]= geometry

    graph.graph["fullIsomorphism"] = fullIsomorphism
    graph.graph["name"] = name
    graph.graph["nameMapping"] = nameMapping
    graph.graph["priority"] = priority
    graph.graph["properties2measure"] = properties2measure

    fileName = str(priority)+"_"+name

    if isinstance( charged , list ) :
        uniqueCharges = set(charged)

        for nodeId in charged:
            nuc = uniqueCharges | nonUniqueCharge
            nuc.remove(nodeId)
            saveAnionJson(graph, fileName, nodeId, nuc)
    else:
        saveAnionJson(graph, fileName, charged, nonUniqueCharge)

def saveAnionJson( graph, fileName, charged, nonUniqueCharges = []):
    mainElement = graph.node[charged]["element"]
    elements = [ mainElement ]

    if "aliases" in graph.node[charged]:
        elements += graph.node[charged]["aliases"]
        graph.node[charged]["aliases"] = []

    graph.node[charged]["charged"] = True
    graph.graph["charged"] = charged
    graph.graph["otherCharges"] = list(nonUniqueCharges)

    oldName = ""
    nameMapping = False
    if "X" in graph.graph["name"] and charged in graph.graph["nameMapping"]:
        oldName = graph.graph["name"]
        nameMapping = graph.graph["nameMapping"][charged]
        graph.graph["nameMapping"].pop(charged)

    for element in elements:
        graph.node[charged]["element"] = element

        if nameMapping:
            graph.graph["name"] = oldName.replace( nameMapping , element)

        dir_path = join("anion_templates", element)
        if not isdir( dir_path ):
            mkdir( dir_path )

        path2save = getUniquePath( dir_path , fileName)
        output = open(path2save, 'w')

        json.dump(node_link_data(graph), output )
        output.close()

    graph.node[charged]["charged"] = False

def getUniquePath(dirPath, fileName):
    path2save = join( dirPath , fileName+".json")
    if not isfile(path2save):
        return path2save

    similarFiles = glob( join(dirPath, fileName)+"_*.json" )
    if not similarFiles:
        return join( dirPath , fileName+"_0.json")

    maxNumber = -1
    for s in similarFiles:
        newNumber = int( s[:-5].split("_")[-1] )
        maxNumber = max(maxNumber, newNumber)

    return join( dirPath , fileName+"_"+str(maxNumber+1)+".json")

def clearAnionTemplates():
    if isdir("anion_templates"):
        shutil.rmtree("anion_templates")
    mkdir("anion_templates")

if __name__ == "__main__":
    clearAnionTemplates()

# atoms, bonds, charged, name, priority, terminating = [], aliases = {}, notAliases = {}, geometry = {}, fullIsomorphism = False
    #OXYGEN

#    #RCOOH
    saveAnion( [ "C" , "C", "O", "O" ], [ (0,1), (1,2), (1,3) ],
              2, "RCOO", 0, terminating = [1, 2, 3],
              geometry = "planar", nonUniqueCharge = [3],
              properties2measure= [ { "kind" : "plane", "atoms" : [ 1, 2, 3 ] , "directionalVector" : [ { "atom" : 1 }, { "center" : [ 2, 3] } ] } ] )

    #ClO, BrO, IO,
    saveAnion([ "CL",  "O" ], [(0, 1)],
              1, "XO", 5, fullIsomorphism = True,
              aliases = { 0 : [ "BR", "I" ] }, nameMapping = { 0 : "X"}, properties2measure= [ {  "kind" : "line", "atoms" : [ 0, 1 ] } ] )

    #NO2, ClO2, BRO2,
    saveAnion([ "N",  "O" , "O" ], [(0, 1), (0,2)],
              1, "XO2", 10, fullIsomorphism = True, aliases = { 0 : ["CL", "BR"]}, nameMapping = { 0 : "X" },
              nonUniqueCharge=[2], properties2measure= [ { "kind" : "plane" , "atoms" : [ 0, 1, 2 ],
                               "directionalVector" : [ { "atom" : 0 }, { "center" : [ 1, 2] } ] } ])

    #NO3, CO3, PO3, SO3, AsO3, BO3, ClO3, BRO3
    saveAnion( ["N", "O", "O", "O"], [(0,1), (0,2), (0,3)],
              1, "XO3", 15, fullIsomorphism = True,
              aliases = { 0 : [ "C", "P", "B", "S", "AS", "CL", "BR", "I" ] }, nameMapping = { 0 : "X" },
              nonUniqueCharge= [2, 3],
              properties2measure= [ { "kind" : "plane", "atoms" : [ 1, 2, 3 ] , "directionalVector" : [ { "closest" : [1, 2, 3] }, { "center" : [ 1, 2, 3] } ]} ])

    #PO4, SO4, AsO4, ClO4, BRO4
    saveAnion( ["P", "O", "O", "O", "O"], [(0,1), (0,2), (0,3), (0, 4)],
              1, "XO4", 20, fullIsomorphism = True,
              aliases = { 0 : [ "S", "AS", "CL", "BR", "I" ] }, nameMapping = { 0 : "X" },
              nonUniqueCharge=[2, 3, 4])

#   Ph-OH
#    saveAnion( [ "C" , "C" , "C" , "C" , "C", "C" , "O" ], [(0,1),(1,2), (2,3), (3,4),( 4, 5), (5, 0), (5,6)],
#              6, "PhOH", 25, terminating = [6], geometry = "planarWithSubstituents")

    #    #RBOOH
    saveAnion( [ "X" , "B", "O", "O" ], [ (0,1), (1,2), (1,3) ],
              2, "RBOO", 30, terminating = [2, 3],
              notAliases = {0 : [ "O" ] },
              nonUniqueCharge=[3],
              properties2measure= [ { "kind" : "plane" , "atoms" : [ 1, 2, 3 ] , "directionalVector" : [ { "atom" : 1 }, { "center" : [ 2, 3] } ]} ])

    #COO
    saveAnion( [  "C", "O", "O" ], [ (0,1), (0,2) ],
              1, "COO", 35, terminating = [1, 2], nonUniqueCharge=[2],
              properties2measure= [ { "kind" : "plane", "atoms" : [ 0, 1, 2 ], "directionalVector" : [ { "atom" : 0 }, { "center" : [ 1, 2] } ] } ] )

    #R-PO4, R-SO4, R-AsO4
    saveAnion( ["P", "O", "O", "O", "O"], [(0,1), (0,2), (0,3), (0, 4)],
              1, "R-XO4", 45, terminating = [ 1, 2, 3 ] ,
              aliases = { 0 : [ "S", "AS" ] }, nameMapping = { 0 : "X" },
              nonUniqueCharge=[2,3])

    #R2-PO4, R2-SO4, R2-AsO4
    saveAnion( ["P", "O", "O", "O", "O"], [(0,1), (0,2), (0,3), (0, 4)],
              1, "R2-XO4", 47, terminating = [ 1, 2 ] ,
              aliases = { 0 : [ "S", "AS" ] }, nameMapping = { 0 : "X" },
              nonUniqueCharge=[2])

    #R3-PO4, R3-SO4, R3-AsO4
#    saveAnion( ["P", "O", "O", "O", "O"], [(0,1), (0,2), (0,3), (0, 4)],
#              1, "R2-XO4", 48, terminating = [ 1 ] ,
#              aliases = { 0 : [ "S", "AS" ] }, nameMapping = { 0 : "X" } )

    #RAsO3, RPO3, RSO3
    saveAnion( ["P", "O", "O", "O", "C"], [(0,1), (0,2), (0,3), (0, 4)],
              1, "RXO3", 50,  terminating = [1, 2, 3] ,
              aliases = { 0 : [ "S", "AS" ] }, nameMapping = { 0 : "X" },
              nonUniqueCharge=[2,3])

    #R2AsO2, R2PO2, RRSO2
#    saveAnion( ["P", "O", "O", "C", "C"], [(0,1), (0,2), (0,3), (0, 4)],
#              1, "R2XO2", 55, terminating = [1, 2],
#              aliases = { 0 : [ "S", "AS" ] }, nameMapping = { 0 : "X" } )

    #F, CL, BR, I, S
    saveAnion( [ "F" ], [], 0, "X", 55, aliases = { 0 : [ "CL", "BR", "I", "S"] },
              fullIsomorphism = True, nameMapping = { 0 : "X"})

    #SCN
    saveAnion([ "S",  "C" , "N" ], [(0, 1), (0,2)],
              [0,1,2], "SCN", 62, fullIsomorphism = True, properties2measure= [ { "kind" : "line", "atoms" : [ 0, 2 ] } ])

#    #RSH
#    saveAnion( [ "X" , "S" ], [ (0,1)],
#              1, "RSH", 60, terminating = [1],
#              notAliases = {0 : [ "O" ] } )
#

    #N3
    saveAnion([ "N",  "N" , "N" ], [(0, 1), (0,2)],
              [0,1], "N3", 70, fullIsomorphism = True, nonUniqueCharge=[2], properties2measure= [ { "kind" : "lineSymmetric", "atoms" : [ 0, 2 ] } ])

    #CN
    saveAnion([  "C" , "N" ], [(0, 1)],
              [0,1], "CN", 75, fullIsomorphism = True, properties2measure= [ { "kind" : "line", "atoms" : [ 0, 1 ] } ])

   #    #RSSR
#    saveAnion( [ "X" , "S", "S" ], [ (0,1), (1,2)],
#              1, "RSS", 80 ,
#              notAliases = {0 : [ "O" ] } )


from django.shortcuts import render
from cowsay_app.models import Input
from cowsay_app.forms import InputForm
import subprocess

# I mainly used this source to figure out subprocess:
# https://linuxhint.com/execute_shell_python_subprocess_run_method/
# I also used Stackoverflow and Python docs
# Also found some useful stuff on Stackoverflow for doing the history:
# https://stackoverflow.com/questions/47428403/how-to-get-the-last-10-item-data-in-django

def index(request):
    if request.method == "POST":
        new_input = InputForm()
        form = InputForm(request.POST)
        if form.is_valid():
            data = form.cleaned_data
            Input.objects.create(
                input=data.get('input')
            )
            cow = subprocess.run(
                ['cowsay', data['input']], capture_output=True
            ).stdout.decode("utf-8")
            return render(request, "index.html", {'form': new_input, 'cow': cow})

    form = InputForm()
    return render(request, "index.html", {"title": "Welcome to Cowsay!", "form": form})

def history(request):
    cowsay_history = Input.objects.order_by('-id')[:10]
    return render(request, 'history.html', {'cowsay_history': cowsay_history})


import urllib

from flask import Blueprint, request, render_template, flash, redirect, url_for

from orders_tracker.blueprints.clients.service import add_client, update_client, remove_client, search_clients, \
    get_form_fields, get_path_args, \
    get_clients_count, render_empty, get_pagination_metadata, paginate_clients
from orders_tracker.forms import NewClientForm, DeleteConfirmForm
from orders_tracker.models import Client, Device
from orders_tracker.tables import ClientsTable

clients_blueprint = Blueprint('clients_bp', __name__, template_folder="templates")

@clients_blueprint.route('/clients/new', methods=['GET', 'POST'])
def new_client():
    form = NewClientForm()
    if request.method == 'POST':
        if form.validate_on_submit():
            created_client = Client(form.name.data, form.phone.data, form.address.data, form.notes.data)
            add_client(created_client)
            return redirect(url_for('clients_bp.clients'))
        else:
            flash('Перевірте введені значення.', category='warning')

    return render_template('new_client.html', form=form)

@clients_blueprint.route('/clients', methods=['GET', 'POST'])
def clients():
    if request.method == 'POST':
        search_field = get_form_fields()
        return redirect(url_for('clients_bp.clients',
                                search_query=search_field))

    search_arg, page_arg = get_path_args()

    stats = {'total': get_clients_count(), 'filter': -1}

    clients_query = search_clients(search_arg)

    stats['filter'] = clients_query.count()
    if stats['filter'] == 0:
        return render_empty(stats, search_arg)

    pagination_metadata = get_pagination_metadata(page_arg, clients_query)

    clients_list = paginate_clients(pagination_metadata, clients_query)
    table = ClientsTable(clients_list)

    return render_template('clients.html',
                           table=table,
                           stats=stats,
                           search_field_value=search_arg,
                           pagination_data=pagination_metadata)

@clients_blueprint.route('/clients/<client_id>', methods=['GET', 'POST'])
def client(client_id):
    address_link = None
    selected_client = Client.query.filter_by(id=client_id).first_or_404()
    if selected_client.address:
        address_link = "https://www.google.com/maps/search/?api=1&query=" + \
                       urllib.parse.quote_plus(selected_client.address)

    devices = Device.query.filter_by(client_id=client_id).all()

    return render_template('client.html',
                           client=selected_client,
                           devices=devices,
                           address_link=address_link)

@clients_blueprint.route('/clients/<client_id>/edit', methods=['GET', 'POST'])
def edit_client(client_id):
    edited_client = Client.query.filter_by(id=client_id).first()
    modal_form = NewClientForm()

    if request.method == 'POST':
        if modal_form.validate_on_submit():
            edited_client.name = modal_form.name.data
            edited_client.phone = modal_form.phone.data
            edited_client.address = modal_form.address.data
            edited_client.notes = modal_form.notes.data
            update_client(edited_client)
            return redirect(url_for('clients_bp.client', client_id=edited_client.id))
        else:
            flash('Дані про клієнта не оновлено.', category='warning')

    modal_form = NewClientForm(edited_client)
    return render_template('edit_client.html',
                           form=modal_form,
                           message_title="Редагування інформації про клієнта",
                           client_id=edited_client.id,
                           color="is-link")

@clients_blueprint.route('/clients/<client_id>/delete', methods=['GET', 'POST'])
def delete_client(client_id):
    deleted_client = Client.query.filter_by(id=client_id).first()
    form = DeleteConfirmForm()

    if request.method == 'POST':
        if form.validate_on_submit():
            remove_client(deleted_client)
            return redirect(url_for('clients_bp.clients'))

    return render_template('delete_confirm.html',
                           form=form,
                           client_id=deleted_client.id,
                           message_title="Видалення клієнта",
                           message="Ви дійсно бажаєте видалити клієнта " + deleted_client.name + "?")


import pygame
import time
import random

pygame.init()
pygame.font.init()
myfont = pygame.font.SysFont('Comic Sans MS', 30)
screen = pygame.display.set_mode((1280,720))
done = False
p1_x=30
p1_y= screen.get_height()-60
#make player
class Player:
    def __init__(self,x,y):
        self.x=x
        self.y=y
    def moveLeft(self):
        if self.x>0:
            self.x-=2
    def moveRight(self):
        if self.x<screen.get_width()-60:
            self.x+=2
    def draw(self):
        pygame.draw.rect(screen, (255,255,255), pygame.Rect(self.x,self.y,60,60))

class Egg:
    def __init__(self):
        self.x=random.randint(0,screen.get_width()-30)
        self.y=0
        self.incr=1
    def update(self):
        if self.y==screen.get_height()-30:
            self.__init__()
        self.y+=self.incr
        self.incr*=1.1
    def draw(self):
        pygame.draw.rect(screen, (255,255,255), pygame.Rect(self.x,self.y,30,30))
p1 = Player(p1_x,p1_y)
egg1=Egg()
while not done:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
    pressed=pygame.key.get_pressed()
    #movement
    if pressed[pygame.K_a] : p1.moveLeft()
    if pressed[pygame.K_d] : p1.moveRight()

    screen.fill((0,0,0))
    #screen.blit(score, ((screen.get_width()/2)-20,0))
    p1.draw()
    egg1.draw()
    egg1.update()
    pygame.display.flip()


import pygame
import numpy as np
import pickle
import datetime
import os
from snake import Snake
from map import Map
from agent import Agent

# Version 1.1
MODEL_DIR = "models"
MODEL_NAME = "model_1v7"  # Name of the pickle file in which we store our model.
MODEL_PATH = os.path.join(MODEL_DIR, MODEL_NAME)
# MODEL_NAME = "models/Best_model"  # Name of the pickle file in which we store our model.

GATHER_DATA = True
DATA_DIR = r"..\data"
DATA_PATH = os.path.join(DATA_DIR, f"data_{MODEL_NAME}_dis")

learn = 1
if learn:
    VISUAL = False
    GENERATIONS = 50
    save = False
    epsilon_dec = 0.000_03
else:
    VISUAL = True
    GENERATIONS = 30
    save = False
    epsilon_dec = 0.1

MAX_ITERATIONS = 7_000  # max iterations in game # Dropped to 5_000!!!
MIN_EPSILON = 0.0001

epsilon_dec = 0.1
GAMMA = 0.4
LEARNING_RATE = 0.2
MIN_LEARNING_RATE = 0.3

def redraw_window(win: pygame.display.set_mode, snake: Snake, playground: Map):
    win.fill((25, 119, 207))
    playground.draw(win)
    snake.draw(win, playground)
    pygame.display.update()  # This updates the screen so we can see our rectangle

def main(visual: bool = True):
    start = datetime.datetime.now()
    st2 = datetime.datetime.now()
    best_score = 0
    best_time = 0
    # MODEL
    if os.path.isfile(MODEL_PATH):
        with open(MODEL_PATH, 'rb') as f:
            q_table, generation = pickle.load(f)
    else:
        if not os.path.isdir(MODEL_DIR):
            os.mkdir(MODEL_DIR)
        q_table = np.zeros((2 ** 11, 3))
        generation = 0

    if os.path.isfile(DATA_PATH):
        with open(DATA_PATH, 'rb') as f:
            gameplay_data = pickle.load(f)
    else:
        if not os.path.isdir(DATA_DIR):
            os.mkdir(DATA_DIR)
        gameplay_data = []

    # Classes
    agent = Agent()
    playground = Map()
    snake = Snake()
    playground.random_snack_pos(snake)

    # PyGame
    if visual:
        win = pygame.display.set_mode((playground.map_size, playground.map_size))
        clock = pygame.time.Clock()
        pygame.display.set_caption("Snake Game, Generation: 0")

    generations_rewards = []
    generation_time = []

    for gen in range(GENERATIONS):
        generation += 1
        current_state = agent.get_state(snake, playground)
        current_binary_state = agent.make_binary(current_state)

        # It should work as proper reset, but who knows...
        snake.reset()
        playground.reset()

        # game_over = False
        generation_reward = 0
        iteration = 0
        # epsilon = max(MIN_EPSILON, 0.9 - generation * 0.0008)
        epsilon = max(MIN_EPSILON, 0.9 - generation * epsilon_dec)
        # LEARNING_RATE = max(0.95 - generation * 0.000_000_004, MIN_LEARNING_RATE)

        if visual:
            pygame.display.set_caption(f"Snake Game, Generation: {generation}")

        for iteration in range(MAX_ITERATIONS):

            if visual:
                clock.tick(30)
                pygame.time.delay(20)
                redraw_window(win, snake, playground)

            # Maybe it can go to agent as get_action.
            # Action ==> 0 - straight, 1 - left, 2 - right
            if np.random.uniform(0, 1) < epsilon:
                action = np.random.randint(3)
            else:
                action = np.argmax(q_table[int(current_binary_state, 2), :])
                probability = max(q_table[int(current_binary_state, 2), :])

            if GATHER_DATA:
                gameplay_data.append([current_state, probability])

            snake.move_action(action, visual)
            playground.random_snack_pos(snake)

            # It can be as one function.
            next_state = agent.get_state(snake, playground)
            next_binary_state = agent.make_binary(next_state)
            game_over, reward = snake.collision(playground, add_snack=True)

            bellman_equation = (1 - LEARNING_RATE) * q_table[int(current_binary_state, 2), action] + LEARNING_RATE *\
                               (reward + GAMMA * max(q_table[int(next_binary_state, 2), :]))
            # bellman_equation = max(q_table[int(next_binary_state, 2), :]) + LEARNING_RATE * (reward + GAMMA + (
            #             max(q_table[int(next_binary_state, 2), :]) - q_table[int(current_binary_state, 2), action]))
            q_table[int(current_binary_state, 2), action] = bellman_equation

            generation_reward += reward

            if game_over:
                if playground.score > best_score:
                    best_score = playground.score
                    if best_score > 10 and save:
                        with open(f"models/Best_model", "wb") as f:
                            data = (q_table, generation)
                            pickle.dump(data, f)
                if iteration > best_time:
                    best_time = iteration
                break

            # current_state = next_state
            current_binary_state = next_binary_state
            if visual:
                print(f"SCORE: {playground.score}")
                print(f"Reward: {reward}, time: {iteration} iterations")

        generations_rewards.append(generation_reward)
        generation_time.append(iteration)
        # print(f"Rewards : {generations_rewards}")
        # print(f"Time : {generation_time}")
        if generation % 100 == 0:
            print(generation, datetime.datetime.now() - st2, best_score, best_time)
            if save:
                with open(MODEL_PATH, "wb") as f:
                    data = (q_table, generation)
                    pickle.dump(data, f)
            if GATHER_DATA:
                with open(DATA_PATH, "wb") as f:
                    pickle.dump(gameplay_data, f)
            st2 = datetime.datetime.now()

    print(f"\nTime of leaning last: {datetime.datetime.now() - start}, for {GENERATIONS} generations.")
    print(f"Best score was: {best_score} and best time was {best_time}.")
    print(f"Age: {generation} generations.")

    if save:
        with open(MODEL_PATH, "wb") as f:
            data = (q_table, generation)
            pickle.dump(data, f)
    if GATHER_DATA:
        with open(DATA_PATH, "wb") as f:
            pickle.dump(gameplay_data, f)

if __name__ == "__main__":
    main(VISUAL)


from jinja2 import Environment, FileSystemLoader
import yaml
import os.path

ENV = Environment(loader=FileSystemLoader('./'))
script_path = 'SCRIPTS/'

script = os.path.join(script_path, 'script.txt')

with open("config.yaml") as _:
    yaml_dict =  yaml.load(_)

template = ENV.get_template("template.text")

with open(script, 'w') as outfile:
    temp = template.render(config=yaml_dict)
    outfile.write(temp)


import pygame
from pygame.locals import *
from entities import User, Enemy
from fonctions import *
from stage import *
from hud import *

import random
import time
import zmq
import threading
from stage import *

from tkinter import *
from playsound import playsound

def choix1():
    global perso
    perso=1
    button1.configure(relief=SUNKEN)
    button2.configure(relief=RAISED)
    button3.configure(relief=RAISED)

def choix2():
    global perso
    perso=2
    button1.configure(relief=RAISED)
    button2.configure(relief=SUNKEN)
    button3.configure(relief=RAISED)

def choix3():
    global perso
    perso=3
    button1.configure(relief=RAISED)
    button2.configure(relief=RAISED)
    button3.configure(relief=SUNKEN)

perso=1
fen=Tk()
fen.geometry("250x300+200+0")
fen.configure(bg = "white")
user1=PhotoImage(file='images/user1.gif')
user2=PhotoImage(file='images/user2.gif')
user3=PhotoImage(file='images/user3.gif')
fen.title("LE JEU")
Label(fen,text="                ",bg="white").grid(row=1,column=0)
Label(fen,text="LE JEU \n\n ",bg="white").grid(row=0,column=2)
Button(fen,text="Jouer ",bg="white",command=fen.destroy).grid(row=1,column=2)
Label(fen,text="\n"*3,bg="white").grid(row=2,column=1)
button1=Button(fen, image=user1,bg="white",command=choix1, relief=SUNKEN)
button1.grid(row=3,column=1)
button2=Button(fen, image=user2,bg="white",command=choix2)
button2.grid(row=3,column=2)
button3=Button(fen, image=user3,bg="white",command=choix3)
button3.grid(row=3,column=3)
Label(fen,text="\n"*3,bg="white").grid(row=4,column=1)
Button(fen,text="Quitter",command=exit).grid(row=5,column=2)
jeu=0
playsound('musique_menu.mp3',block = False)

fen.mainloop()

gameOver = False
pygame.init()
screen = pygame.display.set_mode((620,480))
pygame.display.set_caption('User 1')
screen.fill((50,60,50))
pygame.display.update()

user = User(screen,1,perso)
coop = User(screen,2,3)
hud = HUD(screen)

context = zmq.Context()

usersChan = context.socket(zmq.PAIR)
usersChan.bind("tcp://127.0.0.1:1111".format(coop.id))

murs, enemies, potions, portes, eaus = classic(screen)

def recv(usersChan):
    global coop, gameOver, points
    while True:
        if gameOver == True:
            if points == 16:
                print("WIN !")
            else:
                print("Game Over ! Vous avez {} points".format(points))
            exit()
            return

        try:
            data = usersChan.recv_pyobj(flags=zmq.NOBLOCK)
            coop.pos = data["user"]["pos"]
            coop.vie = data["user"]["vie"]
            coop.attaque = data["user"]["attaque"]
            coop.defense = data["user"]["defense"]
            coop.level = data["user"]["level"]
            coop.xp= data["user"]["xp"]
            ### Supprimer objets qui ne sont pas en communs entre 2 listes python
            for potion in potions:
                ok = False
                for p in data["potions"]:
                    if potion.pos == p["pos"]:
                        ok = True
                if ok == False:
                    potions.remove(potion)

            for enemy in enemies:
                ok = False
                for e in data["enemies"]:
                    if enemy.pos == e["pos"]:
                        enemy.vie = e["vie"]
                        ok = True
                if ok == False:
                    enemies.remove(enemy)

            refresh()
        except zmq.ZMQError as err:
            pass

def refresh():

    screen.fill((50,60,50))
    hud.show(user,coop)
    user.show()
    coop.show()
    for enemy in enemies:
        enemy.show()
    for mur in murs:
        mur.show()
    for potion in potions:
        potion.show()
    for porte in portes:
        porte.show()
    for eau in eaus:
        eau.show()
    user.show()
    coop.show()
    pygame.display.flip()
    pygame.display.update()

# Envoyez première data
usersChan.send_pyobj(setData(user,coop,murs,potions,portes,eaus,enemies,True))
points = 0
# Création du Thread pour recevoir les données
threadRecv = threading.Thread(target=recv, args=(usersChan,))
threadRecv.start()

while not gameOver:
    changement = False
    if user.vie <= 0:
        gameOver = True

    if coop.vie <= 0:
        gameOver = True
    for event in pygame.event.get():

        # Alt + F4 ou fléche en haut
        if event.type == QUIT:
            gameOver = True

            # Si touche pressée
        if event.type == KEYDOWN:
            action = 1
            if event.key == K_UP:
                coord = (0,-1)
            elif event.key == K_DOWN:
                coord = (0,1)
            elif event.key == K_LEFT:
                coord = (-1,0)
            elif event.key == K_RIGHT:
                coord = (1,0)
            else:
                action = 0

            if action != 0:
                user.mouvement(coord)
                if user.pos == coop.pos:
                    user.mouvement((-coord[0],-coord[1]))

            for enemy in enemies:
                if enemy.pos == user.pos:
                    # Attaquer :
                    enemy.vie -= user.attaque + user.arme
                    user.vie -= enemy.defense

                    if user.vie <= 0:
                        user.vie = 0
                        gameOver == True

                    # print("Vie restante :", user.vie, "Vie enemmi :", enemy.vie)
                    if enemy.vie <= 0:
                        user.xp += enemy.level
                        enemies.remove(enemy)
                    # Revenir en arriére
                    else:
                        user.mouvement((-coord[0],-coord[1]))

            if user.xp >= user.level * 2:
                user.levelUP()

            for mur in murs:
                if mur.pos == user.pos :
                    if mur.genre == "lave":
                        user.vie -= 15
                    elif mur.genre == "pont":
                        pass
                    elif mur.genre == "levier":
                        pass
                    else:
                        user.mouvement((-coord[0],-coord[1]))

            for eau in eaus:
                if eau.pos == user.pos :
                    user.mouvement((-coord[0],-coord[1]))

            for potion in potions:
                if user.pos == potion.pos:
                    if potion.type == "heal":
                        user.heal()
                    elif potion.type == "atk":
                        user.atk()
                    elif potion.type == "atkboss":
                        for i in range (20):
                            user.atk()
                    elif potion.type == "xp":
                        user.levelUP()
                    potions.remove(potion)

            for porte in portes:
                if porte.pos == user.pos or porte.pos == coop.pos:
                    print("Changement de map")
                    points += 1
                    user.pos = [32,160]
                    coop.pos = [32,192]
                    if points == 1:
                        murs, enemies, potions, portes, eaus = deux(screen)
                    elif points == 2:
                        murs, enemies, potions, portes, eaus = troix(screen)
                    elif points == 15:
                        murs, enemies, potions, portes, eaus = six(screen)
                    elif points == 16:
                        gameOver = True
                    else:
                        murs, enemies, potions, portes, eaus = random.choice([quatre(screen), cinq(screen)])

                    changement = True

            ### Renvoyez les données
            try:
                message = setData(user,coop,murs,potions,portes,eaus,enemies,changement)
                usersChan.send_pyobj(message)

            except zmq.ZMQError as err:
                print ("Error while trying to send the value " + message + " : " + str(err))

            refresh()

        pygame.display.flip()
    pygame.display.update()
    pygame.time.wait(10)