import pygame, sys
from settings import *
from player import Player
from objects import Laser, Meteor
from animations import AnimatedStar, Explosion
from random import randint
from support import import_folder, importImgs
from overlay import Overlay
from group import AllSprites
from random import choice
from os import path

img_dir = path.join(path.dirname(__file__), 'img')

# # The main function
# def main():
#     introduction = intro()
#     board = initBoard()
#     pretty = printPretty(board)
#     symbol_1, symbol_2 = sym()
#     full = isFull(board, symbol_1, symbol_2) # The function that starts the game is also in here.

# # This function introduces the rules of the game Tic Tac Toe
# def intro():
#     print("Hello! Welcome to Pam's Tic Tac Toe game!")
#     print("\n")
#     print("Rules: Player 1 and player 2, represented by X and O, take turns "
#           "marking the spaces in a 3*3 grid. The player who succeeds in placing "
#           "three of their marks in a horizontal, vertical, or diagonal row wins.")
#     print("\n")
#     input("Press enter to continue.")
#     print("\n")

# def initBoard():
# # This function creates a blank playboard
#     print("Here is the playboard: ")
#     board = [[" ", " ", " "],
#              [" ", " ", " "],
#              [" ", " ", " "]]
#     return board

# def sym():
# # This function decides the players' symbols
#     symbol_1 = input("Player 1, do you want to be X or O? ")
#     if symbol_1 == "X":
#         symbol_2 = "O"
#         print("Player 2, you are O. ")
#     else:
#         symbol_2 = "X"
#         print("Player 2, you are X. ")
#     input("Press enter to continue.")
#     print("\n")
#     return (symbol_1, symbol_2)

# # This function starts the game.
# def startGamming(board, symbol_1, symbol_2, count):
#     # Decides the turn
#     if count % 2 == 0:
#         player = symbol_1
#     elif count % 2 == 1:
#         player = symbol_2
#     print("Player "+ player + ", it is your turn. ")
#     row = int(input("Pick a row:"
#                     "[upper row: enter 0, middle row: enter 1, bottom row: enter 2]:"))
#     column = int(input("Pick a column:"
#                        "[left column: enter 0, middle column: enter 1, right column enter 2]"))

#     # Check if players' selection is out of range, if so, repick.
#     while (row > 2 or row < 0) or (column > 2 or column < 0):
#         outOfBoard(row, column)
#         row = int(input("Pick a row[upper row:"
#                         "[enter 0, middle row: enter 1, bottom row: enter 2]:"))
#         column = int(input("Pick a column:"
#                            "[left column: enter 0, middle column: enter 1, right column enter 2]"))

#         # Check if the square is already filled
#     while (board[row][column] == symbol_1)or (board[row][column] == symbol_2):
#         filled = illegal(board, symbol_1, symbol_2, row, column)
#         row = int(input("Pick a row[upper row:"
#                         "[enter 0, middle row: enter 1, bottom row: enter 2]:"))
#         column = int(input("Pick a column:"
#                             "[left column: enter 0, middle column: enter 1, right column enter 2]"))

#     # Locates player's symbol on the board
#     if player == symbol_1:
#         board[row][column] = symbol_1

#     else:
#         board[row][column] = symbol_2

#     return (board)

# # This function check if the board is full
# def isFull(board, symbol_1, symbol_2):
#     count = 1
#     winner = True
#     while count < 10 and winner == True:
#         gaming = startGamming(board, symbol_1, symbol_2, count)
#         pretty = printPretty(board)

#         if count == 9:
#             print("The board is full. Game over.")
#             if winner == True:
#                 print("There is a tie. ")

#         # Check if here is a winner
#         winner = isWinner(board, symbol_1, symbol_2, count)
#         count += 1
#     if winner == False:
#         print("Game over.")

#     # This is function gives a report
#     report(count, winner, symbol_1, symbol_2)

# # This function tells the players that their selection is out of range
# def outOfBoard(row, column):
#     print("Out of boarder. Pick another one. ")

# # This function prints the board nice!
# def printPretty(board):
#     rows = len(board)
#     cols = len(board)
#     print("---+---+---")
#     for r in range(rows):
#         print(board[r][0], " |", board[r][1], "|", board[r][2])
#         print("---+---+---")
#     return board

# # This function checks if any winner is winning
# def isWinner(board, symbol_1, symbol_2, count):
#     winner = True
#     # Check the rows
#     for row in range (0, 3):
#         if (board[row][0] == board[row][1] == board[row][2] == symbol_1):
#             winner = False
#             print("Player " + symbol_1 + ", you won!")

#         elif (board[row][0] == board[row][1] == board[row][2] == symbol_2):
#             winner = False
#             print("Player " + symbol_2 + ", you won!")

#     # Check the columns
#     for col in range (0, 3):
#         if (board[0][col] == board[1][col] == board[2][col] == symbol_1):
#             winner = False
#             print("Player " + symbol_1 + ", you won!")
#         elif (board[0][col] == board[1][col] == board[2][col] == symbol_2):
#             winner = False
#             print("Player " + symbol_2 + ", you won!")

#     # Check the diagnoals
#     if board[0][0] == board[1][1] == board[2][2] == symbol_1:
#         winner = False
#         print("Player " + symbol_1 + ", you won!")

#     elif board[0][0] == board[1][1] == board[2][2] == symbol_2:
#         winner = False
#         print("Player " + symbol_2 + ", you won!")

#     elif board[0][2] == board[1][1] == board[2][0] == symbol_1:
#         winner = False
#         print("Player " + symbol_1 + ", you won!")

#     elif board[0][2] == board[1][1] == board[2][0] == symbol_2:
#         winner = False
#         print("Player " + symbol_2 + ", you won!")
#     return winner

# def illegal(board, symbol_1, symbol_2, row, column):
#     print("The square you picked is already filled. Pick another one.")

# def report(count, winner, symbol_1, symbol_2):
#     print("\n")
#     input("Press enter to see the game summary. ")
#     if (winner == False) and (count % 2 == 1 ):
#         print("Winner : Player " + symbol_1 + ".")
#     elif (winner == False) and (count % 2 == 0 ):
#         print("Winner : Player " + symbol_2 + ".")
#     else:
#         print("There is a tie. ")

# # Call Main
# if __name__ == "__main__":
#     main()

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

class Game:
    def __init__(self):
        pygame.init()
        self.display_surface = pygame.display.set_mode(SCREEN_SIZE)
        pygame.display.set_caption('Ultimate tactoe')
        self.clock = pygame.time.Clock()

        self.all_sprites = AllSprites()
        self.lasers = pygame.sprite.Group()
        self.meteors = pygame.sprite.Group()

        # imports
        self.star_frames = import_folder('../img/star')
        self.explosion = import_folder('../img/explosion')
        self.meteor_surfaces = import_folder('../img/meteors')
        self.spareImgs = importImgs(img_dir)
        print(self.spareImgs)
        # self.playerimage = pygame.image.load(os.path.join(imgPath, '/img/player.png')).convert_alpha()
        # self.playerimage = pygame.image.load('../img/player.png').convert_alpha()
        # self.broken_surf = pygame.image.load('../img/broken.png').convert_alpha()
        self.broken_rect = self.broken_surf.get_rect(center = (SCREEN_SIZE[0]/2, SCREEN_SIZE[1]/2 - 100))

        self.player = Player(self.all_sprites, (SCREEN_SIZE[0] / 2, SCREEN_SIZE[1] - 100), self.create_laser, self.playerimage)

        # timer
        self.meteor_timer = pygame.USEREVENT + 1
        pygame.time.set_timer(self.meteor_timer, 150)

        # bg stars
        for i in range(randint(50,70)):
            AnimatedStar(self.all_sprites, self.star_frames)

        # overlay
        self.overlay = Overlay()

        # score
        self.score = 0
        self.lifes = 3
        self.start_time = 0
        self.game_over = False

        # font
        self.font = pygame.font.Font(None, 40)

        # restart button
        self.restart_surf = self.font.render('Restart', True, TEXT_COLOR)
        self.restart_rect = self.restart_surf.get_rect(center = (SCREEN_SIZE[0] / 2, SCREEN_SIZE[1] - 100))
        self.restart_surf_dark = self.font.render('Restart', True, BG_COLOR)

        # music
        self.game_music = pygame.mixer.Sound('../audio/game_music.wav')
        self.title_music = pygame.mixer.Sound('../audio/title_music.wav')
        self.laser_sound = pygame.mixer.Sound('../audio/laser.wav')
        self.explosion_sound = pygame.mixer.Sound('../audio/explosion.wav')
        self.damage_sound = pygame.mixer.Sound('../audio/damage.ogg')

    def create_laser(self, pos, direction):

        Laser((self.all_sprites, self.lasers), pos, direction)
        self.laser_sound.play()

    def collisions(self):

        # laser -> meteor
        for laser in self.lasers:
            if pygame.sprite.spritecollide(laser, self.meteors, True, pygame.sprite.collide_mask):
                Explosion(self.all_sprites, self.explosion, laser.rect.midtop)
                laser.kill()
                self.explosion_sound.play()

        # meteor -> player
        if pygame.sprite.spritecollide(self.player, self.meteors, True, pygame.sprite.collide_mask):
            self.lifes -= 1
            self.damage_sound.play()

        if self.lifes <= 0:
            self.score = pygame.time.get_ticks() - self.start_time
            self.game_over = True
            for meteor in self.meteors:
                meteor.kill()
            self.player.rect.center = (SCREEN_SIZE[0] / 2, SCREEN_SIZE[1] - 100)

            self.game_music.stop()
            self.title_music.play()

    def run(self):
        while True:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                if event.type == self.meteor_timer and not self.game_over:
                    Meteor((self.all_sprites, self.meteors), choice(self.meteor_surfaces))

            self.display_surface.fill(BG_COLOR)

            if self.game_over:

                self.display_surface.blit(self.broken_surf,self.broken_rect)
            # text
            text_surf = self.font.render(f'Your score: {self.score}', True, TEXT_COLOR)
            text_rect = text_surf.get_rect(center = (SCREEN_SIZE[0] / 2, SCREEN_SIZE[1] / 2 + 50))
            self.display_surface.blit(text_surf, text_rect)

            # button
            if self.restart_rect.collidepoint(pygame.mouse.get_pos()):
                pygame.draw.rect(self.display_surface, TEXT_COLOR, self.restart_rect.inflate(30,30),0,3)
                self.display_surface.blit(self.restart_surf_dark, self.restart_rect)

                if pygame.mouse.get_pressed()[0]:
                    self.game_over = False
                    self.lifes = 3
                    self.start_time = pygame.time.get_ticks()

                    self.title_music.stop()
                    self.game_music.play()
                else:
                    self.display_surface.blit(self.restart_surf, self.restart_rect)

                pygame.draw.rect(self.display_surface, TEXT_COLOR, self.restart_rect.inflate(30,30), 5,3)
            else:
                dt = self.clock.tick() / 1000

                self.score = pygame.time.get_ticks() - self.start_time
                self.overlay.display_score(self.score)

                self.all_sprites.update(dt)
                self.all_sprites.custom_draw()

                self.collisions()

                self.overlay.display_lifes(self.lifes)

                pygame.display.update()

game = Game()
game.run()


