import json
import csv
import requests
from bs4 import BeautifulSoup

# ▒█▀▄▒█▀▄ lab. PR | FAF | FCIM | UTM | Fall 2023
# ░█▀▒░█▀▄ FAF-212 Cristian Brinza lab2 homework

print('')
print('▒█▀▄▒█▀▄  lab. PR | FAF | FCIM | UTM | Fall 2023')
print('░█▀▒░█▀▄  FAF-212 Cristian Brinza lab2 homework ')
print('')

# User-Agent Rotation: List of user agents to mimic different browsers.
USER_AGENTS = [
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
    'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0',
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.3',
    # Add more user agents if needed
]

def fetch_web_content(product_url):
    """Fetches the content of the given URL."""
    # User-Agent Rotation: Select a user agent based on the hash of the URL.
    headers = {
        'User-Agent': USER_AGENTS[hash(product_url) % len(USER_AGENTS)]
    }
    try:
        # Error Handling: Catch network errors or invalid URLs.
        response = requests.get(product_url, headers=headers)
        response.raise_for_status()
        return BeautifulSoup(response.content, 'html.parser')
    except requests.RequestException as e:
        print(f"Error fetching URL {product_url}. Error: {e}")
        return None

def extract_owner_details(parsed_content):
    """Extracts the owner details from the parsed content."""
    owner_details = {}
    owner_section = parsed_content.find('dl', {'class': 'adPage__aside__stats__owner'})
    owner_details['Name'] = owner_section.find('a', {'class': 'adPage__aside__stats__owner__login buyer_experiment'}).text
    owner_details['On website since'] = owner_section.find('span').text
    last_update_section = owner_section.find_next('div')
    owner_details['Last Update'] = last_update_section.text
    ad_type_section = last_update_section.find_next('div')
    owner_details['Ad type'] = ad_type_section.text
    views_section = ad_type_section.find_next('div')
    owner_details['Views'] = views_section.text
    return owner_details

def extract_product_info(parsed_content):
    """Extracts product information from the parsed content."""
    product_info = {}
    description_section = parsed_content.find('div', {'class': 'adPage__content__description grid_18'})
    if description_section:
        product_info['Description'] = description_section.text
    else:
        product_info['Description'] = 'Description not found.'
    features_section = parsed_content.find('div', {'class': 'adPage__content__features'}).find_all('h2')
    for feature in features_section:
        feature_details = {}
        ul_section = feature.find_next('ul')
        if ul_section:
            list_items = ul_section.find_all('li')
            for item in list_items:
                spans = item.find_all('span')
                if len(spans) == 2:
                    feature_details[spans[0].text] = spans[1].text
                else:
                    feature_details[spans[0].text] = 'None'
        product_info[feature.text] = feature_details
    return product_info

def export_to_csv(filename, data_list):
    """Exports the scraped data to a CSV file."""
    # Export to CSV: Write the scraped data into a CSV format.
    keys = data_list[0].keys()
    with open(filename, 'w', newline='') as output_file:
        dict_writer = csv.DictWriter(output_file, keys)
        dict_writer.writeheader()
        dict_writer.writerows(data_list)

def read_urls_from_file(filename):
    """Reads URLs from a given file."""
    with open(filename, 'r') as file:
        return [url.strip() for url in file.readlines()]

def main():
    """Main function to interact with the user and perform operations."""
    all_data = []

    while True:
        print("\n--- Menu ---")
        print("1. Scrape product details")
        print("2. Scrape product details from a .txt file")
        print("3. Export all scraped data")
        print("4. Exit")
        choice = input("Enter your choice: ")

        if choice == "1":
            # Scrape Multiple URLs: Allow user to input multiple URLs separated by commas.
            target_urls = input("Enter the product URLs (comma-separated): ").split(',')
            for url in target_urls:
                parsed_content = fetch_web_content(url.strip())
                if parsed_content:
                    owner_details = extract_owner_details(parsed_content)
                    product_info = extract_product_info(parsed_content)

                    final_data = {
                        'URL': url,
                        'Owner Details': owner_details,
                        'Product Info': product_info
                    }
                    all_data.append(final_data)
                    print(f"Scraped data for {url}")

        elif choice == "2":
            # Scrape URLs from a .txt file
            file_path = input("Enter the path to the .txt file containing the product URLs (without extension): ")+".txt"
            try:
                target_urls = read_urls_from_file(file_path)
                for url in target_urls:
                    parsed_content = fetch_web_content(url)
                    if parsed_content:
                        owner_details = extract_owner_details(parsed_content)
                        product_info = extract_product_info(parsed_content)

                        final_data = {
                            'URL': url,
                            'Owner Details': owner_details,
                            'Product Info': product_info
                        }
                        all_data.append(final_data)
                        print(f"Scraped data for {url}")
            except FileNotFoundError:
                print(f"Error: File '{file_path}' not found!")

        elif choice == "3":
            print("\n--- Export Options ---")
            print("1. JSON")
            print("2. TXT")
            print("3. CSV")
            print('4. Console')
            export_choice = input("Enter your choice: ")

            if export_choice == "1":
                filename = input("Enter filename (without extension): ")
                with open(f"{filename}.json", "w") as outfile:
                    outfile.write(json.dumps(all_data, indent=2, ensure_ascii=False))
                print(f"Data saved to {filename}.json")
            elif export_choice == "2":
                filename = input("Enter filename (without extension): ")
                with open(f"{filename}.txt", "w") as outfile:
                    outfile.write(json.dumps(all_data, indent=2, ensure_ascii=False))
                print(f"Data saved to {filename}.txt")
            elif export_choice == "3":
                filename = input("Enter filename (without extension): ")
                # Export to CSV: Save the scraped data into a CSV file.
                export_to_csv(f"{filename}.csv", all_data)
                print(f"Data saved to {filename}.csv")
            elif export_choice == "4":
                print(json.dumps(final_data, indent=2, ensure_ascii=False))  # Print the scraped data to console

            else:
                print("Invalid choice!")

        elif choice == "4":
            print("Exiting program. Goodbye!")
            break
        else:
            print("Invalid choice! Please try again.")

if __name__ == '__main__':
    main()


import Person
from Node import Node

class LinkedList:
    def __init__(self):
        self.head = None
        self.tail = None
        self.size = 0

    def add(self, e):
        newNode = Node(e)
        if self.size == 0:
            self.head = newNode
            self.tail = newNode
        else:
            current_last = self.tail
            current_last.setNext(newNode)
            newNode.setPrevious(current_last)
            self.tail = newNode
        self.size = self.size + 1

    def __str__(self):
        stringToReturn = "List size: " + str(self.size)
        current = self.head
        # don't do this
        # while (current != None)
        # while (current)
        while (current is not None):
        # like saying while (not(current is None))
            stringToReturn = stringToReturn + "\n\n" + str(current)
            current = current.getNext()
        return(stringToReturn)

    def swapDataWithNext(self, current:Node):
        old_data = current.getData()
        new_data = current.getNext().getData()
        current.setData(new_data)
        current.getNext().setData(old_data)

        '''
        currentFormerPrevious = current.getPrevious()
        former_next = current.getNext()
        current.setPrevious(former_next)
        current.setNext(former_next.getNext())
        # current's prev and next are bubbled now
        former_next.setNext(current)
        former_next.setPrevious(currentFormerPrevious)
        '''

        '''
        if current.getNext() == None:
            # cannot swap.
            return;
        if current.getNext() == selt.tail:
            # next is tail, so current must become tail.
            if current == self.head:
                #switching head and tail
                self.tail = current
                self.head = current.getNext()
                current.setPrevious(self.head)
                current.setNext(None)
                self.head.setNext(self.tail)
                self.head.setPrevious(None)
            else:
                # switching current and tail
                current.getPrevious().setNext(current.getNext())
                self.tail = current
                current.setPrevious(current.getNext())
                '''

    def bubble_once(self):
        if (self.size <= 1):
            return
        if (self.size == 2):
            if (self.head.getData() > self.tail.getData()):
                self.swapDataWithNext(self.head)
            return
        else:
            current = self.head
            for i in range(self.size - 1):
                if (current.getData() > current.getNext().getData()):
                    self.swapDataWithNext(current)
                current = current.getNext()
            #reached the end of the list? -> todo test
    def bubble(self):
        for i in range(self.size):
            self.bubble_once()

        '''
        if not self.size < 2:
            current_test = self.head

            while (current_test != self.tail):
                if (current_test.getData() > current_test.getNext().getData()):
                    # current data is larger than next data, so they need to swap.

                    new_previous = current_test.getNext()
                    #edge cases:
                    # if (current_test == self.head):
                    #     if
                    #     current_test.setNext
                    '''

if __name__ == "__main__":
    # listOfPeople = LinkedList()
    # listOfPeople.add(Person.Person("Jaime"))
    # listOfPeople.add(Person.Person("Maria"))
    # listOfPeople.add(Person.Person("Maria"))
    # print(listOfPeople)

    myList = LinkedList()
    myList.add(40)
    myList.add(2)
    myList.add(3)
    myList.add(1)

    #print(myList)
    #myList.swapDataWithNext(myList.head)
    print(myList)
    # Testing bubble sort

    myList.bubble()
    print(myList)


# _*_ coding:utf-8 _*_
# __author__ : 'aj'
# __date__ : '2017/12/12 下午5:59'

from .models import AskUser, CourseComponent, UserFavorite, UserMessage, UserCourse

import xadmin

class AskUserAdmin(object):
    list_display = ['name', 'mobile', 'cursor_name', 'add_time']
    filter_fields = ['name', 'mobile', 'cursor_name']
    list_filter = ['name', 'mobile', 'cursor_name', 'add_time']

class CourseComponentAdmin(object):
    list_display = ['user', 'course', 'comments', 'add_time']
    filter_fields = ['user', 'course', 'comments']
    list_filter = ['user', 'course', 'comments', 'add_time']

class UserFavoriteAdmin(object):
    list_display = ['user', 'fav_id', 'fav_type', 'add_time']
    filter_fields = ['user', 'fav_id', 'fav_type']
    list_filter = ['user', 'fav_id', 'fav_type', 'add_time']

class UserMessageAdmin(object):
    list_display = ['user', 'message', 'has_read', 'add_time']
    filter_fields = ['user', 'message', 'has_read']
    list_filter = ['user', 'message', 'has_read', 'add_time']

class UserCourseAdmin(object):
    list_display = ['user', 'course', 'add_time']
    filter_fields = ['user', 'course']
    list_filter = ['user', 'course', 'add_time']

xadmin.site.register(AskUser, AskUserAdmin)
xadmin.site.register(CourseComponent, CourseComponentAdmin)
xadmin.site.register(UserFavorite, UserFavoriteAdmin)
xadmin.site.register(UserMessage, UserMessageAdmin)
xadmin.site.register(UserCourse, UserCourseAdmin)


import os
from random import randint
from functools import partial
from datetime import datetime

from config.log_config import LogConfig
from config.pong_enum import PathEnum, ButtonNamesEnum

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.properties import NumericProperty, ReferenceListProperty, ObjectProperty, StringProperty
from kivy.vector import Vector
from kivy.clock import Clock
from kivy.core.audio import SoundLoader

