# Functions for running an encryption or decryption.

# The values of the two jokers.
JOKER1 = 27
JOKER2 = 28

# This function will convert all alphabets to upper case alphabets
# and will remove any character that is not an alphabet.

def clean_message(message):
    """ (str) -> str

    Return the uppercase alphabetic value of all characters in the
    message(message).

    >>> clean_message('John')
    'JOHN'
    >>> clean_message('Please Call Me')
    'PLEASECALLME'
    """
    cleaned_message=""

    for ch in message:
        if ch.isalpha() == True:
            if ch.isupper() == True:
                cleaned_message = cleaned_message + ch
            elif ch.islower() == True:
                cleaned_message = cleaned_message + ch.upper()
        elif not ch.isalpha():
            ch = ''
            cleaned_message=cleaned_message + ch

    return cleaned_message

# This function will encrypt the letter by adding
# the value of the letter based on it's position to
# the keystream value and converting it back to a
# letter based on the value.

def encrypt_letter(character, keystream_value):
    """ (str, int) -> str

    Return the encrypted character based on the integral value
    of the character and the keystream_value.

    >>> encrypt_letter('A', 3)
    'D'
    >>> encrypt_letter('E', 24)
    'C'
    """
# Variable primarily used to simplify the statements below.

    new_char_val=(ord(character) + keystream_value)

    if (new_char_val - 65) <= 25 and (new_char_val - 65) >= 0:
        return (chr((new_char_val - 65)+ 65))
    elif (new_char_val-65) > 25:
        return chr(0 + ((new_char_val - 65)- 25)+ 64)

# This function will decrypt the encrypted character by
# subtracting the keystream value and finding the original
# position of the character, converting it back to the initial character.

def decrypt_letter(character, keystream_value):
    """ (str, int) -> str

    Return the original character by decrypting the encrypted
    character(encrypted_character) using the keystream
    value(keystream_value).

    >>> decrypt_letter('C', 3)
    'Z'
    >>> decrypt_letter('O', 9)
    'F'
    """
# Variable primarily used to simplify the statements below.

    decr_char_val=(ord(character) - keystream_value)

    if (decr_char_val - 65) <= 25 and (decr_char_val - 65) >= 0:
            return (chr(decr_char_val))
    else:
        return chr(decr_char_val + 26)

# This function will swap the card with the card under it in the deck.

def swap_cards(deck, index):
    """ (list of int, int) -> NoneType

    Return the deck of cards by swapping the card with index(index)
    with the card below it in the deck(deck).

    >>>deck=[1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 3, 6, 9, 12, 15, 18,
    21, 24, 27, 2, 5, 8, 11, 14, 17, 20, 23, 26]
    >>>swap_cards(deck, 3)
    [1, 4, 7, 13, 10, 16, 19, 22, 25, 28, 3, 6, 9, 12, 15, 18, 21, 24,
    27, 2, 5, 8, 11, 14, 17, 20, 23, 26]
    >>>deck=[1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 3, 6, 9, 12, 15, 18,
    21, 24, 26, 2, 5, 8, 11, 14, 17, 20, 23, 27]
    >>>swap_cards(deck, 9)
    [1, 4, 7, 10, 13, 16, 19, 22, 25, 3, 28, 6, 9, 12, 15, 18, 21, 24,
    26, 2, 5, 8, 11, 14, 17, 20, 23, 27]
    """

    if (index) <= 26:
        temp = deck[index+1]
        deck[index+1] = deck[index]
        deck[index] = temp
    elif (index == 27):
        temp = deck[0]
        deck[0] = deck[index]
        deck[index] = temp

# This function will find Joker 1 in the deck and
# replace it with the card below it in the deck.

def move_joker_1(deck):
    """ (list of int) -> NoneType

    Return the deck(deck) after swapping joker 1 with the
    number below it in the deck.

    >>>deck=[1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 3, 6, 9, 12, 15, 18, 21,
    24, 27, 2, 5, 8, 11, 14, 17, 20, 23, 26]
    >>>move_joker_1(deck)
    >>>deck
    [1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 3, 6, 9, 12, 15, 18, 21, 24, 2,
    27, 5, 8, 11, 14, 17, 20, 23, 26]
    >>>move_joker_1(deck)
    >>>deck
    [1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 3, 6, 9, 12, 15, 18, 21, 24, 2,
    5, 27, 8, 11, 14, 17, 20, 23, 26]
    """
    i=0
    for num in deck:
        if num != JOKER1:
            i = i+1
        elif num == JOKER1:
            return swap_cards(deck, i)

# This function will find Joker 2 in the deck
# and replace it with the card below it in the deck.

def move_joker_2(deck):
    """ (list of int) -> NoneType

    Swaps joker 2 with the number below it in the deck.

    >>>deck=[1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 3, 6, 9, 12,
    15, 18, 21, 24, 27, 2, 5, 8, 11, 14, 17, 20, 23, 26]
    >>>move_joker_2(deck)
    >>>deck
    [1, 4, 7, 10, 13, 16, 19, 22, 25, 3, 6, 28, 9, 12, 15, 18,
    21, 24, 27, 2, 5, 8, 11, 14, 17, 20, 23, 26]
    >>>move_joker_2(deck)
    >>>deck
    [1, 4, 7, 10, 13, 16, 19, 22, 25, 3, 6, 9, 12, 28, 15, 18,
    21, 24, 27, 2, 5, 8, 11, 14, 17, 20, 23, 26]
    """
    index = deck.index(JOKER2)
    temp = []

# If the new position is at the end of this deck,
# the cards are moved according to position,
# in the new temporary deck.

    if (index+2) <= 27:
       temp += deck[0:index]
       temp += deck[(index+1):(index+3)]
       temp.append(JOKER2)
       temp += deck[(index+3):]

# If the new position is at the beginning of
# the deck, then these statements would shift the cards
# into a temporary deck according to position.

    elif (index+2) > 27:

# These statements are specific to if the card will
# take position 1 or position 2 in the deck.

            if (index+2-28) != 0:
                temp += deck[(index+2-28): (index+2-27)]
                temp.append(JOKER2)
                temp += deck[(index+2-27):index]
                temp += deck[(index+1):]
                temp.append(deck[0])
            elif (index+2-28)==0:
                temp.append(JOKER2)
                temp += deck[(index+2-27):index]
                temp += deck[index+1:]
                temp.append(deck[(index+2-28)])

# This finally replaces the cards in the original
# deck with the cards in the new deck.

    for item in range(len(deck)):
        deck[item] = temp[item]

# This function will perform a triple cut by switching
# the cards before the first Joker with the cards after the
# second Joker in the deck.

def triple_cut(deck):
    """ (list of int) -> NoneType

    Amends the deck by finding which Joker comes first, finding all the
    cards before that and placing it after the second joker after which
    it takes the cards that come after the second joker and places it
    before the first.

    >>>deck=[1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 3, 6, 9, 12,
    15, 18, 21, 24, 27, 2, 5, 8, 11, 14, 17, 20, 23, 26]
    >>>triple_cut(deck)
    >>>deck
    [2, 5, 8, 11, 14, 17, 20, 23, 26, 28, 3, 6, 9, 12, 15, 18,
    21, 24, 27, 1, 4, 7, 10, 13, 16, 19, 22, 25]
    >>>deck=[1, 4, 7, 10, 13, 16, 19, 22, 25, 26, 3, 6, 9, 12,
    15, 18, 21, 24, 27, 2, 5, 8, 11, 14, 17, 20, 23, 28]
    >>>triple_cut(deck)
    >>>deck
    [27, 2, 5, 8, 11, 14, 17, 20, 23, 28, 1, 4, 7, 10, 13, 16,
    19, 22, 25, 26, 3, 6, 9, 12, 15, 18, 21, 24]
    """
# Each variable is created so that each segment of the deck
# could be copied to a specific list.

    new_end_cards = []
    new_front_cards = []
    middle_cards = []
    index_joker_2 = deck.index(JOKER2)
    index_joker_1 = deck.index(JOKER1)

# In the situation where Joker 1 comes before Joker 2.

    if (index_joker_1) < (index_joker_2):
        new_end_cards = deck[0:index_joker_1]
        new_front_cards = deck[(index_joker_2)+1:]
        middle_cards = deck[(index_joker_1):(index_joker_2)+1]

# In the case where Joker 2 comes before Joker 1.

    else:
        new_end_cards = deck[0:(index_joker_2)]
        new_front_cards = deck[(index_joker_1)+1:]
        middle_cards = deck[index_joker_2:(index_joker_1)+1]

# A temporary list is created and each segment of the deck is copied
# to fit the specifications with the end cards shifted to
# the beginning and vice-versa.

    temp_deck = []
    temp_deck += (new_front_cards)
    temp_deck += (middle_cards)
    temp_deck += (new_end_cards)

#This copies the temporary list values to the deck.

    for item in range(len(deck)):
        deck[item] = temp_deck[item]

# This function will take the value of the last card and take that
# many cards from the front and move it behind the last card.

def insert_top_to_bottom(deck):
    """(list of int) -> NoneType

    Amend the deck(deck) by taking the number of cards equivalent
    to the last number(deck[27]) in the deck from the front of the
    deck and placing them before the last card in the deck.

    >>>deck=[1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 3, 6, 9, 12, 15,
    18, 21, 24, 27, 2, 5, 8, 11, 14, 17, 20, 23, 26]
    >>>insert_top_to_bottom(deck)
    >>>deck
    [23, 1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 3, 6, 9, 12, 15, 18,
    21, 24, 27, 2, 5, 8, 11, 14, 17, 20, 26]
    >>>deck=[1, 4, 7, 10, 13, 16, 19, 22, 25, 26, 3, 6, 9, 12, 15,
    18, 21, 24, 27, 2, 5, 8, 11, 14, 17, 20, 23, 28]
    >>>insert_top_to_bottom(deck)
    >>>deck
    [1, 4, 7, 10, 13, 16, 19, 22, 25, 26, 3, 6, 9, 12, 15, 18, 21,
    24, 27, 2, 5, 8, 11, 14, 17, 20, 23, 28]

    """
    number_of_cards = deck[27]
    temp_deck = []