import sys
def progressify(
    seq,
    message = "",
    offset: int = 0,
    length: int = 0,
):
    """
    Display a progress bar in the terminal while iterating over a sequence.

    This function can be used whereever we iterate over a sequence (i.e.
    something iterable with a length) and we want to display progress being
    made to the user. It works by passing on the values from the sequence (by
    yielding them), which printing an updated progress bar to the terminal. The
    progress is estimated based on how far we are through the sequence (based
    on our iteration step and its length). The progress bar is as long as its
    length, unless that is larger than the maximum length to avoid overflowing
    on small terminal sizes or large input. The maximum length is set to 30, to
    leave some space for a message, that can be printed along with the progress
    bar itself (even on old standard 80-column terminals).

    Printing the progress bar works through the use of block-drawing characters
    and carriage returns (ASCII code 0x0d). In order to avoid the cursor hiding
    part of the progress bar, we use terminal escape codes to temporarily hide
    it during the runtime of this generator.

    Args:
        seq: The sequence of elements to iterate over (often a list).
        message: An optional message that can be printed along with the bar. If
            it is a string, it will be printed, with special sequences starting
            with a percent sign replaced by various values:
                %i    Index (starting from 0)
                %e    Current element
            If it is a callable, it will be called with (index, current_element)
            as arguments, and its return value will be printed.
        offset: An optional offset that can be used to add a value to the index
            counter. Usually used in combination with length to "join" progress
            bars in nested loops.
        length: Override the calculation of maximum length. This can be used
            together with offset as described below, or to allow progressifying
            iterables that aren't sequences.

    Yields:
        The elements from seq.

    Example:
        for element in progressify([0.01, 0.1, 0.25, 0.5, 0.9, 0.99]):
            do_something_with(element)  # progress bar is updated at each step

        for x in range(2):
            def message(index, element):
                return f"step {x*3 + i + 1}/6"
            for y in progressify(range(3), message):
                pass # e.g. "[▓▓░] step 5/6" when x==1 and y==2

        for x in range(2):
            for y in progressify(range(3), offset=x*3, length=6):
                pass # e.g. "[▓▓▓▓▓░]" when x==1 and y==2
    """
    longest = 0
    if isinstance(message, str):
        format_str = message

        def message(i: int, element) -> str:
            # map special sequences to special values
            replacements = {
                "%i": i,
                "%e": element,
            }
            # copies so we evaluate this at every step
            s = format_str
            for key in replacements:
                s = s.replace(key, str(replacements[key]))
            return s
    assert not isinstance(message, str)
    try:
        print("\033[?25l", end="", flush=True)  # hide the cursor
        length = length or len(seq)  # allow overriding maximum length
        maxlen = 30
        for i, element in enumerate(seq):
            i += offset
            msg = message(i, element)
            if len(msg) > longest:
                longest = len(msg)
            # we copy the index (i) in order for %i to refer to the real,
            # rather than the scaled index
            if length > maxlen:
                i_chars = int(i * maxlen/length)
            else:
                i_chars = i
            print(
                "\r[{}{}] {}".format(
                    "▓"*(i_chars+1),
                    "░"*((length if length <= maxlen else maxlen)-i_chars-1),
                    msg.ljust(longest),  # make sure we override previous values
                ),
                file=sys.stderr,
                flush=True,  # to see the updated bar immediately
                end=""
            )
            yield element
    except Exception as e:
        print(e)
    finally:
        print("\033[?25h", end="", flush=True)  # show the cursor again
        if i + 1 == length:
            print()


#!/usr/bin/env python3

"""
A description file for invoke (https://www.pyinvoke.org/)
"""

import inspect

# temp local fix for https://github.com/pyinvoke/invoke/issues/891
if not hasattr(inspect, "getargspec"):
    inspect.getargspec = inspect.getfullargspec

from invoke import task

@task
def download_libzim(c, version=""):
    """download C++ libzim binary"""
    env = f"LIBZIM_DL_VERSION={version}" if version else ""
    c.run(f"{env} python setup.py download_libzim")

@task
def build_ext(c):
    """build extension to use locally (devel, tests)"""
    c.run("PROFILE=1 python setup.py build_ext -i")

@task
def test(c):
    """run test suite"""
    c.run("python -m pytest --color=yes --ff -x .")

@task
def coverage(c):
    """generate coverage report"""
    c.run(
        "python -m pytest --color=yes "
        "--cov=libzim --cov-config=.coveragerc "
        "--cov-report=term --cov-report term-missing ."
    )

@task
def clean(c):
    """remove build folder and generated files"""
    c.run("rm -rf build")
    c.run("rm -f *.so")
    c.run("rm -rf include")
    c.run("rm -rf libzim/libzim.{so,dylib} libzim/libzim.so.* libzim/libzim.*.dylib")

@task
def install_dev(c):
    """install dev requirements"""
    c.run("pip install -r requirements-dev.txt")

@task
def check(c):
    """run Q/A checks"""
    c.run("isort --check-only .")
    c.run("black --check .")
    c.run('echo "one pass for show-stopper syntax errors or undefined names"')
    c.run("flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics")
    c.run('echo "one pass for small stylistic things"')
    c.run("flake8 . --count --statistics")

@task
def lint(c):
    """Apply Q/A linting"""
    c.run("isort .")
    c.run("black .")
    c.run("flake8 .")

if __name__ == "__main__":
    print(
        "This file is not intended to be directly run.\n"
        "Install invoke and run the `invoke` command line."
    )


# -*- coding: utf-8 -*-
""" run """

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

import sys
from argparse import ArgumentParser

from cytomine import CytomineJob

def main():
    """
    Executes some code as a Cytomine Job

    Usage:
        # Execute run.py through your local python
        python run.py --cytomine_host 'localhost-core' --cytomine_public_key '9af03585-c162-464e-bbf9-9196ff084487' --cytomine_private_key 'fb14e576-c534-410d-8206-5e70b0d97d96' --cytomine_id_project 237 --cytomine_id_image_instance 1220 --cytomine_id_software 4882

        # Execute your image on your computer.
        # remember to first build your image: docker build -t cyto_soft-1 .
        docker run --gpus all -it --rm --network=host cyto_soft-1 --cytomine_host 'localhost-core' --cytomine_public_key '9af03585-c162-464e-bbf9-9196ff084487' --cytomine_private_key 'fb14e576-c534-410d-8206-5e70b0d97d96' --cytomine_id_project 237 --cytomine_id_image_instance 1220 --cytomine_id_software 4882

        # Execute your image on your computer sharing your project directory with your docker image
        # so all the changes, during development, can be tested without re-building the the image
        # remember to first build your image: docker build -t cyto_soft-1 .
        docker run --gpus all -it --rm --mount type=bind,source=/home/giussepi/Public/environments/cyto_soft-1/,target=/myapp,bind-propagation=private --network=host cyto_soft-1 --cytomine_host 'localhost-core' --cytomine_public_key '9af03585-c162-464e-bbf9-9196ff084487' --cytomine_private_key 'fb14e576-c534-410d-8206-5e70b0d97d96' --cytomine_id_project 237 --cytomine_id_image_instance 1220 --cytomine_id_software 4882
    """

    parser = ArgumentParser(prog="Cytomine Python client example")

    # Cytomine connection parameters
    parser.add_argument('--cytomine_host', dest='host',
                        default='demo.cytomine.be', help="The Cytomine host")
    parser.add_argument('--cytomine_public_key', dest='public_key',
                        help="The Cytomine public key")
    parser.add_argument('--cytomine_private_key', dest='private_key',
                        help="The Cytomine private key")
    parser.add_argument('--cytomine_id_project', dest='id_project',
                        help="The project from which we want the images")
    parser.add_argument('--cytomine_id_software', dest='id_software',
                        help="The software to be used to process the image")
    parser.add_argument('--cytomine_id_image_instance', dest='id_image_instance',
                        help="The image to which the annotations will be added")

    params, _ = parser.parse_known_args(sys.argv[1:])

    with CytomineJob.from_cli(sys.argv[1:]) as cytomine:
        # Place your processing operations here
        print("Parameters received:")
        print('host: {}'.format(params.host))
        print('public_key: {}'.format(params.public_key))
        print('private_key: {}'.format(params.private_key))
        print('id_project: {}'.format(params.id_project))
        print('id_software: {}'.format(params.id_software))
        print('id_image_instance: {}'.format(params.id_image_instance))
        cytomine.job.update(statusComment="Finished.")

if __name__ == "__main__":
    main()


'''
Sort + Greedy
57672 KB	488 ms
'''

import sys
input = sys.stdin.readline

n = int(input())
ls = sorted([list(map(int, input().split())) for _ in range(n)], key = lambda x : (x[1], x[0]))

# print(ls)
prev = 0
ans = [ls[0]]

for i in range(1, n):
  if ls[i][0] >= ans[-1][1]:
    ans.append(ls[i])

# print(ans)
print(len(ans))


# Definition for a binary tree node.
from typing import List

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution:
    def generateTrees(self, n: int) -> List[TreeNode]:
        if n < 1:
            return []
        return self.getTrees(1, n)

    def getTrees(self, start: int, end: int):
        result = []
        if start > end:
            result.append(None)
            return result
        if start == end:
            result.append(TreeNode(start))
            return result
        i = start
        while i <= end:
            left = self.getTrees(start, i - 1)
            right = self.getTrees(i + 1, end)
            for leftNode in left:
                for rightNode in right:
                    root = TreeNode(i)
                    root.left = leftNode
                    root.right = rightNode
                    result.append(root)
            i += 1
        return result

    def preorder(self, node: TreeNode):
        if node:
            print(node.val)
        if node.left:
            self.preorder(node.left)
        if node.right:
            self.preorder(node.right)

if __name__ == "__main__":
    solution = Solution()
    result = solution.generateTrees(3)
    print(len(result))
    print()
    for node in result:
        solution.preorder(node)
        print()


from selenium import webdriver
import time

PATH = "/home/sanjju/Downloads/chromedriver_linux64/chromedriver"
driver = webdriver.Chrome(PATH)

def startpy():

    URL = "https://wizardingworldz.com/harry-potter-creatures-list/"

    driver.get(URL)
    driver.maximize_window()
    time.sleep(2)

    for i in range(1, 21):
        magical_creatures = driver.find_element_by_xpath(f'//*[@id="tps_slideContainer_500"]/div/h2[{i}]')
        print(magical_creatures.text)

startpy()


# !/usr/bin/env python
# -*- coding: utf-8 -*-
"""
MathGenerator class of the MathEngine module.
"""

__authors__ = ["Luana Juhl", "Lukas Schult"]
__contact__ = "it16156@lehre.dhbw-stuttgart.de"
__credits__ = ["Luana Juhl", "Lukas Schult"]
__date__ = "2021/04/27"
__deprecated__ = False
__email__ = "it16156@lehre.dhbw-stuttgart.de"
__maintainer__ = "developer"
__status__ = "Released"
__version__ = "1.0"

import numpy as np
import operator
import json