log_config = LogConfig()
logger = log_config.configurate_log()

class PongBall(Widget):
    balls_list = os.listdir(PathEnum.BALLS_PATH_ENUM)
    ball_image = StringProperty(PathEnum.BALLS_PATH_ENUM + '/' + balls_list[0])

    velocity_x = NumericProperty(0)
    velocity_y = NumericProperty(0)
    velocity = ReferenceListProperty(velocity_x, velocity_y)

    def move(self):
        self.pos = Vector(*self.velocity) + self.pos

class PongPaddle(Widget):
    score = NumericProperty(0)

    def __init__(self, **kwargs):
        super(PongPaddle, self).__init__(**kwargs)
        self.bounce_sound = SoundLoader.load(PathEnum.BOUNCE_SOUND_PATH_ENUM)

    def bounce_ball(self, ball):
        if self.collide_widget(ball):
            self.bounce_sound.play()
            vx, vy = ball.velocity
            offset = (ball.center_y - self.center_y) / (self.height / 2)
            bounced = Vector(-1 * vx, vy)
            vel = bounced * 1.15
            ball.velocity = vel.x, vel.y + offset
            logger.debug('Game: Ball bounced')

class PongGame(Widget):
    ball = ObjectProperty(None)
    player1 = ObjectProperty(None)
    player2 = ObjectProperty(None)
    is_running = False
    vs_ai = True
    result = StringProperty('')
    start_time = NumericProperty(0)
    elapsed_time = NumericProperty(0)
    backgrounds_list = os.listdir(PathEnum.BACKGROUNDS_PATH_ENUM)
    background_image = StringProperty(PathEnum.BACKGROUNDS_PATH_ENUM + '/' + backgrounds_list[0])

    def __init__(self, **kwargs):
        super(PongGame, self).__init__(**kwargs)
        self.start_button = None
        self.mode_button = None
        self.background_image_button = None
        self.ball_button = None
        self.white_sound = SoundLoader.load(PathEnum.WHITE_SOUND_PATH_ENUM)
        self.move_paddle_event = None  # Event for moving paddles

    def change_background(self, instance):
        logger.debug('UI: Background changed')
        for i in range(len(self.backgrounds_list)):
            if PathEnum.BACKGROUNDS_PATH_ENUM + '/' + self.backgrounds_list[i] == self.background_image:
                if i + 1 == len(self.backgrounds_list):
                    self.background_image = PathEnum.BACKGROUNDS_PATH_ENUM + '/' + self.backgrounds_list[0]
                    break
                else:
                    self.background_image = PathEnum.BACKGROUNDS_PATH_ENUM + '/' + self.backgrounds_list[i + 1]
                    break

    def change_ball(self, instance):
        logger.debug('UI: Ball changed')
        for i in range(len(self.ball.balls_list)):
            if PathEnum.BALLS_PATH_ENUM + '/' + self.ball.balls_list[i] == self.ball.ball_image:
                if i + 1 == len(self.ball.balls_list):
                    self.ball.ball_image = PathEnum.BALLS_PATH_ENUM + '/' + self.ball.balls_list[0]
                    break
                else:
                    self.ball.ball_image = PathEnum.BALLS_PATH_ENUM + '/' + self.ball.balls_list[i + 1]
                    break

    def serve_ball(self, vel=(8, 2)):
        self.ball.center = self.center
        angle = randint(10, 60)  # угол 10 и 240 градусов
        self.ball.velocity = Vector(vel[0], vel[1]).rotate(angle)
        logger.debug('Game: Ball Start')

    def update(self, dt):
        if not self.is_running:
            return

        current_time = datetime.now().timestamp()
        self.elapsed_time = current_time - self.start_time
        self.ball.move()
        self.player1.bounce_ball(self.ball)
        self.player2.bounce_ball(self.ball)

        if (self.ball.y < 0) or (self.ball.top > self.height):
            self.ball.velocity_y *= -1

        if self.ball.x < self.x:
            self.player2.score += 1
            self.serve_ball(vel=(8, 0))

        if self.ball.x > self.width:
            self.player1.score += 1
            self.serve_ball(vel=(-8, 0))

        if self.vs_ai:
            self.move_ai_paddle()

        self.check_results()

    def check_results(self):
        if self.player1.score == 5 or self.player2.score == 5:
            self.is_running = False
            Clock.unschedule(self.update)
            self.show_results()

    def on_touch_move(self, touch):
        if self.vs_ai:
            if touch.x < self.width / 3:
                self.player1.center_y = touch.y
        else:
            if touch.x < self.width / 3:
                self.player1.center_y = touch.y
            elif touch.x > self.width - self.width / 3:
                self.player2.center_y = touch.y

    def show_results(self):
        logger.debug('UI: Pop up created')
        if self.player1.score > self.player2.score:
            winner = "Red Wins!"
        else:
            winner = "Blue Wins!"

        logger.debug(f'Game: {winner}')

        score_message = "Red Score: {}\nBlue Score: {}\nElapsed Time: {:.2f} seconds".format(
            self.player1.score, self.player2.score, self.elapsed_time)

        winner_label = Label(text=winner, font_size='40sp')
        score_label = Label(text=score_message)

        # Создаем BoxLayout для размещения виджетов Label
        layout = BoxLayout(orientation='vertical', padding=(0, 30))
        layout.add_widget(winner_label)
        layout.add_widget(score_label)

        # Создаем Popup с новым контентом
        message_box = Popup(title="Game Over", content=layout, size_hint=(None, None), size=(700, 700))
        message_box.open()

        self.return_to_main_menu()

    def return_to_main_menu(self):
        self.is_running = False
        self.enable_menu()
        self.reset_score()
        Clock.unschedule(self.update)
        self.ball.velocity = (0, 0)
        self.ball.center = self.center
        self.serve_ball()  # Serve the ball for the next match
        self.start_time = 0
        self.elapsed_time = 0
        logger.debug('Game: Returned to main menu')

    def start_game(self, instance):
        self.is_running = True
        self.disable_menu()
        self.reset_score()
        self.serve_ball()
        self.start_time = datetime.now().timestamp()
        logger.debug('Game: Match started')

        if self.vs_ai:
            self.player2.center_y = self.center_y

        Clock.unschedule(self.update)  # Unscheduling previous updates
        Clock.schedule_interval(self.update, 1.0 / 60)  # Schedule the update again

        # Start moving paddles
        self.move_paddle_event = Clock.schedule_interval(partial(self.move_paddles), 1.0 / 60)

    def reset_score(self):
        self.player1.score = 0
        self.player2.score = 0

    def switch_mode(self, instance):
        self.vs_ai = not self.vs_ai
        instance.text = "AI Mode" if self.vs_ai else "2 Players Mode"
        logger.debug('Game: Mode switched to AI Mode' if self.vs_ai else 'Game: Mode switched to 2 Players')

    def move_paddles(self, dt):
        if self.vs_ai:
            self.move_ai_paddle()

    def move_ai_paddle(self):
        if self.ball.center_y > self.player2.center_y:
            self.player2.center_y += min(4.5, self.ball.center_y - self.player2.center_y)
        elif self.ball.center_y < self.player2.center_y:
            self.player2.center_y -= min(4.5, self.player2.center_y - self.ball.center_y)

    def disable_menu(self):
        self.start_button.disabled = True
        self.start_button.opacity = 0
        self.mode_button.disabled = True
        self.mode_button.opacity = 0
        self.background_image_button.disabled = True
        self.background_image_button.opacity = 0
        self.ball_button.disabled = True
        self.ball_button.opacity = 0

    def enable_menu(self):
        self.start_button.disabled = False
        self.start_button.opacity = 1
        self.mode_button.disabled = False
        self.mode_button.opacity = 1
        self.background_image_button.disabled = False
        self.background_image_button.opacity = 1
        self.ball_button.disabled = False
        self.ball_button.opacity = 1

class PongApp(App):

    def build(self):
        game = PongGame()
        layout = BoxLayout(orientation='vertical', spacing=20, padding=(30, 0, 0, 0))

        game.start_button = Button(text=ButtonNamesEnum.START_BTN_ENUM, size_hint=(None, None), size=(290, 100))
        game.start_button.bind(on_press=game.start_game)
        layout.add_widget(game.start_button)

        game.mode_button = Button(text=ButtonNamesEnum.GAME_MODE_BTN_ENUM, size_hint=(None, None),
                                  size=(290, 100))
        game.mode_button.bind(on_press=game.switch_mode)
        layout.add_widget(game.mode_button)

        game.background_image_button = Button(text=ButtonNamesEnum.CHANGE_TABLE_BTN_ENUM, size_hint=(None, None),
                                              size=(290, 100))
        game.background_image_button.bind(on_press=game.change_background)
        layout.add_widget(game.background_image_button)

        game.ball_button = Button(text=ButtonNamesEnum.CHANGE_BALL_BTN_ENUM, size_hint=(None, None),
                                  size=(290, 100))
        game.ball_button.bind(on_press=game.change_ball)
        layout.add_widget(game.ball_button)

        layout.add_widget(Widget(size_hint=(1, 1)))
        game.add_widget(layout)

        # Play the chill.mp3 song
        game.white_sound.loop = True
        game.white_sound.volume = 0.08
        game.white_sound.play()

        logger.debug('Game: Game started')
        return game

if __name__ == '__main__':
    PongApp().run()


# uniq
import sys

if __name__ == '__main__':

    prevLine  = "?"
    firstTime = True

    for line in sys.stdin:

        #strip CR, LF
        line = line.strip('\n')
        line = line.strip('\r')

        # print 1st always
        if firstTime :
            prevLine = line
            firstTime = False
            print(line)
            continue

        if line != prevLine :
            prevLine = line
            print(line)


import os
# os.environ['CUDA_VISIBLE_DEVICES'] = "0"       # in case you are using a multi GPU workstation, choose your GPU here
import tqdm
import pytorch_lightning as pl
import torch
import torch.nn as nn
from torch.utils.data import DataLoader
import torch.nn.functional as F
import pandas as pd
from datasets import load_dataset
from torch.utils.data import TensorDataset, DataLoader

import numpy as np

#define your neural net here:

class MLP(pl.LightningModule):
    def __init__(self, input_size, xcol='emb', ycol='avg_rating'):
        super().__init__()
        self.input_size = input_size
        self.xcol = xcol
        self.ycol = ycol
        self.layers = nn.Sequential(
            nn.Linear(self.input_size, 1024),
            #nn.ReLU(),
            nn.Dropout(0.2),
            nn.Linear(1024, 128),
            #nn.ReLU(),
            nn.Dropout(0.2),
            nn.Linear(128, 64),
            #nn.ReLU(),
            nn.Dropout(0.1),

            nn.Linear(64, 16),
            #nn.ReLU(),

            nn.Linear(16, 1)
        )

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

    def training_step(self, batch, batch_idx):
            x = batch[self.xcol]
            y = batch[self.ycol].reshape(-1, 1)
            x_hat = self.layers(x)
            loss = F.mse_loss(x_hat, y)
            return loss

    def validation_step(self, batch, batch_idx):
        x = batch[self.xcol]
        y = batch[self.ycol].reshape(-1, 1)
        x_hat = self.layers(x)
        loss = F.mse_loss(x_hat, y)
        return loss

    def configure_optimizers(self):
        optimizer = torch.optim.Adam(self.parameters(), lr=1e-3)
        return optimizer