# If the last card is not equivalent to any of the jokers,
# this stores the middle segment of the cards in temp_deck and then adds the first
# few cards after that, finally appending the last card.

    if  number_of_cards != JOKER2 and number_of_cards != JOKER1:
        temp_deck += (deck[(number_of_cards):27])
        temp_deck += deck[0:(number_of_cards)]
        temp_deck.append(number_of_cards)

# If the last card is a Joker then this will use the value of
# JOKER1 and perform the commands above.

    else:
        number_of_cards = JOKER1
        temp_deck += (deck[(number_of_cards):27])
        temp_deck += deck[0:(number_of_cards)]
        temp_deck.append(deck[27])

# Once the temp_deck is created, this loop will transfer all
# the values in temp_deck to the original deck hence amending
# the deck according to the function.

    for item in range(len(deck)):
        deck[item]=temp_deck[item]

# This function finds the card at the position of the
# value of the first card in the deck and returns it.

def get_card_at_top_index(deck):
    """(list of int) -> int

    Return the card at the position of the value of
    the first card in the deck(deck).

    >>>get_card_at_top_index([1, 4, 7, 10, 13, 16, 19, 22, 25, 28,
    3, 6, 9, 12, 15, 18, 21, 24, 27, 2, 5, 8, 11, 14, 17, 20, 23, 26])
    4
    >>>get_card_at_top_index([19, 4, 7, 10, 13, 16, 1, 22, 25, 26, 3,
    6, 9, 12, 15, 18, 21, 24, 27, 2, 5, 8, 11, 14, 17, 20, 23, 28])
    2
    """
    val_card_1=deck[0]

    if (val_card_1 != JOKER2):
        return deck[val_card_1]
    elif (val_card_1 == JOKER2):
        val_card_1 = JOKER1
        return deck[val_card_1]

# This function gets the next keystream value.

def get_next_value(deck):
    """(list of int) -> int

    Return the keystream value for the next card in the deck.

    >>>deck=[1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 3, 6, 9, 12,
    15, 18, 21, 24, 27, 2, 5, 8, 11, 14, 17, 20, 23, 26]
    >>>get_next_value(deck)
    11
    >>>deck=[19, 4, 7, 10, 13, 16, 1, 22, 25, 26, 3, 6, 9, 12,
    15, 18, 21, 24, 27, 2, 5, 8, 11, 14, 17, 20, 23, 28]
    >>>get_next_value(deck)
    15
    """
    move_joker_1(deck)
    move_joker_2(deck)
    triple_cut(deck)
    insert_top_to_bottom(deck)
    return (get_card_at_top_index(deck))

# This function performs the algorithm to find the
# next keystream value within the given range.

def get_next_keystream_value(deck):
    """(list of int) -> int

    Return the next keystream value of the deck(deck) that
    is in the range of 0 to 27.

    >>>deck=[1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 3, 6, 9,
    12, 15, 18, 21, 24, 27, 2, 5, 8, 11, 14, 17, 20, 23, 26]
    >>>get_next_keystream_value(deck)
    18
    >>>get_next_keystream_value(deck)
    14
    """

# This while loop keeps on repeating all steps of the
# algorithm till the keystream value returned is within
# the range of 0 and 27.

    keystream_val = (get_next_value(deck))

    while ((keystream_val) <= 0) or ((keystream_val) >= 27):
        keystream_val = (get_next_value(deck))

    return (keystream_val)

# This function will encrypt or decrypt a message
# based on the users command.

def process_message(deck, message, encrypt_or_decrypt):
    """(list of int, str, str) -> str

    Return an encrypted or decrypted message based on the input.

    >>> deck=[1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 3, 6, 9,
    12, 15, 18, 21, 24, 27, 2, 5, 8, 11, 14, 17, 20, 23, 26]
    >>>process_message(deck, 'It does not do to dwell on dreams and forget to live.', 'e')
    'KILRUMFOUVJIGQONHVUSYNADYCPIMXWKIPJAJGVIL'
    >>>deck=[1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 3, 6, 9,
    12, 15, 18, 21, 24, 27, 2, 5, 8, 11, 14, 17, 20, 23, 26]
    >>>process_message(deck, 'AHGKHWHEFXNOJNXSSTKYQOIBQCPAZQPSWLPURNODP', 'd')
    'ITDOESNOTDOTODWELLONDREAMSANDFORGETTOLIVE'
    """
    encrypted=''
    decrypted=''

# If the user wants the system to encrypt the message, the
# system performs the algorithm, finds the keystream value,
# cleans the message and decrypts it.

    if (encrypt_or_decrypt == 'e'):
        message = clean_message(message)
        for letter in message:
            keystream_value=get_next_keystream_value(deck)
            encrypted = encrypted + str(encrypt_letter(letter, keystream_value))
        return encrypted

# If the user wants the system to decrypt the message, the
# system performs the algorithm again, finds the keystream
# value and decrypts the message.

    elif (encrypt_or_decrypt == 'd'):
        for letter in message:
            keystream_value = get_next_keystream_value(deck)
            decrypted = decrypted + str(decrypt_letter(letter , keystream_value))
        return decrypted

# This function decrypt and encrypts lists of messages.

def process_messages(deck, list_of_messages, encrypt_or_decrypt):
    """(list of int, list of str, str) -> list of str

    Return the encrypted or decrypted list of messages.

    >>>deck=[1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 3, 6, 9, 12,
    15, 18, 21, 24, 27, 2, 5, 8, 11, 14, 17, 20, 23, 26]
    >>>process_messages(deck, ['John', 'can', 'not', 'go', 'home'], 'e')
    ['BCKJ', 'FEH', 'DAN', 'FJ', 'CYNS']
    >>>deck=[1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 3, 6, 9, 12,
    15, 18, 21, 24, 27, 2, 5, 8, 11, 14, 17, 20, 23, 26]
    >>>process_messages(deck, ['BCKJ', 'FEH', 'DAN', 'FJ', 'CYNS'], 'd')
    ['JOHN', 'CAN', 'NOT', 'GO', 'HOME']

    """
    message_after_process = []
    for message in list_of_messages:
        message_after_process.append(process_message(deck, message, encrypt_or_decrypt))
    return (message_after_process)

# This function will open the mentioned file and add every
# line in the file as a string in the list.

def read_messages(open_file):
    """(file open for reading) -> list of str

    Return a list with each line of the opened file(open_file)
    as a string in the list.

    >>>file='/Users/siddharthgautam/Desktop/starter-2/message_file1.txt'
    >>>open_file=open(file, 'r')
    >>>read_messages(open_file)
    ['It does not do to dwell on dreams and forget to live.', 'Albus Dumbledore']
    >>>file='/Users/siddharthgautam/Desktop/starter-2/secret1.txt'
    >>>open_file=open(file, 'r')
    >>>read_messages(open_file)
    ['TCAVORYZALXEZDUJUFFFMHXXVPYHPYNRWWVHVJAHQ', 'BQRAUFQEYXOVOTU']
    """
    line=open_file.readline()
    list_of_messages = []
    while line != '':
        list_of_messages.append(line.strip('\n'))
        line=open_file.readline()
    return list_of_messages

# This function will read the deck and transfer
# every number in the deck to a list.

def read_deck(open_deck):
    """(file open for reading) -> list of int

    Return a list with each number in the deck file being a separate
    string in the list.

    >>>deck_file='/Users/siddharthgautam/Desktop/starter-2/deck1.txt'
    >>>open_deck=open(deck_file, 'r')
    >>>read_deck(open_deck)
    [1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 3, 6, 9, 12, 15,
    18, 21, 24, 27, 2, 5, 8, 11, 14, 17, 20, 23, 26]
    >>>deck_file='/Users/siddharthgautam/Desktop/starter-2/deck2.txt'
    >>>open_deck=open(deck_file, 'r')
    >>>read_deck(open_deck)
    [1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 3, 6, 9, 12, 15,
    18, 21, 24, 27, 2, 5, 8, 11, 14, 17, 20, 23, 26]
    """
    line = open_deck.readlines()
    list_of_integers = []
    number = ''
    for index in range(len(line)):
        for ch in line[index]:
            if (ch != ' ') and (ch !='\n') and (ch != ''):
                number += ch
            else:
                if number != '':
                    list_of_integers.append(int(number))
                number = ''
    return list_of_integers


import re
def top_3_words(text):
    string= re.sub(r' \'* ',' ', text.lower())
    string=re.sub(r'[^a-z|\']',' ', string).split(' ')
    arr=[]
    for i in string:
        if i!='':
            arr.append(i)
    dic={}
    for i in arr:
        if i in dic:
            dic[i]=dic[i]+1
        else:
            dic[i]=1

    return [key for key,value in sorted(dic.items(),key=lambda x: x[1],reverse=True) ][:3]

print(top_3_words(" '  ' //wont won't won't d d d"))

4kyu/Most frequently used words in a text/top_3_words.py


import pygame
import random

pygame.init()