class MathGenerator:
    """
    A Generator of mathematical terms and their textual representaion.
    Also provides a difficulty selection to produce various terms with a selection of answers to the term.
    """

    def __init__(self):
        self.rng = np.random.default_rng()

        self.lvl_generator_functions = {0: self.generate_add_sub_lvl,
                                        1: self.generate_add_sub_mult_lvl,
                                        2: self.generate_random_add_sub_lvl,
                                        3: self.generate_random_mult_div_lvl}
        self.range_modifiers = {0: 20,
                                1: 50,
                                2: 100}

    ops = {
        "+": operator.add,
        "-": operator.sub,
        "*": operator.mul,
        "/": operator.truediv
    }
    operations = ["+", "-", "×", "÷"]

    def get_term(self, difficulty):
        """
        Generates a term for a given difficulty level.
        :param difficulty: int Term level
        :return: serialized data of a term in a dictionary
        """
        if difficulty == 0:
            return self.generate_add_sub_lvl(possible_numbers=np.arange(start=0, stop=21, step=1), only_add=True)
        else:
            generator_selection, start, stop = self.determine_level_range(difficulty)
            if generator_selection == 1:  # add_sub_mul needs 2 ranges given in start and stop lists
                return self.lvl_generator_functions[generator_selection](
                    np.arange(start=start[0], stop=stop[0], step=1),
                    np.arange(start=start[1], stop=stop[1], step=1))
            else:
                return self.lvl_generator_functions[generator_selection](
                    np.arange(start=start[0], stop=stop[0], step=1))

    def determine_level_range(self, difficulty):
        """
        Determines which function to use to generate a term and with which number range it should be generated.
        :param difficulty: int Term level
        :return: generator_selection: level generating function, start + stop: lists for start and stop for np.arrange
        """
        modifier_selection = difficulty % 3
        generator_selection = int(difficulty / 3) % 4

        start = [0 - self.range_modifiers[modifier_selection]]
        stop = [self.range_modifiers[modifier_selection]]

        if generator_selection == 1:
            start.append(max(int(start / 5), 10) if start[0] > 0 else min(int(start[0] / 5), -10))
            stop.append(max(int(stop[0] / 5), 10) + 1)
        return generator_selection, start, stop

    def build_term_string(self, term_steps, operator_symbols):
        """
        Builds a String for a term with the given steps.
        :param term_steps: Steps to be inserted.
        :param operator_symbol: operator symbol to be inserted.
        :return: Term String.
        """
        term_string = f"{term_steps[0]}"
        for i, value in enumerate(term_steps[1:]):
            if type(operator_symbols) == list:
                operation = operator_symbols[i]
            else:
                operation = operator_symbols
            if value < 0 and operation == "-":  # auto convert  - - to +
                operation = "+"
                value = -value
            elif value < 0:  # and operation in ["+", "*", "/"]:  # use parentheses for negative values in mult and div
                value = f"({value})"
            term_string += f" {operation} {value}"
        return term_string + " = ?"

    def generate_add_sub_lvl(self, possible_numbers, only_add=False):
        """
        Generates a addition or subtraction term response.
        :param only_add: removes the random choice for the operator
        :param possible_numbers: All numbers that can occur.
        :return: dictionary of term string, answer options and solution_index
        """
        number_count = 2
        if only_add:
            operator_symbol = "+"
        else:
            operator_symbol = self.rng.choice(["+", "-"])
        term = self.generate_add_or_sub(number_count, possible_numbers, operator_symbol)
        answers, solution_index = self.generate_answers(term[operator_symbol][0], possible_numbers)
        return self.create_response_dict(self.build_term_string(term[operator_symbol][1], operator_symbol),
                                         answers,
                                         solution_index
                                         )

    def generate_add_sub_mult_lvl(self, possible_numbers_add_sub, possible_numbers_mult):
        """
            Generates a addition, subtraction or multiplication term response.
            :param possible_numbers_add_sub: All numbers that can occur for addition and subtraction terms.
            :param possible_numbers_mult: All numbers that can occur for multiplication terms.
            :return: dictionary of term string, answer options and solution_index
        """
        operator_symbol = self.rng.choice(["+", "-", "*"])
        if operator_symbol in ["+", "-"]:
            number_count = self.rng.choice([2, 3])
            term = self.generate_add_or_sub(number_count, possible_numbers_add_sub, operator_symbol)
            answers, solution_index = self.generate_answers(term[operator_symbol][0], possible_numbers_add_sub)

        else:
            term = self.generate_multiplication_value_pair(possible_numbers_mult)
            answers, solution_index = self.generate_answers(term[operator_symbol][0], possible_numbers_mult)
        return self.create_response_dict(self.build_term_string(term[operator_symbol][1], operator_symbol),
                                         answers,
                                         solution_index
                                         )

    def generate_random_add_sub_lvl(self, possible_numbers):
        """
            Generates a mixed term response (combination between addition and subtraction of up to 4 numbers)
            :param possible_numbers: All numbers that can occur.
            :return: dictionary of term string, answer options and solution_index
        """

        term = self.generate_mixed_add_sub(self.rng.choice([3, 4]), possible_numbers)
        answers, solution_index = self.generate_answers(term[0], possible_numbers)
        return self.create_response_dict(self.build_term_string(term[1], operator_symbols=term[2]),
                                         answers,
                                         solution_index
                                         )

    def generate_random_mult_div_lvl(self, possible_numbers):
        """
            Generates a multiplication or division term response.
            :param possible_numbers: All numbers that can occur.
            :return: dictionary of term string, answer options and solution_index
        """
        term_type = self.rng.choice(["*", "/"])
        if term_type == "*":
            term = self.generate_multiplication_value_pair(possible_numbers)
        else:
            term = self.generate_division_value_pair(possible_numbers)
        answers, solution_index = self.generate_answers(term[term_type][0], possible_numbers)
        return self.create_response_dict(self.build_term_string(term[term_type][1], operator_symbols=term_type),
                                         answers,
                                         solution_index
                                         )

    def create_response_dict(self, term_string, answers, solution_index):
        """
            Generates a multiplication or division term response.
            :param term_string: string version of the term (for display)
            :param answers: a json compatible list of possible answers
            :param solution_index: the list index for the correct solution
            :return: dictionary of term string, answer options and solution_index
        """
        return {
            "term": term_string,
            "answers": json.dumps(answers.tolist()),
            "solution_index": solution_index
        }

    def generate_add_or_sub(self, step_count, num_range, operator_symbol, start=0):
        """
        Generates a term for addition or subtraction with a variable number of values that lead to the result.
        :param step_count: Number of values that will lead to the term result.
        :param num_range: The number range for which the term will be generated in.
        :param operator_symbol: + or - operator symbol
        :param start: defines the first value of the term if not 0
        :return: dict with { operation_symbol: [result, array of steps]}
        """
        operation_func = self.ops[operator_symbol]
        steps = np.zeros(step_count, dtype=int)
        steps[0] = start
        while steps[0] == 0:
            choice = self.rng.choice(num_range)
            if operation_func(choice, step_count) in num_range:
                steps[0] = choice

        def get_result():
            step_sum = steps[0]
            for step in steps[1:]:
                step_sum = operation_func(step_sum, step)
            return step_sum

        for i in range(step_count - 1):
            while steps[i + 1] == 0:
                choice = self.rng.choice(num_range)
                if operation_func(operation_func(get_result(), choice), (step_count - (i + 2))) in num_range:
                    steps[i + 1] = choice

        return {operator_symbol: [get_result(), steps]}

    def is_prime(self, n):
        """
        Checks if given number is prime.
        :param n: number to check
        :return: True if prime else False
        """
        for i in range(2, n):
            if n % i == 0:
                return False
        return True

    def generate_multiplication_value_pair(self, num_range):
        """
        Generates a multiplication term with 2 values.
        :param num_range: The number range for which the term will be generated in.
        :return: dict with { operation_symbol: [result, array of steps]}
        """
        retry = True

        while retry:
            result = 0
            negative = False

            while result == 0:
                retry = False
                result = self.rng.choice(num_range)
                # check if result is prime and retry with a 90% chance

                if self.is_prime(abs(result)) and self.rng.choice([True, False], p=[0.9, 0.1]):
                    retry = True

            if result < 0:
                negative = True
                result = -result
            steps = np.zeros(2, dtype=int)

            divisors = []
            i = 1
            while i <= result:  # look for all divisors without residue
                if result % i == 0:
                    divisors.append(i)  # fill divisors list
                i += 1
            steps[0] = self.rng.choice(divisors)  # choose divisor at random for first operand
            steps[1] = result / steps[0]  # calculate the second operand
            if negative:
                negate_idx = self.rng.choice([0, 1])
                steps[negate_idx] = -steps[negate_idx]
                result = -result

            for step in steps:  # avoid terms with multiplication by 1 with 90% probability
                if step == 1 and self.rng.choice([True, False], p=[0.9, 0.1]):
                    retry = True
        return {"*": [result, steps]}

    def generate_division_value_pair(self, num_range):
        """
        Generates a division term with one numerator and one divisor.
        :param num_range: The number range for which the term will be generated in.
        :return: dict with { operation_symbol: [result, array of steps]}
        """
        numerator = 0
        divisor = 0
        while numerator == 0:  # ensures numerator will not be 0
            numerator = self.rng.choice(num_range)
            divisor = self.rng.choice(num_range)
            if divisor == 0:  # ensures not to divide by 0
                numerator = 0
            elif not (numerator / divisor).is_integer():  # only allow for integer values as result
                numerator = 0

        return {"/": [int(numerator / divisor), np.array([numerator, divisor])]}

    def generate_random_add_or_sub_pair(self, num_range):
        """
        Generates a random term with 2 steps and either + or - operation.
        :param num_range: The number range for which the term will be generated in.
        :return: dict with { operation_symbol: [result, array of steps]}
        """
        operation = self.rng.choice(["+", "-"])
        return self.generate_add_or_sub(2, num_range, operation)

    def generate_mixed_add_sub(self, step_count, num_range):
        """
        Generates a term with mixed operations. This includes at least one + and - .
        :param step_count: The number of steps for the requested term.
        :param num_range: The number range for which the term will be generated in.
        :return: Result of the term, steps of the term, operations between steps.
        """
        retry = True
        if step_count == 2:
            return self.generate_random_add_or_sub_pair(num_range)
        while retry:
            steps = np.zeros(step_count, dtype=dict)
            term = self.generate_random_add_or_sub_pair(num_range)  # generate the first term
            operations = list(term.keys())  # list to keep track of the operations between steps
            steps[0] = term[operations[0]][1][0]  # setting saving first and second step
            steps[1] = term[operations[0]][1][1]
            step = 2
            while 0 in steps:  # continues to add values from new terms to the steps
                term = self.generate_random_add_or_sub_pair(num_range)
                operations += list(term.keys())
                # checks if the first value of the term uses the last value of the steps
                if term[operations[step - 1]][1][0] == steps[step - 1]:
                    steps[step] = term[operations[step - 1]][1][1]  # adds the next value since the fist is in steps
                    step += 1
                else:
                    operations.pop()  # remove the operation from the list if the term does not fit the followup value
                if "-" in operations and "+" in operations:  # ensures that the term is mixed
                    retry = False
            result = steps[0]  # setting the initial value for the result calculation
            for i, operation in enumerate(operations, start=1):
                operation_func = self.ops[operation]
                result = operation_func(result, steps[i])  # dynamically use operations to calculate the result
            if not (result in num_range):  # ensures that the result is inside the given number range
                retry = True

        return result, steps, operations

    def generate_answers(self, solution, num_range):
        """
        Generates wrong answers for answer options.
        :param solution: the correct term result
        :param num_range: the boundaries for generated answers
        :return: tuple of answer list and correct answer index
        """
        answers = np.zeros(4)
        indexes = list(range(4))
        np.random.shuffle(indexes)
        answers[indexes[0]] = solution
        for i in [1, 2]:
            answer = solution + self.rng.choice(range(-5, 5))
            while answer == solution or answer not in num_range:
                answer = solution + self.rng.choice(range(-5, 5))
            answers[indexes[i]] = int(answer)
        answer = self.rng.choice(num_range)
        while answer == solution or answer not in num_range:
            answer = self.rng.choice(num_range)
        answers[indexes[3]] = int(answer)
        return answers, indexes[0]


import sys, os, io, atexit
input = lambda : sys.stdin.readline().rstrip('\r\n')
stdout = io.BytesIO()
sys.stdout.write = lambda s : stdout.write(s.encode("ascii"))
atexit.register(lambda : os.write(1, stdout.getvalue()))

T = int(input())

for _ in range(T):
    N = int(input())
    arr = list(map(int, input().split()))
    arr.sort()
    new = [0] * N
    i,j = 0,N-1
    for index in range(N):
        if index % 2 == 0:
            new[i] = arr[index]
            i += 1
        else:
            new[j] = arr[index]
            j -= 1

    #print(new)
    ans = -int(1e9)
    for i in range(1,N):
        ans = max(ans, abs(new[i-1]-new[i]) )
    ans = max(ans, abs(new[-1]-new[0]) )
    print(ans)

#원리는 같지만 물리적으로 배열에 삽입하지 않고 풀이 ...
# T = int(input())
# for _ in range(T):
#     N = int(input())
#     S = list(map(int,input().split()))
#     S.sort()
#     maxv=0
#     for i in range(N-2):
#         maxv = max(maxv,abs(S[i]-S[i+2]))
#     print(maxv)


from pyspark.sql import SparkSession

spark = SparkSession \
    .builder \
    .appName("Python Spark SQL basic example") \
    .config("spark.some.config.option", "some-value") \
    .getOrCreate()