# load the training data

x = np.load ("/mnt/spirit/ava_x.npy")

y = np.load ("/mnt/spirit/ava_y.npy")

val_percentage = 0.05 # 5% of the trainingdata will be used for validation

train_border = int(x.shape()[0] * (1 - val_percentage) )

train_tensor_x = torch.Tensor(x[:train_border]) # transform to torch tensor
train_tensor_y = torch.Tensor(y[:train_border])

train_dataset = TensorDataset(train_tensor_x,train_tensor_y) # create your datset
train_loader = DataLoader(train_dataset, batch_size=256, shuffle=True,  num_workers=16) # create your dataloader

val_tensor_x = torch.Tensor(x[train_border:]) # transform to torch tensor
val_tensor_y = torch.Tensor(y[train_border:])

'''
print(train_tensor_x.size())
print(val_tensor_x.size())
print( val_tensor_x.dtype)
print( val_tensor_x[0].dtype)
'''

val_dataset = TensorDataset(val_tensor_x,val_tensor_y) # create your datset
val_loader = DataLoader(val_dataset, batch_size=512,  num_workers=16) # create your dataloader

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

model = MLP(768).to(device)   # CLIP embedding dim is 768 for CLIP ViT L 14

optimizer = torch.optim.Adam(model.parameters())

# choose the loss you want to optimze for
criterion = nn.MSELoss()
criterion2 = nn.L1Loss()

epochs = 50

model.train()
best_loss =999
save_name = "linear_predictor_L14_MSE.pth"

for epoch in range(epochs):
    losses = []
    losses2 = []
    for batch_num, input_data in enumerate(train_loader):
        optimizer.zero_grad()
        x, y = input_data
        x = x.to(device).float()
        y = y.to(device)

        output = model(x)
        loss = criterion(output, y)
        loss.backward()
        losses.append(loss.item())

        optimizer.step()

        if batch_num % 1000 == 0:
            print('\tEpoch %d | Batch %d | Loss %6.2f' % (epoch, batch_num, loss.item()))
            #print(y)

    print('Epoch %d | Loss %6.2f' % (epoch, sum(losses)/len(losses)))
    losses = []
    losses2 = []

    for batch_num, input_data in enumerate(val_loader):
        optimizer.zero_grad()
        x, y = input_data
        x = x.to(device).float()
        y = y.to(device)

        output = model(x)
        loss = criterion(output, y)
        lossMAE = criterion2(output, y)
        #loss.backward()
        losses.append(loss.item())
        losses2.append(lossMAE.item())
        #optimizer.step()

        if batch_num % 1000 == 0:
            print('\tValidation - Epoch %d | Batch %d | MSE Loss %6.2f' % (epoch, batch_num, loss.item()))
            print('\tValidation - Epoch %d | Batch %d | MAE Loss %6.2f' % (epoch, batch_num, lossMAE.item()))

            #print(y)

    print('Validation - Epoch %d | MSE Loss %6.2f' % (epoch, sum(losses)/len(losses)))
    print('Validation - Epoch %d | MAE Loss %6.2f' % (epoch, sum(losses2)/len(losses2)))
    if sum(losses)/len(losses) < best_loss:
        print("Best MAE Val loss so far. Saving model")
        best_loss = sum(losses)/len(losses)
        print( best_loss )

        torch.save(model.state_dict(), save_name )

torch.save(model.state_dict(), save_name)

print( best_loss )

print("training done")
# inferece test with dummy samples from the val set, sanity check
print( "inferece test with dummy samples from the val set, sanity check")
model.eval()
output = model(x[:5].to(device))
print(output.size())
print(output)


import sys

args = sys.argv
x = int(args[1])
y = str(args[2])

cnt = 0
for i in range(2**x):
  s = ''
  for j in range(x):
    if((i >> j) & 1):
      s += 'M'
    else:
      s += 'V'
  if y in s:
    cnt += 1

print(cnt)


row = int(input("Enter how many rows you want: "))
sum1 = 0
sum2 = 0
sum3 = 0
InputMatrix = []

for i in range(0,row):
    a = []
    for j in range(0,3):
        val = int(input())
        a.append(val)
    InputMatrix.append(a)

print("This is the Matrix you have inserted: ")
for i in range(0,row):
    for j in range(0,3):
        print(InputMatrix[i][j], end="  ")
    print( )

sum = []
for i in range(0,row):
    for j in range(0,3):
        sum1 = sum1 + InputMatrix[j][i]
    sum.append(sum1)
    sum1 = 0

print(sum)

# for i in range(0,row):
#     for j in range(0,3):
#         if(j==0):
#             sum1 = sum1 + InputMatrix[i][j]
#         elif(j==1):
#             sum2 = sum2 + InputMatrix[i][j]
#         elif(j==2):
#             sum3 = sum3 + InputMatrix[i][j]

# for i in range(0,row):
#     for j in range(0,3):
#         pass
#     sum1 = sum1 + InputMatrix[i][0]
#     sum2 = sum2 + InputMatrix[i][1]
#     sum3 = sum3 + InputMatrix[i][2]

print("Total sum for each vectors: ",sum)
if (all(v == 0 for v in sum)):
    print("YES")
else:
    print("NO")


import argparse
import ast
import io
import os.path
import shlex
import shutil
import subprocess
import sys
import textwrap
import urllib.parse

def get_url_filename(url, suffix):
    filename = urllib.parse.urlparse(url).path
    filename = filename.split('/')[-1]
    if not filename.endswith(suffix):
        raise Exception("%r filename doesn't end with %r suffix; url=%r"
                        % (filename, suffix, url))
    return filename

def add_version(package_name, version):
    if version is not None:
        return '%s==%s' % (package_name, version)
    else:
        return package_name

class CI:
    def __init__(self):
        self.source_dir = os.path.abspath(os.path.dirname(__file__))
        self.root_dir = os.path.abspath('work')
        self.set_task_dir()

        self.python_warnings = []
        # self.python_warnings.append('error')
        self.python_dev_mode = True
        # self.python_bytes_warnings = None

        # 2 stands for '-bb'
        self.python_bytes_warnings = 0
        self.read_package_versions()

        if self.python_bytes_warnings and self.python_bytes_warnings > 1:
            self.python_warnings.append('error::BytesWarning')

        self.env = self.create_environ()
        self.python_options = []
        if self.python_bytes_warnings:
            self.python_options.append('-' + 'b' * self.python_bytes_warnings)
        if self.python_dev_mode:
            self.python_options.extend(['-X', 'dev'])
        for warn in self.python_warnings:
            self.python_options.append('-W%s' % warn)

        self._python_version = None
        self._python_version_str = None
        self._orig_python_args = None
        self.set_python(sys.executable)

    def create_environ(self):
        env = dict(os.environ)
        for key in list(env):
            if key.startswith('PYTHON'):
                del env[key]
        if self.python_dev_mode:
            env['PYTHONDEVMODE'] = '1'
        if self.python_warnings:
            env['PYTHONWARNINGS'] = ','.join(self.python_warnings)
        return env

    def log(self, message):
        print(message)

    def mkdir(self, path):
        if os.path.exists(path):
            return
        self.log("Create directory: %s" % path)
        os.mkdir(path)

    def set_python(self, python):
        python = os.path.abspath(python)
        self.python_args = [python] + self.python_options
        if self._orig_python_args is None:
            self._orig_python_args = self.python_args

    def run_command(self, args, quiet=False, **kw):
        cmd_str = ' '.join(shlex.quote(arg) for arg in args)
        cmd_str = cmd_str.replace("\n", "\\n")
        if not quiet:
            text = "Run command: %s" % cmd_str
            if 'cwd' in kw:
                text += ' in %s' % kw['cwd']
            self.log(text)
        if 'stdin' not in kw:
            kw['stdin'] = subprocess.DEVNULL
        if 'env' in kw:
            raise NotImplementedError("cannot override env")
        kw['env'] = self.env

        proc = subprocess.run(args, **kw)

        exitcode = proc.returncode
        if exitcode:
            raise Exception("%s command failed with exit code %s"
                            % (cmd_str, exitcode))

        return proc

    def run_python(self, args, **kw):
        return self.run_command(self.python_args + args, **kw)

    def patch(self, filename, directory=os.path.curdir, level=1):
        filename = os.path.join(self.source_dir, 'patches', filename)
        with open(filename) as fp:
            # --force: do not ask any questions
            self.run_command(['patch', '-p%s' % level, '--force'],
                             stdin=fp,
                             cwd=directory)

    def read_package_versions(self):
        # parse requirements.txt
        self.package_versions = {}
        filename = os.path.join(self.source_dir, 'requirements.txt')
        with io.open(filename, encoding='utf8') as fp:
            for line in fp:
                # strip comments
                line = line.split('#', maxsplit=1)[0]
                line = line.rstrip()
                if '==' in line:
                    name, version = line.split('==', 1)
                else:
                    name = line
                    version = None
                self.package_versions[name] = version

    def pip_install_update(self, packages):
        if not packages:
            raise ValueError
        args = ["-m", "pip", "install", "--upgrade"]
        for name in packages:
            # don't pin the version with --dev
            if not self.args.dev:
                try:
                    version = self.package_versions[name]
                except KeyError:
                    raise Exception("unversionned package: %r" % name)
                arg = add_version(name, version)
            args.append(arg)
        return self.run_python(args)

    def get_python_version(self):
        if self._python_version is not None:
            return self._python_version

        code = "import sys; print(sys.version_info[:3])"
        proc = self.run_python(["-c", code],
                               stdout=subprocess.PIPE,
                               universal_newlines=True,
                               quiet=True)
        line = proc.stdout.rstrip()
        self._python_version = ast.literal_eval(line)
        return self._python_version

    def get_python_version_str(self):
        # Get the Python version string including the Python implementation
        # name. Example: 'cpython-3.8.0b4'
        if self._python_version_str is not None:
            return self._python_version_str

        code = textwrap.dedent("""
            import sys

            if hasattr(sys, 'implementation'):
                name = sys.implementation.name
            else:
                import platform
                name = platform.python_implementation()
            name = name.lower()

            version = sys.version.split()[0]

            print("%s-%s" % (name, version))
        """)

        proc = self.run_python(["-c", code],
                               stdout=subprocess.PIPE,
                               universal_newlines=True,
                               quiet=True)
        self._python_version_str = proc.stdout.rstrip()
        return self._python_version_str

    def download(self, url, filename):
        self.mkdir(self.download_dir)

        filename = os.path.basename(filename)
        filename = os.path.join(self.download_dir, filename)

        # already downloaded: do nothing
        if os.path.exists(filename):
            return filename

        try:
            self.run_command(["wget", "-O", filename, url])
        except:  # noqa
            self.unlink(filename)
            raise

        return filename

        # FIXME: validate a checksum?

    def create_empty_file(self, filename):
        open(filename, 'wb', 0).close()

    def unlink(self, filename):
        if not os.path.exists(filename):
            return
        self.log("Remove file: %s" % filename)
        os.unlink(filename)

    def rmtree(self, dirname):
        if not os.path.exists(dirname):
            return
        self.log("Remove directory: %s" % dirname)
        shutil.rmtree(dirname)

    def package_directory(self, name):
        # Create an absolute path
        # Example: "/path/to/numpy-1.17.2"
        version = self.package_versions[name]
        dirname = "%s-%s" % (name, version)
        return os.path.join(self.task_dir, dirname)

    def task_directory_name(self, name):
        # Example: "cpython-3.8_numpy-1.16.2"
        python = self.get_python_version_str()
        version = self.package_versions[name]
        dirname = "%s_%s-%s" % (python, name, version)
        if self.args.dev:
            dirname += "-dev"
        return dirname

    def download_extract_zip(self, url, dirname):
        filename = get_url_filename(url, '.zip')
        filename = self.download(url, filename)

        self.rmtree(dirname)
        self.run_command(["unzip", "-d", self.task_dir, filename])

    def download_extract_tarball(self, url, dirname):
        filename = get_url_filename(url, '.tar.gz')
        filename = self.download(url, filename)

        self.rmtree(dirname)
        self.run_command(["tar", "-xf", filename])

    def apply_patches(self, patches, dirname):
        for filename in patches:
            self.patch(filename, dirname)

    def setup_venv(self):
        create_venv = not os.path.exists(self.venv_dir)

        if create_venv:
            try:
                self.run_python(["-m", "venv", self.venv_dir])
            except:   # noqa
                self.rmtree(self.venv_dir)
                raise
        else:
            self.log("venv already exists: %s" % self.venv_dir)

        self.set_python(os.path.join(self.venv_dir, "bin", "python"))

        if create_venv:
            self.pip_install_update(["setuptools", "pip"])

    def get_tasks(self):
        task_dir = os.path.join(self.source_dir, 'task')
        names = [name[:-3] for name in os.listdir(task_dir)
                 if not name.startswith("__init__.") and name.endswith(".py")]
        return names

    def parse_options(self):
        tasks = self.get_tasks()
        parser = argparse.ArgumentParser(description='Process some integers.')
        parser.add_argument('command',
                            choices='install test clean cleanall'.split())
        parser.add_argument('task',
                            choices=sorted(tasks))
        parser.add_argument('--dev', action="store_true")
        self.args = parser.parse_args()

    def set_task_dir(self, name=None):
        if name:
            self.task_dir = os.path.join(self.root_dir, name)
        else:
            self.task_dir = self.root_dir
        self.download_dir = os.path.join(self.root_dir, 'download')
        self.venv_dir = os.path.join(self.task_dir, 'venv')

    def chdir(self, path):
        self.log("Change directory: %s" % path)
        os.chdir(path)

    def setup_env(self):
        self.mkdir(self.root_dir)
        self.mkdir(self.task_dir)
        self.chdir(self.task_dir)
        self.setup_venv()

    def _get_task(self):
        task_name = self.args.task

        modname = 'pythonci.task.' + task_name
        mod = __import__(modname).task
        mod = getattr(mod, task_name)
        task_class = mod.Task
        return task_class(self)

    def patch_tox_basepython(self):
        # rely on the current working directory
        filename = 'tox.ini'

        with open(filename, encoding="utf-8") as fp:
            content = fp.read()

        # Don't pass arguments, only the executable
        # Don't use the Python of the venv, but the original Python
        #python = self._orig_python_args[0]
        python = self.python_args[0]
        line = f"basepython = {python}\n"

        testenv = "[testenv]\n"
        pos = content.find(testenv)
        if pos:
            pos += len(testenv)
            content = content[:pos] + line + content[pos:]
        else:
            content = f"{testenv}{line}" + content

        with open(filename, "w", encoding="utf-8") as fp:
            fp.write(content)
            fp.flush()

        self.log(f"basepython overriden in {filename}")

    def main(self):
        self.parse_options()
        if self.args.command == 'cleanall':
            self.rmtree(self.root_dir)
            return

        task = self._get_task()

        command = self.args.command
        if command == 'clean':
            self.rmtree(self.task_dir)
        else:
            if command == 'install':
                task.install()
            elif command == 'test':
                task.run_tests()
            else:
                raise Exception("unknown command: %r" % command)

    def remove_cython_files(self):
        # Force to run Cython: regenerate C files generated by Cython
        # in the current directory and subdirectories.
        cmd = r"rm -f -v $(grep -rl '/\* Generated by Cython') PKG-INFO"
        self.run_command([cmd], shell=True)

    def install_cython(self):
        if self.args.dev:
            url = "git+git://github.com/cython/cython.git@0.29x"
            self.run_python(["-m", "pip", "install", url])
        else:
            self.pip_install_update(["Cython"])