WIDTH = 500
HEIGHT = 500
BG_COLOR = (125, 125, 125)
RED = (255, 0, 0)
ORANGE = (255, 125, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
COLORS = [RED, ORANGE]
FPS = 60

screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

all_sprites = pygame.sprite.Group()
bricks = pygame.sprite.Group()

score = 0
level = 0

score_time = None
run = True

class Brick(pygame.sprite.Sprite):
        def __init__(self, x, y, level):
                pygame.sprite.Sprite.__init__(self)
                self.x = x
                self.y = y
                self.color = COLORS[level]
                self.image = pygame.Surface((50, 20))
                self.image.fill(self.color)
                self.rect = self.image.get_rect()
                self.rect.topleft = (self.x, self.y)
                all_sprites.add(self)
                bricks.add(self)

        def update(self):
                global score
                if self.rect.colliderect(ball.rect):
                        ball.speedy *= -1
                        self.kill()
                        score += 1

class Ball(pygame.sprite.Sprite):
        def __init__(self):
                global score_time
                pygame.sprite.Sprite.__init__(self)
                self.image = pygame.image.load("ball.png")
                self.image = pygame.transform.scale(self.image, (30, 30))
                self.rect = self.image.get_rect()
                self.rect.center = (WIDTH / 2, HEIGHT / 2)
                all_sprites.add(self)
                self.speedx = 8
                self.speedy = -8

        def update(self):
                global run
                self.rect.x += self.speedx
                self.rect.y += self.speedy
                if self.rect.right >= WIDTH or self.rect.left <= 0:
                        self.speedx *= -1

                if self.rect.top <= 0:
                        self.speedy *= -1

                if self.rect.y > HEIGHT + 50:
                        print("YOU LOSE!")
                        run = False

        def wait(self):
                pygame.time.wait(3000)

class Paddle(pygame.sprite.Sprite):
        def __init__(self):
                pygame.sprite.Sprite.__init__(self)
                self.image = pygame.Surface((80, 20))
                self.image.fill((255, 255, 0))
                self.rect = self.image.get_rect()
                self.rect.center = (WIDTH / 2, HEIGHT - 50)
                self.speed = 0
                all_sprites.add(self)

        def update(self):

                self.rect.x += self.speed
                if self.rect.right >= WIDTH:
                        self.rect.right = WIDTH - 1
                if self.rect.left <= 0:
                        self.rect.left = 1

                if self.rect.top <= (ball.rect.bottom + 5) and ball.rect.left <= self.rect.right - 2 and ball.rect.right >= self.rect.left + 2:
                        ball.rect.y -= 10
                        ball.speedy *= -1

paddle = Paddle()
ball = Ball()
for column in range(7):
        brick = Brick(70 * column + 10, 30, level)

def wait():
        global score_time
        ball.rect.y = WIDTH / 3
        ball.rect.x = WIDTH / 2
        current_time = pygame.time.get_ticks()
        if current_time - score_time < 2100:
                ball.speedx = 0
                ball.speedy = 0
        else:
                ball.speedx = random.choice([-8, 8])
                ball.speedy = random.choice([-8, 8])
                score_time = None

while run:
        paddle.speed = 0
        clock.tick(FPS)
        keys = pygame.key.get_pressed()
        if keys[pygame.K_RIGHT]:
                paddle.speed = 12
        elif keys[pygame.K_LEFT]:
                paddle.speed = -12

        for event in pygame.event.get():
                if event.type == pygame.QUIT:
                        run = False
                        pygame.quit()
        if len(bricks) == 0:

                level += 1
                score_time = pygame.time.get_ticks()
                wait()
                if level == len(COLORS):
                        run = False
                        print("YOU WIN!")
                        break

                else:
                        for row in range(level + 1):
                                for column in range(7):
                                        brick = Brick(70 * column + 10,
                                                      30 + (row * 30), row)

        if score_time:
                wait()

        screen.fill(BG_COLOR)
        all_sprites.update()
        all_sprites.draw(screen)
        pygame.display.set_caption('Score: ' + str(score))
        pygame.display.flip()

pygame.quit()


"""Progress bar with a time estimation"""

import time

# pylint: disable=no-name-in-module
from qtpy.QtWidgets import QProgressBar

# pylint: enable=no-name-in-module

class ETAProgressBar(QProgressBar):
    """Progress bar with a time estimation"""

    def __init__(self, parent=None) -> None:
        self.start_time: float = None
        super().__init__(parent)

    def setValue(self, value: int) -> None:
        QProgressBar.setValue(self, value)
        if value == 0:
            value = 1
        if self.start_time is None:
            self.start_time = time.time()
        elapsed_time = time.time() - self.start_time
        eta = (self.maximum() - value) * elapsed_time / value
        eta_minutes, eta_seconds = divmod(eta, 60)
        eta_hours, eta_minutes = divmod(eta_minutes, 60)
        eta_str = (
            (f"{eta_hours:02.00f}:" if eta_hours > 0 else "")
            + (f"{eta_minutes:02.00f}:" if eta_minutes > 0 else "")
            + f"{eta_seconds:05.02f}"
            + ("s" if eta_hours == 0 and eta_minutes == 0 else "")
        )
        self.setFormat(f"{value/self.maximum()*100:.00f}% Estimated time: {eta_str}")

    def setMaximum(self, maximum: int) -> None:
        QProgressBar.setMaximum(self, maximum)
        self.start_time = None


import numpy as np
import matplotlib.pyplot as plt

if __name__ == '__main__':
    t = np.arange(0, np.pi * 10, 0.01)
    x = t * np.cos(t)
    y = t * np.sin(t)

    plt.plot(x, y, color="blue")
    plt.grid(True)
    plt.show()


# coding=utf-8
from models import Lesson, Homeworkcommit, Course, Studentcourse, Coursehomework
from school.models import Student
from constant import *
from django.http import HttpResponse
from django.core.urlresolvers import reverse
from django.shortcuts import redirect, render
import json
from course.auth import has_course_permission
from django.db.models import F
from django.conf import settings
from wechat.client import wechat_client
from course.tasks import send_homework_remind

def startLesson(request):
    lessondata = Lesson.objects.get(id=request.GET.get('lessonid'))
    if not has_course_permission(request.user, lessondata.course):
        if request.is_ajax():
            return HttpResponse(json.dumps({'error': 101, 'message': '没有权限'}), content_type="application/json")
        else:
            return render(request, 'error.html',
                          {'message': '没有权限'})
    if request.is_ajax():
        return HttpResponse(json.dumps(lessondata.startlesson()), content_type="application/json")
    else:
        re = lessondata.startlesson()
        if re['error'] != 0:
            return render(request, 'error.html',
                          {'message': re['message'],
                           'submessage': lessondata.course.title,
                           'jumpurl': str(
                               reverse('course:information', args=[lessondata.course.id]))})
        else:
            if request.GET.get('jumptocheckin', default=0) == '1':
                return redirect(reverse('checkin:startcheckin', args=[lessondata.id]))
            else:
                return redirect(reverse('checkin:lesson_data', args=[lessondata.id]))

def stopLesson(request):
    lessondata = Lesson.objects.get(id=request.GET.get('lessonid'))
    if not has_course_permission(request.user, lessondata.course):
        if request.is_ajax():
            return HttpResponse(json.dumps({'error': 101, 'message': '没有权限'}), content_type="application/json")
        else:
            return render(request, 'error.html',
                          {'message': '没有权限'})
    if request.is_ajax():
        return HttpResponse(json.dumps(lessondata.stoplesson()), content_type="application/json")
    else:
        re = lessondata.stoplesson()
        if re['error'] != 0:
            return render(request, 'error.html',
                          {'message': re['message'],
                           'submessage': lessondata.course.title,
                           'jumpurl': str(
                               reverse('course:information', args=[lessondata.course.id]))})
        else:
            return redirect(reverse('course:information', args=[lessondata.course.id]))

def clearLesson(request):
    lessondata = Lesson.objects.get(id=request.GET.get('lessonid'))
    if not has_course_permission(request.user, lessondata.course):
        if request.is_ajax():
            return HttpResponse(json.dumps({'error': 101, 'message': '没有权限'}), content_type="application/json")
        else:
            return render(request, 'error.html',
                          {'message': '没有权限'})
    if request.is_ajax():
        return HttpResponse(json.dumps(lessondata.cleardata()), content_type="application/json")
    else:
        re = lessondata.cleardata()
        if re['error'] != 0:
            return render(request, 'error.html',
                          {'message': re['message'],
                           'submessage': lessondata.course.title,
                           'jumpurl': str(
                               reverse('course:information', args=[lessondata.course.id]))})
        else:
            return redirect(reverse('course:information', args=[lessondata.course.id]))

def sethomeworkscore(request):
    homeworkcommit = Homeworkcommit.objects.select_related('coursehomework').get(id=request.GET.get('homeworkcommitid'))
    score = request.GET.get('score')
    if not score.isdigit():
        return HttpResponse(json.dumps({'error': 101, 'message': '分数只能设置为数字'}), content_type="application/json")
    if not has_course_permission(request.user, homeworkcommit.coursehomework.course):
        return HttpResponse(json.dumps({'error': 101, 'message': '没有权限'}), content_type="application/json")
    homeworkcommit.score = score
    homeworkcommit.save()
    return HttpResponse(json.dumps({'error': 0, 'score': score, 'message': '评分成功'}), content_type="application/json")

def leavehomeworkcomment(request):
    homeworkcommit = Homeworkcommit.objects.select_related('coursehomework').get(
        id=request.POST.get('homeworkcommitid'))
    comment = request.POST.get('comment', '')
    if comment == '':
        return HttpResponse(json.dumps({'error': 101, 'message': '留言不能为空'}), content_type="application/json")
    if not has_course_permission(request.user, homeworkcommit.coursehomework.course):
        return HttpResponse(json.dumps({'error': 101, 'message': '没有权限'}), content_type="application/json")
    homeworkcommit.comment = comment
    homeworkcommit.save()
    # send wechat notification
    article = {
        "title": u"作业留言提醒!",
        "description": u"教师留言：" + comment,
        "url": "%s%s" % (settings.DOMAIN, reverse('course:homework', args=[
            homeworkcommit.coursehomework.course_id]) + '?homeworkid=%d' % homeworkcommit.coursehomework_id),
        "image": "%s/static/img/homework.png"
    }
    wechat_client.message.send_articles(agent_id=settings.AGENTID, user_ids=[homeworkcommit.student.user.openid],
                                        articles=[article])
    return HttpResponse(json.dumps({'error': 0, 'message': '留言成功'}), content_type="application/json")

def setperformance_score(request, courseid):
    course = Course.objects.get(id=courseid)
    student = Student.objects.get(studentid=request.GET.get('studentid'))
    score = request.GET.get('score')
    if not has_course_permission(request.user, course):
        return HttpResponse(json.dumps({'error': 101, 'message': '没有权限'}), content_type="application/json")
    sc = Studentcourse.objects.get(student=student, course=course)
    sc.performance_score += int(score)
    sc.save()
    return HttpResponse(json.dumps({'error': 0, 'message': '加分成功', 'performance_score': sc.performance_score}),
                        content_type="application/json")

def remind_homework(request, homeworkid):
    homework = Coursehomework.objects.select_related('course').get(id=homeworkid)
    if not has_course_permission(request.user, homework.course):
        return HttpResponse(json.dumps({'error': 101, 'message': '没有权限'}), content_type="application/json")
    send_homework_remind.delay(homework.id)
    return HttpResponse(json.dumps({'error': 0, 'message': '催交成功'}), content_type="application/json")


import pandas as pd
import numpy as np
import time

import shapefile
import shapely
from shapely.geometry import Polygon
from shapely.geometry import Point
from rtree import index

from pandas.io.json import json_normalize
import json

##Get the data
#Public Data (some columns removed, loaded into msgpacks):
nyc_bldgs = pd.read_msgpack('nyc_bldgs')
nyc_crashes = pd.read_msgpack('nyc_crashes')
nyc_crime = pd.read_msgpack('nyc_crime')
phl_bldgs = pd.read_msgpack('phl_bldgs')
phl_crashes = pd.read_msgpack('phl_crashes')
phl_crime = pd.read_msgpack('phl_crime')

#foursquare data (CLIENT_ID and CLIENT_SECRET omitted, get from foursquare)
city_ll_box = {'New York':(-74.3, 40.45, -73.65, 40.95), 'Philadelphia':(-75.45,39.85,-74.85,40.15)}
def interp_grid(box, div):
    h_step = (box[2] - box[0])/div
    v_step = (box[3] - box[1])/div
    xs = np.arange(box[0], box[2], h_step)
    ys = np.arange(box[1], box[3], v_step)
    return np.meshgrid(xs, ys)

nyc_grid = interp_grid(city_ll_box['New York'], 100)
phl_grid = interp_grid(city_ll_box['Philadelphia'], 100)

nyc_grid = [k for k in zip(list(nyc_grid[0].flatten()),list(nyc_grid[1].flatten()))]
phl_grid = [k for k in zip(list(phl_grid[0].flatten()),list(phl_grid[1].flatten()))]

def geog_join(grid, shapefile_name):
    shapefile_instance = shapefile.Reader(shapefile_name+".shp")
    shapes = shapefile_instance.shapes()
    records = shapefile_instance.records()
    shape_points = [k.points for k in shapes]
    polygons = [Polygon(k) for k in shape_points]
    points = [Point(k) for k in grid]

    idx = index.Index()
    for k in range(len(shapes)):
        idx.insert(k, shapes[k].bbox)

    def get_name(n_idx):
        if n_idx == None: return None
        else: return records[n_idx][3]

    pt_nbhd = dict()
    for i in range(len(points)):
        temp = None
        for j in idx.intersection(grid[i]):
            if points[i].within(polygons[j]):
                temp=j
                break
        if temp != None: pt_nbhd[grid[i]] = get_name(temp)
    return pt_nbhd

nyc_nbhd_grid = geog_join(nyc_grid, 'ZillowNeighborhoods-NY')
phl_nbhd_grid = geog_join(phl_grid, 'ZillowNeighborhoods-PA')

CLIENT_ID = ""
CLIENT_SECRET = ""

def get_data(grid):
    relevant = []
    count = 0
    for pt in grid.keys():
        if count%10 == 0:
            time.sleep(5)
        url = "https://api.foursquare.com/v2/venues/search?"\
                "ll={},{}&"\
                "intent=browse&"\
                "radius=500&"\
                "limit=100&"\
                "client_id={}&"\
                "client_secret={}&"\
                "v=20170906".format(pt[1], pt[0], CLIENT_ID, CLIENT_SECRET)
        data = requests.get(url).json()['response']['venues']
        relevant.extend([(grid[pt],
                     k['name'],
                     k['location']['lat'],
                     k['location']['lng'],
                     k['categories'][0]['name']) for k in data if len(k['categories']) == 1])
        count += 1
    df = pd.DataFrame(relevant)
    df.columns = ['nbhd', 'venue', 'venue_lat', 'venue_lon', 'venue_cat']
    return(df)

phl_venues = get_data(phl_nbhd_grid)
nyc_venues = get_data(nyc_nbhd_grid)

##Clean up public data
#normalize labels
nyc_bldgs = nyc_bldgs.rename(columns = {'lon':'lng'})
nyc_crashes = nyc_crashes.rename(columns={'LATITUDE':'lat', 'LONGITUDE':'lng'})
nyc_crime = nyc_crime.rename(columns = {'Longitude':'lng', 'Latitude':'lat'})
phl_crashes = phl_crashes.rename(columns = {'LATITUDE':'lat', 'LONGITUDE':'lng'})

#dropna
nyc_bldgs = nyc_bldgs.dropna()
nyc_crashes = nyc_crashes.dropna()
nyc_crime = nyc_crime.dropna()
phl_bldgs = phl_bldgs.dropna()
phl_crashes = phl_crashes.dropna()
phl_crime = phl_crime.dropna()

#Label records with their neighborhood
def geog_join(df, shapefile_name):
    """
    df should be a pandas dataframe with columns labelled 'lat' and 'lng' for the latitude and longitude,
    shapefile_name is the name of the shapefile containing regions without extension.
    """
    point_coords=[(df['lng'][k], df['lat'][k]) for k in df.index]
    shapefile_instance = shapefile.Reader(shapefile_name+".shp")
    shapes = shapefile_instance.shapes()
    records = shapefile_instance.records()
    shape_points = [k.points for k in shapes]
    polygons = [Polygon(k) for k in shape_points]
    points = [Point(k) for k in point_coords]

    idx = index.Index()
    for k in range(len(shapes)):
        idx.insert(k, shapes[k].bbox)

    nbhd_idx = []
    for i in range(len(points)):
        temp = None
        for j in idx.intersection(point_coords[i]):
            if points[i].within(polygons[j]):
                temp=j
                break
        nbhd_idx.append(temp)

    def get_name(n_idx):
        if n_idx == None: return None
        else: return records[n_idx][3]

    nbhds = [get_name(k) for k in nbhd_idx]
    return nbhds

nyc_bldgs['nbhd'] = geog_join(nyc_bldgs, 'ZillowNeighborhoods-NY')
nyc_crashes['nbhd'] = geog_join(nyc_crashes, 'ZillowNeighborhoods-NY')
nyc_crime['nbhd'] = geog_join(nyc_crime, 'ZillowNeighborhoods-NY')
phl_bldgs['nbhd'] = geog_join(phl_bldgs, 'ZillowNeighborhoods-PA')
phl_crashes['nbhd'] = geog_join(phl_crashes, 'ZillowNeighborhoods-PA')
phl_crime['nbhd'] = geog_join(phl_crime, 'ZillowNeighborhoods-PA')

#standardize columns
nyc_bldgs['other_building'] = nyc_bldgs['numbldgs'].apply(lambda x: x>1)
nyc_bldgs = nyc_bldgs.drop('numbldgs', axis = 1)
nyc_bldgs = nyc_bldgs.rename(columns={'numfloors':'number_stories', 'yearbuilt':'year_built'})
nyc_bldgs = nyc_bldgs.drop('income15', axis=1)
nyc_bldgs = nyc_bldgs.dropna()

phl_bldgs['other_building'] = phl_bldgs['other_building'].apply(lambda x: x == 'Y')
phl_bldgs = phl_bldgs.dropna()

phl_bldgs = phl_bldgs[phl_bldgs['year_built'] != '196Y']
phl_bldgs['year_built'] = phl_bldgs['year_built'].astype(int)

nyc_crashes = nyc_crashes.rename(columns={'NUMBER OF PERSONS INJURED':'injured', 'NUMBER OF PERSONS KILLED':'killed'})

phl_crashes = phl_crashes.rename(columns={'FATAL_COUNT':'killed', 'INJURY_COUNT':'injured'})

nyc_crime = nyc_crime.rename(columns = {'OFNS_DESC':'description'})
nyc_crime_dict = {'CRIMINAL MISCHIEF & RELATED OF':'mischief', 'HARRASSMENT 2':'misc',
       'DANGEROUS DRUGS':'drugs', 'ROBBERY':'theft', 'UNAUTHORIZED USE OF A VEHICLE':'auto_theft',
       'OFFENSES AGAINST PUBLIC ADMINI':'misc', 'FELONY ASSAULT':'assault', 'FORGERY':'fraud',
       'ASSAULT 3 & RELATED OFFENSES':'assault', 'GRAND LARCENY':'theft',
       'OFFENSES AGAINST THE PERSON':'assault', 'GAMBLING':'gambling', 'PETIT LARCENY':'theft',
       'DANGEROUS WEAPONS':'weapons', 'INTOXICATED & IMPAIRED DRIVING':'dui',
       'VEHICLE AND TRAFFIC LAWS':'misc', 'OFF. AGNST PUB ORD SENSBLTY &':'mischief',
       'POSSESSION OF STOLEN PROPERTY':'possess', 'OTHER OFFENSES RELATED TO THEF':'theft',
       "BURGLAR'S TOOLS":'burglary', 'MISCELLANEOUS PENAL LAW':'misc', 'CRIMINAL TRESPASS':'misc',
       'OFFENSES INVOLVING FRAUD':'fraud', 'BURGLARY':'burglary',
       'MURDER & NON-NEGL. MANSLAUGHTER':'murder', 'THEFT-FRAUD':'fraud',
       'GRAND LARCENY OF MOTOR VEHICLE':'auto_theft', 'OTHER STATE LAWS (NON PENAL LA':'misc',
       'ADMINISTRATIVE CODE':'misc', 'FRAUDS':'fraud', 'SEX CRIMES':'rape', 'ARSON':'arson',
       'NYS LAWS-UNCLASSIFIED FELONY':'misc', 'OFFENSES AGAINST PUBLIC SAFETY':'misc',
       'FRAUDULENT ACCOSTING':'misc', 'KIDNAPPING & RELATED OFFENSES':'misc',
       'ALCOHOLIC BEVERAGE CONTROL LAW':'alcohol',
       'OTHER STATE LAWS (NON PENAL LAW)':'misc', 'JOSTLING':'misc', 'THEFT OF SERVICES':'theft',
       'PROSTITUTION & RELATED OFFENSES':'prostitution',
       'AGRICULTURE & MRKTS LAW-UNCLASSIFIED':'misc', 'ENDAN WELFARE INCOMP':'misc',
       'DISORDERLY CONDUCT':'mischief', 'NYS LAWS-UNCLASSIFIED VIOLATION':'misc', 'ESCAPE 3':'misc',
       'HOMICIDE-NEGLIGENT,UNCLASSIFIE':'manslaughter', 'PETIT LARCENY OF MOTOR VEHICLE':'auto_theft',
       'CHILD ABANDONMENT/NON SUPPORT':'child', 'OFFENSES RELATED TO CHILDREN':'child',
       'NEW YORK CITY HEALTH CODE':'misc', 'LOITERING/GAMBLING (CARDS, DIC':'gambling',
       'OTHER STATE LAWS':'misc', 'HOMICIDE-NEGLIGENT-VEHICLE':'manslaughter',
       'INTOXICATED/IMPAIRED DRIVING':'dui', 'KIDNAPPING':'misc',
       'ANTICIPATORY OFFENSES':'misc', 'DISRUPTION OF A RELIGIOUS SERV':'mischief'}
nyc_crime['description'] = nyc_crime['description'].apply(lambda x: nyc_crime_dict[x])

phl_crime = phl_crime.rename(columns = {'text_general_code':'description'})
phl_crime_dict = {'Other Assaults':'assault', 'Thefts':'theft', 'All Other Offenses':'misc', 'Fraud':'fraud',
       'Vandalism/Criminal Mischief':'mischief', 'DRIVING UNDER THE INFLUENCE':'dui',
       'Burglary Non-Residential':'burglary', 'Narcotic / Drug Law Violations':'drugs',
       'Burglary Residential':'burglary', 'Aggravated Assault No Firearm':'assault', 'Rape':'rape',
       'Robbery No Firearm':'theft', 'Weapon Violations':'weapons', 'Robbery Firearm':'theft',
       'Theft from Vehicle':'theft', 'Other Sex Offenses (Not Commercialized)':'rape',
       'Embezzlement':'fraud', 'Recovered Stolen Motor Vehicle':'possess',
       'Motor Vehicle Theft':'auto_theft', 'Disorderly Conduct':'mischief',
       'Aggravated Assault Firearm':'assault',
       'Prostitution and Commercialized Vice':'prostitution', 'Homicide - Criminal':'murder',
       'Forgery and Counterfeiting':'fraud', 'Homicide - Criminal ':'murder',
       'Public Drunkenness':'alcohol', 'Liquor Law Violations':'alcohol', 'Arson':'arson',
       'Vagrancy/Loitering':'misc', 'Receiving Stolen Property':'possess',
       'Offenses Against Family and Children':'child', 'Gambling Violations':'gambling',
       'Homicide - Gross Negligence':'manslaughter'}
phl_crime['description'] = phl_crime['description'].apply(lambda x: phl_crime_dict[x])

#cleaning
phl_crime = phl_crime[phl_crime['date-time']<pd.to_datetime('2017-07')]

phl_crime = phl_crime.dropna()
nyc_crime = nyc_crime.dropna()

#to counts
def to_counts(phl_df, nyc_df, col_name):
    phl_df = phl_df.groupby(['nbhd', col_name]).apply(len).unstack()
    nyc_df = nyc_df.groupby(['nbhd', col_name]).apply(len).unstack()
    out = pd.concat([phl_df, nyc_df], keys = ['Philadelphia', 'New York']).fillna(0)
    return out.groupby(out.index).sum()

story_ct = to_counts(phl_bldgs, nyc_bldgs, 'number_stories')
story_ct = pd.concat([story_ct.loc[:,k:k+0.9].sum(axis = 1) for k in range(91)], axis=1)
venue_ct = to_counts(phl_venues, nyc_venues, 'venue_cat')
age_ct = to_counts(phl_bldgs, nyc_bldgs, 'year_built').drop([0, 195, 1191], axis = 1)
kill_ct = to_counts(phl_crashes, nyc_crashes, 'killed')
inj_ct = to_counts(phl_crashes, nyc_crashes, 'injured')
crime_ct = to_counts(phl_crime, nyc_crime, 'offense_class')

nbhd_ct_table = pd.concat([story_ct, age_ct, kill_ct, inj_ct, crime_ct, venue_ct],
    keys = ['stories', 'ages', 'deaths', 'injuries', 'crimes', 'venues'], axis=1).fillna(0)

nbhd_ct_table.to_msgpack('nbhd_ct_table')
nyc_bldgs.to_msgpack('nyc_bldgs_clean')
nyc_crime.to_msgpack('nyc_crime_clean')
nyc_crashes.to_msgpack('nyc_crashes_clean')
nyc_venues.to_msgpack('nyc_venues_clean')
phl_bldgs.to_msgpack('phl_bldgs_clean')
phl_crime.to_msgpack('phl_crime_clean')
phl_crashes.to_msgpack('phl_crashes_clean')
phl_venues.to_msgpack('phl_venues_clean')


import pandas as pd
import statsmodels.api as sm
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
from sklearn.linear_model import LinearRegression

from statsmodels.stats.diagnostic import linear_rainbow
from scipy.stats import shapiro
from sklearn.model_selection import train_test_split
from statsmodels.stats.diagnostic import het_goldfeldquandt

url = "https://raw.githubusercontent.com/Alyssasorensen/datasci_7_regressions/main/datasets/U.S._Chronic_Disease_Indicators__CDI_%20(2).csv"
df = pd.read_csv(url)
df

### Dependent Variable: DataValue
## This variable represents the value of a particular metric or measurement. It can be considered the dependent variable because it's the value that you might want to predict or analyze in relation to other factors.

### Independent Variable: YearStart
## YearStart is a numerical variable that represents the starting year of a data record. It can be considered the independent variable in this context because it can be used to analyze how the dependent variable (DataValue) changes over different years.

# Filter the dataset to keep only the relevant columns
df = df[['YearStart', 'DataValue']]

# Drop rows with missing values
df.dropna(inplace=True)

X = df[['YearStart']]
y = df['DataValue']

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

regressor = LinearRegression()
regressor.fit(X_train, y_train)

y_pred = regressor.predict(X_test)
y_pred

plt.figure(figsize=(10, 6))
plt.scatter(X_test, y_test, color='blue', label='Actual Data Points')
plt.plot(X_test, y_pred, color='red', linewidth=2, label='Regression Line')
plt.title('Simple Linear Regression')
plt.xlabel('YearStart')
plt.ylabel('DataValue')
plt.legend()
plt.show()

# Check linearity (scatterplot)
plt.figure(figsize=(10, 6))
sns.scatterplot(x=X_test['YearStart'], y=y_test)
plt.title('Linearity Check')
plt.xlabel('YearStart')
plt.ylabel('DataValue')
plt.show()

# Check independence of errors (residual plot)
residuals = y_test - y_pred
plt.figure(figsize=(10, 6))
sns.residplot(x=X_test['YearStart'], y=residuals, lowess=True, line_kws={'color': 'red'})
plt.title('Residual Plot for Independence of Errors')
plt.xlabel('YearStart')
plt.ylabel('Residuals')
plt.show()

# Check constant variance (homoscedasticity)
plt.figure(figsize=(10, 6))
sns.scatterplot(x=y_pred, y=residuals)
plt.title('Homoscedasticity Check')
plt.xlabel('Predicted Values')
plt.ylabel('Residuals')
plt.show()

# Check normality of errors (Q-Q plot)
import scipy.stats as stats
plt.figure(figsize=(10, 6))
stats.probplot(residuals, dist="norm", plot=plt)
plt.title('Normality of Residuals (Q-Q Plot)')
plt.show()


#array is sorted
#index1 < index2
#index starts from 1 and not 0

class Solution:
    def twoSum2(self, numbers, target):
        """
        Input: numbers = [2,7,11,15], target = 9
            Output: [1,2]
            Explanation: The sum of 2 and 7 is 9. Therefore index1 = 1, index2 = 2.
        """
        start = 0
        end = len(numbers)-1
        #binary search
        while(start<=end):
            if numbers[start]+numbers[end]<target:
                start+=1
            elif numbers[start]+numbers[end]>target:
                end-=1
            else:
                return[start+1, end+1]

test = Solution()
print(test.twoSum2([1,2,3,4],4))


from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.service import Service
from selenium.common.exceptions import NoSuchElementException,ElementClickInterceptedException
import pandas as pd
import requests

webdriver_path = 'geckodriver'
firefox_options = Options()
firefox_options.add_argument('--headless')
firefox_options.add_argument('--no-sandbox')
firefox_options.add_argument('disable-infobars')
firefox_options.add_argument("--disable-extensions")
driver = webdriver.Firefox(service=Service(webdriver_path), options=firefox_options)
driver2 = webdriver.Firefox(service=Service(webdriver_path), options=firefox_options)

url = 'https://www.gazeta.uz/oz/list/news?page='

dataset = pd.DataFrame({"title":[""],"content":[""],"category":["news"]})

for page in range(1,1670):
    print('page : ',page)
    print(url+str(page))
    driver.get(url+str(page))

    html_content = driver.page_source
    soup = BeautifulSoup(html_content, "html.parser")
    title_items = soup.find_all("div",class_="nt")

    if len(title_items) < 1:
        continue

    for sub_page in title_items:

        title = sub_page.find_all('a')[0].get_text()

        sub_page_link = "https://www.gazeta.uz" + sub_page.find_all('a')[0]['href']
        print(sub_page_link)
        driver2.get(sub_page_link)
        sub_request = driver2.page_source
        soup_sub = BeautifulSoup(sub_request, "html.parser")
        con = soup_sub.find_all("div",class_="js-mediator-article article-text")

        if len(con) < 1:
            continue
        content = con[0].get_text()[1:]

        new_row = pd.DataFrame({'title':[title], 'content':[content],"category":["news"]})
        dataset = pd.concat([dataset, new_row], ignore_index=True)

dataset = dataset.drop_duplicates(subset=['content'],ignore_index=True)
dataset.to_csv('gazeta_uz.csv', index=False)


from django import template
from django.utils.translation import ugettext as _
from django.utils import safestring
from django.template.defaultfilters import stringfilter
import re
import random
import json as jsonlib

register = template.Library()

@register.filter
def likerttext(value):
    likertdict = { -3: "Strongly oppose",
                   -2: "Moderately oppose",
                   -1: "Slightly oppose",
                    0: "Neither support nor oppose",
                    1: "Slightly support",
                    2: "Moderately support",
                    3: "Strongly support"}
    return likertdict.get(value)

@register.filter
def ordinalhtml(value):
    """
    Converts an integer to its ordinal as HTML. 1 is '1st',
    and so on.
    """
    try:
        value = int(value)
    except ValueError:
        return value
    t = (_('th'), _('st'), _('nd'), _('rd'), _('th'), _('th'), _('th'), _('th'), _('th'), _('th'))
    if value % 100 in (11, 12, 13): # special case
        return safestring.mark_safe("%d%s" % (value, t[0]))
    return safestring.mark_safe('%d%s' % (value, t[value % 10]))

@register.filter(is_safe=True)
@stringfilter
def markdown(value):
    # Renders the string using CommonMark in safe mode, which blocks
    # raw HTML in the input and also some links using a blacklist,
    # plus a second pass filtering using a whitelist for allowed
    # tags and URL schemes.

    import cmarkgfm
    from cmarkgfm.cmark import Options as cmarkgfmOptions

    html = cmarkgfm.github_flavored_markdown_to_html(value, options=cmarkgfmOptions.CMARK_OPT_SAFE)

    import html5lib, urllib.parse
    def filter_url(url):
        try:
            urlp = urllib.parse.urlparse(url)
        except Exception as e:
            # invalid URL
            return None
        if urlp.scheme not in ("http", "https"):
            return None
        return url
    valid_tags = set('strong em a code p h1 h2 h3 h4 h5 h6 pre br hr img ul ol li span blockquote'.split())
    valid_tags = set('{http://www.w3.org/1999/xhtml}' + tag for tag in valid_tags)
    dom = html5lib.HTMLParser().parseFragment(html)
    for node in dom.iter():
        if node.tag not in valid_tags and node.tag != 'DOCUMENT_FRAGMENT':
            node.tag = '{http://www.w3.org/1999/xhtml}span'
        for name, val in list(node.attrib.items()):
            if name.lower() in ("href", "src"):
                val = filter_url(val)
                if val is None:
                    node.attrib.pop(name)
                else:
                    node.set(name, val)
            else:
                # No other attributes are permitted.
                node.attrib.pop(name)

    # If there is an h1 in the output, demote all of the headings
    # so we don't create something that interfere's with the page h1.
    hash1 = False
    for node in dom.iter():
      if node.tag in ("h1", "{http://www.w3.org/1999/xhtml}h1"):
        hash1 = True
    if hash1:
      for node in dom.iter():
        m = re.match("(\{http://www.w3.org/1999/xhtml\})?h(\d)$", node.tag)
        if m:
          node.tag = (m.group(1) or "") + "h" + str(int(m.group(2))+1)

    html = html5lib.serialize(dom, quote_attr_values="always", omit_optional_tags=False, alphabetical_attributes=True)

    return safestring.mark_safe(html)

@register.filter(is_safe=True)
def json(value):
    return safestring.mark_safe(jsonlib.dumps(value))

@register.filter(is_safe=True)
@stringfilter
def stripfinalperiod(value):
    if value.endswith("."):
        value = value[:-1]
    return value

@register.filter
def mult(value, operand):
    return float(value) * float(operand)

@register.filter
def div(value, operand):
    return float(value) / float(operand)


"""
383.赎金信
https://leetcode.cn/problems/ransom-note/
给你两个字符串：ransomNote和magazine，
判断ransomNote能不能由magazine里面的字符构成。
如果可以，返回true；否则返回false。
magazine中的每个字符只能在ransomNote中使用一次。
"""
import collections

def canConstruct(self, ransomNote: str, magazine: str) -> bool:

        if set(ransomNote) > set(magazine):
            return False

        magazine_count = collections.Counter(magazine)
        ransomNote_count = collections.Counter(ransomNote)

        for i, j in ransomNote_count.items():
            if j > magazine_count[i]:
                return False

        return True


import pandas as pd
import matplotlib.pyplot as plt

xrd = pd.read_csv('LCCu1.txt', skipinitialspace=True, skiprows=134)
xrd.dropna(axis=1, inplace=True)

fig, ax = plt.subplots()
ax.plot(xrd['Angle'], xrd['Det1Disc1'], label='experimental data')
plt.legend()
plt.show()


#####################################################
# Introspective Variational Autoencoder Config File #
#####################################################
# A Brock, 2016
import numpy as np
import matplotlib.pyplot as plt

from keras.utils.visualize_util import plot
from keras.models import Model
from keras import backend as K
from keras import objectives
from keras.datasets import mnist

from keras.models import load_model

from keras.layers import Input, Dense, Convolution2D, MaxPooling2D, UpSampling2D,Lambda
from keras.layers.core import Dense, Dropout, Flatten, Reshape

K.set_image_dim_ordering('tf')

class VAE:

    # Start with a low learning rate then increase learning rate on second epoch
    # lr_schedule = {0: 0.0001, 1: 0.005}
    # Configuration Dictionary
    cfg = {'batch_size': 100,
           # 'learning_rate': lr_schedule,
           'reg': 0.001,
           'momentum': 0.9,
           'input_dim': (28, 28),
           'n_channels': 1,
           'n_classes': 10,
           'max_epochs': 50,
           'latent_dim': 2,
           'intermediate_dim': 32,
           }
    data = []
    enc_dec =[]
    enc =[]
    dec =[]
    rmnist = []

    if K.image_dim_ordering() == 'tf':
        original_img_size = (28, 28, 1)
    else:
        original_img_size = (1, 28, 28)

    def __init__(self):
        self.enc_dec = self.get_model()

    def get_data(self,db='mnist'):
        if db=='mnist':
            (x_train, y_train), (x_test, y_test) = mnist.load_data()
            (x_train, y_train), (x_test, y_test) = mnist.load_data()
            x_train = x_train.astype('float32') / 255.
            x_train = x_train.reshape((x_train.shape[0],) + self.original_img_size)
            x_test = x_test.astype('float32') / 255.
            x_test = x_test.reshape((x_test.shape[0],) + self.original_img_size)
            x_train[x_train < 0.5] = 0
            x_train[x_train >= 0.5] = 1
            x_test[x_test < 0.5] = 0
            x_test[x_test >= 0.5] = 1

            self.data = {
                'x_train': x_train,
                'y_train': y_train,
                'x_test': x_test,
                'y_test': y_test
            }
        else:
            raise AssertionError('db missing now')
        print('loading training data done')

    def get_model(self,interp=False):

        if interp:
            batch_size = self.cfg['batch_size']
            original_dim = np.prod(self.original_img_size)
            latent_dim = self.cfg['latent_dim']
            intermediate_dim = 256
            epsilon_std = 0.01

            x = Input(batch_shape=(batch_size, original_dim))
            h = Dense(intermediate_dim, activation='sigmoid')(x)
            z_mean = Dense(latent_dim)(h)
            z_log_var = Dense(latent_dim)(h)

            def sampling(args):
                z_mean, z_log_var = args
                epsilon = K.random_normal(shape=(batch_size, latent_dim), mean=0.,
                                          std=epsilon_std)
                return z_mean + K.exp(z_log_var / 2) * epsilon

            # note that "output_shape" isn't necessary with the TensorFlow backend
            z = Lambda(sampling, output_shape=(latent_dim,))([z_mean, z_log_var])

            # we instantiate these layers separately so as to reuse them later
            decoder_h = Dense(intermediate_dim, activation='sigmoid')
            decoder_mean = Dense(original_dim, activation='sigmoid')
            h_decoded = decoder_h(z)
            x_decoded_mean = decoder_mean(h_decoded)

            def vae_loss(x, x_decoded_mean):
                xent_loss = original_dim * objectives.binary_crossentropy(x, x_decoded_mean)
                kl_loss = - 0.5 * K.sum(1 + z_log_var - K.square(z_mean) - K.exp(z_log_var), axis=-1)
                return xent_loss + kl_loss

            vae = Model(x, x_decoded_mean)
            vae.compile(optimizer='adadelta', loss=vae_loss)
        else:
            batch_size = 100
            original_dim = 28 * 28
            latent_dim = 2
            # nb_epoch = 50

            if K.image_dim_ordering() == 'tf':
                x = Input(shape=(28, 28, 1))
            else:
                x = Input(shape=(1, 28, 28))
            # h = Flatten()(x)
            # x = Input(batch_shape=(batch_size, original_dim))
            # h = Reshape((1,28,28))(x)
            encode_h1 = Convolution2D(16, 3, 3, activation='relu', border_mode='same')
            encode_h2 = MaxPooling2D((2, 2), border_mode='same')
            encode_h3 = Convolution2D(32, 3, 3, activation='relu', border_mode='same')
            encode_h4 = MaxPooling2D((2, 2), border_mode='same')
            encode_h5 = Convolution2D(64, 3, 3, activation='relu', border_mode='same')
            encode_h6 = MaxPooling2D((2, 2), border_mode='same')

            h = encode_h1(x)
            h = encode_h2(h)
            h = encode_h3(h)
            h = encode_h4(h)
            h = encode_h5(h)
            h = encode_h6(h)

            h = Flatten()(h)
            z_mean = Dense(latent_dim)(h)
            z_log_var = Dense(latent_dim)(h)
            encoder = Model(x, z_mean)

            def sampling(args):
                z_mean, z_log_var = args
                epsilon = K.random_normal(shape=(batch_size, latent_dim), mean=0.)
                return z_mean + K.exp(z_log_var / 2) * epsilon

            # note that "output_shape" isn't necessary with the TensorFlow backend
            z = Lambda(sampling, output_shape=(latent_dim,))([z_mean, z_log_var])

            # we instantiate these layers separately so as to reuse them later

            decoder_h1 = Dense(64 * 4 * 4, activation='relu')
            if K.image_dim_ordering() == 'tf':
                decoder_h2 = Reshape((4, 4, 64))
            else:
                decoder_h2 = Reshape((64, 4, 4))
            decoder_h3 = Convolution2D(64, 3, 3, activation='relu', border_mode='same')
            decoder_h4 = UpSampling2D((2, 2))
            decoder_h5 = Convolution2D(32, 3, 3, activation='relu', border_mode='same')
            decoder_h6 = UpSampling2D((2, 2))
            decoder_h7 = Convolution2D(16, 3, 3, activation='relu', border_mode='same')
            decoder_h8 = UpSampling2D((2, 2))
            decoder_h9 = Convolution2D(1, 5, 5, activation='sigmoid', border_mode='valid')

            # g_input = Input(shape=[2])
            H = decoder_h1(z)
            H = decoder_h2(H)
            H = decoder_h3(H)
            H = decoder_h4(H)
            H = decoder_h5(H)
            H = decoder_h6(H)
            H = decoder_h7(H)
            H = decoder_h8(H)
            g_V = decoder_h9(H)

            # def g2b(g_V):
            #     '''grey value to binary'''
            #     return K.round(g_V)
            # g_V = Lambda(g2b, output_shape=g_V._keras_shape[1:4])(g_V)

            def vae_loss(x, g_V):
                xent_loss = original_dim * K.mean(objectives.binary_crossentropy(x, g_V))
                kl_loss = - 0.5 * K.sum(1 + z_log_var - K.square(z_mean) - K.exp(z_log_var), axis=-1)
                return xent_loss + kl_loss

            vae = Model(x, g_V)
            # keras.optimizers.RMSprop(lr=0.001, rho=0.9, epsilon=1e-08, decay=0.0)
            vae.compile(optimizer='rmsprop', loss=vae_loss)

            vae.summary()

            return vae

    def train_vae(self):
        x_train = self.data['x_train']
        x_test = self.data['x_test']
        self.enc_dec.fit(x_train, x_train,
                shuffle=True,
                nb_epoch=self.cfg['max_epochs'],
                batch_size=self.cfg['batch_size'],
                validation_data=(x_test, x_test))

    def encoder(self):
        # load from trained vae model
        x = Input(shape=self.original_img_size)
        h = x
        for i in range(1,9):
            h = self.enc_dec.layers[i](h)

        return Model(x, h)

    def decoder(self):
        # load from trained vae model
        x = Input(shape=(self.cfg['latent_dim'],))
        h = x
        for i in range(11,20):
            h = self.enc_dec.layers[i](h)
        return Model(x, h)

    def input2latent(self):
        # display a 2D plot of the digit classes in the latent space
        encoder = vae.encoder()
        x_test_encoded = encoder.predict(self.data['x_test'], batch_size=self.data['batch_size'])
        plt.figure(figsize=(6, 6))
        plt.scatter(x_test_encoded[:, 0], x_test_encoded[:, 1], c=self.data['y_test'])
        plt.colorbar()
        plt.show()

    def latent2output(self):
        # display a 2D manifold of the digits
        n = 15  # figure with 15x15 digits
        digit_size = 28
        figure = np.zeros((digit_size * n, digit_size * n))
        # we will sample n points within [-15, 15] standard deviations
        grid_x = np.linspace(-0.2, 0.2, n)
        grid_y = np.linspace(-0.2, 0.2, n)

        decoder = vae.decoder()
        for i, yi in enumerate(grid_x):
            for j, xi in enumerate(grid_y):
                z_sample = np.array([[xi, yi]])
                x_decoded = decoder.predict(z_sample)
                digit = x_decoded[0].reshape(digit_size, digit_size)
                figure[i * digit_size: (i + 1) * digit_size,
                j * digit_size: (j + 1) * digit_size] = digit

        plt.figure(figsize=(10, 10))
        plt.imshow(figure)
        plt.show(block=True)

    def reconstruction(self):
        dec = self.decoder()
        enc = self.encoder()
        n = 20
        data = self.data['x_train'][0:n]
        enc_x = enc.predict(data)
        rec_x = dec.predict(enc_x)

        plt.figure(figsize=(20, 4))
        for i in range(n):
            # display original
            ax = plt.subplot(2, n, i+1)
            plt.imshow(data[i].reshape(28, 28), cmap='Greys',interpolation='nearest')
            ax.get_xaxis().set_visible(False)
            ax.get_yaxis().set_visible(False)
            ax = plt.subplot(2, n, i + n+1)

            # display reconstruction
            plt.imshow(rec_x[i].reshape(28, 28), cmap='Greys',interpolation='nearest')
            ax.get_xaxis().set_visible(False)
            ax.get_yaxis().set_visible(False)
        plt.show()
        return rec_x

    def saliency(self):
        '''get saliency info'''
        y_train = self.data['y_train']
        oneidx = np.where(y_train == 1)
        rmnist_train = np.zeros((oneidx[0].shape[0], self.cfg['input_dim'][0], self.cfg['input_dim'][1], 1))
        bmnist_train = np.zeros((oneidx[0].shape[0], self.cfg['input_dim'][0], self.cfg['input_dim'][1], 1))
        for idx,idxx in enumerate(oneidx[0]):
            data = self.data['x_train'] [idxx,:,:,0] # only one channel
            cmax = 1.0
            for ypos in range(28):
                if (data[ypos] == 1).any():
                    d = ypos
                    break
            for ypos in range(d, 28):
                if (data[ypos] == 1).any():
                    xpos = np.where(data[ypos] == 1)
                    tmp = cmax - 10.0/255.0 * (ypos - d)
                    for jdx in xpos[0]:
                        rmnist_train[idx,ypos,jdx,0] = tmp
                        bmnist_train[idx,ypos,jdx,0] = 1

        y_test = self.data['y_test']
        oneidx = np.where(y_test == 1)
        rmnist_test = np.zeros((oneidx[0].shape[0], self.cfg['input_dim'][0], self.cfg['input_dim'][1], 1))
        bmnist_test = np.zeros((oneidx[0].shape[0], self.cfg['input_dim'][0], self.cfg['input_dim'][1], 1))
        for idx,idxx in enumerate(oneidx[0]):
            data = self.data['x_test'] [idxx,:,:,0] # only one channel
            cmax = 1.0
            for ypos in range(28):
                if (data[ypos] == 1).any():
                    d = ypos
                    break
            for ypos in range(d, 28):
                if (data[ypos] == 1).any():
                    xpos = np.where(data[ypos] == 1)
                    tmp = cmax - 10.0/255.0 * (ypos - d)
                    for jdx in xpos[0]:
                        rmnist_test[idx,ypos,jdx,0] = tmp
                        bmnist_test[idx,ypos,jdx,0] = 1
        return{
            'bmnist_train': bmnist_train,
            'bmnist_test': bmnist_test,
            'rmnist_train': rmnist_train,
            'rmnist_test': rmnist_test
        }

    def sal_dec(self):
        data = self.saliency()

        sal = self.decoder()
        sal.compile(optimizer='rmsprop', loss='binary_crossentropy')
        sal.summary()

        encoder = self.encoder()
        enc_x_train = encoder.predict(data['bmnist_train'])
        enc_x_test = encoder.predict(data['bmnist_test'])

        sal.fit(enc_x_train, data['rmnist_train'],
                 shuffle=True,
                 nb_epoch=self.cfg['max_epochs'],
                 batch_size=self.cfg['batch_size'],
                 validation_data=(enc_x_test, data['rmnist_test']))

        n = 5
        binput = data['bmnist_train'][0:n,:,:,:]
        routput = sal.predict(encoder.predict(binput))
        plt.figure(figsize=(20, 4))
        for i in range(n):
            # display original
            ax1 = plt.subplot(2, n, i + 1)
            plt.imshow(binput[i,:,:,0].reshape(28, 28),cmap='Greys',interpolation='nearest')
            ax1.get_xaxis().set_visible(False)
            ax1.get_yaxis().set_visible(False)
            # display sal prediction
            ax2 = plt.subplot(2, n, i + 1 + n)
            plt.imshow(routput[i,:,:,0].reshape(28, 28),cmap='Greys',interpolation='nearest')
            ax2.get_xaxis().set_visible(False)
            ax2.get_yaxis().set_visible(False)
        plt.show(block=True)

        binput = data['bmnist_test'][0:n, :, :, :]
        routput = sal.predict(encoder.predict(binput))
        plt.figure(figsize=(20, 4))
        for i in range(n):
            # display original
            ax1 = plt.subplot(2, n, i + 1)
            plt.imshow(binput[i, :, :, 0].reshape(28, 28), cmap='Greys',interpolation='nearest')
            ax1.get_xaxis().set_visible(False)
            ax1.get_yaxis().set_visible(False)
            # display sal prediction
            ax2 = plt.subplot(2, n, i + 1 + n)
            plt.imshow(routput[i, :, :, 0].reshape(28, 28), cmap='Greys',interpolation='nearest')
            ax2.get_xaxis().set_visible(False)
            ax2.get_yaxis().set_visible(False)
        plt.show(block=True)

if 1:
    vae = VAE()
    vae.get_data()
    vae.train_vae()
    #
    #
    # plot(vae.enc_dec, to_file='model.png')
    # vae.enc_dec.save('enc_dec.h5')  # creates a HDF5 file 'my_model.h5'
    #
    vae.reconstruction()

    vae.sal_dec()

else:
    vae = VAE()
    vae.get_data()

    load_model('my_model.h5')
    vae.enc = vae.encoder()
    vae.dec = vae.decoder()

    vae.latent2output()

    vae.reconstruction()


"""
Constants values used in schemas functions.
"""
import pulp as pl
from ortools.sat.python import cp_model

STRING_TYPE = "String"
BOOLEAN_TYPE = "Boolean"
INTEGER_TYPE = "Integer"
FLOAT_TYPE = "Float"
BASIC_TYPES = [STRING_TYPE, BOOLEAN_TYPE, INTEGER_TYPE, FLOAT_TYPE]

JSON_TYPES = {
    "string": STRING_TYPE,
    "number": FLOAT_TYPE,
    "integer": INTEGER_TYPE,
    "null": None,
    "boolean": BOOLEAN_TYPE,
}

DATASCHEMA = "DataSchema"

INSTANCE_SCHEMA = "instance"
SOLUTION_SCHEMA = "solution"
CONFIG_SCHEMA = "config"

# why it stopped
STATUS_NOT_SOLVED = 0
STATUS_OPTIMAL = 1
STATUS_INFEASIBLE = -1
STATUS_UNBOUNDED = -2
STATUS_UNDEFINED = -3
STATUS_FEASIBLE = 2
STATUS_MEMORY_LIMIT = 3
STATUS_NODE_LIMIT = 4
STATUS_TIME_LIMIT = -4
STATUS_LICENSING_PROBLEM = -5

# is there a solution?
SOLUTION_STATUS_INFEASIBLE = 0
SOLUTION_STATUS_FEASIBLE = 2

PYOMO_STOP_MAPPING = {
    "unbounded": STATUS_UNBOUNDED,
    "infeasible": STATUS_INFEASIBLE,
    "invalidProblem": STATUS_NOT_SOLVED,
    "solverFailure": STATUS_NOT_SOLVED,
    "internalSolverError": STATUS_NOT_SOLVED,
    "error": STATUS_NOT_SOLVED,
    "userInterrupt": STATUS_NOT_SOLVED,
    "resourceInterrupt": STATUS_NOT_SOLVED,
    "licensingProblem": STATUS_LICENSING_PROBLEM,
    "maxTimeLimit": STATUS_TIME_LIMIT,
    "maxIterations": STATUS_TIME_LIMIT,
    "maxEvaluations": STATUS_TIME_LIMIT,
    "globallyOptimal": STATUS_OPTIMAL,
    "locallyOptimal": STATUS_OPTIMAL,
    "optimal": STATUS_OPTIMAL,
    "minFunctionValue": STATUS_UNDEFINED,
    "minStepLength": STATUS_UNDEFINED,
    "other": STATUS_UNDEFINED,
}

PYOMO_STATUS_MAPPING = {
    "ok": SOLUTION_STATUS_FEASIBLE,
    "warning": SOLUTION_STATUS_FEASIBLE,
    "error": SOLUTION_STATUS_INFEASIBLE,
    "aborted": SOLUTION_STATUS_INFEASIBLE,
    "unknown": SOLUTION_STATUS_INFEASIBLE,
}

ORTOOLS_STATUS_MAPPING = {
    cp_model.OPTIMAL: STATUS_OPTIMAL,
    cp_model.FEASIBLE: STATUS_FEASIBLE,
    cp_model.INFEASIBLE: STATUS_INFEASIBLE,
    cp_model.UNKNOWN: STATUS_UNDEFINED,
    cp_model.MODEL_INVALID: STATUS_UNDEFINED,
}

PULP_STATUS_MAPPING = {
    pl.LpStatusInfeasible: STATUS_INFEASIBLE,
    pl.LpStatusNotSolved: STATUS_NOT_SOLVED,
    pl.LpStatusOptimal: STATUS_OPTIMAL,
    pl.LpStatusUnbounded: STATUS_UNBOUNDED,
    pl.LpStatusUndefined: STATUS_UNDEFINED,
}

class InvalidUsage(Exception):
    status_code = 400
    error = "Unknown error"

    def __init__(self, error=None, status_code=None, payload=None):
        Exception.__init__(self)
        if error is not None:
            self.error = error
        if status_code is not None:
            self.status_code = status_code
        self.payload = payload

    def to_dict(self):
        rv = dict(self.payload or ())
        rv["error"] = self.error
        return rv

class AirflowError(InvalidUsage):
    status_code = 400

    def __init__(self, error, status_code=None, payload=None):
        self.error = error
        self.payload = payload
        if status_code is not None:
            self.status_code = status_code

class NoSolverException(Exception):
    pass

class BadConfiguration(Exception):
    pass

class BadInstance(Exception):
    pass

class BadSolution(Exception):
    pass


import pytest
from io import BytesIO

from flask_annex import Annex

from .helpers import AbstractTestAnnex, assert_key_value, get_upload_info

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

@pytest.fixture
def file_annex_path(tmpdir):
    return tmpdir.join("annex").mkdir().strpath

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

class TestFileAnnex(AbstractTestAnnex):
    @pytest.fixture
    def annex_base(self, file_annex_path):
        return Annex("file", file_annex_path)

    def test_save_file_existing_dir(self, annex):
        annex.save_file("foo/qux.txt", BytesIO(b"6\n"))
        assert_key_value(annex, "foo/qux.txt", b"6\n")

    def test_send_file(self, client):
        response = client.get("/files/foo/baz.json")
        assert response.status_code == 200
        assert response.mimetype == "application/json"
        assert "attachment" in response.headers["Content-Disposition"]

    def test_get_upload_info(self, client):
        upload_info = get_upload_info(client, "foo/qux.txt")
        assert upload_info == {
            "method": "PUT",
            "url": "http://localhost/files/foo/qux.txt",
            "headers": {
                "Authorization": None,
            },
        }

    def test_get_upload_info_authorized(self, client):
        upload_info = get_upload_info(
            client,
            "foo/qux.txt",
            headers={
                "Authorization": "Bearer foo",
            },
        )
        assert upload_info == {
            "method": "PUT",
            "url": "http://localhost/files/foo/qux.txt",
            "headers": {
                "Authorization": "Bearer foo",
            },
        }

class TestFileAnnexFromEnv(TestFileAnnex):
    @pytest.fixture
    def annex_base(self, monkeypatch, file_annex_path):
        monkeypatch.setenv("FLASK_ANNEX_STORAGE", "file")
        monkeypatch.setenv("FLASK_ANNEX_FILE_ROOT_PATH", file_annex_path)

        return Annex.from_env("FLASK_ANNEX")

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

def test_error_nonexistent_root_path(tmpdir):
    with pytest.raises(IOError):
        annex = Annex("file", tmpdir.join("dummy").strpath)
        annex.save_file("foo", BytesIO(b""))


# 회의실 배정(그리디)
N = int(input())
time = [list(map(int, input().split())) for _ in range(N)]
time.sort(key=lambda x: [x[1], x[0]])

cnt = 0
et = 0
for i in range(len(time)):
    if time[i][0] >= et:
        cnt += 1
        et = time[i][1]
print(cnt)