"""Emotion model module."""
import random

import pytorch_lightning as pl
import torch
import torch.nn as nn
from torchaudio.transforms import FrequencyMasking, MelSpectrogram, TimeMasking
from torchmetrics.functional import mean_absolute_error, mean_absolute_percentage_error

from emonet.modules import (
    ChunkSpectrogram,
    GRUOutput,
    ReshapeOutput,
    TimeDistributed,
    VadChunk,
    WhiteNoise,
    get_vad,
)
from emonet.utils import get_sample
from emonet.wav_splitter import split_sample

class ConvTimeBlock(nn.Module):
    """Convolutional time block."""

    def __init__(
        self,
        in_channels: int,
        out_channels: int,
        kernel_size: int = 3,
        stride: int = 1,
        padding: int = 1,
        pool_kernel_size: int = 4,
        pool_stride: int = 4,
        dropout: float = 0.3,
    ):
        """
        Create a time-distributed convolutional time block.

        Parameters
        ----------
        in_channels: int
            Number of input channels for convolutional layer.
        out_channels: int
            Number of output channels for convolutional layer.
        kernel_size: int
            Kernel size for convolutional filter.
        stride: int
            Stride size for convolutional filter.
        padding: int
            Padding size for convolutional filter.
        pool_kernel_size: int
            Kernel size for pooling layer.
        pool_stride: int
            Stride size for pooling layer.
        dropout: float
            Dropout probability.
        """
        super().__init__()

        self.block = nn.Sequential(
            TimeDistributed(
                nn.Conv2d(
                    in_channels=in_channels,
                    out_channels=out_channels,
                    kernel_size=kernel_size,
                    stride=stride,
                    padding=padding,
                )
            ),
            TimeDistributed(
                nn.BatchNorm2d(num_features=out_channels),
            ),
            TimeDistributed(
                nn.ReLU(),
            ),
            TimeDistributed(
                nn.MaxPool2d(kernel_size=pool_kernel_size, stride=pool_stride)
            ),
            TimeDistributed(nn.Dropout(p=dropout)),
        )

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        """Pass input through time-distributed convolutional block layer."""
        return self.block(x)

class EmotionRegressor(pl.LightningModule):
    """Emotion regressor model."""

    def __init__(
        self,
        emotion: str,
        lr: float = 0.001,
        weight_decay: float = 0.01,
        snr_low: int = 15,
        snr_high: int = 30,
        freq_mask: int = 20,
        time_mask: int = 20,
        drop: float = 0.3,
        n_mels: int = 128,
        n_fft: int = 128 * 6,
        n_chunks: int = 10,
    ):
        """

        Parameters
        ----------
        emotion: str
            Emotion to train/score.
        lr: float
            Learning rate.
        weight_decay: float
            Weight decay for optimizer.
        snr_low: int
            Signal-to-noise ratio floor for additive white noise augmentation.
        snr_high: int
            Signal-to-noise ratio ceiling for additive white noise augmentation.
        freq_mask: int
            Size of frequency mask for data augmentation.
        time_mask: int
            Size of time mask for data augmentation.
        drop: float
            Dropout rate.
        n_mels: int
            Number of mel filterbanks.
        n_fft: int
            Size of FFT, creates n_fft // 2 + 1 bins.
        n_chunks: int
            Number of time-chunks to create from each sample.
        """
        super().__init__()
        self.emotion = emotion
        self.lr = lr
        self.weight_decay = weight_decay
        self.snr_low = snr_low
        self.snr_high = snr_high
        self.freq_mask = freq_mask
        self.time_mask = time_mask
        self.drop = drop
        self.n_mels = n_mels
        self.n_fft = n_fft
        self.n_chunks = n_chunks
        self.save_hyperparameters()
        self.loss_func = nn.MSELoss()

        self.model = nn.Sequential(
            self.conv_block(), self.lstm_block(), self.linear_block()
        )

    def conv_block(self):
        """Time-distributed CNN block."""
        return nn.Sequential(
            ChunkSpectrogram(self.n_chunks),
            ConvTimeBlock(
                in_channels=1, out_channels=16, pool_kernel_size=2, pool_stride=2
            ),
            ConvTimeBlock(
                in_channels=16, out_channels=32, pool_kernel_size=2, pool_stride=2
            ),
            ConvTimeBlock(
                in_channels=32, out_channels=64, pool_kernel_size=2, pool_stride=2
            ),
            ConvTimeBlock(
                in_channels=64, out_channels=128, pool_kernel_size=2, pool_stride=2
            ),
        )

    @staticmethod
    def lstm_block():
        """LSTM block."""
        return nn.Sequential(
            nn.Flatten(start_dim=2),  # keep batch, timestep dims
            GRUOutput(
                input_size=2048, hidden_size=64, bidirectional=True, batch_first=True
            ),
        )

    def linear_block(self):
        """Fully-connected block."""
        return nn.Sequential(
            nn.Dropout(self.drop),
            ReshapeOutput(),
            nn.Linear(128, 64),
            nn.ReLU(),
            nn.Dropout(self.drop),
            nn.Linear(64, 1),
        )

    def augment_pipe(self, choice, bs):
        """
        Data augmentation pipeline.

        Parameters
        ----------
        choice: int
            Random choice for augmentation.
        bs: int
            Batch size.

        Returns
        -------
        nn.Sequential
            Augmentation pipeline.
        """
        pipes = {
            0: nn.Sequential(
                nn.Identity(), MelSpectrogram(n_mels=self.n_mels, n_fft=self.n_fft)
            ),
            1: nn.Sequential(
                WhiteNoise(bs, self.snr_low, self.snr_high),
                MelSpectrogram(n_mels=self.n_mels, n_fft=self.n_fft),
            ),
            2: nn.Sequential(
                MelSpectrogram(n_mels=self.n_mels, n_fft=self.n_fft),
                FrequencyMasking(self.freq_mask),
            ),
            3: nn.Sequential(
                MelSpectrogram(n_mels=self.n_mels, n_fft=self.n_fft),
                TimeMasking(self.time_mask),
            ),
        }
        return pipes[choice]

    def get_results(self, spec, actual):
        """
        Get model results.

        Parameters
        ----------
        spec: torch.tensor
            Spectrogram.
        actual: float
            Actual emotion score.

        Returns
        -------
        Dict
            Dictionary of model results.
        """
        pred = self.model(spec)

        results = {
            "outputs": pred,
            "loss": self.loss_func(pred, actual),
            "MAE": mean_absolute_error(pred, actual),
            "MAPE": mean_absolute_percentage_error(pred, actual),
        }
        return results

    def training_step(self, batch, idx):
        """Training step."""
        x = batch[0].to(self.device)
        labels = batch[1]
        bs = x.shape[0]
        choice = random.randint(0, 3)
        make_spec = self.augment_pipe(choice, bs)
        spec = make_spec(x).unsqueeze(1)  # add channel dim to spec

        results = self.get_results(spec, labels)
        total_loss = results["loss"]

        self.log_dict(
            {
                "total_train_loss": total_loss,
                "train_loss": results["loss"],
                "train_mae": results["MAE"],
                "train_mape": results["MAPE"],
            },
            prog_bar=True,
            on_step=True,
            on_epoch=True,
            logger=True,
        )
        return total_loss

    def validation_step(self, batch, idx):
        """Validation step."""
        x = batch[0].to(self.device)
        labels = batch[1]
        make_spec = nn.Sequential(MelSpectrogram(n_mels=self.n_mels, n_fft=self.n_fft))
        spec = make_spec(x).unsqueeze(1)  # add channel dim to spec

        results = self.get_results(spec, labels)
        total_loss = results["loss"]

        self.log_dict(
            {
                "total_valid_loss": total_loss,
                "valid_loss": results["loss"],
                "valid_mae": results["MAE"],
                "valid_mape": results["MAPE"],
            },
            prog_bar=True,
            on_step=True,
            on_epoch=True,
            logger=True,
        )
        return total_loss

    def test_step(self, batch, idx):
        """Test step."""
        x = batch[0].to(self.device)
        labels = batch[1]
        raise NotImplementedError

    def predict_step(self, batch, batch_idx, dataloader_idx=0):
        """Predict step."""
        x = batch[0].to(self.device)
        return self.forward(x)

    @staticmethod
    def preprocess(x):
        """Preprocess an audio tensor be applying VAD model."""
        if x.shape[-1] < 16000 * 8:
            raise ValueError(
                "Cannot preprocess tensor less than 8 seconds in duration."
            )
        vad = VadChunk(*get_vad("both"))
        return vad(x)

    def score_file(self, file, sample_rate=16000, vad=True):
        """
        Score a WAV file.

        Splits audio signal into separate 8-second chunks, individually scores each and returns
        mean across splits as final score.

        Parameters
        ----------
        file: Union[str, pathlib.Path]
            Filepath to audio file.
        sample_rate: int
            Sample rate of audio file; default 16,000hz
        vad: bool
            Whether to implement voice activity detection as preprocessing step; default True.

        Returns
        -------
        float
            Emotion score.
        """
        signal, _ = get_sample(file, sample_rate)
        return self.score_signal(signal, vad)

    def score_signal(self, x, vad=True):
        """
        Score a tensor.

        Splits audio signal into separate 8-second chunks, individually scores each and returns
        mean across splits as final score.

        Parameters
        ----------
        x: torch.Tensor
            Audio signal to score.
        vad: bool
            Whether to implement voice activity detection as preprocessing step; default True.

        Returns
        -------
        float
            Emotion score.

        """
        if vad:
            x = self.preprocess(x)
        if x.ndim == 1:
            x = x.unsqueeze(0)  # need dim to match
        return self.forward(x)

    def forward(self, x):
        """
        Score a preprocessed tensor.

        Splits audio signal into separate 8-second chunks, individually scores each and returns
        mean across splits as final score.

        Parameters
        ----------
        x: torch.Tensor

        Returns
        -------
        float
            Emotion score.

        """
        splits = split_sample(x, n_seconds=8)
        spec = MelSpectrogram(n_mels=self.n_mels, n_fft=self.n_fft)
        samples = [spec(s).unsqueeze(1) for s in splits]
        self.model.eval()
        with torch.no_grad():
            preds = [self.model(s) for s in samples]
        return torch.tensor(preds).mean()

    def configure_optimizers(self):
        """Configure optimizer for training."""
        opt = torch.optim.AdamW(
            self.parameters(), lr=self.lr, weight_decay=self.weight_decay
        )
        return {
            "optimizer": opt,
            "lr_scheduler": {
                "scheduler": torch.optim.lr_scheduler.ReduceLROnPlateau(opt),
                "monitor": "train_loss",
                "frequency": 1,
            },
        }


import json

def main():
    # process the car roads
    with open("./Assignments/A05/assets/api/data/roads.geojson", 'r') as infile:
        car_roads = json.load(infile)
        # wipe the properties tag in each document
        for road in car_roads['features']:
            road['properties'] = {'type': 'carroad'}
        with open("./Assignments/A05/assets/api/data/roads_wiped.geojson", 'w') as outfile:
            json.dump(car_roads,outfile,indent='  ')

    # process the rail roads
    with open("./Assignments/A05/assets/api/data/railroads.geojson", 'r') as infile:
        rail_roads = json.load(infile)
        # wipe the properties tag in each document
        for road in rail_roads['features']:
            road['properties'] = {'type': 'railroad'}
        with open("./Assignments/A05/assets/api/data/railroads_wiped.geojson", 'w') as outfile:
            json.dump(rail_roads,outfile,indent='  ')

if __name__ == "__main__":
    main()


import numpy as np
import random
from matplotlib import pyplot as plt
import sys
sys.stdout = open('outputfile.txt', 'w')

#Note: I don't have a lot of experience with Python yet, so suggestions for improving the code are welcome!

relevant_ranks=['bronze','silver','gold']
DEBUG = False

def log(s):
    if DEBUG:
        print(s)

steps_gained_with_win ={
	'bronze':2,
	'silver':2,
	'gold':1,
	'platinum':1,
	'diamond':1
	}

steps_lost_with_loss ={
	'bronze':0,
	'silver':1,
	'gold':1,
	'platinum':1,
	'diamond':1
	}