from unittest import TestCase
import detection
from config import *
import traceback

class TestDetection(object):

    def test_detect_embedding_based_process_monitor(self):
        # monitor = detection.DetectionMonitor(VIDEO_CONFIG_DIR / 'video.json', STREAM_SAVE_DIR, CANDIDATE_SAVE_DIR)
        monitor = detection.EmbeddingControlBasedProcessMonitor(VIDEO_CONFIG_DIR / 'video.json', None, STREAM_SAVE_DIR,
                                                                None, CANDIDATE_SAVE_DIR, )
        monitor.monitor()

    def test_detect_embedding_based_thread_monitor(self):
        try:
            monitor = detection.EmbeddingControlBasedThreadMonitor(VIDEO_CONFIG_DIR / 'video.json', STREAM_SAVE_DIR,
                                                                   None, CANDIDATE_SAVE_DIR)
            monitor.monitor()
        except Exception as e:
            traceback.print_exc()

    def test_detect_embedding_based_thread_and_process_monitor(self):
        monitor = detection.EmbeddingControlBasedThreadAndProcessMonitor(VIDEO_CONFIG_DIR / 'video.json',
                                                                         STREAM_SAVE_DIR, None, None,
                                                                         CANDIDATE_SAVE_DIR)
        monitor.monitor()

    def test_control(self):
        # controller = detection.DetectorController()
        # self.fail()
        pass

if __name__ == '__main__':
    test_detection = TestDetection()
    # test_detection.test_detect_embedding_based_process_monitor()
    # test_detection.test_detect_embedding_based_thread_monitor()
    test_detection.test_detect_embedding_based_thread_and_process_monitor()


class Node:
    def __init__(self, value=None, next=None):
        self.value = value
        self.next = next

class LinkedList:
    def __init__(self, head=None, tail=None):
        self.head = head
        self.tail = tail

    # umiesci nowy wezel na poczatku listy
    def push(self, value):
        new_node = Node(value)
        new_node.next = self.head
        self.head = new_node
        if self.tail is None:
            self.tail = self.head

    # umiesci nowy wezel na koncu listy
    def append(self, value):
        new_node = Node(value)
        if self.head is None:
            self.head = new_node
            self.tail = self.head
        else:
            new_node = Node(value)
            self.tail.next = new_node
            self.tail = new_node
        if self.tail is None:
            self.tail = self.head

    # zwroci wezel znajdujacy sie na wskazanej pozycji
    def node(self, index):
        cur_node = self.head
        node_position = 0
        while cur_node.next is not None:
            if node_position == index - 1:
                return cur_node.value
            node_position += 1
            cur_node = cur_node.next
            if node_position == index - 1:
                return cur_node.value

    # wstawi nowy wezel za wezlem wskazanym w parametrze
    def insert(self, value, after):
        if after == 0:
            self.push(value)
            return
        node_position = 0
        cur_node = self.head
        while cur_node is not None:
            if node_position == after - 1:
                node = Node(value, cur_node.next)
                cur_node.next = node
                break
            cur_node = cur_node.next
            node_position += 1

    # usunie pierwszy element listy i go zwroci
    def pop(self):
        self.head = self.head.next
        return self.head

    # usunie ostatni element z listy i go zwroci
    def remove_last(self):
        element = self.head
        while element.next.next:
            element = element.next
        element.next = None
        self.tail = element
        return self.tail

    # usunie z listy nastepnik wezla przekazanego w parametrze
    def remove(self, after):
        if after == 0:
            self.head = self.head.next
            return

        node_position = 0
        cur_node = self.head
        while cur_node is not None:
            if node_position == after - 1:
                cur_node.next = cur_node.next.next
                break
            cur_node = cur_node.next
            node_position += 1

    def __str__(self):
        element = self.head
        list_elements = ""
        while element is not None:
            list_elements += str(element.value) + ' -> '
            element = element.next
        list_elements += "None"
        return list_elements

    def __len__(self):
        length = 0
        element = self.head
        while element is not None:
            length += 1
            element = element.next
        return length

class Stack:
    def __init__(self):
        self._storage = LinkedList()

    def push(self, value):
        self._storage.append(value)

    def pop(self):
        return self._storage.remove_last().value

    def __str__(self):
        element = self._storage.head
        stack_elements = ''
        while element.next:
            stack_elements += str(element.value) + '\n'
            element = element.next
        stack_elements += str(element.value)
        return stack_elements

    def __len__(self):
        return len(self._storage)

class Queue:
    def __init__(self):
        self._storage = LinkedList()

    def peek(self):
        return self._storage.tail.value

    def enqueue(self, value):
        self._storage.append(value)

    def dequeue(self):
        return self._storage.remove_last().value

    def __str__(self):
        element = self._storage.head
        queue_elements = ''
        while element.next is not None:
            queue_elements += str(element.value) + ', '
            element = element.next
        queue_elements += str(element.value)
        return queue_elements

    def __len__(self):
        return len(self._storage)

list_ = LinkedList()

list_.push(1)
list_.push(2)
print(list_.__str__())

list_.append(3)
print(list_.__str__())

list_.pop()
print(list_.__str__())

list_.insert(4, 1)
print(list_.__str__())

print(list_.node(1))

list_.remove(0)
print(list_.__str__())

list_.remove_last()
print(list_.__str__())

print(list_.__len__())

# stack = Stack()
# stack.push(4)
# stack.push(5)
# stack.push(6)
# print(stack.__str__())
# print('----')
# print(stack.__len__())
# stack.pop()
# print('----')
# print(stack.__str__())

# queue = Queue()
# queue.enqueue(5)
# queue.enqueue(6)
# queue.enqueue(7)
# queue.enqueue(9)
# print(queue.__str__())
# print(queue.peek())
# queue.dequeue()
# print(queue.__str__())
# print(queue.__len__())


"""
@package square_connect.report.management.commands.get_recent_transactions
Gets the most recent transactions from the primary storefronts and adds any selected items to the report database.
We recommend that you run it in a cron job.
"""

from django.core.management.base import BaseCommand, CommandError
from django.conf import settings
from app.models import Service
from report.models import Report, Item
from data.transaction import PaymentRequest

class Command(BaseCommand):
    help = "Gets the last 200 transactions at each service and finds ___-marked items"

    # Allows input of report types to take in. Ex. spoilage and shift drinks.
    def add_arguments(self, parser):
        parser.add_argument('report_type', nargs='+')

    def handle(self, *args, **options):
        # Refresh the Services if necessary
        if Service.objects.count() == 0:
                Service.regenerate_services()

        # Run for each service with discounts
        services = Service.objects.exclude(name__in=settings.SERVICE_EXCLUDES)

        for service in services:
            # Get the recent transactions for that service
            sales_json = PaymentRequest(merchant_id=service.merchant_id).auto()

            # Pass the sales to the report model so it can do its magic
            for report_type in options['report_type']:
                Report.add_items_from_json_data(sales_json, service)