#business
business = spark.read.json("yelp_academic_dataset_business.json")
business1=business.select((business['name'].alias('b_name')), (business['business_id'].alias('b_id')) ,(business['review_count'].alias('b_review_count')),business['attributes'],business['categories'],(business['stars'].alias('business_stars')))
business1.createOrReplaceTempView("business1")

#users
users = spark.read.json("yelp_academic_dataset_user.json")
users1=users.select((users['user_id'].alias('userid')), (users['average_stars'].alias('user_avg_stars')),users['name'],(users['review_count'].alias('user_review_count')),users['useful'],users['yelping_since'],users['funny'],users['cool'])
users1.createOrReplaceTempView("users1")

#reviews
reviews = spark.read.json("yelp_academic_dataset_review.json")
reviews1=reviews.select(reviews['user_id'], reviews['review_id'],reviews['business_id'],(reviews['stars'].alias('review_stars')),reviews['text'])
r1=reviews1.filter(reviews['stars'] == 1).limit(20000)
r2=reviews1.filter(reviews['stars'] == 2).limit(20000)
r3=reviews1.filter(reviews['stars'] == 3).limit(20000)
r4=reviews1.filter(reviews['stars'] == 4).limit(20000)
r5=reviews1.filter(reviews['stars'] == 5).limit(20000)
review=r1.union(r2)
review=review.union(r3)
review=review.union(r4)
review=review.union(r5)
review.createOrReplaceTempView("review")

#join
sqlDF = spark.sql("SELECT * from business1,review where business1.b_id==review.business_id ")
sqlDF.createOrReplaceTempView("sqlDF")
sql1= spark.sql("SELECT sqlDF.review_id, sqlDF.business_stars, sqlDF.user_id, users1.user_review_count, users1.yelping_since, users1.user_avg_stars, sqlDF.business_id, sqlDF.review_stars, sqlDF.text, users1.useful, users1.funny, users1.cool FROM sqlDF,users1 where users1.userid==sqlDF.user_id  ")

sql1.toPandas().to_csv("Ml-Proj-Data.csv", header=True)

Yelp Dataset Challenge/1.feature extraction-combination/Ml-data.py


from neurodynex3.leaky_integrate_and_fire import LIF
from neurodynex3.tools import input_factory
import brian2 as b2

def test_simulate_LIF_neuron():
    """Test LIF model: simulate_LIF_neuron(short pulse, 1ms, default values)"""
    c = input_factory.get_step_current(0, 9, 0.1 * b2.ms, .02 * b2.uA)
    m, spike_monitor = LIF.simulate_LIF_neuron(c, simulation_time=1.1 * b2.ms)
    nr_spikes = spike_monitor.count[0]
    # print("nr_spikes:{}".format(nr_spikes))
    assert nr_spikes > 0, \
        "simulation error: Pulse current did not trigger a spike. " \
        "Check if the LIF default values did change."


from dash import Dash, html

from src.data.bid_data import BidDataFactory
from src.data.item_data import ItemData

from . import (
    accordion,
    bid_analytics,
    classes,
    ids,
    item_search,
    item_table,
    navbar,
    selected_item,
    spec_year_selector,
)

def create_layout(
    app: Dash, item_data: ItemData, bid_data_factory: BidDataFactory
) -> html.Div:
    return html.Div(
        className=classes.APP_DIV,
        children=[
            navbar.render(),
            html.Div(id=ids.ACCORDION_CONTAINER, children=accordion.render(app)),
            html.Div(
                id=ids.SPEC_YEAR_SELECTOR_CONTAINER,
                children=spec_year_selector.render(),
            ),
            html.Div(id=ids.ITEM_SEARCH_CONTAINER, children=item_search.render()),
            html.Div(
                id=ids.ITEM_DATA_TABLE_CONTAINER,
                children=item_table.render(app, item_data),
            ),
            html.Div(
                id=ids.SELECTED_ITEM_CONTAINER,
                children=selected_item.render(app, item_data),
            ),
            html.Div(
                id=ids.BID_ANALYTICS_CONTAINER,
                children=bid_analytics.render(app, bid_data_factory),
            ),
        ],
    )


T = [list(input()) for _ in range(3)]

def find_M(T):
    for i in range(3):
        for j in T[i]:
            if j == 'M':
                return 'M이 존재합니다'

    else:
        return 'M이 존재하지 않습니다'

print(find_M(T))

# 함수로 쓰니까 바로 풀리네.. 함수 없이 하면,
# 계속 답 중복 출력.. break어디다 써야 되나.. 이러고 있었을 듯


import operator

def build_tree(expression):
    OPERATORS = {
    '+': operator.add,
    '-': operator.sub,
    '*': operator.mul,
    '/': operator.truediv
    }

    LEFT_PAREN = '('
    RIGHT_PAREN = ')'

    tree = {}
    stack = [tree]
    current_node = tree

    for token in expression:
        if token == LEFT_PAREN:
            new_node = {}
            current_node['left'] = new_node
            stack.append(new_node)
            current_node = stack[-1]
        elif token == RIGHT_PAREN:
            current_node = stack.pop()
        elif token in OPERATORS:
            current_node['val'] = token
            new_node = {}
            current_node['right'] = new_node
            stack.append(new_node)
            current_node = stack[-1]
        elif isinstance(int(token), int):
            current_node['val'] = token
            stack.pop()
            current_node = stack[-1]

    return tree

def evaluate(tree):

    OPERATORS = {
    '+': operator.add,
    '-': operator.sub,
    '*': operator.mul,
    '/': operator.truediv
    }

    item = tree['val']
    if isinstance(item, int):
        return item
    else:
        operation = OPERATORS[item]
        return operation(evaluate(tree['left']), evaluate(tree['right']))

if __name__ == "__main__":
    expression = ['(', 3, '+', '(', 4, '*', 5 ,')',')']
    #expression = ['(', 2, '+', 2, ')']
    tree = build_tree(expression)
    print(tree)
    result = evaluate(tree)
    print(result)


import scrapy

class ComputersSpider(scrapy.Spider):
    name = "computers"
    start_urls = [
        'https://ikman.lk/en/ads/colombo/computers-tablets?categoryType=ads&categoryName=Computers+%26+Tablets&type'
        '=for_sale',
    ]

    def parse(self, response):
        # follow links to computers pages
        for href in response.css('div.item-content a::attr(href)'):
            yield response.follow(href, self.parse_computers)

        # follow pagination links
        href = response.css('a.pag-next::attr(href)')[0]
        yield response.follow(href, self.parse)

    def parse_computers(self, response):
        def extract_with_css(query):
            return response.css(query).extract_first()

        # define properties()
        attribute_type = response.css('div.item-properties dt::text').extract()
        attribute_value = response.css('div.item-properties dd::text').extract()

        properties = {}
        for i in range(0, len(attribute_type)):
            properties[attribute_type[i]] = attribute_value[i]

        def extract_attribute(property):
            value = ''
            if property in properties.keys():
                value = properties[property]
            return value

        yield{
            'item_name': extract_with_css('div.item-top h1::text'),
            'sale_by': extract_with_css('span.poster a::text'),
            'date': extract_with_css('span.date::text'),
            'location': extract_with_css('span.location::text'),
            'price': extract_with_css('span.amount::text'),
            'condition': extract_attribute('Condition:'),
            'item_type': extract_attribute('Device type:'),
            'brand': extract_attribute('Brand:'),
            'model': extract_attribute('Model:'),
            'description': response.css('div.item-description p::text').extract(),

        }


import json
import networkx as nx
from tqdm import tqdm
import numpy as np
import scipy.sparse as sp
import pickle

kw_max_keep_num = 5
feats_size = 200
class_num = 8
train_p = 0.7
val_p = 0.2
test_p = 0.1

def preprocess():

    with open('../data/subgraph_v11_1.json', 'r') as f:
        nodes = f.readlines()

    g = nx.DiGraph()

    print('node num: ', len(nodes))
    id2idx = {}
    all_node = []
    all_kw = {}
    cnt_bad_nodes = 0
    edge_num = 0
    all_class = {}
    for idx in tqdm(range(len(nodes))):
        cur_node = {}
        mes = json.loads(nodes[idx])
        id2idx[mes['id']] = idx
        bad_node = False
        try:
            feat_list = mes['fos']
            kw_mes = []
            for _ in feat_list:
                obj = (_['name'], _['w'])
                kw_mes.append(obj)
            # sort by weight and get top K keywords
            kw_mes.sort(key=lambda x: x[1], reverse=True)
            kw_mes = kw_mes[: min(len(kw_mes), kw_max_keep_num)]
            for _ in kw_mes:
                _ = _[0]
                if _ not in all_kw:
                    all_kw[_] = 1
                else:
                    all_kw[_] += 1
            cur_node['kw'] = [_[0] for _ in kw_mes]
        except:
            cur_node['kw'] = []
            bad_node = True

        try:
            label = mes['venue']
            # conference with id
            assert len(label) > 1
            label = label['raw']
            cur_node['label'] = label
            if label in all_class:
                all_class[label] += 1
            else:
                all_class[label] = 1

        except:
            bad_node = True
            cur_node['label'] = None

        # we currently overlook weight here
        if bad_node:
            cnt_bad_nodes += 1
        cur_node['id'] = mes['id']
        cur_node['references'] = mes['references']
        edge_num += len(cur_node['references'])
        all_node.append(cur_node)
    print('edge num:         ', edge_num)
    print('class num:        ', len(all_class))
    print('all keywords num: ', len(all_kw))
    print('bad nodes num:    ', cnt_bad_nodes)
    print('bad nodes percent:', round(cnt_bad_nodes / len(nodes) * 100, 3), '%')
    print('average keyword mentioned num:', (len(nodes) - cnt_bad_nodes) * kw_max_keep_num / len(all_kw))
    cnttt = 0
    for _ in all_kw:
        if all_kw[_] < 10:
            cnttt += 1
    print('kw percent < 10:  ', cnttt / len(all_kw) * 100, '%')
    print('start generating graph nodes', '***' * 10)
    # filter out bad nodes, so we need to construct a dict to record the idxes of the filtered-out nodes
    convert_back = {}
    convert = {}
    cnt = 0
    feats = []
    class_map = {}
    for idx in tqdm(range(len(all_node))):
        # filter out bad nodes
        if len(all_node[idx]['kw']) == 0 or all_node[idx]['label'] is None:
            continue
        convert_back[cnt] = idx
        convert[idx] = cnt
        g.add_node(cnt)
        feats.append(np.zeros(shape=[feats_size]))
        class_map[str(cnt)] = np.random.randint(class_num)
        cnt += 1
    feats = np.asarray(feats)
    print('feats shape: ', feats.shape)
    print('len classmap:', len(class_map))
    print('start generating graph edges', '***' * 10)
    cnt_edge = 0
    cnt_node = 0
    for idx in tqdm(range(len(all_node))):
        if idx in convert:
            cnt_node += 1
            for neighbor_idx in all_node[idx]['references']:
                if neighbor_idx not in id2idx:
                    continue
                neighbor_idx = id2idx[neighbor_idx]
                if neighbor_idx in convert:
                    # undirected graph
                    g.add_edge(convert[idx], convert[neighbor_idx])
                    g.add_edge(convert[neighbor_idx], convert[idx])
                    cnt_edge += 1
    print('final node num: ', len(g.nodes()))
    print('final edge num: ', len(g.edges()))
    print('start saving dataset')
    sp.save_npz('../data/adj_full.npz', nx.adjacency_matrix(g))
    print('adj_full.npz saved')
    sp.save_npz('../data/adj_train.npz', nx.adjacency_matrix(g))
    print('adj_train.npz saved')
    np.save('../data/feats.npy', feats)
    print('feats.npy saved')
    with open('../data/class_map.json', 'w') as f:
        json.dump(class_map, f)
    print('class_map.json saved')
    # role
    role = {'tr': [], 'va': [], 'te': []}
    rand_idx = np.random.permutation(feats.shape[0]).tolist()
    role['tr'] = rand_idx[:int(feats.shape[0] * train_p)]
    role['va'] = rand_idx[int(feats.shape[0] * train_p): int(feats.shape[0] * (train_p + val_p))]
    role['te'] = rand_idx[int(feats.shape[0] * (train_p + val_p)):]
    with open('../data/role.json', 'w') as f:
        json.dump(role, f)
    print('role.json saved')
    pickle.dump(convert, open('../data/idx_convert.pkl', 'wb'))
    print('idx_convert.pkl saved')
    print('finished')
    return