def expected_games_without_tier_protection(game_win_prob, rank, bestof):

	"""The setting without tier protection is relatively easy.
	For bestof = 1, this function gives the exact expected number of games to reach the next rank in best-of-one.
	For bestof = 3, this function gives an approximation for the expected number of games to reach the next rank in best-of-three.
	This approximation assumes that any match takes 2.5 games.

	To determine this, this function creates a matrix to represent the system of equations of the form Ax=b
	Let x[n] represent the expected number of games to hit the next rank from state n
	For non-endpoint states n, it holds that x[n] = winrate * {1 + x[n+steps_gained_with_win]) + lossrate * (1 + x[n-steps_lost_with_loss])
	This implies that x[n] - winrate * x[n+steps_gained_with_win] - lossrate * x[n-steps_lost_with_loss] = 1
	A matrix is created with these numbers, making appropriate adjustments for endpoint states, then solved

	Parameters -
		game_win_prob: Probability to win any game
		rank: the rank we're interested in, e.g., 'silver'
		bestof: must be 1 or 3

	Returns - a number that represents the expected number of games to reach the next rank
	"""
	if (bestof == 1):
		multiplier = 1
		winrate = game_win_prob
	if (bestof == 3):
		multiplier = 2
		winrate = game_win_prob * game_win_prob + 2 * game_win_prob * game_win_prob * (1 - game_win_prob)
	lossrate = 1 - winrate

	steps_per_rank ={ k: v*4 for k, v in steps_per_tier.items()}
	A = np.zeros( (steps_per_rank[rank], steps_per_rank[rank]) )
	b = np.ones( steps_per_rank[rank] )

	for n in range(0, steps_per_rank[rank]):
		A[ n, n ] = 1
		A[ n, max(0, n - multiplier * steps_lost_with_loss[rank]) ] -= lossrate
		if (n + multiplier * steps_gained_with_win[rank] < steps_per_rank[rank]):
			A[ n, n + multiplier * steps_gained_with_win[rank] ] -= winrate

	x = np.linalg.solve(A, b)
	if (bestof == 1):
		return x[0]
	if (bestof == 3):
		return x[0] * 2.5

def give_index(rank, tier, step, protection):

	"""The challenging aspect with tier protection is turning the three-dimensional state space into a single dimension, as required for solving the LP
	There surely is a better way to do this, but my convoluted method should at least work
	State is given as (tier, step, protection)
	For steps>=2, protection must be 0
	For step 0 or step 1, protection can be 3, 2, 1, or 0.
	(Step 1, protection 3 never happens in practice. Also, step 1, protection 1 is equivalent to step 1, protection 0. They are included to allow fewer exceptions later in the code.)
	Consider Gold rank as an example.
	Index 0 is (4, 0, 0)
	Index 1 is (4, 1, 0)
	...
	Index 5 is (4, 5, 0)
	Index 6 is (3, 0, 0)
	Index 7 is (3, 1, 0)
	...
	Index 23 is (1, 5, 0)
	THEN
	Index 24 is (3, 0, 3)
	Index 25 is (3, 0, 2)
	Index 26 is (3, 0, 1)
	Index 27 is (2, 0, 3)
	Index 28 is (2, 0, 2)
	...
	Index 33 is (3, 1, 3)
	Index 34 is (3, 1, 2)
	Index 35 is (3, 1, 1)
	...
	Index 41 is (1, 1, 1)
	"""
	if (protection == 0):
		return (4 - tier) * steps_per_tier[rank] + step
	if (protection > 0 and step == 0):
		return 4 * steps_per_tier[rank] + (3 - tier) * 3 + 3 - protection
	if (protection > 0 and step == 1):
		return 4 * steps_per_tier[rank] + 9 + (3 - tier) * 3 + 3 - protection