#-*- encoding: UTF-8 -*-
import urllib
from AlyMoly.reporte.excepciones import AbstractClassException
from AlyMoly.settings import REPORT_HOST, REPORT_PORT, REPORT_APP, REPORT_DIR,\
                     NOMBRE_SUCURSAL, CANTIDAD_PRODUCTOS_MAS_VENDIDOS,\
                    CANTIDAD_PROMOCIONES_MAS_VENDIDAS
from AlyMoly.reporte.conexion import URLRetriever
from django.http import HttpResponse
from django.core.urlresolvers import reverse

from HTMLParser import HTMLParser
import htmlentitydefs

class HTMLReportFixer(HTMLParser):
    """Cambia el título de una página html, a un titulo más institucional"""
    def __init__(self):
        HTMLParser.__init__(self)
        self.flag = False
        self.pieces = []

    def handle_starttag(self, tag, attrs):
        if tag == 'title':
            self.flag = True
        if tag == 'img':
            new_attrs = []
            for k,v in attrs:
                if k == 'src':
                    v = v.replace('/birt/preview',reverse('reporte:get_birt_img'))
                    new_attrs.append((k,v.encode()))
            attrs = new_attrs
        strattrs = "".join([' %s="%s"' % (key, value) for key, value in attrs])
        self.pieces.append("<%(tag)s%(strattrs)s>" % locals())

    def handle_endtag(self, tag):
        if tag == 'title':
            self.flag = False
        self.pieces.append("</%(tag)s>" % locals())

    def handle_data(self, data):
        if self.flag:
            data = "Reporte | %s" % (NOMBRE_SUCURSAL)
        self.pieces.append("%(data)s" % locals())

    def handle_charref(self,ref):
        self.pieces.append("&#%(ref)s;" % locals())

    def handle_comment(self, text):
        self.pieces.append("<!--%(text)s-->" % locals())

    def handle_entityref(self, ref):
        self.pieces.append("&%(ref)s" % locals())
        if htmlentitydefs.entitydefs.has_key(ref):
            self.pieces.append(";")

    def handle_pi(self, text):
        self.pieces.append("<?%(text)s>" % locals())

    def handle_decl(self, text):
        self.pieces.append("<!%(text)s>" % locals())

    def output(self):
        return "".join(self.pieces).replace("\n",'').strip()

class Reporte(object):
    """Clase abstracta padre que implementa la representacion un reporte genérico de
    archivo de reporte"""

    HTML = 'html'
    PDF = 'pdf'
    FORMATO = ( HTML, )

    def __new__(self, *args):
        if self is Reporte :
            raise AbstractClassException
        return object.__new__(self)

    def __init__(self,data):
        self.extension = "rptdesign"
        self.params = {}
        self.formato = data['formato']
    def __unicode__(self):
        return self.nombre + '.' + self.extension

    def get_url_params(self):
        list_params = []
        for key,val in self.params.items():
            list_params.append(key + "=" + urllib.quote(str(val)))
        url_params = "&".join(list_params)
        if url_params != '':
            return "&"+url_params
        return ''

    def get_filename(self):
        return "%s.%s" % (self.nombre,self.extension)

    def get_url(self):
        return ("http://%s:%s/%s/preview?__format=%s&__report=%s%s" % (REPORT_HOST,
                                                               REPORT_PORT,
                                                               REPORT_APP,
                                                               self.formato,
                                                               REPORT_DIR, self.get_filename())) + self.get_url_params()
    def get_response(self):
        retriever = URLRetriever(self.get_url())
        response = None
        if self.formato == 'pdf':
            response = HttpResponse(retriever.get(),mimetype='application/pdf')
            response['Content-Disposition'] = 'attachment; filename=%s.pdf' % self.__class__.__name__
        else:
            parser = HTMLReportFixer()
            parser.feed(retriever.get())
            response = HttpResponse(parser.output())
        return response

class ReportePeriodoTiempo(Reporte):

    def __new__(self, *args):
        if self is ReportePeriodoTiempo :
            raise AbstractClassException
        return object.__new__(self)

    def __init__(self,data):
        super(ReportePeriodoTiempo,self).__init__(data)
        fecha_inicio = 'fecha_inicio'
        fecha_fin = 'fecha_fin'
        if data.get('fecha',False):
            fecha_inicio = fecha_fin = 'fecha'
        self.params.update({'fecha_inicio':data[fecha_inicio].strftime('%Y-%m-%d'),
                            'fecha_fin':data[fecha_fin].strftime('%Y-%m-%d')})

##########       REPORTES        ##########

class Productos(Reporte):

    def __init__(self,data):
        super(Productos,self).__init__(data)
        self.nombre = "Productos"

class ProductosCodigoBarra(Reporte):

    def __init__(self,data):
        super(ProductosCodigoBarra,self).__init__(data)
        self.nombre = "ProductosCodigoBarra"

class ProductosCodigoManual(Reporte):

    def __init__(self,data):
        super(ProductosCodigoManual,self).__init__(data)
        self.nombre = "ProductosCodigoManual"

class ProductosExentos(Reporte):

    def __init__(self,data):
        super(ProductosExentos,self).__init__(data)
        self.nombre = "ProductosExentos"

class ProductosAfectos(Reporte):

    def __init__(self,data):
        super(ProductosAfectos,self).__init__(data)
        self.nombre = "ProductosAfectos"

class Promociones(Reporte):

    def __init__(self,data):
        super(Promociones,self).__init__(data)
        self.nombre = "Promociones"

class Existencias(Reporte):

    def __init__(self,data):
        super(Existencias,self).__init__(data)
        self.nombre = "Existencias"
        self.params.update({
                            'bodega_id':data['bodega'],
                            })

class ExistenciaPorCategoria(Reporte):

    def __init__(self,data):
        super(ExistenciaPorCategoria,self).__init__(data)
        self.nombre = "ExistenciasPorCategoria"
        self.params.update({
                            'bodega_id':data['bodega'],
                            'categoria_id':data['categoria']
                            })

class VentasPorTurno(Reporte):

    def __init__(self,data):
        super(VentasPorTurno,self).__init__(data)
        self.nombre = "EstadoDeTurno"
        self.params.update({
                            'turno_id':data['turno'],
                            })

class VentasPorTurnoDetalle(Reporte):

    def __init__(self,data):
        super(VentasPorTurnoDetalle,self).__init__(data)
        self.nombre = "VentasPorTurno"
        self.params.update({
                            'turno_id':data['turno'],
                            })

class VentasPorTurnoResumenAfectos(Reporte):

    def __init__(self,data):
        super(VentasPorTurnoResumenAfectos,self).__init__(data)
        self.nombre = "VentasPorTurnoResumenAfectos"
        self.params.update({
                            'turno_id':data['turno'],
                            })
class VentasPorTurnoResumenExentos(Reporte):

    def __init__(self,data):
        super(VentasPorTurnoResumenExentos,self).__init__(data)
        self.nombre = "VentasPorTurnoResumenExentos"
        self.params.update({
                            'turno_id':data['turno'],
                            })
class VentasPorTurnoResumenDevoluciones(Reporte):

    def __init__(self,data):
        super(VentasPorTurnoResumenDevoluciones,self).__init__(data)
        self.nombre = "VentasPorTurnoResumenDevoluciones"
        self.params.update({
                            'turno_id':data['turno'],
                            })
class VentasPorTurnoResumenPromociones(Reporte):

    def __init__(self,data):
        super(VentasPorTurnoResumenPromociones,self).__init__(data)
        self.nombre = "VentasPorTurnoResumenPromociones"
        self.params.update({
                            'turno_id':data['turno'],
                            })
class VentasPorTurnoResumenStockCritico(Reporte):

    def __init__(self,data):
        super(VentasPorTurnoResumenStockCritico,self).__init__(data)
        self.nombre = "VentasPorTurnoResumenStockCritico"
        self.params.update({
                            'turno_id':data['turno'],
                            })

class VentasPorMes(Reporte):

    def __init__(self,data):
        super(VentasPorMes,self).__init__(data)
        self.nombre = "VentaPorMes"
        fecha = data['anio'] + '-' + data['mes'] + '-01'
        self.params.update({
                            'mes_turno':fecha,
                            })

class VentasGraficoProducto(ReportePeriodoTiempo):

    def __init__(self,data):
        super(VentasGraficoProducto,self).__init__(data)
        self.nombre = "VentaGraficoProductosPorFechaPorCategorias"
        self.params.update({
                            'cantidad':CANTIDAD_PRODUCTOS_MAS_VENDIDOS,
                            })

class VentasGraficoPromocion(ReportePeriodoTiempo):

    def __init__(self,data):
        super(VentasGraficoPromocion,self).__init__(data)
        self.nombre = "VentaGraficoPromocionesPorFechaPorCategorias"
        self.params.update({
                            'cantidad':CANTIDAD_PRODUCTOS_MAS_VENDIDOS,
                            })

class VentasGraficoProductoPorCategoria(ReportePeriodoTiempo):

    def __init__(self,data):
        super(VentasGraficoProductoPorCategoria,self).__init__(data)
        self.nombre = "VentaGraficoProductosPorFechaPorCategoria"
        self.params.update({
                            'cantidad':CANTIDAD_PROMOCIONES_MAS_VENDIDAS,
                            'categoria_id':data.get("categoria"),
                            })

class VentasGraficoPromocionPorCategoria(ReportePeriodoTiempo):

    def __init__(self,data):
        super(VentasGraficoPromocionPorCategoria,self).__init__(data)
        self.nombre = "VentaGraficoPromocionesPorFechaPorCategoria"
        self.params.update({
                            'cantidad':CANTIDAD_PROMOCIONES_MAS_VENDIDAS,
                            'categoria_id':data.get("categoria"),
                            })

class VentasPorMesResumido(Reporte):

    def __init__(self,data):
        super(VentasPorMesResumido,self).__init__(data)
        self.nombre = "VentaPorMesResumido"
        fecha = data['anio'] + '-' + data['mes'] + '-01'
        self.params.update({
                            'mes_turno':fecha,
                            })


# -*- coding: utf-8 -*-
# !/usr/bin/env python
# @Time    : 2019-08-06 16:16
# @Author  : lidong@immusician.com
# @Site    :
# @File    : base.py

import requests
from UnitTest.settings import HOST, PORT, HEADERS

class BaseResponse:
    def __init__(self):
        pass