if __name__ == '__main__':
    preprocess()


import sys
from schevo.lib import optimize

import gtk
from gtk import gdk

WATCH = gdk.Cursor(gdk.WATCH)

class TemporaryCursor(object):

    def __init__(self, window, cursor=WATCH, exit_cursor=None):
        self.window = window
        self.cursor = cursor
        self.exit_cursor = exit_cursor

    def __enter__(self):
        window = self.window.toplevel.window
        if window is not None:
            window.set_cursor(self.cursor)
            while gtk.events_pending():
                gtk.main_iteration()

    def __exit__(self, exc_type, exc_val, exc_tb):
        window = self.window.toplevel.window
        if window is not None:
            window.set_cursor(self.exit_cursor)
            while gtk.events_pending():
                gtk.main_iteration()
        # Do not ignore exception.
        return False

optimize.bind_all(sys.modules[__name__])  # Last line of module.


import pandas as pd

df_filtrado = pd.read_csv("C:/Users/deb/Documents/Tesis/incident-classifier/data/df_filtrado.csv")

df_groupone = df_filtrado[(df_filtrado['NUMERO_CLASIFICADOR']=='B.25')]
df_grouptwo = df_filtrado[(df_filtrado['NUMERO_CLASIFICADOR']=='D.68')]

frames = [df_groupone.iloc[0:2000], df_grouptwo.iloc[0:2000]]

df_balanceado = pd.concat(frames)

print(df_balanceado)

ruta_destino = "C:/Users/deb/Documents/Tesis/incident-classifier/data/df_balanceado.csv"
df_balanceado.to_csv(ruta_destino, index=False)


import pickle
import random
import joblib
import numpy as np
from sklearn import metrics
from sklearn.svm import SVC
from sklearn.metrics import classification_report
from sklearn.model_selection import train_test_split

pick_in = open('./data/picked.pickle', 'rb')
data = pickle.load(pick_in)
pick_in.close()
random.shuffle(data)

features_list = []
lables_list = []

for feature, label in data:
    features_list.append(feature)
    lables_list.append(label)

kernels = ['Polynomial', 'RBF', 'Sigmoid','Linear']

def getClassifier(ktype):
    if ktype == 0:
        # Polynomial kernal
        return SVC(kernel='poly', degree=8, gamma="auto")
    elif ktype == 1:
        # Radial Basis Function kernal
        return SVC(kernel='rbf', gamma="auto")
    elif ktype == 2:
        # Sigmoid kernal
        return SVC(kernel='sigmoid', gamma="auto")
    elif ktype == 3:
        # Linear kernal
        return SVC(kernel='linear', gamma="auto")

for i in range(4):
    X_train, X_test, y_train, y_test = train_test_split(features_list, lables_list, test_size = 0.20)
    svclassifier = getClassifier(i)
    svclassifier.fit(X_train, y_train)
    joblib.dump(svclassifier, './models/{}_model.npy'.format(i))
    y_pred = svclassifier.predict(X_test)
    print("Evaluation:", kernels[i], "kernel")
    print(classification_report(y_test,y_pred, labels=np.unique(y_pred)))
    # print(metrics.f1_score(y_test,y_pred, average=None,labels=np.unique(y_pred)))


#!/usr/bin/python

import argparse, shutil, os
from multiprocessing import cpu_count
from subprocess import call
#from glob import glob

VERSION = 3.2
CORES = cpu_count()

DOC_SOURCE_DIR = './resources_source/doc'
DOC_DIR = './resources/help'
LOC_SOURCE_DIR = './resources_source/lang'
LOC_DIR = './resources/lang'
PLUGINS_DIR = './plugins'
TEMP_DIR = './tmp'

LOC_SOURCE_FILES = ['agros2d-binary/', 'agros2d-library/',
                    'pythonlab-binary/', 'pythonlab-library/',
                    'agros2d-solver/', 'util/']
LOC_TARGET_FILES = ['resources_source/lang/en_US.ts', 'resources_source/lang/cs_CZ.ts',
                    'resources_source/lang/pl_PL.ts', 'resources_source/lang/ru_RU.ts',
                    'resources_source/lang/fr_FR.ts']

LOC_PLUGINS_SOURCE_FILES = ['plugins/']
LOC_PLUGINS_TARGET_FILES = ['resources_source/lang/plugin_en_US.ts',
                            'resources_source/lang/plugin_cs_CZ.ts',
                            'resources_source/lang/plugin_pl_PL.ts',
                            'resources_source/lang/plugin_ru_RU.ts',
                            'resources_source/lang/plugin_fr_FR.ts']

def documentation(format):
    call(['make', format, '-C', DOC_SOURCE_DIR])

    if (os.path.exists(DOC_DIR)):
        shutil.rmtree(DOC_DIR)

    ignored = ['doctrees']
    shutil.copytree('{0}/build/'.format(DOC_SOURCE_DIR), DOC_DIR, ignore=shutil.ignore_patterns(*ignored))

def equations():
    for root, dirs, files in os.walk(PLUGINS_DIR):
        for file in files:
            if (os.path.splitext(file)[1] != '.py'):
                continue

            call(['python', '{0}/{1}'.format(root, file)])

def release_localization():
    for file in os.listdir(LOC_SOURCE_DIR):
        if (os.path.splitext(file)[1] != '.ts'):
            continue

        call(['lrelease', '{0}/{1}'.format(LOC_SOURCE_DIR, file)])

    for file in os.listdir(LOC_SOURCE_DIR):
        if (os.path.splitext(file)[1] != '.qm'):
            continue

        if (not os.path.exists(LOC_DIR)):
            os.mkdir(LOC_DIR)

        shutil.copy2('{0}/{1}'.format(LOC_SOURCE_DIR, file), LOC_DIR)

def files_for_localization(source):
    sources = list()
    for root, dirs, files in os.walk(source):
        for file in files:
            if (file.endswith('.cpp') or file.endswith('.h')) and (not file.startswith('moc_')):
                sources.append(os.path.join(root, file))

    return sources

def update_localization():
    sources = list()
    for source in LOC_SOURCE_FILES:
      sources += files_for_localization(source)

    call(['lupdate'] + sources + ['-ts'] + LOC_TARGET_FILES)

    sources = list()
    for source in LOC_PLUGINS_SOURCE_FILES:
      sources += files_for_localization(source)

    call(['lupdate'] + sources + ['-ts'] + LOC_PLUGINS_TARGET_FILES)

def build_project(cores):
    call(['cmake', '.'])
    call(['make', '-j', str(cores)])

    call(['./agros2d_generator'])
    call(['cmake', PLUGINS_DIR + '/CMakeLists.txt'])
    call(['make', '-C', PLUGINS_DIR, '-j', str(cores)])

def run_project(project, file, run_script, server):
    env = dict(os.environ)
    env['LD_LIBRARY_PATH'] = 'libs'

    args = list()
    if (server):
        args.append('xvfb-run')
        args.append('--auto-servernum')

    args.append('./{0}'.format(project))

    if (run_script):
        args.append('-r')

    if (file != ''):
        args.append(file)

    call(args, env=env)

def source_package(version):
    call(['git', 'clean', '-fdx'])

    temp = '{0}/agros2d-{1}'.format(TEMP_DIR, version)

    ignored = ['tmp', '.git*', '*.mph']
    shutil.copytree('./', temp, ignore=shutil.ignore_patterns(*ignored))

    os.chdir(temp)
    call(['debuild', '-S', '-sa'])

def binary_package():
    call(['dpkg-buildpackage', '-sgpg', '-rfakeroot'])

def callgrind():
	call(['valgrind --tool=callgrind --smc-check=all-non-file --fn-skip=QMetaObject::activate* --fn-skip=QMetaObject::metacall* --fn-skip=*::qt_metacall* --fn-skip=*::qt_static_metacall* ./agros2d'])

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers(dest='command')

    # documentation
    doc = subparsers.add_parser('doc', help='generate documentation')
    doc.add_argument('-f', '--format', nargs='?', default='html', type=str, required=False,
                     help='output format (default parameter is html)')

    # localization
    loc = subparsers.add_parser('loc', help='release or update localization')
    loc.add_argument('-r', '--release', default=False, action='store_true', required=False)
    loc.add_argument('-u', '--update', default=False, action='store_true', required=False)

    # build
    build = subparsers.add_parser('build', help='build project')
    build.add_argument('-c', '--cores', nargs='?', default=CORES, type=int, required=False,
                      help='number of used cores')

    # run
    run = subparsers.add_parser('run', help='run project')
    run.add_argument('-p', '--project', nargs='?', default='agros2d', type=str, required=False,
                     help='project (valid parameters are agros2d, agros2d_pythonalb, agros2d_generator, agros2d_solver)')
    run.add_argument('-f', '--file', nargs='?', default=str(), type=str, required=False,
                     help='open Agros2D data file or Python script')
    run.add_argument('-r', '--run', action='store_true', required=False,
                     help='run Python script defined as file')
    run.add_argument('-s', '--server', action='store_true', required=False,
                     help='run project with X virtual framebuffer')

    # package
    pack = subparsers.add_parser('pack', help='make source or binary package')
    pack.add_argument('-s', '--source', default=True, action='store_true')
    pack.add_argument('-b', '--binary', default=False, action='store_true')
    pack.add_argument('-v', '--version', nargs='?', default=VERSION, type=float, required=False,
                      help='version of package')

    # equations
    eqs = subparsers.add_parser('eqs', help='generate equations from modules')

	  # callgrind
    cgrind = subparsers.add_parser('callgrind', help='call callgrind')

    args = parser.parse_args()

    if (args.command == 'doc'):
        documentation(args.format)

    if (args.command == 'loc'):
        if (args.release):
            release_localization()
        if (args.update):
            update_localization()

    if (args.command == 'build'):
        build_project(args.cores)

    if (args.command == 'run'):
        run_project(args.project, args.file, args.run, args.server)

    if (args.command == 'pack'):
        if (args.source):
            source_package(args.version)
        if (args.binary):
            binary_package()

    if (args.command == 'eqs'):
        equations()

    if (args.command == 'callgrind'):
        callgrind()


import random

n = int(input('Введите кол-во бочонков: '))
s = []
for i in range(n):  # заполнение списка бочонками с рандомными числами которые не повторяються
    ran = random.randint(1, n)
    while len(s) != n:
        ran = random.randint(1, n)
        if ran not in s:
            s.append(ran)

while True:  # цикл для жеребьевки
    print(s.pop(0))  # удаление бочонка
    if len(s) == 0:
        print('Бочонки закончились')
        quit()


IS_DEBUG_MODE = False
class Cell:
    def __init__(self, value=None):
        self.value = value
        self.constraints = set()
        self.can_save = []

    def __str__(self):
        string = ''
        if IS_DEBUG_MODE:
            string = str(self.value) + ': '
            string += str(self.values_can_be())
        else:
            string += str(self.value)
        # for i in self.constraints:
        # string += str(i) + ', '
        return string

    def values_can_be(self):
        array = []
        for i in range(1, 10):
            if i not in self.constraints:
                array.append(i)
        self.can_save = array
        return array