def give_tier(index):
	if (index < 4 * steps_per_tier[rank] ):
		return 4 - ((index ) // steps_per_tier[rank])
	if (index >= 4 * steps_per_tier[rank] and index < 4 * steps_per_tier[rank] + 9):
		return 3 - ((index ) - 4 * steps_per_tier[rank]) // 3
	if (index >= 4 * steps_per_tier[rank] + 9):
		return 3 - ((index )- (4 * steps_per_tier[rank] + 9)) // 3

def give_step(index):
	if (index < 4 * steps_per_tier[rank]):
		return (index ) % steps_per_tier[rank]
	if (index >= 4 * steps_per_tier[rank] and index < 4 * steps_per_tier[rank] + 9):
		return 0
	if (index >= 4 * steps_per_tier[rank] + 9):
		return 1

def give_protection(index):
	if (index < 4 * steps_per_tier[rank]):
		return 0
	if (index >= 4 * steps_per_tier[rank] and index < 4 * steps_per_tier[rank] + 9):
		return 3 - ( (index - 4 * steps_per_tier[rank]) % 3)
	if (index >= 4 * steps_per_tier[rank] + 9):
		return 3 - ( (index - (4 * steps_per_tier[rank] + 9) ) % 3)

def describe_state(index):
	tier=str(give_tier(index))
	step=str(give_step(index))
	protection=str(give_protection(index))
	return "the state with tier " + tier + ", step " + step + ", and protection " + protection

def expected_games_with_tier_protection(game_win_prob, rank, bestof):
	"""The setting with tier protection is more involved.
	For bestof = 1, this function gives the exact expected number of games to reach the next rank in best-of-one.
	For bestof = 3, this function gives an approximation for the expected number of games to reach the next rank in best-of-three.
	This approximation assumes that any match takes 2.5 games.

	To determine this, this function creates a matrix to represent the system of equations of the form Ax=b

	Parameters -
		game_win_prob: Probability to win any game
		rank: the rank we're interested in, e.g., 'silver'
		bestof: must be 1 or 3

	Returns - a number that represents the expected number of games to reach the next rank
	"""

	if (bestof == 1):
		multiplier = 1
		winrate = game_win_prob
		protection = 3
	if (bestof == 3):
		multiplier = 2
		winrate = game_win_prob * game_win_prob + 2 * game_win_prob * game_win_prob * (1 - game_win_prob)
		protection = 1
	lossrate = 1 - winrate

	steps_per_rank ={ k: v*4 for k, v in steps_per_tier.items()}
	TotalNumberOfStates = steps_per_rank[rank] + 3 * 3 + 3 * 3
	A = np.zeros( (TotalNumberOfStates, TotalNumberOfStates) )
	b = np.ones( TotalNumberOfStates )

	for index in range(0, TotalNumberOfStates):
		log("\n")
		log("Index number " + str(give_index(rank, give_tier(index), give_step(index), give_protection(index))) + " is " + describe_state(index))
		A[ index, index ] = 1
		if (index + multiplier * steps_gained_with_win[rank] < steps_per_rank[rank]):
			#This means that a win won't advance you to the next rank and that you don't have protection
			if (give_step(index) + multiplier * steps_gained_with_win[rank] < steps_per_tier[rank]):
				#With a win, move to the next step in the same tier
				A[ index, index + multiplier * steps_gained_with_win[rank] ] -= winrate
				log( "--We take off winrate from " + describe_state(index + multiplier * steps_gained_with_win[rank]) )
			if (give_step(index) + multiplier * steps_gained_with_win[rank] >= steps_per_tier[rank]):
				#With a win, move to the next tier with protection, unless we're in Bronze Bo3 or Silver Bo3 and would end up in step 2+ with unnecessary protection
				new_step_with_win = give_step(index) + multiplier * steps_gained_with_win[rank] - steps_per_tier[rank]
				proper_protection = protection if new_step_with_win < 2 else 0
				A[ index, give_index(rank, give_tier(index) - 1, new_step_with_win, proper_protection) ] -= winrate
				log( "--We take off winrate from " + describe_state( give_index(rank, give_tier(index) - 1, new_step_with_win, proper_protection) ) )
			A[ index, max(0, index - multiplier * steps_lost_with_loss[rank]) ] -= lossrate
			log( "--We take off lossrate from " + describe_state( max(0, index - multiplier * steps_lost_with_loss[rank]) ) )
		if (index + multiplier * steps_gained_with_win[rank] >= steps_per_rank[rank] and give_protection(index) == 0):
			#This means that a win will advance you to the next rank
			A[ index, max(0, index - multiplier * steps_lost_with_loss[rank]) ] -= lossrate
			log( "--We take off lossrate from " + describe_state( max(0, index - multiplier * steps_lost_with_loss[rank]) ) )
		if (give_protection(index) > 0):
			#This means that you have protection
			new_step_with_win = give_step(index) + multiplier * steps_gained_with_win[rank]
			new_protection_with_win = 0 if new_step_with_win >= 2 else give_protection(index) - 1
			if (new_step_with_win < steps_per_tier[rank]):
				#With a win, move to the next step in the same tier
				A[ index, give_index(rank, give_tier(index), new_step_with_win, new_protection_with_win) ] -= winrate
				log( "--We take off winrate from " + describe_state( give_index(rank, give_tier(index), new_step_with_win, new_protection_with_win) ) )
			if (new_step_with_win >= steps_per_tier[rank]):
				#This should only happen in Bronze or Silver Bo3, but with a win, move to the next tier or rank
				new_step_with_win = new_step_with_win - steps_per_tier[rank]
				if (give_tier(index) > 1):
					proper_protection = protection if new_step_with_win < 2 else 0
					A[ index, give_index(rank, give_tier(index) - 1, new_step_with_win, proper_protection) ] -= winrate
					log( "--We take off winrate from " + describe_state( give_index(rank, give_tier(index) - 1, new_step_with_win, proper_protection) ) )
			A[ index, give_index(rank, give_tier(index), max(0, give_step(index) - multiplier * steps_lost_with_loss[rank]), give_protection(index) - 1) ] -= lossrate
			log( "--We take off lossrate from " + describe_state( give_index(rank, give_tier(index), max(0, give_step(index) - multiplier * steps_lost_with_loss[rank]), give_protection(index) - 1) ) )

	x = np.linalg.solve(A, b)
	if (bestof == 1):
		return x[0]
	if (bestof == 3):
		return x[0] * 2.5

def run_simulation(game_win_prob, rank, bestof):
	"""Simulaton approach, with tier protection.
	For bestof = 1, this approximates the expected number of games to reach the next rank in best-of-one.
	For bestof = 3, this approximates the expected number of games to reach the next rank in best-of-three.
	The approximation accurately takes into account that the expected number of games per match is different for matches won and matches lost.

	Parameters -
		game_win_prob: Probability to win any game
		rank: the rank we're interested in, e.g., 'silver'
		bestof: must be 1 or 3

	Returns - a number that approximates the expected number of games to reach the next rank
	"""

	if (bestof == 1):
		multiplier = 1
		winrate = game_win_prob
		protection = 3
	if (bestof == 3):
		multiplier = 2
		winrate = game_win_prob * game_win_prob + 2 * game_win_prob * game_win_prob * (1 - game_win_prob)
		protection = 1
		games_per_match_won = (2 * game_win_prob * game_win_prob + 3 * 2 * game_win_prob * game_win_prob * (1 - game_win_prob) ) / winrate
		games_per_match_lost = (2 * (1 - game_win_prob) * (1 - game_win_prob) + 3 * 2 * (1 - game_win_prob) * (1 - game_win_prob) * game_win_prob ) / (1 - winrate)
	lossrate = 1 - winrate

	games_per_simulation = []
	for x in range(50000):
		curr_tier = 4
		curr_step = 0
		curr_protection = 0
		match_count = 0
		curr_wins = 0
		curr_losses = 0
		continue_playing = True
		while(continue_playing):
			match_count += 1
			if(random.random() < winrate):
				match_win = True
				curr_wins +=1
			else:
				match_win = False
				curr_losses +=1
			if (match_win and curr_tier == 1 and curr_step + multiplier * steps_gained_with_win[rank] >= steps_per_tier[rank]):
				#Advance to the next rank
				continue_playing = False
			elif (match_win and curr_tier > 1 and curr_step + multiplier * steps_gained_with_win[rank] >= steps_per_tier[rank]):
				#Move to the next tier with protection
				curr_tier -= 1
				curr_protection = protection
				curr_step = curr_step + multiplier * steps_gained_with_win[rank] - steps_per_tier[rank]
			elif (match_win and curr_step + multiplier * steps_gained_with_win[rank] < steps_per_tier[rank]):
				#Move up steps in the same tier
				curr_step += multiplier * steps_gained_with_win[rank]
				curr_protection -= 1
			elif ((not match_win) and curr_step < multiplier * steps_lost_with_loss[rank] and curr_protection <= 0 and curr_tier < 4):
				#Fall back a tier
				curr_step = steps_per_tier[rank] - multiplier * steps_lost_with_loss[rank]
				curr_tier += 1
			elif ((not match_win) and curr_step < multiplier * steps_lost_with_loss[rank] and curr_protection > 0):
				#Remain at the start of the tier with reduced protection
				curr_protection -= 1
				curr_step = 0
			elif ((not match_win) and curr_step >= multiplier * steps_lost_with_loss[rank]):
				#Move down steps in the same tier
				curr_step -= multiplier * steps_lost_with_loss[rank]
				curr_protection -= 1
		if (bestof == 1):
			games_per_simulation.append(match_count)
		if (bestof == 3):
			game_count = curr_wins * games_per_match_won + curr_losses * games_per_match_lost
			games_per_simulation.append(game_count)
	return np.mean(games_per_simulation)

#Do some checks for verification
steps_per_tier ={
	'bronze':4,
	'silver':5,
	'gold':6,
	'platinum':7,
	'diamond':7
	}

rank = 'gold'
bestof = 1
win_prob = 0.55

number_games_exact = expected_games_without_tier_protection(win_prob, rank, bestof)
print(f'Under Preaseason 1 progression without tier protection, the exact E[games] required to go from the start of {rank.title()} to the next rank with a {win_prob*100:.1f}% winrate is {number_games_exact:.3f}.')
print(f'The correct number should be 195.364 games according to the work of others. So that is good, but things are easy without tier protection. \n')

for bestof in [1,3]:
	for rank in relevant_ranks:
		number_games_exact = expected_games_with_tier_protection(win_prob, rank, bestof)
		number_games_sim = run_simulation(win_prob, rank, bestof)
		print(f'Under Preaseason 1 progression with tier protection, the "exact" E[games] to go from {rank.title()} to the next rank in best-of-{bestof} with a {win_prob*100:.1f}% winrate is {number_games_exact:.3f}.')
		print(f'The simulation estimates {number_games_sim:.3f} games. Seems close enough. \n')

#Since everything checked out, let's get the Preseason 2 results for Limited.
steps_per_tier ={
	'bronze':4,
	'silver':5,
	'gold':5,
	'platinum':5,
	'diamond':5
	}

#First, output the Limited results as semicolon separated values
win_probs = [0.4+i*2/100 for i in range(0,16)]
bestof = 1
print("LIMITED win_prob; bronze to silver; silver to gold; gold to platinum")
for win_prob in win_probs:
	outputline=f'{win_prob:.3f}; '
	for rank in relevant_ranks:
		outputline += f'{expected_games_with_tier_protection(win_prob, rank, bestof):.3f}; '
	print(outputline)

#Second, output the Limited results as a plot
x_axis = np.arange(0.48, 0.64, 0.001)
y_axis = np.empty(161)
fig, ax = plt.subplots()
for rank in relevant_ranks:
	for i in range(0,161):
		y_axis[i]=expected_games_with_tier_protection(0.48+i/1000, rank, bestof)
	ax.plot(x_axis, y_axis, label=rank.title())
	ax.set(xlabel='Game win rate', ylabel='Expected number of games',
		   title='Expected games to reach the next rank in Limited')
	ax.set_xticklabels(['{:.0%}'.format(x) for x in ax.get_xticks()])
	ax.grid()
	plt.legend()
fig.savefig("Expected_number_of_games_Limited.png")

#Third, give the impact of tier protection
rank='gold'
for win_prob in [.5,.6]:
	number_games_exact = expected_games_without_tier_protection(win_prob, rank, bestof)
	print(f'Under Preaseason 2 Limited progression WITHOUT tier protection, the exact E[games] to go from {rank.title()} to the next rank in best-of-{bestof} with a {win_prob*100:.1f}% winrate is {number_games_exact:.3f}.')

#Next, let's get the Preseason 2 results for Constructed.
steps_per_tier ={
	'bronze':6,
	'silver':6,
	'gold':6,
	'platinum':6,
	'diamond':6
	}

for rank in relevant_ranks:

	#First, output the Constructed results as semicolon separated values
	win_probs = [0.45, 0.5, 0.52, 0.54, 0.56, 0.6, 0.62, 0.64, 0.66, 0.68, 0.7, 0.75, 0.8]
	print(f'\nCONSTRUCTED win_prob in rank {rank}; bo1; bo3; bo1 sim check; bo3 exact check')
	for win_prob in win_probs:
		outputline=f'{win_prob:.3f}; '
		outputline += f'{expected_games_with_tier_protection(win_prob, rank, 1):.3f}; '
		outputline += f'{run_simulation(win_prob, rank, 3):.3f}; '
		outputline += f'{run_simulation(win_prob, rank, 1):.3f}; '
		outputline += f'{expected_games_with_tier_protection(win_prob, rank, 3):.3f}'
		print(outputline)

	#Second, output the Constructed results as a plot
	x_axis = np.arange(0.48, 0.64, 0.01)
	y_axis = np.empty(17)
	fig, ax = plt.subplots()
	for i in range(0,17):
		y_axis[i]=expected_games_with_tier_protection(0.48+i/100, rank, 1)
	ax.plot(x_axis, y_axis, label='best-of-1')
	for i in range(0,17):
		y_axis[i]=run_simulation(0.48+i/100, rank, 3)
	ax.plot(x_axis, y_axis, label='best-of-3')

	ax.set(xlabel='Game win rate', ylabel='Expected number of games',
		   title=f'Expected games from {rank.title()} to the next rank in Constructed')
	ax.set_xticklabels(['{:.0%}'.format(x) for x in ax.get_xticks()])
	ax.grid()
	plt.legend()
	fig.savefig(f'Expected_number_of_games_Constructed_{rank.title()}.png')


import json
import random
import uuid
import time
import argparse
import sys
from concurrent.futures import ThreadPoolExecutor

# import the logging library
import logging

# import the boto3 library
import boto3
from botocore.exceptions import ClientError

# create a function that parses json strings and converts them to a dictionary
def parse_json(json_string):
    return json.loads(json_string)

# create a function to create a list of account ids
def create_account_ids():
    account_ids = []
    for i in range(0, 10):
        account_ids.append(str(uuid.uuid4()))
    logging.debug(account_ids)
    return account_ids

# create a function to create a list of site ids for each account
def create_site_ids(account_ids):
    site_ids = {}
    for account_id in account_ids:
        site_ids[account_id] = []
        for i in range(0, 20):
            site_ids[account_id].append(str(uuid.uuid4()))
    logging.debug(site_ids)
    return site_ids

# create a function to create a list of queue ids from a list of site ids
def create_queue_ids(site_ids):
    queue_ids = {}
    for site_id in site_ids:
        queue_ids[site_id] = []
        for i in range(0, 30):
            queue_ids[site_id].append(str(uuid.uuid4()))
    logging.debug(queue_ids)
    return queue_ids

# create a function that generates a dictionary of random data with the schema in ./schema/acceptance.json
def generate_data(schema_file, account_ids, site_ids, queue_ids):
    # create a dictionary to hold the data
    data = {}

    # open the schema file and read the contents
    with open(schema_file, 'r') as s:
        schema = parse_json(s.read())
        logging.debug(schema)

    # iterate over the schema and generate random data
    for key, value in schema.items():
        if value == 'integer':
            data[key] = random.randint(1, 20)
        elif value == 'timestamp':
            data[key] = time.strftime('%Y-%m-%d %H:%M:%S')
        elif value == 'boolean':
            data[key] = bool(random.getrandbits(1))
        elif value == 'special':
            if key == 'account_id':
                # random selection from a list of account ids
                data[key] = random.choice(account_ids)
            elif key == 'site_id':
                # random selection from a list of site ids
                data[key] = random.choice(site_ids[data['account_id']])
            elif key == 'queue_id':
                # random selection from a list of queue ids
                data[key] = random.choice(queue_ids[data['site_id']])
            elif key == 'media':
                data[key] = random.choice(['phone', 'chat', 'other'])
            elif key == 'outcome':
                data[key] = random.choice(['finished', 'escalated', 'transferred'])
            elif key == 'environment_name':
                data[key] = random.choice(['acceptance'])
        # uid
        elif value == 'uuid':
            data[key] = str(uuid.uuid4())
        else:
            logging.warning("Unknown key or value - %s:%s.", key, value)

    # return the data
    logging.debug(data)
    return data

# create a function that connects to AWS MSK and sends the data
# def send_data_msk(data, stream_name, partition_key):
#         # create a client for the kinesis service
#         client = boto3.client('kafka')
#         logging.debug(client)

#         # create a json string from the data
#         json_string = json.dumps(data)

#         response = None
#         try:
#             response = client.send_command(
#                 ClusterArn=stream_name,
#                 Command='SEND-RAW-MESSAGE',
#                 Data=json_string,
#                 PartitionKey=partition_key)
#         except ClientError as e:
#             print(e)
#             logging.exception("Couldn't put record in stream %s.", stream_name)
#             raise
#         logging.debug(response)
#         return response

# create a function that connects to AWS Kinesis and sends the data
def send_data_kinesis(data, stream_name, partition_key, region_name):

    # Create a kinesis client with the cluster arn
    client = boto3.client(
        'kinesis',
        region_name=region_name
    )

    logging.debug(client)

    # create a json string from the data
    json_string = json.dumps(data)

    response = None
    try:
        response = client.put_record(
            StreamName=stream_name,
            Data=json_string,
            PartitionKey=partition_key)
    except ClientError as e:
        print(e)
        logging.exception("Couldn't put record in stream %s.", stream_name)
        raise
    logging.debug(response)
    return response

# create a usage function
def usage():
    print("Usage: python3 datagenerator.py --stream-type <kinesis> \
                                           --stream-name <stream name> \
                                           --partition-key <partition key> \
                                           --region-name <region name> \
                                           --schema-file <schema file> \
                                           --records <number of records> \
                                           --threads <number of threads>")
    exit(1)

# function for the thread pool
def execute(args, account_ids, site_ids, queue_ids):
    # create a counter for the number of records sent
    records_sent = 0

    # create a loop that generates data and sends it to AWS Kinesis
    while records_sent < args.records:
        # generate some data
        data = generate_data(
            args.schema_file,
            account_ids,
            site_ids,
            queue_ids
        )

        # Kinesis or MSK?
        if args.stream_type == 'kinesis':
            # send the data
            response = send_data_kinesis(data, args.stream_name, args.partition_key, args.region_name)
        elif args.stream_type == 'msk':
            # send the data
            #response = send_data_msk(data, args.stream_name, args.partition_key)
            pass

        # log the response
        logging.info(response)

        # increment the counter
        records_sent += 1

# main function
def main():

    # create an argument parser
    parser = argparse.ArgumentParser()

    # add the argument for the number of records to generate
    parser.add_argument('--records', type=int, default=1000)

    # add the argument for the pause between records
    parser.add_argument('--pause', type=int, default=0)

    # add the argument for the log level
    parser.add_argument('--log-level', type=str, default='INFO')

    # add the argument for the log file
    parser.add_argument('--log-file', type=str, default='datagenerator.log')

    # add the argument for the log format
    parser.add_argument('--log-format', type=str, default='%(asctime)s %(thread)d %(levelname)s %(message)s')

    # add the argument for the log date format
    parser.add_argument('--log-date-format', type=str, default='%Y-%m-%d %H:%M:%S')

    # add an argument for stream name
    parser.add_argument('--stream-name', type=str, default='csa-stream')

    # add an argument for partition key
    parser.add_argument('--partition-key', type=str, default='account_id')

    # add an argument for the schema file
    parser.add_argument('--schema-file', type=str, default='./schema/acceptance.json')

    # add an argument for the number of threads
    parser.add_argument('--threads', type=int, default=100)

    # add an argument for the stream type
    parser.add_argument('--stream-type', type=str, default='kinesis')

    # add an argument for the region name
    parser.add_argument('--region-name', type=str, default='us-east-1')

    # print the usage if help is requested
    if '--help' in sys.argv or '-h' in sys.argv:
        usage()

    # parse the arguments
    args = parser.parse_args()

    # update the code below to use the arguments
    # set the log level
    logging.basicConfig(filename=args.log_file, level=args.log_level, format=args.log_format, datefmt=args.log_date_format)

    # generate a fixed list of account ids
    account_ids = create_account_ids()

    # generate a fixed list of site ids for each account
    site_ids = create_site_ids(account_ids)

    # extract the site ids from the site_ids dictionary
    site_ids_list = [site_id for account_id in site_ids for site_id in site_ids[account_id]]
    logging.debug(site_ids_list)

    # generate a fixed list of queue ids for each site
    queue_ids = create_queue_ids(site_ids_list)

     # Make things concurrent now. Implement thread pool
    futures = []
    with ThreadPoolExecutor(max_workers=args.threads) as executor:
        futures.append(executor.submit(execute, args, account_ids, site_ids, queue_ids))

    # wait for the futures to complete
    for future in futures:
        future.result()

# call the main function
if __name__ == '__main__':
    main()


from datetime import datetime

from solr import SolrConnection

from datahub.core import app
from datahub.util import datetime_add_tz

def connection():
    return SolrConnection(app.config['SOLR_URL'],
                          http_user=app.config.get('SOLR_USER'),
                          http_pass=app.config.get('SOLR_PASSWORD'))

def site_id():
    return app.config.get('SITE_ID', 'datahub.local')

def to_key(entity):
    return 'datahub/%s//%s' % (entity.__tablename__, entity.id)

def flatten_dict(d, prefix='meta', sep='_'):
    """ Flatten a dict to a list of values with each key
    joined to `prefix` by `sep`. """
    flat = {}
    for k, v in d.items():
        key = "".join([prefix, sep, k])
        if isinstance(v, dict):
            flat.update(flatten_dict(v, prefix=key, sep=sep))
        else:
            flat[key] = v
    return flat

def index_add(entity):
    """ Add an SQLAlchemy-controlled entity to the elastic search index
    """
    if not hasattr(entity, '__tablename__'):
        raise TypeError('Can only index entities with a __tablename__')
    if not hasattr(entity, 'to_dict'):
        raise TypeError('Can only index entities with a to_dict')
    conn = connection()
    data = entity.to_dict()
    data['_key'] = to_key(entity)
    data['site_id'] = site_id()
    data['doc_type'] = entity.__tablename__
    flat_data = {}
    for k, v in data.items():
        if isinstance(v, dict):
            flat_data.update(flatten_dict(v, prefix=k))
        else:
            flat_data[k] = v
    data = flat_data
    for k, v in data.items():
        if isinstance(v, datetime):
            data[k] = datetime_add_tz(v)
    #from pprint import pprint
    #pprint(data)
    try:
        conn.add_many([data])
        conn.commit()
    finally:
        conn.close()

def index_delete(entity):
    """ Deleta an SQLAlchemy-controlled entity from the elastic search
    index, catching any NotFoundExceptions. """
    if not hasattr(entity, '__tablename__'):
        raise TypeError('Can only index entities with a __tablename__')
    conn = connection()
    try:
        conn.delete_query('+_key:"%s" AND +site_id:"%s"' % (to_key(entity),
            site_id()))
        conn.commit()
    finally:
        conn.close()

def reset_index():
    """ Delete all entries from the index. """
    conn = connection()
    try:
        conn.delete_query('+site_id:"%s"' % site_id())
        conn.commit()
    finally:
        conn.close()


from collections import deque

n, m = map(int, input().split())

k = int(input())

visit = [False] * (k + 1)
horizon_bus = []
vertical_bus = []
bus = [[0]]
isHorizon = [False] * (k + 1)
for _ in range(k):
    b, x1, y1, x2, y2 = list(map(int, input().split()))
    if x1 > x2:
        x2, x1 = x1, x2
    if y1 > y2:
        y2, y1 = y1, y2

    if x1 - x2:
        vertical_bus.append([b, y1, x1, x2])
    else:
        horizon_bus.append([b, x1, y1, y2])
        isHorizon[b] = True
    bus.append([b, x1, y1, x2, y2])
bus.sort(key=lambda x: x[0])
dest = list(map(int, input().split()))
start = dest[:2]
end = dest[2:]

queue = deque()
answer = 0
for index, y, x1, x2 in vertical_bus:
    if start[1] == y and (x1 <= start[0] <= x2):
        queue.append([1, index, start[0], start[1]])
        visit[index] = True
for index, x, y1, y2 in horizon_bus:
    if start[0] == x and (y1 <= start[1] <= y2):
        queue.append([1, index, start[0], start[1]])
        visit[index] = True

def solve():
    while queue:
        count, thisBus, thisX, thisY = queue.popleft()
        thisBusData = bus[thisBus]
        if isHorizon[thisBus]:
            if thisX == end[0] and thisBusData[2] <= end[1] <= thisBusData[4]:
                return count
        else:
            if thisY == end[1] and thisBusData[1] <= end[0] <= thisBusData[3]:
                return count

        for nextBus, nextY, nextX1, nextX2 in vertical_bus:
            if visit[nextBus]:
                continue
            if isHorizon[thisBus]:
                if (nextX1 <= thisX <= nextX2) and (thisBusData[2] <= nextY <= thisBusData[4]):
                    queue.append([count + 1, nextBus, thisX, nextY])
                    visit[nextBus] = True
            else:
                if thisY == nextY and ((thisBusData[3] <= nextX1) != (thisBusData[1] <= nextX2)):
                    queue.append([count + 1, nextBus, nextX1, thisY])
                    visit[nextBus] = True

        for nextBus, nextX, nextY1, nextY2 in horizon_bus:
            if visit[nextBus]:
                continue
            if not isHorizon[thisBus]:
                if (nextY1 <= thisY <= nextY2) and (thisBusData[1] <= nextX <= thisBusData[3]):
                    queue.append([count + 1, nextBus, nextX, thisY])
                    visit[nextBus] = True

            else:
                if thisX == nextX and ((thisBusData[4] <= nextY1) != (thisBusData[2] <= nextY2)):
                    queue.append([count + 1, nextBus, thisX, nextY1])
                    visit[nextBus] = True

print(solve())

백준/Gold/2536. 버스 갈아타기/버스 갈아타기.py


#!/usr/bin/env python3
"""
A file housing all functions for preprocessing Twitter data.
"""

from nltk.corpus import stopwords
from nltk.stem.wordnet import WordNetLemmatizer
from nltk.tokenize import word_tokenize

def preprocess_text(text):
    """
    Preprocess the given text into tokens. This function
        - Removes stop words
        - Lemmatizes tokens
    Preconditions:
        text : String. The text to preprocess.
    Returns:
        The cleaned tokens, in dictionary format with all tokens mapped to True (i.e. the correct format for NLTK classifiers).
    """
    tokens = word_tokenize(text)

    stop_words = stopwords.words('english')
    lemmatizer = WordNetLemmatizer()
    cleaned_tokens = {
        lemmatizer.lemmatize(token) : True for token in tokens if not token in stop_words
    }

    return cleaned_tokens


# ==========================================================
# Author: Ankush Gupta, Tomas Jakab
# ==========================================================
from __future__ import print_function
from __future__ import absolute_import

from tensorflow.contrib.framework.python.ops import variables
import tensorflow as tf
import os.path as osp

# network definition:
from imm.models.imm_model import IMMModel
from imm.utils.box import Box

import imm.train.cnn_train_multi as tru
from imm.utils.colorize import colorize

import metayaml
from imm.utils.dataset_import import import_dataset
"""
So the main steps are:
  1. create the dataset object
  2. get a model factory
  3. build the training/summary ops
  4. run the training loop.
"""

class model_factory():
  """
  Factory which can be used to
  instantiate models.
  """
  def __init__(self, network, **kwargs):
    self.network = network
    self.net_args = kwargs

  def create(self):
    return self.network(**self.net_args)

def load_configs(file_names):
  """
  Loads the yaml config files.
  """
  # with open(file_name, 'r') as f:
  #   config_str = f.read()
  # config = Box.from_yaml(config_str)
  config = Box(metayaml.read(file_names))
  return config

def main(args):
  config = load_configs(args.configs)
  train_config = config.training
  gpus = range(args.ngpus)

  # get the data and logging (checkpointing) directories:
  data_dir = train_config.datadir
  log_dir = train_config.logdir

  SUBSET = 'train'
  NUM_STEPS = 30000000
  # value at which the gradients are clipped
  GRAD_CLIP = train_config.gradclip

  if args.checkpoint is not None:
    checkpoint_fname = args.checkpoint
  else:
    print(colorize('No checkpoint file specified. Initializing randomly.','red',bold=True))
    checkpoint_fname = osp.join(log_dir,'INVALID')

  opts = {}
  opts['gpu_ids'] = gpus
  opts['log_dir'] = log_dir
  opts['n_summary'] = 10 # number of iterations after which to run the summary-op
  if hasattr(train_config,'n_test'):
    opts['n_test'] = train_config.n_test
  else:
    opts['n_test'] = 500
  opts['n_checkpoint'] = train_config.ncheckpoint # number of iteration after which to save the model

  batch_size = train_config.batch
  graph = tf.Graph()
  with graph.as_default():
    global_step = variables.model_variable('global_step',shape=[],
                                            initializer=tf.constant_initializer(args.reset_global_step),
                                            trainable=False)

    # common model / optimizer parameters:
    lr = args.lr_multiple * tf.train.exponential_decay(train_config.lr.start_val,
                                global_step,
                                train_config.lr.step,
                                train_config.lr.decay,
                                staircase=True)
    if train_config.optim.lower() == 'adam':
      optim = tf.train.AdamOptimizer(lr, name='Adam')
    elif train_config.optim.lower() == 'adadelta':
      optim = tf.train.AdadeltaOptimizer(lr, rho=0.95,epsilon=1e-06,use_locking=False,name='Adadelta')
    elif train_config.optim.lower() == 'adagrad':
      optim = tf.train.AdagradOptimizer(lr, use_locking=False,name='AdaGrad')
    else:
      raise ValueError('Optimizer = %s not suppoerted'%train_config.optim)

    factory = model_factory(IMMModel,
                            config=config.model,
                            global_step=global_step)

    opts['batch_size'] = batch_size
    tf.summary.scalar('lr', lr) # add a summary
    print(colorize('log_dir: ' + log_dir,'green',bold=True))
    print(colorize('BATCH-SIZE: %d'%batch_size,'red',bold=True))

    # dynamic import of a dataset class
    dset_class = import_dataset(train_config.dset)

    # default datasets parameters
    train_dset_params = {}
    test_dset_params = {}

    train_subset = 'train'
    test_subset = 'test'
    if hasattr(train_config, 'train_dset_params'):
      train_dset_params.update(train_config.train_dset_params)
      if 'subset' in train_dset_params:
        train_subset = train_dset_params['subset']
        # delete because not positional kwarg
        del train_dset_params['subset']
    if hasattr(train_config, 'test_dset_params'):
      test_dset_params.update(train_config.test_dset_params)
      if 'subset' in test_dset_params:
        test_subset = test_dset_params['subset']
        # delete because not positional kwarg
        del test_dset_params['subset']

    train_dset = dset_class(train_config.datadir, subset=train_subset,
                            **train_dset_params)
    train_dset = train_dset.get_dataset(batch_size, repeat=True, shuffle=False,
                                        num_preprocess_threads=12)

    if hasattr(train_config, 'max_test_samples'):
      raise ValueError('max_test_samples attribute deprecated')
    test_dset = dset_class(train_config.datadir, subset=test_subset,
                           **test_dset_params)
    test_dset = test_dset.get_dataset(batch_size, repeat=False, shuffle=False,
                                      num_preprocess_threads=12)

    # set up inputs
    training_pl = tf.placeholder(tf.bool)
    handle_pl = tf.placeholder(tf.string, shape=[])
    base_iterator = tf.data.Iterator.from_string_handle(
      handle_pl, train_dset.output_types, train_dset.output_shapes)
    inputs = base_iterator.get_next()

    split_gpus = False
    if hasattr(config.model, 'split_gpus'):
      split_gpus = config.model.split_gpus

    # create the network distributed over multi-GPUs:
    loss, train_op, train_summary_op, test_summary_op, _ = tru.setup_training(
      opts, graph, optim, inputs, training_pl, factory, global_step,
      clip_value=GRAD_CLIP, split_gpus=split_gpus)

    # run the training loop:
    if args.restore_optim:
      restore_vars = 'all'
    else:
      restore_vars = 'model'

    tru.train_loop(opts, graph, loss, train_dset, training_pl, handle_pl,
                   train_op, train_summary_op, test_summary_op, NUM_STEPS,
                   global_step, checkpoint_fname,
                   test_dataset=test_dset,
                   ignore_missing_vars=args.ignore_missing_vars,
                   reset_global_step=args.reset_global_step,
                   vars_to_restore=restore_vars,
                   exclude_vars=[],
                   allow_growth=train_config.allow_growth)

if  __name__=='__main__':
  import argparse
  parser = argparse.ArgumentParser(description='Train Unsupervised Sequence Model')
  parser.add_argument('--configs', nargs='+', default=[], help='Paths to the config files.')
  parser.add_argument('--ngpus',type=int,default=1,required=False,help='Number of GPUs to use for training.')
  parser.add_argument('--lr-multiple',type=float,default=1,help='multiplier on the learning rate.')
  parser.add_argument('--checkpoint',type=str,default=None,
                      help='checkpoint file-name of the *FULL* model to restore.')
  parser.add_argument('--restore-optim',action='store_true',help='Restore the optimizer variables.')
  parser.add_argument('--reset-global-step',type=int,default=-1,help='Force the value of global step.')
  parser.add_argument('--ignore-missing-vars',action='store_true',help='Skip re-storing vars not in the checkpoint file.')
  args = parser.parse_args()
  main(args)


#!/usr/bin/python

# -*- coding: utf-8 -*-
import RPIO
import time
import telebot
import vars
import MySQLdb

bot = telebot.TeleBot(vars.token)
telegram_id = vars.telegramId
input_pins = (18,19,20,21,22,23,24,25,26,27)

def writeDoorState(when, state):
  db = MySQLdb.connect(vars.mysqlHost,vars.mysqUser,vars.mysqlPassword,vars.mysqlDatabase)
  cursor = db.cursor()
  sql = "INSERT INTO door(bool, date, name) VALUES (0, '%s', '%s')" % (when , state)
  try:
     # Execute the SQL command
     cursor.execute(sql)
     # Commit your changes in the database
     db.commit()
  except:
     # Rollback in case there is any error
     db.rollback()
  db.close()

for i in xrange(len(input_pins)):
  RPIO.setup(input_pins[i], RPIO.IN, pull_up_down=RPIO.PUD_DOWN)

def write_door_state(gpio_id, val):
  if val==0:
    bot.send_message(telegram_id, "Openning")
    writeDoorState(time.strftime("%d.%m.%Y %H:%M:%S"), 'Open')
  else:
    bot.send_message(telegram_id, "Closing")
    writeDoorState(time.strftime("%d.%m.%Y %H:%M:%S"), 'Close')

RPIO.add_interrupt_callback(24, write_door_state,pull_up_down=RPIO.PUD_DOWN,threaded_callback=True, debounce_timeout_ms=50)
RPIO.wait_for_interrupts()


"""base URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from django.urls.conf import include
from core import views
from accounts import views as e

urlpatterns = [

    path('', e.authenticationUser, name='login'),
    path('home/', views.home, name='home'),
    path('example/', views.example, name='example'),
    path('auditoria/', views.auditoria, name='auditoria'),
    path('', include('fiscalizacao.urls')),
    # modificado
    path('', include('monitoramento.urls')),
    #
    path('denuncias/', views.denuncias, name='denuncias'),
    path('fraudes/', views.fraudes, name='fraudes'),
    path('lista_negativa_agr/', views.lista_negativa_agr, name='lista_negativa_agr'),
    path('dossies/', views.dossies, name='dossies'),
    path('admin/', admin.site.urls),
    path('', include('cadastro.urls')),
    path('', include('accounts.urls'))
]


print("Welcome to the tip Calculator!")
total_bill = float(input("What was the total bill? $"))
percentage_tip = int(input("What percentage tip would you like to give? 10, 12 or 15"))
people_split = int(input("How many people to split the bill? "))
tip_percent = percentage_tip / 100
total_tipamount = total_bill * tip_percent
t_bill = total_bill * total_tipamount
bpp = t_bill / people_split
final_am = round(bpp, 2)
print(f"Each person should pay: ${final_am}")


from cnnClassifier.constants import *
from cnnClassifier.components.prepare_base_model import PrepareBaseModel
from cnnClassifier import logger
from cnnClassifier.config.configuration import ConfigurationManager
import torch

STAGE_NAME = "Prepare base model"

class PrepareBaseModelTrainingPipeline:
    def __init__(self):
        pass

    def main(self):
        logger.info(f"Stage: {STAGE_NAME}")
        config_manager = ConfigurationManager()
        config = config_manager.get_prepare_base_model_config()
        prepare_base_model = PrepareBaseModel(config)
        torch.save(prepare_base_model, config.updated_base_model_path)

        logger.info(f"Updated base model saved at {config.updated_base_model_path}")

if __name__ == "__main__":
    try:
        logger.info(f">>>>> Stage {STAGE_NAME} started <<<<<")
        prepare_base_model = PrepareBaseModelTrainingPipeline()
        prepare_base_model.main()
        logger.info(f">>>>> Stage {STAGE_NAME} completed. <<<<< \n")

    except Exception as e:
        logger.exception(e)
        raise e


import requests
from bs4 import BeautifulSoup
import csv

URL = 'https://www.detmir.ru/catalog/index/name/lego/'

HEADERS = {'user-agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:89.0) Gecko/20100101 Firefox/89.0',
           'accept': '*/*'}
HOST = 'https://www.detmir.ru/'
FILE = 'legos.csv'

def get_html(url, params=None):
    r = requests.get(url, headers=HEADERS, params=params)
    return r

def get_pages_count(html):
    soup = BeautifulSoup(html, 'html.parser')
    pagination = soup.find_all('span', class_= 'mhide')
    if pagination:
        return int(pagination[-1].get_text())
    else:
        return 1

def get_content(html):
    soup = BeautifulSoup(html, 'html.parser')
    items = soup.find_all('div', class_='be80pr-1') # Здесь обращаемся к объекту суп и ищем элементы.
    cards = []

    for item in items:
        cards.append(
            {
                'title': item.find('a', class_='cpshbz-0').get_text(strip=True), # Берем заголовок карточки
                'price': item.find('span', class_='price').get_text(strip=True),
                'city': item.find('span', class_='item region').get_text(
                    strip=True),
                'promo': item.find('div', class_='promo').get_text(),
                'link': HOST + item.find('div', class_='link').find('a').get('href'), # Получаем ссылку
            }
        )
    return cards

def save_file(items, path):
    with open(path, 'w', newline='') as file:
        writer = csv.writer(file, delimiter=';')
        writer.writerow(['Наименование', 'Цена', 'Город', 'Промо цена',
                          'Ссылка на страницу с товаром'])
        for item in items:
            writer.writerow([item['title'], item['price'], item['city'],
                             item['promo'], item['link']])

def parser():
    html = get_html(URL)
    if html.status_code == 200:
        legos = []
        print(get_content(html.text))
        pages = get_pages_count(html.text)
        for page in range(1, pages + 1):
            html = get_html(URL, params={'pages': page})
            legos.extend(get_content(html.text))
            if len(legos) > 5:
                save_file(legos, FILE)
            else:
                print('Количество элементов меньше 500!')
        print(legos)
    else:
        print('Error')

parser()


"""Clip likes

Revision ID: f659e63d8f95
Revises: 8da406f568b8
Create Date: 2018-06-20 13:07:58.907447

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = 'f659e63d8f95'
down_revision = '8da406f568b8'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('comments', sa.Column('content', sa.String(), nullable=True))
    op.drop_column('comments', 'media_id')
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('comments', sa.Column('media_id', sa.VARCHAR(), autoincrement=False, nullable=True))
    op.drop_column('comments', 'content')
    # ### end Alembic commands ###


# binary tree postorder traversal
class Node:
    def __init__(self, key):
        self.left = None
        self.right = None
        self.val = key

# class Solution:
#     def postorderTraversal(self, node):
#         if node is None:
#             return []
#         else:
#             res = []
#             res+=self.postorderTraversal(node.left)
#             res+=self.postorderTraversal(node.right)
#             res.append(node.val)
#         return res

# A function to do postorder tree traversal
def printPostorder(root):
    if root:
        printPostorder(root.left)
        printPostorder(root.right)
        print(root.val)

if __name__ == "__main__":
    root = Node(1)
    root.left = Node(2)
    root.right = Node(3)
    root.left.left = Node(4)
    root.left.right = Node(5)

    printPostorder(root)


import tensorflow as tf
import numpy as np
from tensorflow import keras
from keras import backend as K

import os
from keras.models import Model, model_from_json, load_model
from keras.utils.vis_utils import plot_model

from keras.losses import Loss

import utils

xs = np.array([-1.0, 0.0, 1.0, 2.0, 3.0, 4.0], dtype=float)
ys = np.array([-3.0, -1.0, 1.0, 3.0, 5.0, 7.0], dtype=float)

model = tf.keras.Sequential([keras.layers.Dense(units=1, input_shape=[1])])
model.compile(optimizer='sgd', loss='mean_squared_error')
model.fit(xs, ys, epochs=500, verbose=0)
print("optimizer='sgd', loss='mean_squared_error': ", model.predict([10.0]))

def my_huber_loss_with_threshold(threshold=1):
    def my_huber_loss(y_true, y_pred):
        error = y_true - y_pred
        is_small_error = tf.abs(error) <= threshold
        small_error_loss = tf.square(error) / 2
        big_error_loss = threshold * (tf.abs(error) - (0.5 * threshold))
        return tf.where(is_small_error, small_error_loss, big_error_loss)

    return my_huber_loss

def my_huber_loss(y_true, y_pred):
    threshold = 1
    error = y_true - y_pred
    is_small_error = tf.abs(error) <= threshold
    small_error_loss = tf.square(error) / 2
    big_error_loss = threshold * (tf.abs(error) - (0.5 * threshold))
    return tf.where(is_small_error, small_error_loss, big_error_loss)

model = tf.keras.Sequential([keras.layers.Dense(units=1, input_shape=[1])])
model.compile(optimizer='sgd', loss=my_huber_loss)
model.fit(xs, ys, epochs=500, verbose=0)
print("optimizer='sgd', loss=my_huber_loss: ", model.predict([10.0]))

class MyHuberLoss(Loss):
    threshold = 1

    def __init__(self, threshold):
        super().__init__()
        self.threshold = threshold

    def call(self, y_true, y_pred):
        error = y_true - y_pred
        is_small_error = tf.abs(error) <= self.threshold
        small_error_loss = tf.square(error) / 2
        big_error_loss = self.threshold * (tf.abs(error) - (0.5 * self.threshold))
        return tf.where(is_small_error, small_error_loss, big_error_loss)

    def get_config(self):
        return {'threshold': self.threshold}
    #
    # @classmethod
    # def from_config(cls, config):
    #     return cls(**config)

# Set options for model save/load.
MUST_SAVE_THE_MODEL = True
MUST_LOAD_MODEL = True

# SAVE_LOAD_MODEL_METHOD = 'model.to_json'
SAVE_LOAD_MODEL_METHOD = 'model.save'

MODEL_DIRECTORY = 'Data\Huber_loss_function\Models'
MODEL_FILE = os.path.join(MODEL_DIRECTORY, 'saved_model.pb')
WEIGHTS_FILE = os.path.join(MODEL_DIRECTORY, 'model_weights.h5')

OPTIMIZER = 'sgd'
LOSS = MyHuberLoss(threshold=1)
# METRICS = ['accuracy']

EPOCHS = 500
# BATCH_SIZE = 32

# Load or create model.
if MUST_LOAD_MODEL and os.path.exists(MODEL_FILE):
    # Load saved model if it exists.

    if SAVE_LOAD_MODEL_METHOD == 'model.to_json':
        json_file = open(MODEL_FILE, 'r')
        loaded_model_json = json_file.read()
        json_file.close()
        model = model_from_json(loaded_model_json)
        print("Model was load from disk!")

        model.load_weights(WEIGHTS_FILE)
        print("Weights loaded!")
        # model.compile(optimizer=OPTIMIZER, loss=LOSS, metrics=METRICS)
    else:
        model = load_model(MODEL_FILE,
                           custom_objects={'MyHuberLoss': MyHuberLoss})
        print("Model was load from disk!")

    plot_model(model, show_shapes=True, show_layer_names=True,
               to_file=os.path.join(MODEL_DIRECTORY, 'loaded-model.png'))
    print(model.summary())
    print("optimizer='sgd', loss=MyHuberLoss(threshold=1): ", model.predict([10.0]))

else:
    # Creating model

    model = tf.keras.Sequential([keras.layers.Dense(units=1, input_shape=[1])])
    model.compile(optimizer=OPTIMIZER, loss=LOSS)
    print("Model was created!")

    try:
        os.makedirs(MODEL_DIRECTORY)
    except:
        pass
    plot_model(model, show_shapes=True, show_layer_names=True,
               to_file=os.path.join(MODEL_DIRECTORY, 'model.png'))
    print(model.summary())

    # TRAIN model
    history = model.fit(xs, ys, epochs=EPOCHS, verbose=0)
    print("optimizer='sgd', loss=MyHuberLoss(threshold=1): ", model.predict([10.0]))
    print('history: ', history)

    # SAVING model and weights (if necessary)
    if MUST_SAVE_THE_MODEL:
        if SAVE_LOAD_MODEL_METHOD == 'model.to_json':
            model_json = model.to_json()
            with open(MODEL_FILE, 'w') as json_file:
                json_file.write(model_json)
                print("Model saved!")
                json_file.close()
            model.save_weights(WEIGHTS_FILE)
            print("Weights saved!")
        else:
            model.save(MODEL_FILE)
            print("Model saved!")

def my_rmse(y_true, y_pred):
    error = y_true - y_pred
    sqr_error = K.square(error)
    mean_sqr_error = K.mean(sqr_error)
    sqrt_mean_sqr_error = K.sqrt(mean_sqr_error)
    return sqrt_mean_sqr_error


# https://semver.org/

# compare metadata sets according to semver
# returns 1 if set_a has precedence over set_b
# returns 0 if the sets are equal
# returns -1 if set_b has precedence over set_a
def compare_meta(set_a, set_b):
    # if both sets are empty at the same time they are equal
    if (not len(set_a)) and (not len(set_b)):
        return 0

    # we know at least one set has items remaining
    # if one set empties first it has lower precedence
    if (not len(set_a)) or (not len(set_b)):
        return 1 if not len(set_b) else -1

    # both sets have items to compare at this level
    a = set_a.pop(0)
    b = set_b.pop(0)

    try:
        if int(a) == int(b):
            return compare_meta(set_a, set_b)
        return 1 if int(a) > int(b) else -1
    except ValueError:
        if str(a) == str(b):
            return compare_meta(set_a, set_b)
        return 1 if str(a) > str(b) else -1

# esure returned object is of type
def ensure_type(T):
    def decorator(f):
        def inner(*args, **kwargs):
            return T(f(*args, **kwargs))

        return inner

    return decorator

# class to operate on version numbers
class SemanticVersion:
    # determine if input string takes precedence over this version using semantic versioning
    # returns 0 if versions are the same
    # returns 1 if a has higher precedence
    # returns -1 if a has lower precedence
    @staticmethod
    def precedence(a, b):
        a = SemanticVersion.conform(a)
        b = SemanticVersion.conform(b)

        # first compare the major.minor.patch portion
        if a.major != b.major:
            return 1 if a.major > b.major else -1
        if a.minor != b.minor:
            return 1 if a.minor > b.minor else -1
        if a.patch != b.patch:
            return 1 if a.patch > b.patch else -1

        # if they are both release versions then they match
        if (not a.is_prerelease) and (not b.is_prerelease):
            return 0

        # now we know at least one is not a release version
        # if one is a release version then it will take precedeece
        if (not a.is_prerelease) or (not b.is_prerelease):
            return 1 if (not a.is_prerelease) else -1

        # now both are known to be prerelease versions
        if a.metadata != b.metadata:
            a = a.metadata.split(".")
            b = b.metadata.split(".")
            return compare_meta(a, b)

        # since the metadata strings matched these two versions have equal precedence
        return 0

    @staticmethod
    def conform(input):
        try:
            input._is_semver
            return input
        except AttributeError:
            if isinstance(input, str):
                return SemanticVersion.from_semver(input)
            raise TypeError("cannot conform input to semver")

    @classmethod
    def from_semver(cls, input):
        try:
            (numeral, metadata) = input.split("-", 1)
        except ValueError:
            numeral = input
            metadata = None
        (major, minor, patch) = numeral.split(".", 2)
        return cls(major, minor, patch, metadata)

    @staticmethod
    def match(a, b):
        return (
            True
            if SemanticVersion.conform(a).matches(SemanticVersion.conform(b))
            else False
        )

    def __init__(self, major, minor, patch, metadata=None):
        self._is_semver = True
        self._major = major
        self._minor = minor
        self._patch = patch
        self._metadata = metadata

    @property
    @ensure_type(int)
    def major(self):
        return self._major

    @property
    @ensure_type(int)
    def minor(self):
        return self._minor

    @property
    @ensure_type(int)
    def patch(self):
        return self._patch

    @property
    def is_prerelease(self):
        return (self._metadata is not None) and (self._metadata is not "")

    @property
    @ensure_type(str)
    def metadata(self):
        return self._metadata

    def to_string(self):
        # return f'{self.major}.{self.minor}.{self.patch}{"" if not self.is_prerelease "-"}{"" if not self.is_prerelease else self.metadata}'
        res = str(self.major) + "." + str(self.minor) + "." + str(self.patch)
        if self.is_prerelease:
            res += "-" + self.metadata
        return res

    # check if this version comes before the version b
    # returns True if the version b is preceded by this version
    # a result of True means that version b is an upgrade
    def precedes(self, b):
        return (
            True
            if (SemanticVersion.precedence(SemanticVersion.conform(b), self) == 1)
            else False
        )

    # checks if this version comes after version b
    # returns True if version b precedes this version
    # a result of True means that this version is an upgrade over version b
    def succeeds(self, b):
        return (
            True
            if (SemanticVersion.precedence(SemanticVersion.conform(b), self) == -1)
            else False
        )

    # checks if versions are equivalent
    def matches(self, b):
        return (
            True
            if (SemanticVersion.precedence(SemanticVersion.conform(b), self) == 0)
            else False
        )


#merge sort

def merge(array, left, middle, right):

    left_array = array[left:middle + 1]
    right_array = array[middle + 1:right + 1]
    i = j = 0
    k = left

    while i < len(left_array) and j < len(right_array):
        if left_array[i] < right_array[j]:
            array[k] = left_array[i]
            i += 1
        else:
            array[k] = right_array[j]
            j += 1

        k += 1

    while i < len(left_array):
        array[k] = left_array[i]
        i += 1
        k += 1

    while j < len(right_array):
        array[k] = right_array[j]
        j += 1
        k += 1

def merge_sort(array, left, right):
    if len(array) < 1:
        return

    if left >= right:
        return array[left]

    middle = (right + left) // 2

    merge_sort(array, left, middle)
    merge_sort(array, middle + 1, right)

    merge(array, left, middle, right)

array = [5, 7, 2, 4, 1, 8, 7, 4, 4, 4]
print(array)
merge_sort(array, 0, len(array) - 1)
print(array)


class Solution:
    def nextGreater(self, A):
        ngr = [-1]
        stack = [A[len(A)-1]]
        for i in range(len(A)-2, -1,-1):
            ele = A[i]
            while len(stack) > 0 and ele >= stack[len(stack)-1]:
                stack.pop()
            if len(stack) > 0:
                ngr.insert(0, stack[len(stack)-1])
            else:
                ngr.insert(0, -1)
            stack.append(A[i])
        return ngr


#%%
# Script to show why we cannot just use a naive solution
import numpy as np
from scipy import linalg
import matplotlib.pyplot as plt

# parameters
# no. of elements in psf array
psf_size = 10
# std of noise
noise_level = 0.005

# Creating input
x1,x2,x3,x4 = [0]*11,[1]*10,[-1]*10,[0]*10
x = np.array((x1 +x2 +x3 +x4))

# Creating PSF and Toeplitz matrix
def normd(x):
    prob_density = (np.pi) * np.exp(-0.5*((x)/1)**2)
    return prob_density

p = np.zeros(psf_size)
# array for plotting psf
p_plot = p
p[0] = normd(0)
for i in range(1,psf_size):
    p[i]=normd(0.25*i)
p *= 1/(2*np.sum(p)-p[0])
print("p is", p)
p_plot = np.append(p,np.zeros(x.size//4))
p = np.append(p,np.zeros(x.size-psf_size))
print("p is now", p)
A = linalg.toeplitz(p,p)
print(A)
print("cond of A is",np.linalg.cond(A))

# Adding noise
noise = np.random.normal(0,noise_level,size=x.size)
print("2-norm of noise is", np.linalg.norm(noise))
b_smooth = A@x
b_smooth_noise = b_smooth + noise

# Recreating input signal
x_solve = linalg.solve(A,b_smooth_noise)

print("2-norm of solution x is", np.linalg.norm(x_solve))
# Plotting results
plt.figure(0)
plt.plot(range(x.size),x)
plt.title("Input signal")

plt.figure(1)
plt.plot(range(x.size),x,label = "True signal")
plt.plot(range(b_smooth_noise.size),b_smooth_noise, label = "Blurred signal")
#plt.title("True and blurred signal", fontsize = 18)
plt.legend(loc =2, fontsize = 8)
# small plot
plt.axes([.65, .6, .2, .2])
a = plt.plot(np.append(np.flip(p_plot),p_plot),'g')
plt.axis('on')
plt.title("Point Spread Function", fontsize=8)
plt.xticks([])
plt.yticks([])
plt.savefig('1dsimple.png',dpi = 350)

plt.figure(3)
plt.plot(range(x.size),x_solve)
plt.title("Reconstructed input")
plt.savefig("bad_recon.png", dpi = 350)

# Maybe wanted to do some subplots
# fig, sub = plt.subplots(3)
# sub[0].plot(range(x.size),x)
# sub[0].set_title("Input signal")
# sub[1].plot(range(x.size),x)
# sub[1].plot(range(x.size),b_smooth)
# sub[1].set_title("Input + blurred input")
# sub[2].plot(range(x.size),x_solve)
# sub[2].set_title("Reconstructed input signal")

# %%
# plots for presentation
plt.figure(4)
plt.plot(range(b_smooth_noise.size),b_smooth_noise)
plt.savefig("lesgo.png", dpi = 350)

plt.figure(5)
plt.plot(range(x.size),x_solve)
plt.title(r'$A^{-1}b$',fontname="Times New Roman",fontweight="bold")
plt.savefig("lesgo2.png", dpi = 350)

plt.figure(6)
plt.plot(range(x.size),x)
plt.title(r'$\text{x}$',fontname="Times New Roman",fontweight="bold")
plt.savefig("lesgo3.png", dpi = 350)


import requests
from bs4 import BeautifulSoup

def getOriginalAspectRatio(title, imdb_number=None):
    BASE_URL = "https://www.imdb.com/"
    HEADERS = {
        'User-Agent': 'Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148'}

    if imdb_number:
        URL = "{}/title/{}/".format(BASE_URL, imdb_number)
    else:
        URL = BASE_URL + "find/?q={}".format(title)
        search_page = requests.get(URL, headers=HEADERS)

        # lxml parser would have been better but not currently supported in Kodi
        soup = BeautifulSoup(search_page.text, 'html.parser')

        title_url_tag = soup.select_one(
            '.ipc-metadata-list-summary-item__t')
        if title_url_tag:
            # we have matches, pick the first one
            title_url = title_url_tag['href']
            imdb_number = title_url.rsplit(
                '/title/', 1)[-1].split("/")[0]
            # this below could have worked instead but for some reason SoupSieve not working inside Kodi
            """title_url = soup.css.select(
                '.ipc-metadata-list-summary-item__t')[0].get('href')
                """

            URL = BASE_URL + title_url

    title_page = requests.get(URL, headers=HEADERS)
    soup = BeautifulSoup(title_page.text, 'html.parser')

    # this below could have worked instead but for some reason SoupSieve not working inside Kodi
    aspect_ratio_tags = soup.find(
        attrs={"data-testid": "title-techspec_aspectratio"})
    if aspect_ratio_tags:
        aspect_ratio_full = aspect_ratio_tags.select_one(
            ".ipc-metadata-list-item__list-content-item").decode_contents()

        """aspect_ratio_full = soup.find(
            attrs={"data-testid": "title-techspec_aspectratio"}).css.select(".ipc-metadata-list-item__list-content-item")[0].decode_contents()
            """

        if aspect_ratio_full:
            aspect_ratio = aspect_ratio_full.split(':')[0].replace('.', '')
    else:
        # check if video has multiple aspect ratios
        URL = "{}/title/{}/technical/".format(BASE_URL, imdb_number)
        tech_specs_page = requests.get(URL, headers=HEADERS)
        soup = BeautifulSoup(tech_specs_page.text, 'html.parser')
        aspect_ratio_li = soup.select_one("#aspectratio").find_all("li")
        if len(aspect_ratio_li) > 1:
            aspect_ratios = []

            for li in aspect_ratio_li:
                aspect_ratio_full = li.select_one(
                    ".ipc-metadata-list-item__list-content-item").decode_contents()
                aspect_ratio = aspect_ratio_full.split(':')[0].replace('.', '')
                aspect_ratios.append(aspect_ratio)

            return aspect_ratios

    return aspect_ratio


from datetime import date, datetime, timedelta, time
import inflect
import sys
p = inflect.engine()

def main():
    fecha_birth = input("Date of birth: ")

    try:
        fecha_birth2 = check_date(fecha_birth)
        if fecha_birth2 == None:
            raise sys.exit('Invalid date')
    except:
        raise sys.exit('Invalid date')

    date_hoy = datetime.combine(date.today(), time(hour=0, minute=0, second=0, microsecond=0))
    time_lapse = date_hoy - fecha_birth2
    minutes = time_lapse / timedelta(minutes=1)
    minutes = int(minutes)
    text = p.number_to_words(minutes, andword="")
    print (text.capitalize(), "minutes")
    #output = p.number_to_words(minutes)
    #print(output.capitalize(), "minutes")

def check_date(birth):
    try:
        birth2 = datetime.strptime(birth, '%Y-%m-%d')
        #print (type(birth2))
        return birth2
    except:
        return None

if __name__ == "__main__":
    main()


from ASCMedia import mediaDownloader
import sys

if __name__ == '__main__':
    # Log in
    # Ask for playlist name
    # Find playlist id
    # Get track data
    # Find in youutbe
    # Download
    # Insert metadata
    if(len(sys.argv) > 1):
        playlistName = sys.argv[1]
        print(playlistName)

    playlistID = mediaDownloader.getPlaylistID(playlistName)
    mediaDownloader.downloadTracksInPlaylist(playlistID, playlistName)

# END


# Nested Statement And Scope
# python deals with variables name you assign.When you create variable name in python the name is stored
# in name-space.Variable name also have scope. The determine the visibilty of scope

# Example
x = 25

def printer():
    x = 50
    return x

print(x)
print(printer())

# The SCOPE can be describe into 3 general Rules
# 1. Name of the assignments will create or change local names by default
# 2. Name refernce search four scope
# -local
# -enclosing Function
# -global
# -built-in
# 3. The Names declared in global and nonlocal statements map assigned names to enclosing modules and Function scope

# LEGB Rules
# -Local - Name assign with in the Function

def f(x):
    return x**2

f(5)

# - Enclosed Function Local
# Name in the local scope of any and all enclosing functions(def/lambda) from inner to outer
name = "This is global Name"

def greet():
    # Enclosing Function
    name = "Sammy"

    def hello():
        print('Hello' + name)

    hello()

greet()
# Global- Name assign to top-of the module file,or declare with in the def
print(name)
x = 50

def glob_funct():
    global x
    print("This Function is now using the global x!")
    print("Beacuse of the x is:", x)
    x = 2
    print("Ran funct() changed global x to", x)

print("Before calling Funct(), x is:", x)
glob_funct()
print("value of x outside the function", x)

# Built-In -Names Pre-assigned in the built-names modules: open,range
print(len('Amit'))

Methods and Functions/Nested statement and scope/NestedStatement.py


import numpy as np
import random
#from scipy.fftpack import dct
import json
import sys
import config
from env import make_env
import time

final_mode = True
render_mode = True
RENDER_DELAY = False

def make_model(game):
  # can be extended in the future.
  model = Model(game)
  return model

def sigmoid(x):
  return 1 / (1 + np.exp(-x))

def relu(x):
  return np.maximum(x, 0)

def passthru(x):
  return x

def softmax(x):
  e_x = np.exp(x - np.max(x))
  return e_x / e_x.sum(axis=0)

def sample(p):
  return np.argmax(np.random.multinomial(1, p))

class Model:
  ''' simple feedforward model '''
  def __init__(self, game):
    self.noise_level = 0.0
    self.env_name = game.env_name

    self.input_size = game.input_size
    self.output_size = game.output_size

    self.shapes = [ (game.input_size, game.output_size) ]

    self.sample_output = False
    if game.activation == 'relu':
      self.activations = [relu]
    elif game.activation == 'sigmoid':
      self.activations = [sigmoid]
    elif game.activation == 'passthru':
      self.activations = [np.tanh]
    else:
      self.activations = [np.tanh]

    self.weight = []
    self.param_count = game.input_size * game.output_size

    for shape in self.shapes:
      self.weight.append(np.zeros(shape=shape))

    self.render_mode = False

  def make_env(self, seed=-1, render_mode=False, load_model=True):
    self.render_mode = render_mode
    self.env = make_env(self.env_name, seed=seed, render_mode=render_mode, load_model=load_model)

  def get_action(self, x):
    # if mean_mode = True, ignore sampling.
    h = np.array(x).flatten()

    num_layers = len(self.weight)
    for i in range(num_layers):
      w = self.weight[i]
      h = np.matmul(h, w)
      h = self.activations[i](h + np.random.randn()*self.noise_level)

    return h

  def set_model_params(self, model_params):
    pointer = 0
    for i in range(len(self.shapes)):
      w_shape = self.shapes[i]
      s_w = np.product(w_shape)
      s = s_w
      chunk = np.array(model_params[pointer:pointer+s])
      self.weight[i] = chunk[:s_w].reshape(w_shape)
      pointer += s

  def load_model(self, filename):
    with open(filename) as f:
      data = json.load(f)
    print('loading file %s' % (filename))
    self.data = data
    model_params = np.array(data[0]) # assuming other stuff is in data
    self.set_model_params(model_params)
    # also load the vae and rnn
    self.env.vae.load_json('tf_models/vae.json')
    self.env.rnn.load_json('tf_models/rnn.json')

  def get_random_model_params(self, stdev=0.1):
    #return np.random.randn(self.param_count)*stdev
    return np.random.standard_cauchy(self.param_count)*stdev # spice things up!

  def init_random_model_params(self, stdev=0.1):
    params = self.get_random_model_params(stdev=stdev)
    self.set_model_params(params)
    vae_params = self.env.vae.get_random_model_params(stdev=stdev)
    self.env.vae.set_model_params(vae_params)
    rnn_params = self.env.rnn.get_random_model_params(stdev=stdev)
    self.env.rnn.set_model_params(rnn_params)

def evaluate(model):
  # run 100 times and average score, according to the reles.
  model.env.seed(0)
  total_reward = 0.0
  N = 100
  for i in range(N):
    reward, t = simulate(model, train_mode=False, render_mode=False, num_episode=1)
    total_reward += reward[0]
  return (total_reward / float(N))

def simulate(model, train_mode=False, render_mode=True, num_episode=5, seed=-1, max_len=-1):

  reward_list = []
  t_list = []

  max_episode_length = 2100

  if train_mode and max_len > 0:
    max_episode_length = max_len

  if (seed >= 0):
    random.seed(seed)
    np.random.seed(seed)
    model.env.seed(seed)

  for episode in range(num_episode):

    obs = model.env.reset()

    if obs is None:
      obs = np.zeros(model.input_size)

    total_reward = 0.0

    for t in range(max_episode_length):

      if render_mode:
        model.env.render("human")
        if RENDER_DELAY:
          time.sleep(0.01)

      action = model.get_action(obs)

      prev_obs = obs

      obs, reward, done, info = model.env.step(action)

      if (render_mode):
        pass
        #print("action", action, "step reward", reward)
        #print("step reward", reward)
      total_reward += reward

      if done:
        break

    if render_mode:
      print("reward", total_reward, "timesteps", t)
      model.env.close()

    reward_list.append(total_reward)
    t_list.append(t)

  return reward_list, t_list

def main():

  global RENDER_DELAY
  global final_mode

  assert len(sys.argv) > 2, 'python model.py gamename render/norender path_to_model.json [seed]'

  gamename = sys.argv[1]

  game = config.games[gamename]

  final_mode_string = str(sys.argv[2])
  if (final_mode_string == "render"):
    final_mode = False # don't run 100 times, just visualize results.

  use_model = False
  if (len(sys.argv) > 3):
    use_model = True
    filename = sys.argv[3]
    print("filename", filename)

  the_seed = np.random.randint(10000)
  if len(sys.argv) > 4:
    the_seed = int(sys.argv[4])
    print("seed", the_seed)

  model = make_model(game)
  print('model size', model.param_count)

  if (use_model):
    model.make_env(render_mode=render_mode)
    model.load_model(filename)
  else:
    model.make_env(render_mode=render_mode, load_model=False)
    model.init_random_model_params(stdev=np.random.rand()*0.01)

  if final_mode:
    total_reward = 0.0
    np.random.seed(the_seed)
    model.env.seed(the_seed)
    reward_list = []

    for i in range(100):
      reward, steps_taken = simulate(model, train_mode=False, render_mode=False, num_episode=1)
      print("iteration", i, "reward", reward[0])
      total_reward += reward[0]
      reward_list.append(reward[0])
    print("seed", the_seed, "average_reward", total_reward/100, "stdev", np.std(reward_list))

  else:

    reward, steps_taken = simulate(model,
      train_mode=False, render_mode=render_mode, num_episode=1)
    print ("terminal reward", reward, "average steps taken", np.mean(steps_taken)+1)

if __name__ == "__main__":
  main()


"""
2차원 바람

"""
import sys

input = sys.stdin.readline

def rotate_square(x1, y1, x2, y2):
    tmp = [[-1] * M for _ in range(N)] # 새로운 배열 생성

    for i in range(y2, y1, -1): # 위에 회전
        tmp[x1][i] = data[x1][i - 1]

    for i in range(x2,x1,-1):
        tmp[i][y2] = data[i-1][y2]

    for i in range(y1,y2):
        tmp[x2][i] = data[x2][i+1]

    for i in range(x1,x2):
        tmp[i][y1] = data[i+1][y1]

    for i in range(N): # 배열 복사
        for j in range(M):
            if tmp[i][j] != -1:
                data[i][j] = tmp[i][j]

def convert_avg(x1,y1,x2,y2):
    global data

    dx = [0, 0, -1, 1]
    dy = [-1, 1, 0, 0]

    tmp = [[-1] * M for _ in range(N)]

    for i in range(x1,x2+1):
        for j in range(y1,y2+1):
            tot = data[i][j]
            cnt = 1
            for d in range(4):
                nx,ny = i + dx[d], j + dy[d]

                if 0 <= nx < N and 0 <= ny < M:
                    tot += data[nx][ny]
                    cnt += 1

            tmp[i][j] = tot // cnt

    for i in range(N): # 배열 복사
        for j in range(M):
            if tmp[i][j] != -1:
                data[i][j] = tmp[i][j]

N, M, Q = map(int, input().split())
data = [list(map(int, input().split())) for _ in range(N)]
command = []

for _ in range(Q):
    a1, a2, a3, a4 = map(int, input().split())
    command.append((a1 - 1, a2 - 1, a3 - 1, a4 - 1))

for cmd in command:
    xx1, xy1, yx2, yy2 = cmd

    rotate_square(xx1, xy1, yx2, yy2)
    convert_avg(xx1,xy1,yx2,yy2)

for i in range(N):
    for j in range(M):
        print(data[i][j], end= ' ')
    print()


# What is the smallest positive number that is evenly divisible by all of the numbers
# from 1 to 20?

numbers = 20
# Start with the current minimum number = 2,
# since it is common knowledge that 2 is divisible by both 2 and 1.
currMinNum = 2
# nextNum represents the next integer that currMinNum has to be divisible by.
nextNum = 3
while nextNum <= numbers:
    temp = currMinNum
    addInt = nextNum - 1
    while currMinNum % temp != 0 or currMinNum % nextNum != 0:
        currMinNum += addInt
    nextNum += 1
print("Smallest Positive Number that is evenly divisible by all numbers from 1 to 20 :")
print(currMinNum)


def shift_alphabet(i, n):
    alphabet = list('abcdefghijklmnopqrstuvwxyz')
    index = alphabet.index(i)
    shifted_index = (index + n) % len(alphabet)
    shifted_char = alphabet[shifted_index]
    return shifted_char

char = input("Введите символ латинского алфавита: ")
num = int(input("Введите целое число: "))

shifted_char = shift_alphabet(char, num)
print(f"Смещенный символ: {shifted_char}")


from __future__ import annotations

import os

from fastapi import FastAPI, status
from fastapi.requests import Request
from fastapi.responses import StreamingResponse

app = FastAPI()

def video_to_chunks(source: str, chunk_size: int, start: int, size: int) -> bytes:
    bytes_read = 0

    with open(source, mode="rb") as stream:
        stream.seek(start)

        while bytes_read < size:
            bytes_to_read = min(chunk_size, size - bytes_read)
            yield stream.read(bytes_to_read)
            bytes_read += bytes_to_read

@app.get("/video")
def stream_video(request: Request):
    chunk_size = 1024 * 1024
    range = request.headers.get("Range")
    start, end = range.replace("bytes=", "").split("-")
    start = int(start)
    end = int(end) if end else start + chunk_size
    source = "red-leaves-in-autumn.mp4"
    total_size = os.path.getsize(source)

    return StreamingResponse(
        content=video_to_chunks(
            source=source, chunk_size=chunk_size, start=start, size=total_size
        ),
        status_code=status.HTTP_206_PARTIAL_CONTENT,
        headers={
            "Accept-Ranges": "bytes",
            "Content-Length": total_size,
            "Content-Range": f"bytes {start}-{start + chunk_size}/{total_size}",
            "Content-Type": "video/mp4",
        },
    )


class Map:
  _instance = None
  _initialized = False
  def __new__(cls, *args):
      '''Since we only want to initialize the map once this method is resposible for
      a one time creation of the map
      cls._instance: This ensures that only one creation of this class is made as required'''
      if cls._instance is None:
         cls._instance = super().__new__(cls)
      return cls._instance
  def __init__(self):
      if not Map._initialized:
          self.load_map(1)
          Map._initialized = True
  def __getitem__ (self,row):
      '''This is a getter method that will return the location that was requested'''
      return self._map[row]
  def __len__(self):
        '''This is the method that will give us the length of our map when we request for it'''
        n_rows = 0
        for i in self._map:
            n_rows += 1
        return n_rows
  def show_map (self,loc):
    """This is how the map will show at the end of all the calculations"""
    string_showmap = ""
    for row_indx in range(len(self._revealed)):
        for column_indx in range(len(self._revealed)):
            if self._revealed[row_indx][column_indx] == False:
                if row_indx == loc[0] and column_indx == loc[1]:
                    string_showmap += "*"
                else:
                    string_showmap += "x"
            else:
                if row_indx == loc[0] and column_indx == loc[1]:
                    string_showmap += "*"
                else:
                    string_showmap += ""+str(self._map[row_indx][column_indx])+ ""
        string_showmap += "\n"
    return string_showmap
  def reveal (self,loc):
      '''This is the method resposible for revealing the map at the location of where the'''
      self._revealed[loc[0]][loc[1]] = True
  def remove_at_loc(self,loc):
      '''This is the method resposible for removing any monsters on the map once the hero
        defeats it'''
      self._map[loc[0]][loc[1]] = "n"
  def load_map (self, map_num):
    '''This is the number for the map we are to load for the game. Maps are listed
    from one to three'''
    file = open ("map"+str(map_num)+".txt")
    row_map = file.readlines()
    self._map = []
    for row in row_map:
        list = []
        for column in row:
            if column != "\n":
                list.append(column)
        self._map.append(list)
        self._revealed = []
    for row in row_map:
        list = []
        for column in row:
            if column != "\n":
                list.append(False)
        self._revealed.append(list)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Sep  8 09:38:15 2019
@author: tim
"""

class Board():
    def __init__(self):
        self.rows, self.cols = (9, 9)
        self.board = [[None for i in range(self.cols)]
                      for j in range(self.rows)]

    def set_square(self, row, column, value):
        self.board[row][column] = value

    def unset_square(self, row, column):
        self.board[row][column] = None

    def draw_board(self):
        for i in range(self.rows):
            print('| ', end='')
            for j in range(self.cols):
                block = self.board[i][j]
                if (block):
                    print(' ' + str(block), end=' ')
                else:
                    print(' - ', end='')
                if ((j + 1) % 3 == 0):
                    print('|', end='')

            print('\n')
            if ((i + 1) % 3 == 0):
                for i in range(self.cols - 3):
                    print(' === ', end='')
            print('\n')

    def in_row(self, row, value):
        return value in self.board[row]

    def in_col(self, col, value):
        search_col = []

        for i in range(len(self.board)):
            search_col.append(self.board[i][col])

        return value in search_col

    def in_block(self, row, col, value):
        x_val = int(col / 3)
        y_val = int(row / 3)

        search_block = []

        for i in range(int(len(self.board) / 3)):
            for j in range(int(len(self.board[0]) / 3)):
                search_block.append(self.board[j + y_val * 3][i + x_val * 3])

        return value in search_block

    def is_valid(self, row, col, val):

        return not (self.in_row(row, val) or self.in_col(col, val)
                    or self.in_block(row, col, val))

    def get_board(self):
        return self.board

    def set_board(self, brd):
      if len(brd) != 9:
        print("Cannot set board!")
        return False

      for i in brd:
        if len(i) != 9:
          print("Cannot set board!")
          return False

      self.board = brd

def solve(brd):

    empty_spaces = []

    for row_index, row in enumerate(brd.get_board()):
        for col_index, col in enumerate(row):
            if col == None:
                empty_spaces.append((row_index, col_index))

    if not empty_spaces:
        return brd

    target = empty_spaces[0]

    for i in range(9):
        if brd.is_valid(target[0], target[1], i+1):
            brd.set_square(target[0], target[1], i+1)
            solution = solve(brd)
            if not solution:
                brd.unset_square(target[0], target[1])
            else:
                return solution

    return False

input_board = []

print("Please enter the board using 0's for empty spaces: ")

for i in range(9):
  input_board.append([None if int(x) == 0 else int(x) for x in input()])

brd = Board()

brd.set_board(input_board)

solution = solve(brd)

print('\n\n')

solution.draw_board()


import ast

height_ = '100%'
width_ = '100%'

nodes_ = {
    'shape': 'box',
    'margin': 10,
    'size': 25,
    'borderWidth': 2,
    'borderWidthSelected': 2,
    'font': {
        'multi': 'markdown',
        'align': 'center',
    },
    'labelHighlightBold': True,
    'widthConstraint': {
        'minimum': 30,
        'maximum': 100,
    }
}

edges_ = {
    'color': {
        'inherit': 'both',
    },
    'arrows': {
        'to': {
            'enabled': True,
            'scaleFactor': 0.5
        }
    },
    'chosen': False,
    "arrowStrikethrough": False,
    'smooth': {
        'type': "dynamic",
        'roundness': 0.5,
    }
}

physics_ = {
    'enabled': True,
}

manipulation_ = {
    'enabled': True,
    'initiallyActive': True,
    'addNode': """function(nodeData,callback) {
      nodeData.label = 'hello world';
      callback(nodeData);
}""",
    'addEdge': True,
    'editNode': None,
    'editEdge': True,
    'deleteNode': True,
    'deleteEdge': True,
}

interaction_ = {
    'hover': True,
    'hoverConnectedEdges': True,
    'multiselect': True,
    'keyboard': {
        'enabled': True,
        'bindToWindow': False,
        'autoFocus': True,
    },
    'navigationButtons': True,
}

layout_ = {
    'improvedLayout': True,
}

configure_ = {
    'enabled': False,
    'showButton': False,
}

default_options_ = dict(autoResize=True, height=height_, width=width_, configure=configure_, nodes=nodes_, edges=edges_,
                        layout=layout_, interaction=interaction_, manipulation=manipulation_, physics=physics_, )

def str_to_dict(str_data: str) -> dict:
    try:
        return ast.literal_eval(str_data)
    except Exception as e:
        print(e)
        return {}

def dict_to_str(dict_data: dict) -> str:
    try:
        return ast.literal_eval(dict_data)
    except Exception as e:
        print(e)
        return {}


def prime(n):  # 소수일때 True를 반환하는 함수
    count = 0
    for i in range(1, n+1):
        if n % i == 0:
            count += 1
    if count == 2:
        return True
    else:
        return False

N = int(input())
num_list = list(map(int, input().split()))

result = 0
for i in range(N):
    if prime(num_list[i]):
        result += 1
print(result)

[백준] 단계별로풀어보기/08 기본 수학 2/1978.py


import os
import logging
import pandas as pd
from typing import NoReturn
from omegaconf import DictConfig
import hydra

from src.configs.eval_params import EvalPipelineParamsSchema, EvalPipelineParams
from src.build_features import make_features, deserialize_transformer
from src.models import predict_model, deserialize_model

logger = logging.getLogger("eval_pipeline")
formatter = logging.Formatter("%(asctime)s %(levelname)s: %(message)s")
logger.setLevel(logging.INFO)

def eval_pipeline(params: EvalPipelineParams) -> NoReturn:
    logger.info(f"start eval pipeline with params {params}")
    df = pd.read_csv(params.input_df_path)
    logger.info(f"df.shape is {df.shape}")
    transformer = deserialize_transformer(params.transformer_path)
    transformed_df = make_features(transformer, df)
    logger.info(f"transformed_df.shape is {transformed_df.shape}")

    model = deserialize_model(params.model_path)
    preds = predict_model(
        model,
        transformed_df,
    )
    logger.info(f"preds.shape is {preds.shape}")
    pd.DataFrame(preds).to_csv(params.preds_path, header=False)
    logger.info(f"predicts saved to the {params.preds_path}")
    return preds

@hydra.main(config_path="configs", config_name="eval_config")
def eval_pipeline_command(cfg: DictConfig):
    os.chdir(hydra.utils.to_absolute_path("."))
    schema = EvalPipelineParamsSchema()
    params = schema.load(cfg)
    eval_pipeline(params)

if __name__ == "__main__":
    eval_pipeline_command()


for _ in range(int(input())):
    s = input()
    res = 0.0000
    p = ""
    for i in range(len(s)):
        if s[i]!='e':
            p+=s[i]
        else:
            res+=float(p)
            p=""
    if len(p)!=0:
        res+=int(p)
    print(format(res,'.4f'))