class BaseRequest:
    def __init__(self, host=None, port=None):
        self._host = host
        if not self._host:
            self._host = HOST

        self._port = port
        if not self._port:
            self._port = PORT

        self.__url = self._host + ":" + str(self._port)
        self.__headers = HEADERS

    def _check_url_and_headers(self, url, headers):
        url = self.__url + url

        if not headers:
            headers = self.__headers
        return url, headers

    def get(self, url, param=None, **kwargs):
        headers = kwargs.get("headers", None)
        url, headers = self._check_url_and_headers(url, headers)
        return requests.get(url, param, headers=headers, **kwargs)

    def post(self, url, json=None, **kwargs):
        headers = kwargs.get("headers", None)
        url, headers = self._check_url_and_headers(url, headers)
        return requests.post(url, json=json, headers=headers)

    def run(self):
        dir_list = self.__dir__()
        for func in dir_list:
            if not func.startswith("_"):
                if func not in ["get", 'post', 'run']:
                    getattr(self, func)()
                    # self._show_data(func, url, ret)

    @staticmethod
    def _show_data(func_name, url, response):
        print("*"*10, func_name, "*"*10)
        print("")
        print("url: ", url)
        print("status: ", response.status_code)
        print("json: ", response.json())
        print("")
        print("")

if __name__ == '__main__':
    BaseRequest().run()


#YAPI Rewrite - Yet Another Package Manager

#Imports
import modules.config_import as config_import
import modules.installer as installer
import gui.interface as interface
import modules.search as search
import json
import sys
import os
try:
    os.chdir(os.path.dirname(__file__)) #Change file location if outside of YAPI
except:
    pass #Already in directory of YAPI.
if len(sys.argv) != 2:
    try:
        config = json.loads(config_import.get_config())
        os_platform = config['OS.platform']
        cache_boolean = ('True' == config['Cache.keep_cache'])
        cache_location = config['Cache.cache_location']
        search_local = ('True' == config['Search.search_local'])
        search_url = config['Search.search_url']
        remote_location = config['Remote.location']
        remote_branch = config['Remote.branch']
        file_extension = config['Remote.file_extension']
        language_selected = config['Languages.selected']
    except:
        print('Config not able to be imported. Run \"python3 yapi.py config\" to fix the error')

#Main Program
if len(sys.argv) == 1:
    result = interface.start()
elif len(sys.argv) == 2:
    if sys.argv[1] == 'config':
        config_import.update_config()
elif len(sys.argv) == 3:
    if sys.argv[1] == 'search':
        matches = search.search(search_url, file_extension, search_local, cache_location, sys.argv[2])
        for match in matches:
            print(match)
    elif sys.argv[1] == 'download':
        file_name = sys.argv[2] + file_extension
        file_url = remote_location + os_platform + '/' + remote_branch + '/scripts/' + file_name
        os.chdir(cache_location)
        output = installer.get_file(file_url, file_name)
    elif sys.argv[1] == 'run':
        file_name = sys.argv[2] + file_extension
        os.chdir(cache_location)
        output = installer.run_script(file_name, cache_boolean)
    elif sys.argv[1] == 'install':
        output = installer.full_install(sys.argv[2])


import os
import sys
import importlib
import datetime
import time
import shutil
import numpy as np
import pandas as pd
from pathlib import Path

from evidence.post_processing import postprocess

# UltraNest imports
try:
    from ultranest import ReactiveNestedSampler
    import ultranest.stepsampler
except ImportError:
    raise ImportError("Install UltraNest to use this module.")

# MPI imports
try:
    from mpi4py import MPI
    comm = MPI.COMM_WORLD
    rank = comm.Get_rank()
    size = comm.Get_size()
except ImportError:
    print("Install mpi4py to use with OpenMPI. Continuing with one thread.")
    rank = 0
    size = 1

def run(model, rundict, priordict, ultrasettings=None):
    """
    Runs UltraNest on the chosen data and model. When UltraNest is finished
    running it automatically runs a post processing script on the output creating
    plots of the posterior and saving basic information like the evidence and
    run settings on a text file for future reference.

    Parameters
    ----------
    model : object
        Custom model class that contains your desired model. This class has to
        have a method called log_likelihood(x) which takes a parameter array x
        and returns the corresponding log Likelihood. The order of the array x is
        given by the order that results from calling list(priordict.keys()) (see
        description for priordict for more information.)
        Your custom model class should inherit from either RVModel if it's a
        radial velocities model or from BaseModel otherwise.
    rundict : dict
        Dictionary with basic information about the run itself. Keys it should
        include are:
            target : Name of target or function to analyse
            runid : String to identify the specific model or configuration being
                    used
            comment (optional) : Optional comment for a third layer of identification
            prior_names (optional) : List with the names and ranges of the priors
            nplanets (optional) : Number of planets in the RV model. If not
                                  provided, it will use the number of planets
                                  present in the configfile.
            star_params (optional) : Dictionary with the stars parameters like
                                     star_mass (mass of the star in solar masses),
                                     star_radius (radius of star in solar radii),
                                     star_rot (roation period of star). These
                                     can be be ufloats to include the uncertainty.
            savedir (optional) : Save directory for the output of UltraNest
            order_planets (optionsl) : Boolean indicating if the planets should
                                       be ordered by period. This is to avoid
                                       periods jumping between the different
                                       planets. Default is False.
    priordict : dict
        Dictionary with the priors to all free parameters. Keys are the names
        of the parameters. Values are object with a method .ppf(x) which is the
        inverse of the CDF of the chosen probability distribution of the prior.
        It takes a uniformly sampled number between 0 and 1 and returns the
        physical parameter distributed according to the prior.
        The method log_likelihood in your custom model should take the same order
        or parameters that results from calling list(priordict.keys()).
    ultrasettings : dict, optional
        Dictionary containing custom parameters for UltraNest setting like nlive
        or nrepeats. If None are given the defualt UltraNest settings are used.

    Returns
    -------
    output : Output object
        Object with the all sorts of outputs from the Nested Sampling run.
        Very similar in structure to the output from PolyChord but without all
        custom PolyChord objects.
        Several attributes are added before returning. These are used for the
        post processing script.
    """

    # Create list of parameter names
    parnames = model.parnames
    rundict_keys = list(rundict.keys())

    # Count "real" number of planets if not provided by rundict or model
    nplanets = 0
    if 'nplanets' in rundict_keys:
        # Check if nplanets is in rundict
        nplanets = rundict['nplanets']
    elif hasattr(model, 'nplanets'):
        # Check if nplanets is in the model
        nplanets = model.nplanets
    else:
        # Count number of planets by checking for periods
        for i, par in enumerate(parnames):
            if ('planet' in par) and ('period' in par):
                nplanets += 1

    planets = []
    planet_idxs = []
    for n in range(1, nplanets+1):
        planets.append([])
        for i, par in enumerate(parnames):
            if f'planet{n}' in par:
                planets[n-1].append(i)
                if 'period' in par:
                    planet_idxs.append(i)

    # Prepare run
    nderived = 0
    ndim = len(parnames)

    # Function to convert from hypercube to physical parameter space
    def prior(hypercube):
        """
        Converts a point in the unit hypercube to the physical parameters using
        their respective priors.
        """

        # Claculate physical parameters with ppf from prior
        theta = np.ones_like(hypercube)
        for i, x in enumerate(range(ndim)):
            param = parnames[i]
            theta[x] = priordict[param].ppf(hypercube[i])

        return theta

    # LogLikelihood

    def loglike(x):
        """
        Calculates de logarithm of the Likelihood given the parameter vector x.
        """

        return model.log_likelihood(x)

    # Starting time to identify this specific run
    # If it's being run with more than one core the isodate on the first core
    # is broadcasted to the rest so they all share the same variable
    isodate = datetime.datetime.today().isoformat()
    if size > 1:
        isodate = comm.bcast(isodate, root=0)

    # Create settings object for this run
    settings = set_ultrasettings(rundict, ultrasettings, ndim, nderived, isodate, parnames)

    # Find and indicate wrapped (circular) parameters like phases
    wrapped_params = np.zeros(ndim, dtype=bool)
    for i, par in enumerate(parnames):
        if 'omega' in par or 'ml0' in par:
            wrapped_params[i] = True

    # Set up the sampler
    sampler = ReactiveNestedSampler(parnames, loglike, prior,
                                    log_dir = settings['log_dir'],
                                    num_test_samples = 100,
                                    wrapped_params = wrapped_params,
                                    num_bootstraps = settings['num_bootstraps'],
                                     #resume=False,
                                    # vectorized = True
                                    )

    # Use a slice sampler instead of rejection sampling
    sampler.stepsampler = ultranest.stepsampler.RegionSliceSampler(nsteps=settings['nsteps'], adaptive_nsteps='move-distance')

    # Initialise clocks
    ti = time.process_time()

    # ----- Run UltraNest ------
    sampler.run(min_num_live_points = settings['nlive'],
                cluster_num_live_points = int(0.1*settings['nlive']),
                dlogz = settings['dlogz'],
                frac_remain = settings['frac_remain']
                )
    # --------------------------

    # Stop clocks
    tf = time.process_time()

    if size > 1:
        # Reduce clocks to min and max to get actual wall time
        ti = comm.reduce(ti, op=MPI.MIN, root=0)
        tf = comm.reduce(tf, op=MPI.MAX, root=0)

    # Print General results
    sampler.print_results()

    # Save results
    if rank == 0:
        output = Output()
        # Assign additional parameters to output
        output.runtime = datetime.timedelta(seconds=tf-ti)
        output.rundict = rundict.copy()
        output.datadict = dict(model.datadict)
        output.fixedpardict = dict(model.fixedpardict)
        output.model_name = str(model.model_path.stem)
        output.nlive = settings['nlive']
        output.nrepeats = settings['nsteps']
        output.isodate = isodate
        output.ncores = size
        output.parnames = parnames
        output.ndim = ndim
        output.sampler = 'UltraNest'
        output.base_dir = settings['log_dir']
        output.file_root = settings['file_root']
        output.logZ = sampler.results['logz']
        output.logZerr = sampler.results['logzerr']
        output.nlike = sampler.results['ncall']

        output.samples = pd.DataFrame(sampler.results['samples'], columns=parnames)

        # Add additional information if provided
        if 'prior_names' in rundict_keys:
            output.priors = rundict['prior_names']

        if 'star_params' in rundict_keys:
            output.starparams = rundict['star_params']

        # Print run time
        print(f'\nTotal run time was: {output.runtime}')

        # Plot results
        sampler.plot()

        base_dir_parent = str(Path(output.base_dir).parent.absolute())
        runid_dir = Path(output.base_dir).parent.parent.absolute()
        # Save model file
        shutil.copy(model.model_path, base_dir_parent)
        # Save output as pickle file
        # print(base_dir_parent)
        # run_label = os.path.basename(base_dir_parent)
        # print(run_label)
        dump2pickle(output, output.file_root+'.pkl')

        # Copy post processing script to this run's folder
        parent = Path(__file__).parent.parent.absolute()
        shutil.copy(os.path.join(parent, 'post_processing.py'), base_dir_parent)
        # Copy FIP criterion scirpt to parent of runid
        shutil.copy(os.path.join(parent, 'fip_criterion.py'), runid_dir)

        # Copy model file
        shutil.copy(model.model_path, base_dir_parent)

        # Run post processing script
        postprocess(base_dir_parent)

    return #output