class Map:
    def __init__(self, matrix):
        self.matrix = [[Cell(0) for _ in range(9)] for _ in range(9)]
        self._set_values(matrix)
        self.set_constraints()

    def set_constraints(self):
        for i in range(9):
            for j in range(9):
                value = self.matrix[i][j].value
                self._add_constraints(i, j, value)

    def add_value(self, i, j, value):
        self.matrix[i][j].value = value
        self._add_constraints(i, j, value)

    def _set_values(self, matrix: [[Cell]]):
        for i, row in enumerate(matrix):
            for j, col in enumerate(row):
                self.matrix[i][j] = Cell(col)

    def _add_constraints(self, i, j, value):
        self._add_row_constraints(i, value)
        self._add_col_constraints(j, value)
        self._add_square_constraints(i, j, value)

    def _add_row_constraints(self, row, value):
        for cell in self.matrix[row]:
            cell.constraints.add(value)

    def _add_col_constraints(self, col, value):
        for row in self.matrix:
            row[col].constraints.add(value)

    def _add_square_constraints(self, i, j, value):
        i = (i // 3) * 3
        j = (j // 3) * 3

        for row in range(i, i + 3):
            for col in range(j, j + 3):
                self.matrix[row][col].constraints.add(value)

    def __str__(self):
        string = ''
        for i in range(9):
            for j in range(9):
                string += str(self.matrix[i][j]) + ' '
            string += '\n'
        return string

    def is_solve(self):
        for row in self.matrix:
            for col in row:
                if col.value == 0:
                    return False
        return True

def get_inputs():
    map = []
    for i in range(9):
        map.append([int(i) for i in input().split()])
    return map

def normalize(map: Map):
    for i in range(9):
        for j in range(9):
            cell = map.matrix[i][j]
            if cell.value == 0 and len(cell.values_can_be()) == 1:
                cell.value = cell.can_save[0]
                map.add_value(i, j, cell.value)

if __name__ == '__main__':
    map = Map(get_inputs())
    while not map.is_solve():
        normalize(map)

    print(map)


class Solution:

    def _check_can_put_queen(self,
        queens: List[Tuple[int]],
        pos: Tuple[int]
    ) -> bool:

        for q in queens:

            # Check + direction
            if pos[0] == q[0] or pos[1] == q[1]:
                return False

            # Check X direction
            if abs(pos[0] - q[0]) == abs(pos[1] - q[1]):
                return False
        return True

    def _gen_ans(self,
        N: int,
        queens: List[Tuple[int]]
    ) -> List[List[str]]:
        res = []
        assert len(queens) == N
        for q in queens:
            j = q[1]
            row = "." * N
            row = row[:j] + 'Q' + row[j+1:]
            res.append(row)
        return res

    def _find2(self,
        N: int,
        ans: List[List[str]],
        queens: List[Tuple[int]] = [],
        level = 0,
    ) -> None:
        i = level
        for j in range(N):
            queen = (i, j)
            if self._check_can_put_queen(queens,queen):
                if level + 1 >= N:
                    # END
                    assert level + 1 == N
                    res = self._gen_ans(N, queens + [queen])
                    ans.append(res)
                else:
                    self._find2(N, ans, queens + [queen], level + 1)

    def solveNQueens(self, n: int) -> List[List[str]]:
        ans = []
        self._find2(n, ans = ans)
        return ans


import matplotlib.pyplot as plt
import numpy as np

def PillarDesign(sigma_z, pillar_width, room_width, height, design_fos):
    """
    The Purpose of this program is to successfully design pillar for room and
    pillar underground mining method based on example Measurements.
    Copyright Joaquin Roibal 2016
    New Mexico Institute of Mining and Technology
    """

    pillar_stress = PillarStress(sigma_z, pillar_width, room_width)
    ps = PillarStrength(height,pillar_width)
    factor_of_safety = FactorOfSafety(ps, pillar_stress)

    print("Original Pillar Stress: {}".format(pillar_stress))
    print("Calculated Pillar Strength: {}".format(ps))
    print("Factor of Safety of Original Design Requirements: {}".format(factor_of_safety))

    while factor_of_safety > design_fos:
        room_width += .1
        pillar_width -= .1
        ps = PillarStrength(height, pillar_width)
        pillar_stress = PillarStress(sigma_z, pillar_width, room_width)
        factor_of_safety = FactorOfSafety(ps, pillar_stress)
    print("Final Design Requirements for FOS = {}\nRoom Width: {} \nPillar Width: {}".format(factor_of_safety,
                                                                                room_width, pillar_width))
    print("Pillar Strength: {}".format(ps))
    print("Extraction Ratio: {}".format(ExtractionRatio(pillar_width,room_width)))
    print("Extraction Ratio: {}".format(ExtractionRatio(pillar_width,room_width)))

    while factor_of_safety < design_fos:
        room_width -= .1
        pillar_width +=.1
        ps = PillarStrength(height,pillar_width)
        pillar_stress = PillarStress(sigma_z, pillar_width, room_width)
        factor_of_safety = FactorOfSafety(ps, pillar_stress)
    print("Final Design Requirements for FOS = {}\nRoom Width: {} \nPillar Width: {}".format(factor_of_safety,
                                                                                room_width, pillar_width))
    print("Pillar Stress: {}".format(pillar_stress))
    print("Pillar Strength: {}".format(ps))
    print("Extraction Ratio: {}".format(ExtractionRatio(pillar_width,room_width)))

def PillarStrength(height, width):
    return 10.44*height**(-.7)*width**(0.5)

def FactorOfSafety(p_strength, p_stress):
    return p_strength/p_stress

def ExtractionRatio(pillar_width,room_width):
    return ((pillar_width+room_width)**2-(pillar_width**2))/((pillar_width+room_width)**2)

def PillarStress(sigma_z, pillar_width, room_width):
    return sigma_z*((pillar_width+room_width)/pillar_width)**2

def PlotExample():
    """
    Example Plot for varying Pillar, Room Widths which displays the
    Varying Extraction Ratios.
    """
    er = []
    wp = [x for x in range(1,15)]
    wo = [y for y in range(1,15)]
    for w_p in wp:
        w_open = []
        for w_o in wo:
            w_open.append(ExtractionRatio(w_p,w_o))
        er.append(w_open)
        plt.plot(wo, w_open, label = 'Pillar Length: {}'.format(w_p))
    plt.xlabel('Width Opening of Tunnel')
    plt.ylabel('Extraction Ratio')
    plt.title('Extraction Ratio, Varying Room and Pillar Sizing')
    print(er)
    plt.legend(loc=4)

    plt.figure(2)
    er2 = []
    sigma_z = 3.375
    height = 3
    for w_p in wp:
        w_open2 = []
        for w_o in wo:
            pstress = PillarStress(sigma_z, w_p, w_o)
            pstrength = PillarStrength(height, w_p)
            FOS = FactorOfSafety(pstrength, pstress)
            w_open2.append(FOS)
        er2.append(w_open2)
        plt.plot(wo, w_open2, label = 'Pillar Length: {}'.format(w_p))
    plt.xlabel('Width Opening of Tunnel')
    plt.ylabel('Factor of Safety')
    plt.title('Factor of Safety, Varying Room and Pillar Sizing')
    plt.legend(loc=1)
    plt.show()

def main():
    depth = 150                             #Meters
    height = 3                              #Pillar Height in Meters
    gamma_rock = 22.5                       #kN/m^3
    pillar_width = 7                        #Meters
    room_width = 6                          #Meters
    sigma_z = depth * gamma_rock/1000
    design_fos = [1.3, 1.6]
    for fos in design_fos:
        PillarDesign(sigma_z, pillar_width, room_width, height, fos)

    PlotExample()

if __name__ == "__main__":
    main()


# Day 5 - Loop
def Loop(n):
    i=1
    y=1
    r=10
    for i in range(r):
        i+=1
        y=n*i
        print("{} x {} = {}".format(n, i, y))

    return y

if __name__ == "__main__":
    n = int(input())
    #print()
    if (n>=2 and n<=20):
        res=Loop(n)
        #print()
        #print(res)
    else:
        print("n out of calculation range")


'''

题目
给定一个只包括 '('，')'，'{'，'}'，'['，']' 的字符串，判断字符串是否有效。

有效字符串需满足：

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。

'''

# 解法：

s = "({}"

def isValid(s):
    """
    :type s: str
    :rtype: bool
    """
    st = []
    dic = {')': '(', '}': '{', ']': '['}

    for c in s:
        if c == "{" or c == "(" or c == "[":  # 先加入列表
            st.append(c)
        elif c == "}" or c == ")" or c == "]":  # 字典中存的值和和列表中的键是配对的符号
            if st.pop() != dic[c] or len(st) == 0 :  # s="({}))"  ，len(st) == 0 多输入一个)时会走这个分支，因为之前列表已经被全部删除
                return False

    return len(st) == 0  # for循环完了之后，判断列表是否等于0 ，等于0说明已经完全匹配

print(isValid(s))

算法题目练习汇总/1、leetcode算法练习--简单/5、给定 '('，')'、'{'，'}'，判断是否成对.py


# Instalam request si beautifulsoup cu pip install in terminal
import requests

# Definim URL-ul paginii pe care dorim sa o analizam
url = "https://animax.ro/collections/pasari"
base_url=url
#Preluam html-ul si folosim dictionar headers pt a nu ni se bloca accesul de catre server
Headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0;  Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'}
response = requests.get(url, headers=Headers)
html = response.content

#Verificam daca solicitarea a fost realizata cu succes
if response.status_code == 200:
    print("Solicitarea a fost realizata cu succes")
else:
   print("Solicitarea are buba")

from bs4 import BeautifulSoup

#Cream liste in care vom stoca datele obtinute pentru scrierea in fisier
BRAND=[]
NUME=[]
CODARTICOL=[]
PRET=[]
PRET_Redus=[]

#definim variabila pentru parcurgerea paginilor
page_num=2

while requests.get(url, headers=Headers).status_code==200  :

    soup = BeautifulSoup(html, 'html.parser')
    #Gasim toate elementele de tip div cu clasa necesara
    products = soup.find_all('div', class_='col-6 col-sm-6 col-md-4 col-lg-4 col-xl-3')

    #cream noul url pt pagina urmatoare
    url=f'{base_url}?page={page_num}'
    page_num=page_num+1

    #html pentru noua pagina
    html = requests.get(url, headers=Headers).content

    #extrasem din pagina informatiile referitoare la butonul de "Urmatoarea pagina"
    next_page_link = soup.find("a", {"class": "pagination__item pagination__item--prev pagination__item-arrow btn"})

    #Pentru fiecare produs gasim anterior, luam brandul, numele, id-ul, pretul si pretul redus(daca exista)
    #Preturile vor fi transformate prin cast in date de tip float

    for product in products:
        #Luam brandul, numele, id-ul si pretul produsului
        brand = product.find('div', class_='product-collection__more-info mb-3').text.strip()
        BRAND.append(brand)
        nume= product.find('h4', class_='m-0').text.strip()
        NUME.append(nume)
        codArticol=product.find('p', class_='m-0').text.strip().replace('Cod articol: ','')
        CODARTICOL.append(codArticol)
        pret = product.find('span', class_ = 'price' ).text.strip().replace(' lei',' ')
        Pret=[]
        for x in pret:
            if x!=" ":
                Pret.append(x)
            else:
                break
        pret="".join(Pret)

        # pret_redus=product.find('span', class_ = 'price price--sale')
        # Daca exista, luam si pretul redus

        if product.find('span', class_ = 'price price--sale') is None:
            pret_redus = 'NaN'
            #pret = product.find('span', class_ = 'price').text.strip().replace(' lei','')
        else:
            pret_redus=product.find('span', class_= 'price price--sale').text.strip().replace(' lei','').replace(pret, "")
            pret_redus=pret_redus.replace(",",".")
            pret_redus=float(pret_redus)
            #print("s a facut strip", pret_redus)

        #cast la float
        #tratam cazul in care pretul este mai mare de 999.99 si vor aparea 2 puncte in float-> va produce eroare
        if len(pret)<7:
            pret=pret.replace(",",".")
        else:
            pret=pret.replace(",","", 1).replace(",",".")
        pret=float(pret)

        PRET.append(pret)
        PRET_Redus.append(pret_redus)

        #afisam si pe ecran
        print(brand, nume, codArticol, pret, pret_redus)

    #daca nu avem butonul de "Urmatoarea pagina "  in pagina curenta, inseamna ca este ultima pagina si iesim din while/
    # am terminat de extras produse din categoria respectiva
    if  next_page_link is None:
       break

#importam csv pentru scrierea datelor in fisier csv
import csv

CapTabel=["Cod_Articol","Brand","Nume","Pret", "Pret_Redus"]

#Cu fisierul deschis, scriem capul de tabel si informatiile obtinute, pe fiecare rand
with open('Produse_Animax.csv', 'w',encoding='utf-8-sig', newline='') as file:
    writer = csv.writer(file)
    #scriem capul de tabel
    writer.writerow(CapTabel)

    #scriem datele in fisier
    for i in range(len(BRAND)):

        writer.writerow([CODARTICOL[i],BRAND[i],NUME[i],PRET[i],PRET_Redus[i]])


from requests import Request, post, put, get
from VinylShop.spotify_api.playlist import Playlist
from  VinylShop.spotify_api.song import Song
from pickle import *
from VinylShop.spotify_api.credentials import *
from flask import redirect
from copy import deepcopy
from flask import session

BASE_URL = "https://api.spotify.com/v1/"

null = None
false = False
true = True

availableVinyls = {'ab67616d0000b273692d9189b2bd75525893f0c1':"The Beatles",
                       'ab67616d0000b273370c12f82872c9cfaee80193':"Tame Impala",
                       'ab67616d0000b2734ada80e2e0d11d8f6a99d42e':"Pink Floyd"}

EXAMPLE_PLAYLISTS_RESPONSE = {
  "href": "https://api.spotify.com/v1/users/9zjte07qm6qxb3ynn9bm6atiu/playlists?offset=0&limit=3",
  "items": [
    {
      "collaborative": false,
      "description": "",
      "external_urls": {
        "spotify": "https://open.spotify.com/playlist/5p4U0hdrqumFpgpfIN30Eq"
      },
      "href": "https://api.spotify.com/v1/playlists/5p4U0hdrqumFpgpfIN30Eq",
      "id": "5p4U0hdrqumFpgpfIN30Eq",
      "images": [
        {
          "height": 640,
          "url": "https://mosaic.scdn.co/640/ab67616d0000b273176e82d09ac75d62810f0056ab67616d0000b273692d9189b2bd75525893f0c1ab67616d0000b273bfa99afb5ef0d26d5064b23bab67616d0000b273ca69f52416a728ebd0b9103c",
          "width": 640
        },
        {
          "height": 300,
          "url": "https://mosaic.scdn.co/300/ab67616d0000b273176e82d09ac75d62810f0056ab67616d0000b273692d9189b2bd75525893f0c1ab67616d0000b273bfa99afb5ef0d26d5064b23bab67616d0000b273ca69f52416a728ebd0b9103c",
          "width": 300
        },
        {
          "height": 60,
          "url": "https://mosaic.scdn.co/60/ab67616d0000b273176e82d09ac75d62810f0056ab67616d0000b273692d9189b2bd75525893f0c1ab67616d0000b273bfa99afb5ef0d26d5064b23bab67616d0000b273ca69f52416a728ebd0b9103c",
          "width": 60
        }
      ],
      "name": "T6 - Big Chungus Waz Ere",
      "owner": {
        "display_name": "johncaffrey",
        "external_urls": {
          "spotify": "https://open.spotify.com/user/creedbrattonheymah"
        },
        "href": "https://api.spotify.com/v1/users/creedbrattonheymah",
        "id": "creedbrattonheymah",
        "type": "user",
        "uri": "spotify:user:creedbrattonheymah"
      },
      "primary_color": null,
      "public": false,
      "snapshot_id": "NDcsN2FhYTU1MGUwMGZkODVkYjY5MjNjZWExMTY3MDI4YWZjY2FkYjI3OQ==",
      "tracks": {
        "href": "https://api.spotify.com/v1/playlists/5p4U0hdrqumFpgpfIN30Eq/tracks",
        "total": 69
      },
      "type": "playlist",
      "uri": "spotify:playlist:5p4U0hdrqumFpgpfIN30Eq"
    },
    {
      "collaborative": false,
      "description": "",
      "external_urls": {
        "spotify": "https://open.spotify.com/playlist/2LhU2BKMxiPDHjdM4QWzrq"
      },
      "href": "https://api.spotify.com/v1/playlists/2LhU2BKMxiPDHjdM4QWzrq",
      "id": "2LhU2BKMxiPDHjdM4QWzrq",
      "images": [
        {
          "height": 640,
          "url": "https://mosaic.scdn.co/640/ab67616d0000b273176e82d09ac75d62810f0056ab67616d0000b2732557f5ed1ca07d5111d49b93ab67616d0000b27334ef8f7d06cf2fc2146f420aab67616d0000b27358267bd34420a00d5cf83a49",
          "width": 640
        },
        {
          "height": 300,
          "url": "https://mosaic.scdn.co/300/ab67616d0000b273176e82d09ac75d62810f0056ab67616d0000b2732557f5ed1ca07d5111d49b93ab67616d0000b27334ef8f7d06cf2fc2146f420aab67616d0000b27358267bd34420a00d5cf83a49",
          "width": 300
        },
        {
          "height": 60,
          "url": "https://mosaic.scdn.co/60/ab67616d0000b273176e82d09ac75d62810f0056ab67616d0000b2732557f5ed1ca07d5111d49b93ab67616d0000b27334ef8f7d06cf2fc2146f420aab67616d0000b27358267bd34420a00d5cf83a49",
          "width": 60
        }
      ],
      "name": "Stephen’s Opti 24th Sep 2021",
      "owner": {
        "display_name": "Paulcaff123",
        "external_urls": {
          "spotify": "https://open.spotify.com/user/9zjte07qm6qxb3ynn9bm6atiu"
        },
        "href": "https://api.spotify.com/v1/users/9zjte07qm6qxb3ynn9bm6atiu",
        "id": "9zjte07qm6qxb3ynn9bm6atiu",
        "type": "user",
        "uri": "spotify:user:9zjte07qm6qxb3ynn9bm6atiu"
      },
      "primary_color": null,
      "public": false,
      "snapshot_id": "MjM1LDM0MzM4M2UxMWVkYjQwZDc2OTk5NDM2NzgxM2IyNjE5NzY3OTA3NWE=",
      "tracks": {
        "href": "https://api.spotify.com/v1/playlists/2LhU2BKMxiPDHjdM4QWzrq/tracks",
        "total": 70
      },
      "type": "playlist",
      "uri": "spotify:playlist:2LhU2BKMxiPDHjdM4QWzrq"
    },
    {
      "collaborative": false,
      "description": "The songs that influenced everything that has happened since. Cover: Jimi Hendrix",
      "external_urls": {
        "spotify": "https://open.spotify.com/playlist/37i9dQZF1DX5qNE4zrflL7"
      },
      "href": "https://api.spotify.com/v1/playlists/37i9dQZF1DX5qNE4zrflL7",
      "id": "37i9dQZF1DX5qNE4zrflL7",
      "images": [
        {
          "height": null,
          "url": "https://i.scdn.co/image/ab67706f00000003a37256f94f873658dfd43bb6",
          "width": null
        }
      ],
      "name": "Alternative 60s",
      "owner": {
        "display_name": "Spotify",
        "external_urls": {
          "spotify": "https://open.spotify.com/user/spotify"
        },
        "href": "https://api.spotify.com/v1/users/spotify",
        "id": "spotify",
        "type": "user",
        "uri": "spotify:user:spotify"
      },
      "primary_color": null,
      "public": false,
      "snapshot_id": "MTYzMzQ5MTc5MiwwMDAwMDAwNzAwMDAwMTdjNTNiMmIzZGEwMDAwMDE3YzUzOWVjNDgw",
      "tracks": {
        "href": "https://api.spotify.com/v1/playlists/37i9dQZF1DX5qNE4zrflL7/tracks",
        "total": 80
      },
      "type": "playlist",
      "uri": "spotify:playlist:37i9dQZF1DX5qNE4zrflL7"
    }
  ],
  "limit": 3,
  "next": "https://api.spotify.com/v1/users/9zjte07qm6qxb3ynn9bm6atiu/playlists?offset=3&limit=3",
  "offset": 0,
  "previous": null,
  "total": 71
}

EXAMPLE_RESPONSE = {
  "items": [
    {
      "track": {
        "album": {
          "artists": [
            {
              "external_urls": {
                "spotify": "https://open.spotify.com/artist/3WrFJ7ztbogyGnTHbHJFl2"
              },
              "href": "https://api.spotify.com/v1/artists/3WrFJ7ztbogyGnTHbHJFl2",
              "id": "3WrFJ7ztbogyGnTHbHJFl2",
              "name": "The Beatles",
              "type": "artist",
              "uri": "spotify:artist:3WrFJ7ztbogyGnTHbHJFl2"
            }
          ],
          "href": "https://api.spotify.com/v1/albums/2BtE7qm1qzM80p9vLSiXkj",
          "id": "2BtE7qm1qzM80p9vLSiXkj",
          "name": "Magical Mystery Tour (Remastered)"
        },
        "href": "https://api.spotify.com/v1/tracks/0qHMhBZqYb99yhX9BHcIkV",
        "id": "0qHMhBZqYb99yhX9BHcIkV",
        "name": "Magical Mystery Tour - Remastered 2009"
      }
    },
      {
          "track": {
              "album": {
                  "artists": [
                      {
                          "external_urls": {
                              "spotify": "https://open.spotify.com/artist/16eRpMNXSQ15wuJoeqguaB"
                          },
                          "href": "https://api.spotify.com/v1/artists/16eRpMNXSQ15wuJoeqguaB",
                          "id": "16eRpMNXSQ15wuJoeqguaB",
                          "name": "The Flaming Lips",
                          "type": "artist",
                          "uri": "spotify:artist:16eRpMNXSQ15wuJoeqguaB"
                      }
                  ],
                  "href": "https://api.spotify.com/v1/albums/49LA20VMk65fQyEaIzYdvf",
                  "id": "49LA20VMk65fQyEaIzYdvf",
                  "name": "Yoshimi Battles the Pink Robots"
              },
              "href": "https://api.spotify.com/v1/tracks/0ScgmigVOJr2mFsAtwFQmz",
              "id": "0ScgmigVOJr2mFsAtwFQmz",
              "name": "Fight Test"
          }
      },
{
      "track": {
        "album": {
          "artists": [
            {
              "external_urls": {
                "spotify": "https://open.spotify.com/artist/16eRpMNXSQ15wuJoeqguaB"
              },
              "href": "https://api.spotify.com/v1/artists/16eRpMNXSQ15wuJoeqguaB",
              "id": "16eRpMNXSQ15wuJoeqguaB",
              "name": "The Flaming Lips",
              "type": "artist",
              "uri": "spotify:artist:16eRpMNXSQ15wuJoeqguaB"
            }
          ],
          "href": "https://api.spotify.com/v1/albums/49LA20VMk65fQyEaIzYdvf",
          "id": "49LA20VMk65fQyEaIzYdvf",
          "name": "Yoshimi Battles the Pink Robots"
        },
        "href": "https://api.spotify.com/v1/tracks/0ScgmigVOJr2mFsAtwFQmz",
        "id": "0ScgmigVOJr2mFsAtwFQmz",
        "name": "Fight Test"
      }
    },
    {
      "track": {
        "album": {
          "artists": [
            {
              "external_urls": {
                "spotify": "https://open.spotify.com/artist/0epOFNiUfyON9EYx7Tpr6V"
              },
              "href": "https://api.spotify.com/v1/artists/0epOFNiUfyON9EYx7Tpr6V",
              "id": "0epOFNiUfyON9EYx7Tpr6V",
              "name": "The Strokes",
              "type": "artist",
              "uri": "spotify:artist:0epOFNiUfyON9EYx7Tpr6V"
            }
          ],
          "href": "https://api.spotify.com/v1/albums/2xkZV2Hl1Omi8rk2D7t5lN",
          "id": "2xkZV2Hl1Omi8rk2D7t5lN",
          "name": "The New Abnormal"
        },
        "href": "https://api.spotify.com/v1/tracks/5ruzrDWcT0vuJIOMW7gMnW",
        "id": "5ruzrDWcT0vuJIOMW7gMnW",
        "name": "The Adults Are Talking"
      }
    }
  ]
}

at = None

def get_auth_code():
    scopes = 'playlist-read-private playlist-read-collaborative user-library-read user-top-read user-read-private user-read-email'

    url = Request('GET', 'https://accounts.spotify.com/authorize',
                  params={
                      'scope': scopes,
                      'response_type': 'code',
                      'redirect_uri': REDIRECT_URI,
                      'client_id': CLIENT_ID
                  }).prepare().url

    return url

def spotify_callback(request):
    code = request.args['code']

    response = post('https://accounts.spotify.com/api/token', data={
        'grant_type': 'authorization_code',
        'code': code,
        'redirect_uri': REDIRECT_URI,
        'client_id': CLIENT_ID,
        'client_secret': CLIENT_SECRET
    }).json()

    access_token = response.get('access_token')
    token_type = response.get('token_type')
    refresh_token = response.get('refresh_token')
    expires_in = response.get('expires_in')
    error = response.get('error')

    global at

    at = access_token

    return redirect(SERVER_URL+"/displayPlaylists/" + str(access_token))

def spotify_api_request(endpoint, at, post_=False, put_=False):
    #access_token = at  # FIX - User token
    access_token = session.get('access_token')
    headers = {'Content-Type': 'application/json',
               'Authorization': "Bearer " + access_token}

    if post_:
        post(BASE_URL + endpoint, headers=headers)
    if put_:
        put(BASE_URL + endpoint, headers=headers)

    response = get(BASE_URL + endpoint, {}, headers=headers)
    try:
        return response.json()
    except:
        return {'Error': 'Issue with request'}

def get_playlists(at):
    endpoint = "me/playlists"  # "users/user_id/playlists"
    response = spotify_api_request(endpoint, at)

    if 'error' in response or 'items' not in response:
        print("ERROR IN RESPONSE FOR PLAYLISTS")
        return response, None  # FIX: RETURN AN ERROR

    playlists_dictionary = response.get('items')

    playlists = list()

    for playlist in playlists_dictionary:
        playlists.append({'name': playlist['name'], 'id': playlist['id'],
                          'playlist_img': playlist['images'][0]['url'][27:]})

    return playlists

def get_songs_in_playlist(playlist_id, at, playlist_obj=None):
    playlist = playlist_obj
    if playlist is None:
        print("Printing")
        playlist = uploadPlaylist(playlist_id, at, save_playlist=False)

    songs = list()

    for song in playlist.songs:
        songs.append({'name': song.name, 'artist': song.artist,
                      'album': song.album, 'album_img': song.album_img, 'artist_img': song.artist_img})

    return songs

def make_playlist_objects():
    playlist_ids, playlist_names = get_playlists()
    playlist_objects = list()
    for i in range(len(playlist_ids)):
        playlistID = playlist_ids[i]
        playlistName = playlist_names[i]
        newPlaylist = Playlist(playlistName, playlistID)
        playlist_objects.append(newPlaylist)

def find_most_popular_album(playlist):
    albums = dict()
    highest_album_amount = 0
    highest_album_name = ""
    for song in playlist.songs:
        album = song.album
        if album in albums:
            albums[album] += 1
        else:
            albums[album] = 1
        if albums[album] > highest_album_amount:
            highest_album_name = album
            highest_album_amount = albums[album]
    print(highest_album_amount, highest_album_name)

def getTopArtists(playlist):
    artists = dict()
    playlist_songs = deepcopy(playlist.songs)
    for song in playlist_songs:
        artist = song.artist
        if artist in artists:
            artists[artist]['count'] += 1
        else:
            artists[artist] = {'count':1, 'song':song}
    sortedArtists = sorted(artists, key=lambda i: artists[i]['count'], reverse=True)
    orderedArtists = list()
    position = 0
    for artist in sortedArtists:
        song_of_artist = artists[artist]['song']
        artist_img = song_of_artist.artist_img
        count = artists[artist]['count']
        artist_info = {'name': artist, 'artist_img': artist_img, 'count': count, 'position': str(position)}
        position += 1
        orderedArtists.append(artist_info)
    return orderedArtists

def getTopAlbums(playlist):
    albums = dict()
    playlist_songs = deepcopy(playlist.songs)
    for song in playlist_songs:
        album = song.album
        if album in albums:
            albums[album]['count'] += 1
        else:
            albums[album] = {'count': 1, 'song': song}
    sortedAlbums = sorted(albums, key=lambda i: albums[i]['count'], reverse=True)
    orderedAlbums = list()
    for album in sortedAlbums:
        song_of_album = albums[album]['song']
        album_img = song_of_album.album_img
        artist = song_of_album.artist
        count = albums[album]['count']
        album_info = {'name': album, 'album_img': album_img, 'artist': artist, 'count': count}
        orderedAlbums.append(album_info)
    return orderedAlbums

def find_most_popular_artist(playlist):
    artists = dict()
    highest_artist_amount = 0
    highest_artist_name = ""
    for song in playlist.songs:
        artist = song.artist
        if artist in artists:
            artists[artist] += 1
        else:
            artists[artist] = 1
        if artists[artist] > highest_artist_amount:
            highest_artist_name = artist
            highest_artist_amount = artists[artist]
    print(highest_artist_name, highest_artist_amount)

def getArtistImages(artistIDs, accessToken=None):
    global at
    if accessToken is None:
        accessToken = at

    artist_id_string = ""

    count = 0
    for artist in artistIDs:
        if count == 0:
            artist_id_string += artist
        else:
            artist_id_string += "%2C" + artist
        count += 1

    endpoint = "artists?ids=" + artist_id_string
    response = spotify_api_request(endpoint, accessToken)

    if 'error' in response or 'artists' not in response:
        print(response)
        return  # FIX: RETURN AN ERROR

    artists_list = response.get('artists')
    artistImgs = list()

    for artist in artists_list:
        artistImgs.append(artist['images'][0]['url'][24:])

    print("Artist imgs", artistImgs)

    return artistImgs

def updateArtistImages(playlist):
    artistIDs = list()

    songs = playlist.songs

    for song in songs:
        artistIDs.append(song.artistID)

    artistImgs = getArtistImages(artistIDs)

    count = 0
    for song in songs:
        song.artist_img = artistImgs[count]
        count += 1

def uploadPlaylist(playlist_id, at, playlist_name='Playlist', playlist_img='None', save_playlist=False):

    endpoint = "playlists/" + playlist_id + "/tracks?fields=items(track(name%2Chref%2Calbum(name%2Chref%2Cimages%2C%20artists)))&limit=50"
    response = spotify_api_request(endpoint, at)

    if 'error' in response or 'items' not in response:
        print(response)
        return  # FIX: RETURN AN ERROR

    songs_dictionary = response.get('items')

    songs = list()

    for song in songs_dictionary:
        track = song['track']
        name = track['name']
        song_id = 2
        album = track['album']['name']
        artist = track['album']['artists'][0]['name']
        artistID = track['album']['artists'][0]['id']
        artist_img = track['album']['images'][0]['url'][24:]
        album_img = track['album']['images'][0]['url'][24:]

        newSong = Song(name, song_id, album, artist, artistID, artist_img=artist_img, album_img=album_img)

        songs.append(newSong)

    playlist_obj = Playlist(playlist_name, playlist_id, img=playlist_img)
    playlist_obj.songs = songs

    if save_playlist:
        print("Saved playlist to database") # FIX DATABASE STUFF

    updateArtistImages(playlist_obj)

    return playlist_obj

def getAvailableVinylsByArtist(artist_name):
    global availableVinyls
    vinyls = list()
    for vinyl in availableVinyls:
        if availableVinyls[vinyl] == artist_name:
            vinyls.append(vinyl)

    return vinyls

def checkAlbumAvailability(album):
    global availableVinyls
    if album in availableVinyls:
        return True
    return False


# -*- coding: utf-8 -*-
"""
CCT MSc DA -- Programming Python (Amilcar Aponte amilcar@cct.ie)
@author: Lajos Reisenleitner sba-21-727

Calculator v1.3

"""
import numpy # for round(complex) only

class Calculator:
	'''Basic Arithmetic Calculator
		A - Addition
		S - Subtraction
		P - Product
		D - Division
		E - Exponential
		R - Root
		M - Modulus
		C - Close the program
	'''

	op_str = "ASPDERMC"
	menu_str = {'A':"Addition",'S':"Subtraction",'P':"Product",'D':"Division",'E':"Exponential",'R':"Root",'M':"Modulus",'C':"Close the program"}
	menu_str2 = ["only two inputs","of n numbers"]
	msg = {"C_ON":"The Calculator is running...","C_OFF":"...The Calculator has stopped.",
		"MT":"------ Operation menu ------","CH":"Please choose!",
		"N":"How many numbers would you like to type in? ", "F":"Give the number", "X":" (X:finish)",
		"ERR_N":"You need to give an integer number between 2 and 20.", "ERR_F":"You need to give a number",
		"ERR_OP":"Not enough input ::: ", "ERR_VAL":"Value Error", "ERR_ZDIV":"Zero Division Error"}

	def on(self):
		"""Start the running"""
		print("\n"+self.msg["C_ON"])
		self.main()

	def off(self):
		"""Close the running"""
		print("\n"+self.msg["C_OFF"])

	def menu(self):
		''' Prints the menu '''

		print("\n\t"+self.msg["MT"]+"\n")

		for s in self.op_str:
			s_ = "\t "+s+" - "+self.menu_str[s]

			if s == 'C':
				print("\n"+s_)
			else:
				print(s_+" ("+self.menu_str2[s in "AP"]+")")

	def operation(self,op):
		"""Operations - the hearth of the calculation"""

		o_ = {'A':"+",'S':"-",'P':"*",'D':"/",'E':"**",'R':"V‾",'M':"%",'C':""}
		n = 2
		nums = []
		print("\n\t <====== "+self.menu_str[op].upper()+" ======>")

	# n=?
		if op in "AP":
			while True:
				try:
					n = int (input(self.msg["N"]+" > ").strip())
					if 2<=n<=20: break
				except: pass
				print(self.msg["ERR_N"])

	# n1, n2... =?
		isX = False
		print("\t\t\t\t\t\t"+self.msg["X"])
		for i in range(0, n):

			while True:
				try:
					f = input(self.msg["F"]+" "+str(i+1)+"#"+str(n)+" > ").strip()
					if f in "xX" and f:
						isX = True
						break
					f = float(f)
					if f== -0.0: f=0.0
				except:
					print(self.msg["ERR_F"])
					continue
				nums.append(f)
				break
			# ..while
			if isX: break
		#..for

	# operations
		n = len(nums)
		result_str=""
		if n<2: print(self.msg["ERR_OP"])
		else:
			f = nums.pop(0)
			result_str = str(f)
			result = f

			try:
				for i in range(0, n-1):
					f = nums.pop(0)
					if op=='R': result_str = str(f)+o_[op]+" "+result_str
					else: result_str += " "+o_[op]+" "+str(f)

					if   op=='A': result += f
					elif op=='S': result -= f
					elif op=='P': result *= f
					elif op=='D': result /= f
					elif op in "ER":
						if op=='E': result **= f
						else: result **= (1/f)
						if type(result) == float: result=round(result, 8)
						elif type(result) == complex: result=numpy.around(result, 8)
					elif op=='M': result %= f

				result_str += " = "+str(result)
				print(result_str)
				print("\n"+str(result))
			except: print(self.msg["ERR_ZDIV"])

	def main(self):
		"""Main program"""

		self.menu()
		while True:

			op = input(self.msg["CH"]+" > ").strip().upper()
			if len(op) != 1 or op not in self.op_str:
				print(self.msg["ERR_OP"]+op)
				continue
			elif op == "C": break

			self.operation(op)

			self.menu()

		self.off()
#==============================================================================

# Create object
calculator = Calculator()

# Running...
calculator.on()