def dump2pickle(output, filename, savedir=None):
    """
    Takes the output from UltraNest and saves it as a pickle file.

    Parameters
    ----------
    output : Output object
        Object file with the output infos from the UltraNest run
    filename : str
        Name of the saved file
    savedir : str, optional
        Directory on where to save the pickled file
    """

    # Try to import pickle. Raise warning if not installed.
    try:
        import pickle
    except ImportError:
        print('Install pickle to save the output. Try running:\n pip install pickle')
        return

    if savedir is None:
        # Save directory in parent of base dir
        pickledir = Path(output.base_dir).parent
    else:
        # Unless specified otherwhise
        pickledir = savedir

    # Create directory if it doesn't exist.
    os.makedirs(pickledir, exist_ok=True)

    full_path = os.path.join(pickledir, filename)
    with open(full_path, 'wb') as f:
        pickle.dump(output, f)

    return

def set_ultrasettings(rundict, ultrasettings, ndim, nderived, isodate, parnames):
    """
    Sets the correct settings for UltraNest and returns a dictionary with the
    settings. It combines the default settings and overwrites the used defined
    settings. It cointains the settings for both the initialization of the
    samples and the its run function.

    Parameters
    ----------
    rundict : dict
        Dictionary with information about the run itself.
    polysettings : dict
        Dictionary with the custom UltraNest settings to be set for this run
    ndim : int
        Number of free parameters
    nderived : int
        Number of derived parameters
    isodate : datetime
        Date stamp to identify the current run
    parnames : list
        List containing the names of the free parameters

    Returns
    -------
    settings : dict
        Object with all the information that UltraNest needs to run nested
        sampling on this model.
    """

    rundict_keys = list(rundict.keys())
    # Define UltraNest settings
    # Use the settings provided in ultrasettings otherwise use default
    # Definition of default values for the UltraNest settings
    default_settings = {'nlive': 25*ndim,
                        'nsteps': 3*ndim,
                        'dlogz': 0.5,
                        'frac_remain': 0.01,
                        'num_bootstraps': 30
                        }

    # Update default values with settings provided by user
    if ultrasettings != None:
        if type(ultrasettings) is not dict:
            raise TypeError("ultrasettings has to be a dictionary")
        else:
            default_settings.update(ultrasettings)

    # Define fileroot name (identifies this specific run)
    rundict['target'] = rundict['target'].replace(' ', '')  # Remove any whitespace
    rundict['runid'] = rundict['runid'].replace(' ', '')  # Remove any whitespace
    file_root = rundict['target']+'_'+rundict['runid']

    # Add comment if it exists and is not empty
    if 'comment' in rundict_keys:
        if rundict['comment'] != '':
            file_root += '-' + rundict['comment']

    # Add number of planets if it exists
    if 'nplanets' in rundict_keys:
        if rundict['nplanets'] is not None:
            file_root += f'_k{rundict["nplanets"]}'

    # Check if there is a drift and add "d{n}" to file name
    drift_order = 0
    for par in parnames:
        if 'drift' in par:
            if par[6:] in ['lin', 'quad', 'cub', 'quar']:
                drift_order += 1
    if drift_order > 0:
        file_root += f'_d{drift_order}'

    # Label the run with nr of planets, live points, nr of cores, sampler and date
    file_root += f'_nlive{default_settings["nlive"]}'
    file_root += f'_ncores{size}'
    file_root += '_ultranest'
    file_root += '_'+isodate

    # Base directory
    # Check if a save directory was provided
    if 'save_dir' in rundict_keys:
        save_dir = rundict['save_dir']
    else:
        save_dir = ''
    base_dir = os.path.join(save_dir, file_root, 'ultraresults')

    # Update settings dictionary with fileroot and basedir
    default_settings.update({'log_dir': base_dir, 'file_root': file_root})

    return default_settings

class Output:
    pass


from bs4 import BeautifulSoup
import requests

country = raw_input("Enter the country:")
#print(country)

site_to_scrape = "https://en.wikipedia.org/wiki/List_of_national_capitals_and_largest_cities_by_country"
r = requests.get(site_to_scrape)
data = r.text
soup = BeautifulSoup(data)

print("Capital: "+soup.find('a',title=country).parent.findNext('td').find('a').string)


import sys

student_file = 'lab7.py'

f = open(student_file)
lines = f.readlines()
f.close()
lines = [line.strip() for line in lines]
lines = ['' if line.startswith('#') else line for line in lines]
code_clean = True
for i in range(len(lines)):
    if 'import' in lines[i] and not lines[i].endswith('math'):
        print(f'Line {i} of {student_file} contains an import or eval() statement. You must delete this line.')
        code_clean = False
    elif 'input' in lines[i]:
        print(f'Line {i} of {student_file} contains an input() statement. You must delete this line.')
        code_clean = False
    elif 'open' in lines[i]:
        print(f'Line {i} of {student_file} contains an open() statement. You must delete this line.')
        code_clean = False
    elif 'exit' in lines[i] or 'sys.exit' in lines[i]:
        print(f'Line {i} of {student_file} contains an exit() statement. You must delete this line.')
        code_clean = False

if not code_clean:
    print('Your ' + student_file + ' file contains one or more invalid lines of code.')
    print('You will need to remove them before running the driver.')
    print('Note that the presence of those lines renders your work ungradeable!')
    sys.exit()

def check_float_actual(exp, act):
    if isinstance(act, float):
        print('Actual return value:   {:.3f}'.format(act))
    else:
        print(f'Actual return value:   {act}')
    if isinstance(act, float) and abs(exp - act) <= 0.001:
        print('Correct!')
        return True
    elif not isinstance(act, float):
        print('Incorrect! (wrong value and/or wrong return type)')
        return False
    else:
        print('Incorrect!')
        return False

part_counts = [0] * 1
test_counts = []

from lab7 import *

part = 1
func = check_halves
args = [["abcdefgabcdegf"], ["abcdabcd"], ["aa"], ["a"], ["qwertyuiop"], ["xyx"], ["xxxy"], ["ggggggggggg"], ]
expected_return_values = [5, 4, 1, 0, 0, 0, 1, 5, ]
test_counts.append(len(args))

print('#' * 25 + f' Testing Part {part} ' + '#' * 25)
for arg_list, expected in zip(args, expected_return_values):
    print('Testing ' + func.__name__ + '() with args = ' + ', '.join([str(a) for a in arg_list]))
    print(f'Expected return value: {expected}')
    actual = func(*arg_list)
    print(f'Actual return value:   {actual}')
    if expected == actual:
        part_counts[part - 1] += 1
    print()
print('#' * 66 + '\n')

print('Results:')
for i in range(part):
    print(f'Part {i+1}: {part_counts[i]}/{test_counts[i]} tests passed')

#print('\n*** Please note that different test cases will be used during grading! ***')


from cases import *
import pandas as pd
import scipy.io
import sys
def compare_cases():
    coefs=scipy.io.loadmat("../data/timeseries.mat")
    trend_coefs=pd.read_csv("../data/trends.csv")
    season_coefs=pd.read_csv("../data/season.csv")
    num_years=1
    start_year=2020
    num_simulations=100
    seed=0
    params=[coefs,trend_coefs,season_coefs,num_years,start_year,seed,"independent",0,0]
    cases=[case0(*params[:-2]),case1(*params),case2(*params),case3_1(*params),case3_2(*params),case3_3(*params)]
    for case in cases:
        case.sendable_max=0
        try:
            case.platform_restriction=0
        except:
            pass
        case.simulate_n_years(n=num_simulations)
        assert np.all(np.abs(case.get_CO2()-cases[0].get_CO2())/1e9<1e-12)
compare_cases()
def simulate_5_steps_test(): #Test wether the simulation set up works as intended by more explicitely calculating the results than my for loops
    def coefs_to_function(trend_coef,season_coef,period):
        trendfunc=np.poly1d(trend_coef)
        seasonfunc=np.poly1d(season_coef)
        def seasonfunc_periodic(t):
            return seasonfunc((t-1)%period)
        return (lambda t:seasonfunc_periodic(t*period/52)+trendfunc(t*period/52))
    coefs=scipy.io.loadmat("../data/timeseries.mat")
    trend_coefs=pd.read_csv("../data/trends.csv")
    season_coefs=pd.read_csv("../data/season.csv")
    sigma_windsun=coefs["windsun_sigma"]
    #print(sigma_windsun)
    num_years=1
    start_year=2020
    num_simulations=100
    seed=0
    params=[coefs,trend_coefs,season_coefs,num_years,start_year,seed,0,0]
    testcase=case0(*params[:-2])
    testcase.simulate_n_years(n=1) #Simulate for one year
    simulation_results=testcase.simulation_results[:,:10]/(24*7)
    rng_wind=np.random.default_rng(0)
    rng_load=np.random.default_rng(1)
    rng_water=np.random.default_rng(2)
    order=["wind NO","wind DE","load NO","load DE","water NO","solar DE"]
    periods=[52,52,52,52,13,52]
    functions=[]
    for i in range(6):
        trend=trend_coefs[order[i]]
        season=season_coefs[order[i]]
        functions.append(coefs_to_function(trend,season,period=periods[i]))

    sigma_windsun=coefs["windsun_sigma"]
    matrix_windsun=coefs["windsun_coefs"][0]
    #print(matrix_windsun) #test correctness
    #print(sigma_windsun) #test correctness
    matrix_load_ar1=coefs["load_coefs"][0]
    matrix_load_ar2=coefs["load_coefs"][1]
    matrix_load_ar3=coefs["load_coefs"][2]
    sigma_water=coefs["water_sigma"]
    sigma_load=coefs["load_sigma"]
    #print(matrix_load_ar1);print(matrix_load_ar2);print(matrix_load_ar3);print(sigma_load) #test correctness
    #print(sigma_water)
    random_numbers_windsun=np.zeros((10,3))
    random_numbers_load=np.zeros((10,2))
    for i in range(10):
        random_numbers_windsun[i]=rng_wind.multivariate_normal(np.zeros(3),sigma_windsun)
        random_numbers_load[i]=rng_load.multivariate_normal(np.zeros(2),sigma_load)
    #print(random_numbers_windsun)
    random_numbers_water=np.zeros(10)
    sigmawater=np.sqrt(sigma_water[1,1]) #standard deviation for water
    sigmaload=np.sqrt(sigma_water[0,0]) #Standard deviation for load
    p=sigma_water[1,0]/(sigmawater*sigmaload) #rho in the covariance matrix
    for i in range(10):
        random_numbers_water[i]=rng_water.normal(sigmawater/sigmaload*p*random_numbers_load[i,0],np.sqrt((1-p**2))*sigmawater)

    results_windsun=np.zeros((10,3))
    results_loads=np.zeros((10,2))
    results_water=np.zeros(10)
    for i in range(10):
        results_windsun[i]=matrix_windsun@results_windsun[i-1]+random_numbers_windsun[i]
        results_loads[i]=matrix_load_ar1@results_loads[i-1]+matrix_load_ar2@results_loads[i-2]+matrix_load_ar3@results_loads[i-3]+random_numbers_load[i]
    results=np.zeros((10,6))
    for i in range(0,4):
        results_water[i]=random_numbers_water[i]
    for i in range(4,8):
        mean=np.mean(results_water[0:4])
        results_water[i]=random_numbers_water[i]+mean*1.189324
    for i in range(8,10):
        mean=np.mean(results_water[4:8])
        mean_prev=np.mean(results_water[0:4])
        results_water[i]=random_numbers_water[i]+mean*1.189324+mean_prev*(-0.484997)
    for i in range(10):
        time=i+(start_year-2017)*52
        results[i,0]=np.exp(functions[0](time)+results_windsun[i,0]) #Norwegian wind
        results[i,2]=np.exp(functions[2](time)+results_loads[i,0]) #Norwegian load
        results[i,1]=np.exp(functions[1](time)+results_windsun[i,1]) #German wind
        results[i,3]=np.exp(functions[3](time)+results_loads[i,1]) #German load
        results[i,4]=np.exp(functions[4](time)+results_water[i]) #Water NO
        results[i,5]=np.exp(functions[5](time)+results_windsun[i,2]) #German sun
    assert np.all(np.abs(results.T-simulation_results)<0.01)
simulate_5_steps_test()


'''
Guilherme Araújo Mendes de Souza - 156437
UNIFESP - ICT
AED 2
'''
import time

def separa(p, r, v):
    c = v[r]
    j = p
    for k in range(p, r):
        if v[k] <= c:
            t = v[j]
            v[j] = v[k]
            v[k] = t
            j += 1
    v[r] = v[j]
    v[j] = c
    return j

def quicksort (p, r, v):
    if(p<r):
        j = separa(p, r, v)
        quicksort(p, j-1, v)
        quicksort(j+1, r, v)

nome = input('Informe o nome do arquivo: ')
tamanho_vetor = int(input('Informe o tamanho do arquivo: '))
vetor = []

arquivo = open(nome, 'r')

for linhas in arquivo:
    vetor.append(linhas.strip())

arquivo.close()

inicio = time.process_time()
quicksort(0, tamanho_vetor-1, vetor)
fim = time.process_time()

tempo_decorrido = fim - inicio
print(f'Tempo de CPU com {tamanho_vetor} posições no vetor: {tempo_decorrido*1000} milissegundos')


from datetime import datetime, timedelta
import random
import re
import wsgiref.handlers
import cgi
import base64
from google.appengine.api import xmpp
from google.appengine.api import users
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext.ereporter import report_generator
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp import xmpp_handlers
from google.appengine.api.taskqueue import Task

from conversation import *
from stats import *

drinkers = set([])
informed = set([])
settingprefs = set([])
teacountdown = False
doublejeopardy = ""
lastround = datetime.now()

def send_random(recipient, choices, prefix=""):
  xmpp.send_message(recipient, prefix + random.sample(choices, 1)[0])

class Roster(db.Model):
  jid = db.StringProperty(required=True)
  teaprefs = db.StringProperty(required=False, default="")
  askme = db.BooleanProperty(required=False, default=True)
  newbie = db.BooleanProperty(required=False, default=True)

def get_roster():
  return Roster.all().fetch(limit=999)

def howTheyLikeItClause(message, talker):
  global TRIGGER_TEAPREFS
  global HOW_TO_TAKE_IT

  fromaddr = talker.jid

  # Try to work out if this includes a how they like it clause
  clauses = message.split(",")
  if len(clauses) > 1:
    del clauses[0]
    secondSentence = " ".join(clauses)
    if re.search(TRIGGER_TEAPREFS, secondSentence, re.IGNORECASE):
      talker.teaprefs = secondSentence
      talker.put()
      return

  # If they haven't given any preferences before
  if talker.teaprefs == "":
    send_random(fromaddr, HOW_TO_TAKE_IT)
    settingprefs.add(fromaddr)
    return

def selectByMadeVsDrunkRatio(drinkers):
  # Build a dictionary mapping the contents of drinkers onto their made drunk ratio
  probs = dict()
  probTotal = 0.0

  for person in drinkers:
    ratio = getMadeDrunkRatio(person)
    probs[person] = ratio
    probTotal += ratio

  # Now if we generate a random point between 0 and the total probs, then iterate through
  # the dictionary of listeners, summing the probabilities as we go, as soon as the probs
  # tip over the total, that person has been randomly selected with a weight.
  goalNumber = probTotal * random.random()
  probSum = 0.0
  for person in probs.keys():
    probSum += probs[person]
    if probSum >= goalNumber:
      return person

  # We probably had a floating point rounding error. Randomly select the first person in the list :P
  return drinkers[0]

def getSalutation(jid):
  return jid.split("@")[0].replace(".", " ").title()

def buildWellVolunteeredMessage(person):
  finalMessage = random.sample(WELL_VOLUNTEERED, 1)[0] + '\n'

  for drinker in drinkers:
    if drinker != person:
      temp = Roster.get_by_key_name(drinker)
      teapref = temp.teaprefs
      finalMessage += " * " + getSalutation(drinker) + " ("+teapref+")" + '\n'

  return finalMessage

class XmppHandler(xmpp_handlers.CommandHandler):
  """Handler class for all XMPP activity."""

  def unhandled_command(self, message=None):
    message.reply("I don't have any secret easter egg commands.....")

  def text_message(self, message=None):
    global NOBACKOUT
    global GREETING
    global AHGRAND
    global GOOD_IDEA
    global HUH
    global RUDE
    global NO_TEA_TODAY
    global JUST_MISSED
    global ADDPERSON
    global WANT_TEA

    global TRIGGER_HELLO
    global TRIGGER_YES
    global TRIGGER_TEA
    global TRIGGER_RUDE
    global TRIGGER_GOAWAY
    global TRIGGER_ADDPERSON
    global TRIGGER_TEAPREFS

    global teacountdown
    global drinkers
    global settingprefs
    global lastround

    fromaddr = self.request.get('from').split("/")[0]
    talker = Roster.get_or_insert(key_name=fromaddr, jid=fromaddr)

    # If they showed up in the middle of a round, ask them if they want tea in
    # the normal way after we've responded to this message
    if(talker.askme == False and teacountdown):
      send_random(fromaddr, WANT_TEA)
      informed.add(fromaddr)

    talker.askme=True
    talker.put()

    # Mrs Doyle takes no crap
    if re.search(base64.b64decode(TRIGGER_RUDE), message.body, re.IGNORECASE):
      send_random(fromaddr, RUDE)
      return

    # And sometimes people take no crap.
    if re.search(TRIGGER_GOAWAY, message.body, re.IGNORECASE):
      talker.askme=False
      talker.put()
      send_random(fromaddr, NO_TEA_TODAY)
      xmpp.send_presence(fromaddr, status=":( Leaving " + getSalutation(fromaddr) + " alone. So alone...", presence_type=xmpp.PRESENCE_TYPE_AVAILABLE)
      return

    xmpp.send_presence(fromaddr, status="", presence_type=xmpp.PRESENCE_TYPE_AVAILABLE)

    # See if we're expecting an answer as regards tea preferences
    if fromaddr in settingprefs:
      talker.teaprefs = message.body
      talker.put()
      settingprefs.remove(fromaddr)
      xmpp.send_message(fromaddr, "Okay!")
      return

    if teacountdown:
      if fromaddr in drinkers:
        if re.search(TRIGGER_TEAPREFS, message.body, re.IGNORECASE):
          xmpp.send_message(fromaddr, "So you like your tea '" + message.body + "'?")
          talker.teaprefs = message.body
          talker.put()
        elif re.search(TRIGGER_YES, message.body, re.IGNORECASE):
          xmpp.send_message(fromaddr, "Okay!")
        else:
          send_random(fromaddr, NOBACKOUT)
        return

      if re.search(TRIGGER_YES, message.body, re.IGNORECASE):
        drinkers.add(fromaddr)
        send_random(fromaddr, AHGRAND)
        howTheyLikeItClause(message.body, talker)

      else:
        send_random(fromaddr, AH_GO_ON)

    elif re.search(TRIGGER_ADDPERSON, message.body, re.IGNORECASE):
      emailtoinvite = re.search("("+TRIGGER_ADDPERSON+")", message.body, re.IGNORECASE).group(0)
      xmpp.send_invite(emailtoinvite)
      send_random(fromaddr, ADDPERSON)

    elif re.search(TRIGGER_TEA, message.body, re.IGNORECASE):
      send_random(fromaddr, GOOD_IDEA)
      howTheyLikeItClause(message.body, talker)

      drinkers.add(fromaddr)
      informed.add(fromaddr)

      for person in get_roster():
        if person.askme and not person.jid == fromaddr:
          xmpp.send_presence(jid=person.jid, presence_type = xmpp.PRESENCE_TYPE_PROBE)

      doittask = Task(countdown="120", url="/maketea")
      doittask.add()
      teacountdown = True

    elif re.search(TRIGGER_HELLO, message.body, re.IGNORECASE):
      send_random(fromaddr, GREETING)

    elif re.search(TRIGGER_YES, message.body, re.IGNORECASE) and (datetime.now() - lastround) < timedelta(seconds=120):
      send_random(fromaddr, JUST_MISSED)

    else:
      send_random(fromaddr, HUH)

class ProcessTeaRound(webapp.RequestHandler):
    def post(self):
      global ON_YOUR_OWN
      global WELL_VOLUNTEERED
      global OTHEROFFERED

      global drinkers
      global teacountdown
      global doublejeopardy
      global lastround
      global informed

      if len(drinkers) == 1:
        for n in drinkers:
          send_random(n, ON_YOUR_OWN)
      elif len(drinkers) > 0:
        # Select someone who wasn't the last person to make the tea
        doublejeopardy = teamaker = selectByMadeVsDrunkRatio(filter(lambda n : n != doublejeopardy, drinkers))

        for person in drinkers:
          if person == teamaker:
            statDrinker(person, len(drinkers))
            statRound  (person, len(drinkers))

            xmpp.send_message(person, buildWellVolunteeredMessage(person))
          else:
            send_random(person, OTHEROFFERED, getSalutation(teamaker))
            statDrinker(person)

      teacountdown = False
      drinkers = set([])
      settingprefs = set([])
      informed = set([])
      lastround = datetime.now()

class Register(webapp.RequestHandler):
    def post(self):
      global WANT_TEA
      global NEWBIE_GREETING
      global teacountdown
      global informed

      fromaddr = self.request.get('from').split("/")[0]
      person = Roster.get_or_insert(key_name=fromaddr, jid=fromaddr)

      if(person.newbie):
        xmpp.send_message(fromaddr, NEWBIE_GREETING)
        person.newbie = False
        person.put()

      if(not person.askme):
        xmpp.send_presence(fromaddr, status=":( Haven't heard from " + getSalutation(fromaddr) + " in a while...", presence_type=xmpp.PRESENCE_TYPE_AVAILABLE)
      else:
        xmpp.send_presence(fromaddr, status="", presence_type=xmpp.PRESENCE_TYPE_AVAILABLE)

      if(teacountdown and person.askme and fromaddr not in informed):
        send_random(fromaddr, WANT_TEA)
        informed.add(fromaddr)

def main():
  app = webapp.WSGIApplication([
      ('/maketea', ProcessTeaRound),
      ('/_ah/xmpp/message/chat/', XmppHandler),
      ('/_ah/xmpp/presence/available/', Register),
      ('/_ah/xmpp/subscription/subscribe/', Register),
      ], debug=True)
  wsgiref.handlers.CGIHandler().run(app)

if __name__ == '__main__':
  main()