time = int(input("Enter number of seconds: "))

days = 0
hours = 0
minutes = 0
seconds = time

one_day = 24 * 60 * 60
if seconds > one_day:
    days = seconds // one_day
    seconds -= days * one_day

one_hour_seconds = 60 * 60

if seconds > one_hour_seconds:
    hour = seconds // one_hour_seconds
    seconds -= hour * one_hour_seconds

one_minute_seconds = 60

if seconds > one_hour_seconds:
    minute = seconds // one_minute_seconds
    seconds -= minute * one_minute_seconds

print(f"{time}:, seconds equals to {days} days, and {hours} hours, and {minutes} minutes, and {seconds} seconds.")


import typing

import numpy
import numpy as np
import pandas as pd
from googleapiclient.http import MediaFileUpload

from .base import GoogleBase

class GoogleSheets(GoogleBase):

    def __init__(self, credentials, sheet_url):
        self.credentials = credentials
        self.service = self.__get_sheets_service__()
        self.spreadsheet_id = self.__get_spreadsheet_id__(sheet_url)

        # Current worksheet (tab)
        self.worksheet_title = None
        self.worksheet_id = None
        self.endRowIndex = 1  # Helper variable to keep track of where to start writing values

    @staticmethod
    def __get_spreadsheet_id__(sheet_url):
        """
        Splits sheet url (https://docs.google.com/spreadsheets/d/1Bjj2WZO1l_6ZEnyAnd94Ui7rrSKHjOF-1SJRDznfADI/edit#gid=218800792)
        by "/", returns the id part (1Bjj2WZO1l_6ZEnyAnd94Ui7rrSKHjOF-1SJRDznfADI)
        """
        return sheet_url.split("/")[-2]

    def get_sheet(self, sheet_id=None, sheet_title=None):

        """
        This function sets current worksheet within the "parent" sheet. Call this function before working with insert
        data or chart functions or if worksheet is needed.
        :param sheet_id:
        :param sheet_title:
        :return: worksheet object or None if not found
        """

        if sheet_id is None and sheet_title is None:
            return None

        spreadsheet = self.service.spreadsheets().get(spreadsheetId=self.spreadsheet_id).execute()

        for _sheet in spreadsheet['sheets']:
            if (sheet_id and _sheet['properties']['sheetId'] == sheet_id) or \
                    (sheet_title and _sheet['properties']['title'] == sheet_title):
                self.worksheet_id = sheet_id
                self.worksheet_title = sheet_title

                return _sheet

        return None

    def create_sheet(self, title, rows, cols, tab_color=False):

        sheet_props = {
            "properties": {
                "title": title,
                "gridProperties": {
                    "rowCount": rows,
                    "columnCount": cols
                }
            }
        }

        if tab_color is True:
            sheet_props['properties']["tabColor"] = {
              "red": 0.7,
              "green": 0.0,
              "blue": 0.0
            }

        resp = self.service.spreadsheets().batchUpdate(spreadsheetId=self.spreadsheet_id, body={"requests": [
            {
                "addSheet": sheet_props
            }
        ]
        }).execute()

        self.worksheet_title = title
        self.worksheet_id = resp['replies'][0]['addSheet']['properties']['sheetId']

    def remove_sheet(self, sheet_id):
        resp = self.service.spreadsheets().batchUpdate(spreadsheetId=self.spreadsheet_id, body={"requests": [
            {
                "deleteSheet": {
                    "sheetId": sheet_id
                }
            }
        ]
        }).execute()

    def insert_data(self, data, row, column="B") -> dict:
        """
        Inserts rows into a sheet

        :param data:
        :param row:
        :param column:
        :return:
        """

        # Transform  column to uppercase
        column = column.upper()

        coords = {
            "startRowIndex": row - 1,  # indexes start at 0 not 1 !
            "endRowIndex": row + len(data) - 1,
            "startColumnIndex": ord(column) - 65,
            "endColumnIndex": ord(column) + len(data[0]) - 65
        }

        self.endRowIndex = row + len(data)

        # TODO: replace with ...values.append(...) ?
        self.service.spreadsheets().values().append(
            spreadsheetId=self.spreadsheet_id,
            range=f"{self.worksheet_title}!{column}{row}:{chr(ord(column) + len(data[0]))}{row + len(data)}",
            # range=f"{self.worksheet_title}!A1:Z1",
            valueInputOption="USER_ENTERED",
            body={
                "values": data
            }).execute()

        return coords

    @staticmethod
    def column_to_index(col):
        if isinstance(col, str):
            return ord(col) - 65
        return col

    def insert_chart(self,
                     data: pd.DataFrame = None,
                     title: str = "Chart",
                     chart_type: str = "LINE",
                     **kwargs) -> dict:

        """

        Insert data into the worksheet. Index is used as domain for chart, columns as individual series.

        :param data: pandas DataFrame with data to plot
        :param title: title of chart
        :param chart_type: one of: (BAR, LINE, AREA, COLUMN, SCATTER, COMBO, STEPPED_AREA)
        :param kwargs: data_offset, legend_x_title, legend_y_title, legend_position, ...
            data_offset can specify the offset used when inserting chart data
        :return: result dict
        """

        # TODO: add option to add data to a different sheet (better visual)

        # 1.)   Check if data is an instance of pandas DataFrame, if not, convert it
        if not isinstance(data, pd.DataFrame):
            data = pd.DataFrame(data=data)

        # 2.)   Insert data into current sheet
        data_to_insert = data.values.tolist()

        data_offset = kwargs.get("data_offset", self.endRowIndex)

        data_to_insert.insert(0, list(data.columns))

        coords = self.insert_data(data_to_insert, row=data_offset, column=kwargs.get("data_column_letter", "B"))

        # 3.)   Prepare chart request body

        domain_source = {
            "sheetId": self.worksheet_id,
            "startRowIndex": coords['startRowIndex'],
            "endRowIndex": coords['endRowIndex'],
            "startColumnIndex": coords['startColumnIndex'],
            "endColumnIndex": coords['startColumnIndex'] + 1
        }

        series = list()

        for i, column in enumerate(data.columns, start=1):
            series.append({
                "series": {
                    "sourceRange": {
                        "sources": [
                            {
                                "sheetId": self.worksheet_id,
                                "startRowIndex": coords['startRowIndex'],
                                "endRowIndex": coords['endRowIndex'],
                                "startColumnIndex": coords['startColumnIndex'] + i,
                                "endColumnIndex": coords['startColumnIndex'] + i + 1
                            }
                        ]
                    }
                },
                "targetAxis": "LEFT_AXIS"
            })

        body = {
            "addChart": {
                "chart": {
                    "spec": {
                        "title": title,
                        "basicChart": {
                            "chartType": chart_type,
                            "legendPosition": kwargs.get("legend_position", "BOTTOM_LEGEND"),
                            "axis": [
                                {
                                    "position": "BOTTOM_AXIS",
                                    "title": kwargs.get("legend_x_title", "x")
                                },
                                {
                                    "position": "LEFT_AXIS",
                                    "title": kwargs.get("legend_y_title", "y")
                                }
                            ],
                            "domains": [
                                {
                                    "domain": {
                                        "sourceRange": {
                                            "sources": [
                                                domain_source
                                            ]
                                        }
                                    }
                                }
                            ],
                            "series": series,
                            "headerCount": 1
                        }
                    },
                    "position": {
                        "overlayPosition": {
                            "anchorCell": {
                                "sheetId": kwargs.get("worksheet_id", self.worksheet_id),
                                "rowIndex": kwargs.get("row_index", self.endRowIndex - len(data_to_insert)),
                                "columnIndex": self.column_to_index(kwargs.get("column", len(data_to_insert[0]) + 2)),
                            },
                        },
                    }
                }
            }
        }

        result = self.service.spreadsheets().batchUpdate(
            spreadsheetId=self.spreadsheet_id,
            body={"requests": [body]}).execute()
        return result


"""Added 5k

Revision ID: 543d4a576dbd
Revises: ef5be88b8c83
Create Date: 2021-09-09 17:57:32.534329

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '543d4a576dbd'
down_revision = 'ef5be88b8c83'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('fivek',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('seconds', sa.Float(), nullable=False),
    sa.Column('date_completed', sa.Date(), nullable=False),
    sa.Column('user_id', sa.Integer(), nullable=False),
    sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_table('fivek')
    # ### end Alembic commands ###


#Input
person = input("What is your name")
person

#Output
print("Hello World!!")

#str.format
#Program 2.1
country = input("Which country do you live in?")
print("I live in {0}".format(country))

#Program 2.2
a = 10
b = 20
print("The values of a is {0} and b is is {1}".format(a, b))
print("The values of b is {1} and a is is {0}".format(a, b))

print("Give me {ball} ball".format(ball = "tennis"))

#f-strings
#Program 2.3
country = input("Which country do you live in?")
print(f"I live in {country}")

#Program 2.4
radius = int(input("Enter the radius of a circle"))
area_of_a_circle = 3.1415 * radius * radius
circumference_of_a_circle = 2 * 3.1415 * radius
print(f"Area = {area_of_a_circle} and Circumference={circumference_of_a_circle}")

#Program 2.5
number_of_days = int(input("Enter number of days"))
number_of_years = int(number_of_days / 365)
number_of_weeks = int(number_of_days % 365 / 7)
remaining_number_of_days = int(number_of_days % 365 % 7)
print(f"Years = {number_of_years}, Weeks = {number_of_weeks}, Days = {remaining_number_of_days}")


""""Declares a Python object mapping to the ``transactions`` relation."""
import sqlalchemy

from .base import Relation

class Transaction(Relation):
    """Maintains information about iDIN transactions.
    """

    __tablename__ = 'transactions'

    #: Transaction ID as specified by the intermediary.
    txid = sqlalchemy.Column(
        sqlalchemy.String,
        name='txid',
        primary_key=True,
        nullable=False
    )

    #: The date/time at which the transaction was created, in milliseconds
    #: since the UNIX epoch.
    created = sqlalchemy.Column(
        sqlalchemy.BigInteger,
        name='created',
        nullable=False
    )

    #: Current status of the transaction, may be one of ``open``,
    #: ``success``, ``cancelled``, ``failure`` or ``expired``.
    status = sqlalchemy.Column(
        sqlalchemy.String,
        name='status',
        nullable=False,
        default='open'
    )

    #: Entrance code to be included in the response from the iDIN
    #: acquirer.
    ec = sqlalchemy.Column(
        sqlalchemy.String,
        name='ec',
        nullable=False
    )

    #: Reference at the intermediary for accounting purposes.
    ref = sqlalchemy.Column(
        sqlalchemy.String,
        name='ref',
        nullable=False
    )

# pylint: skip-file


import rumps
import vlc

DEFAULT_STREAM = 'Groove Salad'

STREAMS = {
    DEFAULT_STREAM: 'https://ice4.somafm.com/groovesalad-128-mp3',
    'Chillsky': 'http://hyades.shoutca.st:8043/stream'
}

# rumps.debug_mode(True)

class GrooveApp(rumps.App):
    def __init__(self, name):
        self.player = None

        menu = [rumps.MenuItem(s, callback=self.menu_click) for s in STREAMS]
        menu.append(None)
        super(GrooveApp, self).__init__('Groove App', menu=menu, icon='stop.png', template=True)

    def vlc_event(self, event, stream_name):
        playing = event.type == vlc.EventType.MediaPlayerPlaying

        self.icon = 'play.png' if playing else 'stop.png'

        for m in self.menu:
            # need to ignore the separator
            if type(self.menu[m]) != rumps.MenuItem:
                continue

            self.menu[m].state = playing and self.menu[m].title == stream_name

    # i haven't found a better way to set the initial menu state to -1
    @rumps.timer(0.1)
    def timeout(self, sender):
        sender.stop()

        for m in STREAMS:
            self.menu[m].state = -1

        self.start_stream(DEFAULT_STREAM)

    def menu_click(self, sender):
        if sender.state == 0:
            sender.state = -1
            self.start_stream(sender.title)
        elif sender.state == 1:
            self.player.stop()

    def start_stream(self, stream_name):
        if self.player:
            self.player.stop()

        self.player = vlc.MediaPlayer(STREAMS[stream_name])

        self.events = self.player.event_manager()
        self.events.event_attach(vlc.EventType.MediaPlayerPlaying, self.vlc_event, stream_name)
        self.events.event_attach(vlc.EventType.MediaPlayerStopped, self.vlc_event, stream_name)

        self.player.play()

if __name__ == '__main__':
    GrooveApp('Groove').run()


import unittest
import nose.tools

from mia.reduction.reducers import *
from ..test_utils import *

class ReducersRegressionTest(unittest.TestCase):

    @classmethod
    def setupClass(cls):
        cls._img_dir = get_file_path("mias")
        cls._msk_dir = get_file_path("mias/masks")

    def test_blob_feature_reduction(self):
        reduction = BlobFeaturesReduction(self._img_dir, self._msk_dir)
        blobs_df = reduction.reduce()

        nose.tools.assert_equal(blobs_df.shape[1], 4)
        expected_columns = ['x', 'y', 'radius', 'breast_area']
        assert_data_frame_columns_match(blobs_df, expected_columns)

    def test_line_feature_reduction(self):
        reduction = LineFeaturesReduction(self._img_dir, self._msk_dir)
        lines_df = reduction.reduce()

        nose.tools.assert_equal(lines_df.shape[1], 6)
        expected_columns = ['area', 'min_row', 'min_col', 'max_row',
                            'max_col', 'breast_area']
        assert_data_frame_columns_match(lines_df, expected_columns)

    def test_patch_intensity_feature_reduction(self):
        reduction = BlobFeaturesReduction(self._img_dir, self._msk_dir)
        blobs_df = reduction.reduce()

        reduction = PatchIntensityFeaturesReduction(self._img_dir,
                                                    self._msk_dir)
        intensity_df = reduction.reduce(blobs_df)

        expected_columns = ['x', 'y', 'radius', 'breast_area', 'count',
                            'mean', 'std', 'min', '25%', '50%', '75%',
                            'max', 'skew', 'kurtosis']

        nose.tools.assert_equal(intensity_df.shape[1], 14)
        assert_data_frame_columns_match(intensity_df, expected_columns)

    def test_patch_texture_feature_reduction(self):
        reduction = BlobFeaturesReduction(self._img_dir, self._msk_dir)
        blobs_df = reduction.reduce()

        reduction = PatchTextureFeaturesReduction(self._img_dir,
                                                  self._msk_dir)
        texture_df = reduction.reduce(blobs_df)

        expected_columns = ['x', 'y', 'radius', 'breast_area', 'contrast',
                            'dissimilarity', 'homogeneity', 'energy']

        nose.tools.assert_equal(texture_df.shape[1], 8)
        assert_data_frame_columns_match(texture_df, expected_columns)


import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F

import re
import torchvision
import torch.nn.utils.spectral_norm as spectral_norm
import torch.fft

class FFC(nn.Module):

    def __init__(self, in_channels, out_channels, kernel_size,
                 ratio_gin=0.75, ratio_gout=0.75, stride=1, padding=0,
                 dilation=1, groups=1, bias=False, enable_lfu=False,
                 padding_type='reflect', gated=False, **spectral_kwargs):
        super(FFC, self).__init__()

        assert stride == 1 or stride == 2, "Stride should be 1 or 2."
        self.stride = stride

        in_cg = int(in_channels * ratio_gin)
        in_cl = in_channels - in_cg
        out_cg = int(out_channels * ratio_gout)
        out_cl = out_channels - out_cg
        #groups_g = 1 if groups == 1 else int(groups * ratio_gout)
        #groups_l = 1 if groups == 1 else groups - groups_g

        self.ratio_gin = ratio_gin
        self.ratio_gout = ratio_gout
        self.global_in_num = in_cg

        module = nn.Identity if in_cl == 0 or out_cl == 0 else nn.Conv2d
        self.convl2l = module(in_cl, out_cl, kernel_size,
                              stride, padding, dilation, groups, bias, padding_mode=padding_type)
        module = nn.Identity if in_cl == 0 or out_cg == 0 else nn.Conv2d
        self.convl2g = module(in_cl, out_cg, kernel_size,
                              stride, padding, dilation, groups, bias, padding_mode=padding_type)
        module = nn.Identity if in_cg == 0 or out_cl == 0 else nn.Conv2d
        self.convg2l = module(in_cg, out_cl, kernel_size,
                              stride, padding, dilation, groups, bias, padding_mode=padding_type)
        module = nn.Identity if in_cg == 0 or out_cg == 0 else SpectralTransform
        self.convg2g = module(
            in_cg, out_cg, stride, 1 if groups == 1 else groups // 2, enable_lfu, **spectral_kwargs)

        self.gated = gated
        module = nn.Identity if in_cg == 0 or out_cl == 0 or not self.gated else nn.Conv2d
        self.gate = module(in_channels, 2, 1)

    def forward(self, x):
        x_l, x_g = x if type(x) is tuple else (x, 0)
        out_xl, out_xg = 0, 0

        if self.gated:
            total_input_parts = [x_l]
            if torch.is_tensor(x_g):
                total_input_parts.append(x_g)
            total_input = torch.cat(total_input_parts, dim=1)

            gates = torch.sigmoid(self.gate(total_input))
            g2l_gate, l2g_gate = gates.chunk(2, dim=1)
        else:
            g2l_gate, l2g_gate = 1, 1

        if self.ratio_gout != 1:
            try:
                out_xl = self.convl2l(x_l) + self.convg2l(x_g) * g2l_gate
            except:
                import ipdb;ipdb.set_trace()
                aa=1
        if self.ratio_gout != 0:
            out_xg = self.convl2g(x_l) * l2g_gate + self.convg2g(x_g)

        return out_xl, out_xg

class FourierUnit(nn.Module):

    def __init__(self, in_channels, out_channels, groups=1, spatial_scale_factor=None, spatial_scale_mode='bilinear',
                 spectral_pos_encoding=False, use_se=False, se_kwargs=None, ffc3d=False, fft_norm='ortho'):
        # bn_layer not used
        super(FourierUnit, self).__init__()
        self.groups = groups

        self.conv_layer = torch.nn.Conv2d(in_channels=in_channels * 2 + (2 if spectral_pos_encoding else 0),
                                          out_channels=out_channels * 2,
                                          kernel_size=1, stride=1, padding=0, groups=self.groups, bias=False)
        self.bn = torch.nn.BatchNorm2d(out_channels * 2)
        self.relu = torch.nn.ReLU(inplace=True)

        # squeeze and excitation block
        self.use_se = use_se
        if use_se:
            if se_kwargs is None:
                se_kwargs = {}
            self.se = SELayer(self.conv_layer.in_channels, **se_kwargs)

        self.spatial_scale_factor = spatial_scale_factor
        self.spatial_scale_mode = spatial_scale_mode
        self.spectral_pos_encoding = spectral_pos_encoding
        self.ffc3d = ffc3d
        self.fft_norm = fft_norm

    def forward(self, x):
        batch = x.shape[0]

        if self.spatial_scale_factor is not None:
            orig_size = x.shape[-2:]
            x = F.interpolate(x, scale_factor=self.spatial_scale_factor, mode=self.spatial_scale_mode, align_corners=False)

        r_size = x.size()
        # (batch, c, h, w/2+1, 2)
        fft_dim = (-3, -2, -1) if self.ffc3d else (-2, -1)
        ffted = torch.fft.rfftn(x, dim=fft_dim, norm=self.fft_norm)
        ffted = torch.stack((ffted.real, ffted.imag), dim=-1)
        ffted = ffted.permute(0, 1, 4, 2, 3).contiguous()  # (batch, c, 2, h, w/2+1)
        ffted = ffted.view((batch, -1,) + ffted.size()[3:])

        if self.spectral_pos_encoding:
            height, width = ffted.shape[-2:]
            coords_vert = torch.linspace(0, 1, height)[None, None, :, None].expand(batch, 1, height, width).to(ffted)
            coords_hor = torch.linspace(0, 1, width)[None, None, None, :].expand(batch, 1, height, width).to(ffted)
            ffted = torch.cat((coords_vert, coords_hor, ffted), dim=1)

        if self.use_se:
            ffted = self.se(ffted)

        ffted = self.conv_layer(ffted)  # (batch, c*2, h, w/2+1)
        ffted = self.relu(self.bn(ffted))

        ffted = ffted.view((batch, -1, 2,) + ffted.size()[2:]).permute(
            0, 1, 3, 4, 2).contiguous()  # (batch,c, t, h, w/2+1, 2)
        ffted = torch.complex(ffted[..., 0], ffted[..., 1])

        ifft_shape_slice = x.shape[-3:] if self.ffc3d else x.shape[-2:]
        output = torch.fft.irfftn(ffted, s=ifft_shape_slice, dim=fft_dim, norm=self.fft_norm)

        if self.spatial_scale_factor is not None:
            output = F.interpolate(output, size=orig_size, mode=self.spatial_scale_mode, align_corners=False)

        return output

class SpectralTransform(nn.Module):

    def __init__(self, in_channels, out_channels, stride=1, groups=1, enable_lfu=False, **fu_kwargs):
        # bn_layer not used
        super(SpectralTransform, self).__init__()
        self.enable_lfu = enable_lfu
        if stride == 2:
            self.downsample = nn.AvgPool2d(kernel_size=(2, 2), stride=2)
        else:
            self.downsample = nn.Identity()

        self.stride = stride
        self.conv1 = nn.Sequential(
            nn.Conv2d(in_channels, out_channels //
                      2, kernel_size=1, groups=groups, bias=False),
            nn.BatchNorm2d(out_channels // 2),
            nn.ReLU(inplace=True)
        )
        self.fu = FourierUnit(
            out_channels // 2, out_channels // 2, groups, **fu_kwargs)
        if self.enable_lfu:
            self.lfu = FourierUnit(
                out_channels // 2, out_channels // 2, groups)
        self.conv2 = torch.nn.Conv2d(
            out_channels // 2, out_channels, kernel_size=1, groups=groups, bias=False)

    def forward(self, x):

        x = self.downsample(x)
        x = self.conv1(x)
        output = self.fu(x)

        if self.enable_lfu:
            n, c, h, w = x.shape
            split_no = 2
            split_s = h // split_no
            xs = torch.cat(torch.split(
                x[:, :c // 4], split_s, dim=-2), dim=1).contiguous()
            xs = torch.cat(torch.split(xs, split_s, dim=-1),
                           dim=1).contiguous()
            xs = self.lfu(xs)
            xs = xs.repeat(1, 1, split_no, split_no).contiguous()
        else:
            xs = 0

        output = self.conv2(x + output + xs)

        return output

class FFC_BN_ACT(nn.Module):

    def __init__(self, in_channels, out_channels,
                 kernel_size, ratio_gin, ratio_gout,
                 stride=1, padding=0, dilation=1, groups=1, bias=False,
                 norm_layer=nn.BatchNorm2d, activation_layer=nn.Identity,
                 padding_type='reflect',
                 enable_lfu=False, **kwargs):
        super(FFC_BN_ACT, self).__init__()
        self.ffc = FFC(in_channels, out_channels, kernel_size,
                       ratio_gin, ratio_gout, stride, padding, dilation,
                       groups, bias, enable_lfu, padding_type=padding_type, **kwargs)
        lnorm = nn.Identity if ratio_gout == 1 else norm_layer
        gnorm = nn.Identity if ratio_gout == 0 else norm_layer
        global_channels = int(out_channels * ratio_gout)
        self.bn_l = lnorm(out_channels - global_channels)
        self.bn_g = gnorm(global_channels)

        lact = nn.Identity if ratio_gout == 1 else activation_layer
        gact = nn.Identity if ratio_gout == 0 else activation_layer
        self.act_l = lact(inplace=True)
        self.act_g = gact(inplace=True)

    def forward(self, x):
        x_l, x_g = self.ffc(x)
        x_l = self.act_l(self.bn_l(x_l))
        x_g = self.act_g(self.bn_g(x_g))
        return x_l, x_g

class FFCResnetBlock(nn.Module):
    def __init__(self, dim, padding_type, norm_layer, activation_layer=nn.ReLU, dilation=1,
                 spatial_transform_kwargs=None, inline=False, **conv_kwargs):
        super().__init__()
        self.conv1 = FFC_BN_ACT(dim, dim, kernel_size=3, padding=dilation, dilation=dilation,
                                norm_layer=norm_layer,
                                activation_layer=activation_layer,
                                padding_type=padding_type,
                                **conv_kwargs)
        self.conv2 = FFC_BN_ACT(dim, dim, kernel_size=3, padding=dilation, dilation=dilation,
                                norm_layer=norm_layer,
                                activation_layer=activation_layer,
                                padding_type=padding_type,
                                **conv_kwargs)

        self.inline = inline

    def forward(self, x):
        if self.inline:
            x_l, x_g = x[:, :-self.conv1.ffc.global_in_num], x[:, -self.conv1.ffc.global_in_num:]
        else:
            x_l, x_g = x if type(x) is tuple else (x, 0)

        id_l, id_g = x_l, x_g

        x_l, x_g = self.conv1((x_l, x_g))
        x_l, x_g = self.conv2((x_l, x_g))

        x_l, x_g = id_l + x_l, id_g + x_g
        out = x_l, x_g
        if self.inline:
            out = torch.cat(out, dim=1)
        return out

class FFC_layer(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, padding=0):
        super(FFC_layer, self).__init__()
        self.ffc = FFC(in_channels=in_channels, out_channels=out_channels, kernel_size=kernel_size, padding=padding, gated=False)

    def forward(self, x):
        x_l, x_g = x[:, :-self.ffc.global_in_num], x[:, -self.ffc.global_in_num:]
        x_l, x_g = self.ffc((x_l, x_g))
        out = x_l, x_g
        out = torch.cat(out, dim=1)
        return out

class FFC_SPADE(nn.Module):
    def __init__(self, config_text, norm_nc, label_nc):
        super().__init__()

        assert config_text.startswith('spade')
        parsed = re.search('spade(\D+)(\d)x\d', config_text)
        param_free_norm_type = str(parsed.group(1))
        ks = int(parsed.group(2))

        if param_free_norm_type == 'instance':
            self.param_free_norm = nn.InstanceNorm2d(norm_nc, affine=False)
        # elif param_free_norm_type == 'syncbatch':
        #     self.param_free_norm = SynchronizedBatchNorm2d(norm_nc, affine=False)
        elif param_free_norm_type == 'batch':
            self.param_free_norm = nn.BatchNorm2d(norm_nc, affine=False)
        else:
            raise ValueError('%s is not a recognized param-free norm type in SPADE'
                             % param_free_norm_type)

        # The dimension of the intermediate embedding space. Yes, hardcoded.
        nhidden = 128

        pw = ks // 2
        self.mlp_shared = nn.Sequential(
            nn.Conv2d(label_nc, nhidden, kernel_size=ks, padding=pw),
            nn.ReLU()
        )
        self.mlp_gamma = FFC_layer(nhidden, norm_nc, kernel_size=ks, padding=pw)
        self.mlp_beta = FFC_layer(nhidden, norm_nc, kernel_size=ks, padding=pw)

    def forward(self, x, segmap):

        # Part 1. generate parameter-free normalized activations
        normalized = self.param_free_norm(x)

        # Part 2. produce scaling and bias conditioned on semantic map
        segmap = F.interpolate(segmap, size=x.size()[2:], mode='nearest')
        actv = self.mlp_shared(segmap)
        gamma = self.mlp_gamma(actv)
        beta = self.mlp_beta(actv)

        # apply scale and bias
        out = normalized * (1 + gamma) + beta

        return out

class FF_SPADEResnetBlock(nn.Module):
    def __init__(self, fin, fout, opt):
        super().__init__()
        # Attributes
        self.learned_shortcut = (fin != fout)
        fmiddle = min(fin, fout)

        # create conv layers
        self.conv_0 = FFC_layer(fin, fmiddle, kernel_size=3, padding=1)
        self.conv_1 = FFC_layer(fmiddle, fout, kernel_size=3, padding=1)
        if self.learned_shortcut:
            self.conv_s = FFC_layer(fin, fout, kernel_size=1)

        # apply spectral norm if specified
        if 'spectral' in opt.norm_G:
            self.conv_0 = spectral_norm(self.conv_0)
            self.conv_1 = spectral_norm(self.conv_1)
            if self.learned_shortcut:
                self.conv_s = spectral_norm(self.conv_s)

        # define normalization layers
        spade_config_str = opt.norm_G.replace('spectral', '')
        self.norm_0 = FFC_SPADE(spade_config_str, fin, opt.semantic_nc)
        self.norm_1 = FFC_SPADE(spade_config_str, fmiddle, opt.semantic_nc)
        if self.learned_shortcut:
            self.norm_s = FFC_SPADE(spade_config_str, fin, opt.semantic_nc)

    # note the resnet block with SPADE also takes in |seg|,
    # the semantic segmentation map as input
    def forward(self, x, seg):
        x_s = self.shortcut(x, seg)

        dx = self.conv_0(self.actvn(self.norm_0(x, seg)))
        dx = self.conv_1(self.actvn(self.norm_1(dx, seg)))

        out = x_s + dx

        return out

    def shortcut(self, x, seg):
        if self.learned_shortcut:
            x_s = self.conv_s(self.norm_s(x, seg))
        else:
            x_s = x
        return x_s

    def actvn(self, x):
        return F.leaky_relu(x, 2e-1)

# ResNet block used in pix2pixHD
# We keep the same architecture as pix2pixHD.
class FF_ResnetBlock(nn.Module):
    def __init__(self, dim, norm_layer, activation=nn.ReLU(False), kernel_size=3):
        super().__init__()

        pw = (kernel_size - 1) // 2
        self.conv_block = nn.Sequential(
            nn.ReflectionPad2d(pw),
            norm_layer(FFC_layer(dim, dim, kernel_size=kernel_size)),
            activation,
            nn.ReflectionPad2d(pw),
            norm_layer(FFC_layer(dim, dim, kernel_size=kernel_size))
        )

    def forward(self, x):
        y = self.conv_block(x)
        out = x + y
        return out


import heapq
from collections import defaultdict

class HeapDict:

    """
    O(logn)で要素の挿入
    O(logn)で要素の削除
    O(1)で要素の存在確認
    O(1)で最小値の取得
    """

    def __init__(self):
        """
        h : 最小値を保持すするヒープ
        d : (値:重複個数) の連想配列
        """
        self.h = []
        self.d = defaultdict(int)

    def insert(self, x):
        heapq.heappush(self.h, x)
        self.d[x] += 1

    def erase(self, x):
        if not self.is_exist(x):
            raise RuntimeError(f"{x} not in Dict.")
        self.d[x] -= 1
        # 最小値を更新
        while len(self.h) != 0:
            if self.d[self.h[0]] == 0:
                heapq.heappop(self.h)
            else:
                break

    def is_exist(self, x):
        if x in self.d and self.d[x] != 0:
            return True
        else:
            return False

    def get_min(self, default=0):
        if len(self.h):
            return self.h[0]
        else:
            return default


import pandas as pd
import numpy as np
#import matplotlib.pyplot as plt
import seaborn as sns
#%matplotlib inline

from urllib.request import urlopen
from bs4 import BeautifulSoup

url = "http://www.hubertiming.com/results/2017GPTR10K"
html = urlopen(url)

soup = BeautifulSoup(html, 'lxml')
type(soup)
#bs4.BeautifulSoup

# Get the title
title = soup.title
print(title)

# Print out the text
text = soup.get_text()
#print(soup.text)

#soup.find_all('a')

all_links = soup.find_all("a")
for link in all_links:
    print(link.get("href"))

# Print the first 10 rows for sanity check
rows = soup.find_all('tr')
print(rows[:10])

for row in rows:
    row_td = row.find_all('td')
print(row_td)
type(row_td)

str_cells = str(row_td)
cleantext = BeautifulSoup(str_cells, "lxml").get_text()
print(cleantext)


class Solution(object):
    def countDistinctIntegers(self, nums):
        new_nums = []
        for i in nums:
            num_str = str(i)
            num_rev = num_str[::-1]
            str_num = int(num_rev)
            new_nums.append(str_num)
        new_nums.extend(nums)
        new_nums = set(new_nums)

        return len(new_nums)
akua = Solution()
print(akua.countDistinctIntegers([1,13,10,12,31]))


import os
import sys
import unittest
from unittest.mock import patch

from terrasafe import terrasafe

class TerrasafeTest(unittest.TestCase):
    resource_delete = {
        "change": {
            "actions": [
                "delete"
            ]
        }
    }

    resource_recreate = {
        "change": {
            "actions": [
                "delete",
                "create"
            ]
        }
    }

    resource_update = {
        "change": {
            "actions": [
                "update"
            ]
        }
    }

    def setUp(self):
        self.input_file = open('test/test-input.json', 'r')
        sys.stdin = self.input_file

    def tearDown(self):
        self.input_file.close()

    def test_load_config(self):
        config = terrasafe.load_config("./test/test-config.json")
        self.assertListEqual(config["ignore_deletion"],
                             ["aws_ecs_task_definition*", "1"])
        self.assertListEqual(config["ignore_deletion_if_recreation"],
                             ["aws_ecs_task_definition*", "2"])
        self.assertListEqual(config["unauthorized_deletion"],
                             ["aws_ecs_task_definition*", "3"])

    def test_parse_ignored_from_env_var(self):
        os.environ["TERRASAFE_ALLOW_DELETION"] = "a;b;c"
        res = terrasafe.parse_ignored_from_env_var()
        self.assertListEqual(res, ["a", "b", "c"])

    def test_parse_ignored_from_empty_env_var(self):
        os.environ["TERRASAFE_ALLOW_DELETION"] = ""
        res = terrasafe.parse_ignored_from_env_var()
        self.assertListEqual(res, [])

    def test_get_resource_deletion(self):
        all_deletion = terrasafe.get_resource_deletion()
        all_deletion_address = list(map(lambda res: res["address"], all_deletion))
        self.assertListEqual(all_deletion_address, ['aws_s3_bucket.b[0]', 'aws_test.test'])

    def test_has_delete_action(self):
        self.assertTrue(terrasafe.has_delete_action(self.resource_delete))
        self.assertTrue(terrasafe.has_delete_action(self.resource_recreate))
        self.assertFalse(terrasafe.has_delete_action(self.resource_update))

    def test_is_resource_recreate(self):
        self.assertFalse(terrasafe.is_resource_recreate(self.resource_delete))
        self.assertTrue(terrasafe.is_resource_recreate(self.resource_recreate))
        self.assertFalse(terrasafe.is_resource_recreate(self.resource_update))

    def test_is_resource_match_any(self):
        self.assertTrue(terrasafe.is_resource_match_any("ab.cd", ["c", "d", "ab*"]))
        self.assertFalse(terrasafe.is_resource_match_any("ab.cd", ["c", "ab"]))

    def test_is_deletion_commented(self):
        self.assertFalse(terrasafe.is_deletion_commented("test", "test"))
        self.assertFalse(terrasafe.is_deletion_commented("aws_s3_bucket", "b"))
        self.assertFalse(terrasafe.is_deletion_commented("aws_s3_bucket", "other_bucket"))
        self.assertTrue(terrasafe.is_deletion_commented("aws_type", "abc"))
        self.assertTrue(terrasafe.is_deletion_commented("aws_type2", "def"))

    def test_is_deletion_in_disabled_file(self):
        self.assertTrue(terrasafe.is_deletion_in_disabled_file("aws_type3", "disabled"))
        self.assertFalse(terrasafe.is_deletion_in_disabled_file("aws_s3_bucket", "b"))

    def test_all_tf_files(self):
        self.assertCountEqual(terrasafe.get_all_files(".tf"), ["./test/test.tf", "./test/test2.tf"])

    def test_main_fail(self):
        with patch.object(sys, 'argv', ["terrasafe"]), self.assertRaises(SystemExit):
            terrasafe.main()

    def test_main_fail_with_unauthorized(self):
        with patch.object(sys, 'argv', ["terrasafe", "--config", "./test/test-config-unauthorized.json"]), \
             self.assertRaises(SystemExit):
            terrasafe.main()

    def test_main_ok_ignore(self):
        with patch.object(sys, 'argv', ["terrasafe", "--config", "./test/test-config-ignore-all.json"]):
            terrasafe.main()

    def test_main_ok_ignore_with_var(self):
        os.environ["TERRASAFE_ALLOW_DELETION"] = "aws_s3_bucket.b[0];aws_test.*"
        with patch.object(sys, 'argv', ["terrasafe"]):
            terrasafe.main()


import asyncio
from collections import defaultdict
from datetime import timedelta

import pytest

from yui.api import SlackAPI
from yui.bot import Bot
from yui.box import Box
from yui.types.slack.response import APIResponse

from .util import FakeImportLib

def test_bot_init(monkeypatch, bot_config):
    importlib = FakeImportLib()

    monkeypatch.setattr("importlib.import_module", importlib.import_module)

    bot_config.APPS = ["yui.app1", "yui.app2"]
    box = Box()
    bot = Bot(bot_config, using_box=box)

    assert bot.config == bot_config
    assert bot.channels == []
    assert bot.ims == []
    assert bot.groups == []
    assert bot.restart is False
    assert isinstance(bot.api, SlackAPI)
    assert bot.box is box
    assert isinstance(bot.queue, asyncio.Queue)
    assert importlib.import_queue == [
        "yui.app1",
        "yui.app2",
    ]

@pytest.mark.asyncio()
async def test_call(bot_config, response_mock):
    token = "asdf1234"  # noqa: S105

    response_mock.post(
        "https://slack.com/api/test11",
        payload={"res": "hello world!"},
    )
    response_mock.post(
        "https://slack.com/api/test12",
        payload={"res": "hello world!", "data": {"extra": "wow"}},
    )

    response_mock.post(
        "https://slack.com/api/test21",
        payload={"error": "aaa"},
        status=404,
    )
    response_mock.post(
        "https://slack.com/api/test22",
        payload={"error": "aaa"},
        status=404,
    )
    response_mock.post(
        "https://slack.com/api/test3",
        payload={"res": "hello world!"},
    )

    box = Box()
    bot = Bot(bot_config, using_box=box)
    bot.api.throttle_interval = defaultdict(lambda: timedelta(0))

    resp = await bot.call("test11")
    assert isinstance(resp, APIResponse)
    assert resp.body == {"res": "hello world!"}
    assert resp.status == 200
    assert resp.headers["Content-Type"] == "application/json"

    resp = await bot.call("test12", data={"extra": "wow"})
    assert isinstance(resp, APIResponse)
    assert resp.body == {"res": "hello world!", "data": {"extra": "wow"}}
    assert resp.status == 200
    assert resp.headers["Content-Type"] == "application/json"

    resp = await bot.call("test21")
    assert isinstance(resp, APIResponse)
    assert resp.body == {"error": "aaa"}
    assert resp.status == 404
    assert resp.headers["Content-Type"] == "application/json"

    resp = await bot.call("test22", data={"extra": "wow"})
    assert isinstance(resp, APIResponse)
    assert resp.body == {"error": "aaa"}
    assert resp.status == 404
    assert resp.headers["Content-Type"] == "application/json"

    resp = await bot.call("test3", token=token)
    assert isinstance(resp, APIResponse)
    assert resp.body == {"res": "hello world!"}
    assert resp.status == 200
    assert resp.headers["Content-Type"] == "application/json"


#!/usr/bin/env python3
#
# Patches and hooks for the binary translation of MENU2.EXE.
# This is an alternate build of the main menu for Disk 2,
# and it's also where the final cutscene is stored.
#
# Menus and the intro are in Javascript land now, so we only
# use this binary to run the final cutscene from SHOW2.SHW.
# As a result, let's rename this to "show2.exe" once translated.
#
# Micah Elizabeth Scott <micah@scanlime.org>
#

import os
import sys
import sbt86
import bt_common

basedir = sys.argv[1]
b = sbt86.DOSBinary(os.path.join(basedir, 'menu2.exe'))
b.basename = "show2.exe"

bt_common.patchJoystick(b)
bt_common.patchFramebufferTrace(b)
b.hook(b.entryPoint, 'enable_framebuffer_trace = true;')

# Time everything in this EXE, not just sound subroutines
sbt86.Subroutine.clockEnable = True

# Dynamic branch for cutscene sound effects
b.patchDynamicBranch('019E:068B', [
    sbt86.Addr16(str='019E:069B'),
    sbt86.Addr16(str='019E:06E3'),
    sbt86.Addr16(str='019E:06BE')
])

# This isn't actually self-modifying code, but some data stored in the code segment
# will trigger some warnings that we can silence by marking the area explicitly as data.
b.patchDynamicLiteral('019E:0434', length=2)
b.patchDynamicLiteral('019E:0436', length=2)

# Go directly to the end-game cutscene after we get the SHW file reader setup.
# This also skips over some code for skipping menu and loading images, as we've removed those.
b.patch('019E:00F8', 'jmp 0x185')

# At the very end of the final cutscene, we're greeted with an
# infinite loop. Break that loop with a delay.
final_loop = sbt86.Addr16(str='019E:0221')
b.markSubroutine(final_loop)
b.patchAndHook(final_loop, 'ret',
   	'g.hw->output.pushFrameCGA(g.stack, g.proc->memSeg(0xB800));'
    'g.hw->output.pushDelay(1000);'
    'g.proc->continueFrom(r, &sub_%X);' % final_loop.linear)

# Split up delays.
# Keyboard input will skip the delay, so flush any queued keystrokes after we come back.
for (call_site, delay) in [
    ('019E:018B', 1000),
    ('019E:0204', 1500),
    ('019E:0218', 1500),
]:
    call_site = sbt86.Addr16(str=call_site)
    continue_at = call_site.add(3)

    b.patchAndHook(call_site, 'ret',
        'g.hw->output.pushFrameCGA(g.stack, g.proc->memSeg(0xB800));'
        'g.hw->output.pushDelay(%d);'
        'g.proc->continueFrom(r, &sub_%X);' % (delay, continue_at.linear))
    b.markSubroutine(continue_at)
    b.hook(continue_at, 'g.hw->input.clear();')

# The cutscenes use a function I'm calling show_sfx_interruptible, which
# polls for keyboard input while playing a buffer of sound effects.
# Wrap each call site with some code that inserts a delay and breaks control flow.
# (Each invocation would include a joystick and DOS input poll, which takes
# some time)
show_sfx_interruptible = sbt86.Addr16(str='019E:0665')
for call_site in [
    '019E:0196',
    '019E:01A4',
    '019E:01B2',
    '019E:01C3',
    '019E:01D1',
    '019E:01DF',
    '019E:01ED',
    '019E:01FE',
    '019E:0212',
]:
    call_site = sbt86.Addr16(str=call_site)
    target = b.jumpTarget(call_site)
    assert target.linear == show_sfx_interruptible.linear
    continue_at = call_site.add(3)
    b.markSubroutine(continue_at)
    b.markSubroutine(target)
    b.patchAndHook(call_site, 'ret',
        'g.hw->output.pushFrameCGA(g.stack, g.proc->memSeg(0xB800));'
        'g.hw->output.pushDelay(50);'
        'sub_%X();'
        'g.proc->continueFrom(r, &sub_%X);' % (
            target.linear, continue_at.linear))

b.writeCodeToFile(os.path.join(basedir, 'bt_show2.cpp'), 'Show2EXE')


# Given a string, sort it in decreasing order based on the frequency of characters.

# Example 1:

# Input:
# "tree"

# Output:
# "eert"

# Explanation:
# 'e' appears twice while 'r' and 't' both appear once.
# So 'e' must appear before both 'r' and 't'. Therefore "eetr" is also a valid answer.
# Example 2:

# Input:
# "cccaaa"

# Output:
# "cccaaa"

# Explanation:
# Both 'c' and 'a' appear three times, so "aaaccc" is also a valid answer.
# Note that "cacaca" is incorrect, as the same characters must be together.
# Example 3:

# Input:
# "Aabb"

# Output:
# "bbAa"

# Explanation:
# "bbaA" is also a valid answer, but "Aabb" is incorrect.
# Note that 'A' and 'a' are treated as two different characters.

class Solution:
    def frequencySort(self, s: str) -> str:
        if not s:
            return ""

        dict = collections.Counter(s)
        max_freq = max(dict.values())

        my_list = list([] for i in range(max_freq + 1))
        for k, v in dict.items():
            my_list[v].append(k)

        res = []
        for i in range(len(my_list) - 1, 0, -1):
            for char in my_list[i]:
                res.append(char * i)

        return "".join(res)

"""
    counter dictionary then create a bucket with max value

    create a counter dict
    get the max frequency max(dict.values())
    create a 2d bucket, going up to the max freq + 1

    iterate through counter dict:
        append character into [v] = v will serve as the index and the # of times it needs to be repeated

    create a result list

    iterate through the bucket backwards
        iterate through the eles in bucket, add to the res list

    return the joined res list

"""


import random
import numpy as np

'''
Loop invaraint: At the start of each iteration of the loop 'for k = l to r do' in the subroutine Merge, the subarray arr[l..k-1] contains the k-l smallest
elements of L[1.. n_l + 1] and R[1... n_r + 1] in sorted order. Further, L[i] and R[j] are the smallest elements of these in L and R not copied to A.

    Initialization: For k = l, arr[l...k-1] is empty and i = j = 1. Hence, arr[l..k-1] has 0 smallest elements of L and R, both L[i] and R[j] are the smallest
    of these in L and R

    Maintenance: Assume the invariant is true for k-1 >= l and we prove it for k. Assume L[i] <= R[j]. Then L[i] is the smallest element not copied to A yet.
    Because A[l...k-1] has the k-l smallest elements, after L[i] is copied to A[k], A[l..k] has k-l+1 smallest elements.
    Incrementing k and i reestablishes the invariant for the next iteration. The proof for case L[i] > R[j] is similar.

    Termination: At termination of Merge, k = r+1. By the invariant above, arr[l..k-1] = arr[l..r] has r-l+1 smallest elements of L[1..n_l+1] and R[1..n_r+1] in sorted order.
    L and R have n_l + n_r + 2 = r - l + 3 elements. All  but two elements of infinity have been copied back to arr. So, when mergesort terminates, A has n elements in sorted order.

Running Time:

    Let T(n) be the running time of mergesort. T(1) = c, c > 0 a constant.
    Divide array of size n takes cn time
    Recursion on array of size n/2 takes T(n/2) time.
    Merge two arrays of size n/2 take cn Time
    T(n) = cn + T(n/2) + T(n/2) + cn
         = O(n logn)
'''
def sort(arr):

    if len(arr) > 1:

        mid = len(arr)//2
        L = arr[:mid].copy()
        R = arr[mid:].copy()

        sort(L)
        sort(R)

        i = j = k = 0

        while i < len(L) and j < len(R):
            if L[i] < R[j]:
                arr[k] = L[i]
                i += 1
            else:
                arr[k] = R[j]
                j += 1
            k += 1

        while i < len(L):
            arr[k] = L[i]
            i += 1
            k += 1

        while j < len(R):
            arr[k] = R[j]
            j += 1
            k += 1

def main():
    arr = np.zeros(10)
    for i in range(10):
        arr[i] = random.randint(1,100)

    print("Before Insertion-sort")
    print(arr)

    sort(arr)

    print("After Insertion-sort")
    print(arr)

if __name__ == '__main__':
    main()


# documentation https://radimrehurek.com/gensim/auto_examples/core/run_corpora_and_vector_spaces.html

import logging
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)

# create a small corpus
documents = [
    "Human machine interface for lab abc computer applications",
    "A survey of user opinion of computer system response time",
    "The EPS user interface management system",
    "System and human system engineering testing of EPS",
    "Relation of user perceived response time to error measurement",
    "The generation of random binary unordered trees",
    "The intersection graph of paths in trees",
    "Graph minors IV Widths of trees and well quasi ordering",
    "Graph minors A survey",
]

# next we will tokenize the text, remove stopwords, and words that appear once

from pprint import pprint  # pretty-printer
from collections import defaultdict

# remove common words and tokenize
stoplist = set('for a of the and to in'.split())
texts = [
    [word for word in document.lower().split() if word not in stoplist]
    for document in documents
]

# remove words that appear only once
frequency = defaultdict(int)
for text in texts:
    for token in text:
        frequency[token] += 1

texts = [
    [token for token in text if frequency[token] > 1]
    for text in texts
]

pprint(texts)

# next we will convert words to vectors using document representation called "bag-of-words"
# each document is represented by one vector
# each vector represents question-answer pair

from gensim import corpora
dictionary = corpora.Dictionary(texts)
dictionary.save('/tmp/deerwester.dict')  # store the dictionary, for future reference
print(dictionary)

# mapping between questions and IDs is called dictionary
print(dictionary.token2id)

# we can also convert tokenized documents to vectors
new_doc = "Human computer interaction"
new_vec = dictionary.doc2bow(new_doc.lower().split())
print(new_vec)  # the word "interaction" does not appear in the dictionary and is ignored

# result of the code above is [(0, 1), (1, 1)]
# where (0,1) is for human, and (1,1) is for computer (both words appear in the dictionary)
# interaction didn't appear in the text, thus not part of the dictionary

corpus = [dictionary.doc2bow(text) for text in texts]
corpora.MmCorpus.serialize('/tmp/deerwester.mm', corpus)  # store to disk, for later use
print(corpus)

from smart_open import open  # for transparently opening remote files

# we are going to open document that is stored online

class MyCorpus:
    def __iter__(self):
        for line in open('https://radimrehurek.com/mycorpus.txt'):
            # assume there's one document per line, tokens separated by whitespace
            yield dictionary.doc2bow(line.lower().split())

# Gensim accepts any corpus (no need for it to be pandas, list or array)
# the document can we created on the fly
 # doesn't load the corpus into memory!
corpus_memory_friendly = MyCorpus()
print(corpus_memory_friendly)

# load one vector into memory at a time
for vector in corpus_memory_friendly:
    print(vector)

# construct dictionary without loading text into memory
# collect statistics about all tokens
dictionary = corpora.Dictionary(line.lower().split() for line in open('https://radimrehurek.com/mycorpus.txt'))
# remove stop words and words that appear only once
stop_ids = [
    dictionary.token2id[stopword]
    for stopword in stoplist
    if stopword in dictionary.token2id
]
once_ids = [tokenid for tokenid, docfreq in dictionary.dfs.items() if docfreq == 1]
dictionary.filter_tokens(stop_ids + once_ids)  # remove stop words and words that appear only once
dictionary.compactify()  # remove gaps in id sequence after words that were removed
print(dictionary)


"""
To run the app
$ streamlit run front.py
"""

import streamlit as st
import requests, json
import pandas as pd

def get_records(record_type, record_time, event):
    data_request = {"event": event, "record_time": str(record_time), "record_type": record_type}
    response = requests.post(
        "https://wca-nr-api-jhaooholda-ue.a.run.app/get_nr_countries", data=json.dumps(data_request)
    ).json()
    # response = requests.post("http://127.0.0.1:8000/get_nr_countries", data=json.dumps(data_request)).json()
    if response["result"]:
        result_df = pd.DataFrame.from_dict(response["result"])[
            ["personId", "name", "gender", "best", "countryId", "eventId"]
        ]
    else:
        result_df = (
            f"Sorry, with this time you cannot beat any existing National Records in {event} but you may try a country"
            " where the record wasn't set yet"
        )
    return response["database_date"], result_df

EVENT_LIST = [
    "222",
    "333",
    "333bf",
    "333fm",
    "333ft",
    "333oh",
    "444",
    "444bf",
    "555",
    "555bf",
    "666",
    "777",
    "clock",
    "magic",
    "minx",
    "mmagic",
    "pyram",
    "skewb",
    "sq1",
]

st.set_page_config("WCA NR", page_icon="images/rubik.png")
st.sidebar.markdown("Enter a time for a specific event")
st.title("WCA NR")
record_type = st.radio("Single or Average?", ("Single", "Average"))
record_time = int(
    st.number_input(
        label="What is your record (format in seconds x100, ex: 4.86s -> 486, except FM just put the number of moves)?",
        min_value=0,
        max_value=100_000,
        step=1,
        value=1000,
    )
)
event = st.selectbox("Select the event", EVENT_LIST)

if st.button("Launch"):
    database_date, result_df = get_records(record_type, record_time, event)
    st.write(f"### Latest update from WCA database: {database_date}")
    if isinstance(result_df, str):
        st.write(result_df)
    else:
        st.dataframe(result_df, width=800, height=210)


# -*- coding:utf-8 -*-

###############################################################################
#该模块定义了对modis文件的操作的各种方法
#整个处理遥感数据需要的一些方法。
###############################################################################

import os
import gdal
import shutil
import numpy as np
import matplotlib as mpl
mpl.use('Agg')
import matplotlib.pyplot as plt
from gdalconst import *

#检查素材文件夹是否存在，不存在建立
def checkEnv(names):
	for i in names:
		if os.path.exists(i):
			continue;
		else:
			os.mkdir(i)

#~ #返回形式为 [['0501.hdf', '0502.hdf'],['0601.hdf','0602.hdf']] 的文件索引
#~ #参数： folder为根目录，keywords为文件名的关键字
def getRasters(folder,keywords):
	result = []
	for root ,dirs,files in os.walk(folder):
		#只有显示二级目录
		if files ==[]:
			continue
		else:
			temp= []
			#连接文件名
			for name in files:
				str =  os.path.join(root,name)
				#根据关键字过滤
				for j in keywords:
					if j in str and 'xml' not in str:
						temp.append(str)
						break
		result.append(temp)

	return result

#遍历文件夹，只显示文件
def readFile(path):
	for root ,dirs,files in os.walk(path):
		#只有显示二级目录
		if files ==[]:
			continue
		else:
			temp= []
			#连接文件名
			for name in files:
				str =  os.path.join(root,name)
				temp.append(str)
		return temp

#输入path1, 输出 [ [band1,band2,...],[name1,name2...] ]
def getBandName(path):
	dataset = gdal.Open(path,GA_ReadOnly)
	#获取子波段
	subdatasets = dataset.GetSubDatasets()
	pathname=[]
	bandname=[]
	for i in subdatasets:
		#排除一个质量图层
		#~ if '[1x2400x2400]'in i[1]:
			#~ continue
		pathname.append(i[0])
		bandname.append(i[1])

	result = [pathname,bandname]
	dataset = None
	return result

#转换
#转换
def transHDF(infile,outfile):
                os.system('gdal_translate \'%s\' %s -of GTiff' %(infile,'temp/'+outfile))
# modified by neptune by add single quote to enclose infile to prevent error caused by space in infile

#拼接
def merge(infiles,outfile):
	str=''
	for i in infiles:
		#过滤xml文件
		if 'xml' in i:
			continue
		str+=i+' '
	os.system('gdal_merge.py -o %s -of GTiff %s' %(outfile,str))

#更改投影
def warp(infile,outfile):
	os.system('gdalwarp %s %s -r near -t_srs EPSG:4326' % (infile,outfile))
	return 'warp ok. generate'+outfile

#矢量图重投影
def shpRepro(inshp,outshp):
	os.system('ogr2ogr -t_srs EPSG:4326 %s %s' % (outshp, inshp))

#从栅格图中裁剪
# -crop_to_cutline  忽略矢量图外部分
def mask(inshp,inraster,outraster):
	os.system('gdalwarp -cutline %s %s %s -crop_to_cutline'% (inshp,inraster,outraster) )

	return 'warp ok. generate'+outraster

#生成缩略图
def makeThumbnail(src):
	dataset = gdal.Open(src)
	#判断数据集的波段数
	if(dataset.RasterCount<1):
		return
	if(dataset.RasterCount>1):
		ds = dataset.GetRasterBand(1).ReadAsArray()
	else:
		ds = dataset.ReadAsArray()

	A = np.array(ds)
	fig = plt.figure(frameon = False)    #生成画布
	ax = fig.add_subplot(111)             #增加子图
	ax.imshow(A, interpolation='nearest', vmin = 0,vmax = 16,cmap=plt.cm.gist_earth)    #子图上显示数据
	plt.savefig(src.replace('.tif','THUMBNAIL.png'),dpi = 80)
	ax.set_xticks([])                            #去除坐标轴
	ax.set_yticks([])
	plt.savefig(src.replace('.tif','.png'),dpi = 300)
	ds = None
	dataset = None


#!/usr/bin/env python
# just testing basic parallelization that will be used in the actual project
from __future__ import division,unicode_literals
from future.builtins import map,zip, range
import numpy as np
import itertools as it

# setup proper logging
import logging
logger = logging.getLogger('psnobfit')
logger.setLevel(logging.INFO)
# logger.setLevel(logging.DEBUG)
log_stream_handler = logging.StreamHandler()
log_stream_handler.setLevel(logging.DEBUG)
log_formatter = logging.Formatter('%(asctime)s %(name)s/%(levelname)-9s %(message)s')
log_stream_handler.setFormatter(log_formatter)
logger.addHandler(log_stream_handler)
del logging, log_stream_handler, log_formatter

# read cmd line options
from optparse import OptionParser
opt_parser = OptionParser()
opt_parser.add_option("-p", "--profile", dest="client_profile", default="unissh", action="store_const",
                      help="the profile to use for ipython.parallel")
options, args = opt_parser.parse_args()

# START: create remote evaluators and a few (or one) special one for #
# generating new points
logger.info("init")
from IPython.parallel import Client, require
c = Client(profile=options.client_profile)
c.clear()  # clears remote engines
c.purge_results('all')  # all results are memorized in the hub

if len(c.ids) < 2:
    raise Exception('I need at least 2 clients.')
nbGens = min(1, len(c.ids) - 1)
generators = c.load_balanced_view(c.ids[:nbGens])
evaluators = c.load_balanced_view(c.ids[nbGens:])

# MAX number of tasks in total
MAX = 5000
# length of test data, sent over the wire
DIMSIZE = 10
# when adding machines, this is the number of additional tasks
# beyond the number of free machines
new_extra = DIMSIZE

# import some packages  (also locally)
with c[:].sync_imports():
    from IPython.utils.timing import time  # time.time & time.clock for cpu time
    #import time
    from random import random
    from numpy import pi, sum
    import numpy
    import math

# the actual function

def func_one(tid, data):
    return tid, 1

def func_sum(tid, data):
    'x is either a number or a list/vector of numbers'
    time.sleep(math.log(1 + random()))
    return tid, numpy.sum(data)

def func_eval(tid, data):
    np = numpy
    data = data * numpy.pi / 2
    v = np.multiply(np.cos(numpy.pi + data), np.sin(data + numpy.pi / 2))
    v = np.exp(np.linalg.norm(v - 1, 1) / len(data))
    #s = np.sin(data[::2] + numpy.pi / 2)
    #c = np.cos(data[1::2])
    # v += np.sum(s) + np.sum(c) #np.append(s,c))
    # time.sleep(1e-3)
    #time.sleep(1e-2 + math.log(1 + random()))
    return tid, v

func = func_eval

# some stats
added = 0
queue_size = 0
added = 0
nb_finished = 0
nb_generated = 0
loops = 0
tasks_added = 0
cum_sum = 0
best_x = None
best_obj = numpy.infty
last_best = best_obj

def status():
    global last_best
    s = '*' if last_best != best_obj else ' '
    logger.info(
        "pend %4d | + %2d | tot: %4d | finished: %4d | gen: %3d | best_obj: %.10f %s" %
        (queue_size, new, added, nb_finished, nb_generated, best_obj, s))
    last_best = best_obj

logger.info("start")
start_time = time.time()

# pending is the set of jobs we are expecting in each loop
pending = set([])
pending_generators = set([])
new_points = []
# collects all returns
results = []
allx = dict()  # store all x vectors

def gen_points(new, DIMSIZE, cur_best_res=None, cur_best_x=None):
    '''
    generates @new new points, depends on results and allx
    '''
    np = numpy
    #lambda rp : 10 * (np.random.rand(DIMSIZE) )
    FACT = 3
    OFF = 0

    if np.random.random() < .2 or not cur_best_res:
        return np.array([FACT * (np.random.rand(DIMSIZE) + OFF) for _ in range(new)])

    # better local value new best point
    ret = []
    for i in range(new):
        rv = (np.random.rand(DIMSIZE) - .5) / 5
        # make it sparse
        sp = np.random.rand(DIMSIZE) < .9
        rv[sp] = 0
        #import scipy
        #rv = scipy.sparse.rand(DIMSIZE, 1, 0.1)
        ret.append(np.minimum(2, np.maximum(0, rv + cur_best_x)))
    return np.array(ret)

# itertools counter for successive task ID numbers
tid_counter = it.count(0)

while pending or added < MAX:
    evaluators.spin()  # check outstanding tasks
    loops += 1

    # get new points if they have arrived

    # check if we have to generate new points
    if not new_points:
        if results:
            cur_best_res = min(results, key=lambda _: _[1])
            cur_best_x = allx[cur_best_res[0]]
        else:
            cur_best_res, cur_best_x = None, None
        new = len(c.ids) - queue_size + new_extra
        # at the end, make sure to not add more tasks then MAX
        new = min(new, MAX - added)
        # update the counter
        added += new
        new_points_tasks = generators.map_async(
            gen_points,
            [new],
            [DIMSIZE],
            [cur_best_res],
            [cur_best_x],
            ordered=False)
        # print ">>>", new_points_tasks.msg_ids
        list(map(pending_generators.add, new_points_tasks.msg_ids))

    finished_generators = pending_generators.difference(generators.outstanding)
    pending_generators = pending_generators.difference(finished_generators)

    # if we have generated points in the queue, eval the function
    for msg_id in finished_generators:
        res = generators.get_result(msg_id)
        nb_generated += len(res.result)
        for g in res.result:
            #logger.info('new points "%s" = %s' % (msg_id, g))
            cs = max(1, min(5, len(res.result)))
            newt = evaluators.map_async(func, tids, vals, chunksize=cs, ordered=False)
            cum_sum += 1

    # check, if we have to create new tasks
    queue_size = len(pending)
    if queue_size <= len(c.ids) + new_extra and added < MAX:
        tasks_added += 1
        new = len(c.ids) - queue_size + new_extra
        # at the end, make sure to not add more tasks then MAX
        new = min(new, MAX - added)
        # update the counter
        added += new
        status()
        # create new tasks
        tids, vals = list(it.islice(tid_counter, new)), gen_points(new, DIMSIZE)
        chunksize = max(1, min(new, len(c.ids)))
        newt = evaluators.map_async(func, tids, vals, chunksize=chunksize, ordered=False)
        allx.update(list(zip(tids, vals)))
        list(map(pending.add, newt.msg_ids))
    else:
        new = 0

    # finished is the set of msg_ids that are complete
    finished = pending.difference(evaluators.outstanding)
    # update pending to exclude those that just finished
    pending = pending.difference(finished)

    # collect results from finished tasks
    for msg_id in finished:
        # we know these are done, so don't worry about blocking
        res = evaluators.get_result(msg_id)
        nb_finished += len(res.result)

        # each job returns a list of length chunksize
        for t in res.result:
            logger.debug("result '%s' = %s" % (msg_id, t))
            results.append(t)
            cum_sum += 1  # t[1] ## just to test how many results come back
            if t[1] < best_obj:
                best_obj = t[1]
                best_x = allx[t[0]]

    # wait for 'pending' jobs or 1/1000s
    evaluators.wait(None, 1e-3)  # pending.union(pending_generators), 1e-3)

status()
logger.debug("queues:")
for k, v in sorted(evaluators.queue_status().items()):
    logger.debug("%5s: %s" % (k, v))

logger.info("pending: %s" % pending)
logger.info("added in total:   %s" % added)

#logger.info("results: %s" % sorted([r[0] for r in results]))
logger.info("# machines = %s" % len(c.ids))
logger.info("# results = %s" % len(results))
logger.info("cum_sum = %s" % cum_sum)
logger.info(
    "# total loops %s | of that, %s times tasks were added | %.4f%%" %
    (loops, tasks_added, tasks_added / float(loops) * 100.))
ttime = time.time() - start_time
evalspersec = added / ttime
logger.info("total time: %s [s] | %.5f [feval/s]" % (ttime, evalspersec))
logger.info("best:")
logger.info(" obj. value: %f" % best_obj)
logger.info(" x:\n%s" % best_x)
logger.info("finished")


import os
import pydicom
import numpy
from matplotlib import pyplot
from PIL import Image
import PIL
import SimpleITK as sitk
import vtk
from vtkmodules.util import numpy_support
import cv2
import io
from natsort import natsorted

PathDicom = "E:/Dicom/test/DicomResource"  # 与python文件同一个目录下的文件夹
lstFilesDCM = []
DcmName = []
for dirName, subdirList, fileList in sorted(os.walk(PathDicom)):
    fileList = natsorted(fileList)
    for filename in fileList:
        if ".dcm" in filename.lower():  # 判断文件是否为dicom文件
            lstFilesDCM.append(os.path.join(dirName, filename))  # 加入到列表中
            DcmName.append(filename)

'''
RefDs = pydicom.read_file(lstFilesDCM[0],force=True)
reader = sitk.ImageSeriesReader()
dicom_names = reader.GetGDCMSeriesFileNames(PathDicom)
reader.SetFileNames(dicom_names)
image = reader.Execute()
columns = RefDs.Columns
row = RefDs.Rows
ConstOrigin = image.GetOrigin()
ConstPixelSpacing = image.GetSpacing()
ConstPixelDims = (int(row), int(columns), len(lstFilesDCM))
'''
gap = len(DcmName) - 1
file_one = pydicom.read_file(lstFilesDCM[0],force=True)
z_one = file_one.ImagePositionPatient[2]
file_tow = pydicom.read_file(lstFilesDCM[gap],force=True)
z_tow = file_tow.ImagePositionPatient[2]
columns = file_one.Columns
row = file_one.Rows
ConstPixelDims = (int(row), int(columns), len(lstFilesDCM))
if z_one > z_tow:
    slice_gap = (z_one - z_tow)/gap
    ConstOrigin = (file_tow.ImagePositionPatient[0],file_tow.ImagePositionPatient[1],file_tow.ImagePositionPatient[2])
    ConstPixelSpacing = (float(file_tow.PixelSpacing[0]), float(file_tow.PixelSpacing[1]), float(slice_gap))
else:
    slice_gap = (z_tow - z_one)/gap
    ConstOrigin = (file_one.ImagePositionPatient[0],file_one.ImagePositionPatient[1],file_one.ImagePositionPatient[2])
    ConstPixelSpacing = (float(file_one.PixelSpacing[0]), float(file_one.PixelSpacing[1]), float(slice_gap))

image_1 = int(ConstPixelDims[0]//2)
image_2 = int(ConstPixelDims[1]//2)
image_3 = int(ConstPixelDims[2]//2)
x = numpy.arange(0.0, (ConstPixelDims[0] + 1) * ConstPixelSpacing[0],ConstPixelSpacing[0])  # 0到（第一个维数加一*像素间的间隔），步长为constpixelSpacing
y = numpy.arange(0.0, (ConstPixelDims[1] + 1) * ConstPixelSpacing[1],ConstPixelSpacing[1])  #
z = numpy.arange(0.0, (ConstPixelDims[2] + 1) * ConstPixelSpacing[2],ConstPixelSpacing[2])  #
ArrayDicom = numpy.zeros(ConstPixelDims, dtype=file_one.pixel_array.dtype)

# 遍历所有的dicom文件，读取图像数据，存放在numpy数组中
for filenameDCM in lstFilesDCM:
    ds = pydicom.read_file(filenameDCM,force=True)
    ArrayDicom[:, :, lstFilesDCM.index(filenameDCM)] = ds.pixel_array

'''
fig1 = pyplot.figure(dpi=300)
pyplot.axes().set_aspect('equal','datalim')
pyplot.set_cmap(pyplot.gray())
pyplot.pcolormesh(x, y, numpy.flipud(ArrayDicom[:, :, image_3]))  # 第三个维度表示现在展示的是第几层
pyplot.axis('off')
buffer_ = io.BytesIO()
pyplot.savefig(buffer_,format='png')
buffer_.seek(0)
img1 = PIL.Image.open(buffer_)
img_arr1 = numpy.asarray(img1)
buffer_.close()

fig2 = pyplot.figure(dpi=300)
pyplot.axes().set_aspect('equal','datalim')
pyplot.set_cmap(pyplot.gray())
pyplot.pcolormesh(y, z, numpy.fliplr(numpy.rot90((ArrayDicom[image_1, :, :]),3)))
pyplot.axis('off')
buffer_ = io.BytesIO()
pyplot.savefig(buffer_,format='png')
buffer_.seek(0)
img2 = PIL.Image.open(buffer_)
img_arr2 = numpy.asarray(img2)
buffer_.close()

fig3 = pyplot.figure(dpi=300)
pyplot.axes().set_aspect('equal','datalim')
pyplot.set_cmap(pyplot.gray())
pyplot.pcolormesh(x, z, numpy.fliplr(numpy.rot90((ArrayDicom[:, image_2, :]),3)))
pyplot.axis('off')
buffer_ = io.BytesIO()
pyplot.savefig(buffer_,format='png')
buffer_.seek(0)
img3 = PIL.Image.open(buffer_)
img_arr3 = numpy.asarray(img3)
buffer_.close()

pyplot.figure(figsize=(3,1),dpi=300)
pyplot.subplot(131)
pyplot.imshow(img_arr1)
pyplot.title('AxialSlice',fontsize=4,y=0.9)
pyplot.axis('off')
pyplot.xticks([])
pyplot.yticks([])
pyplot.subplot(132)
pyplot.imshow(img_arr2)
pyplot.title('CoronalSlice',fontsize=4,y=0.9)
pyplot.axis('off')
pyplot.xticks([])
pyplot.yticks([])
pyplot.subplot(133)
pyplot.imshow(img_arr3)
pyplot.title('SagitalSlice',fontsize=4,y=0.9)
pyplot.axis('off')
pyplot.xticks([])
pyplot.yticks([])
pyplot.tight_layout(pad=0.5,w_pad=2)
pyplot.subplots_adjust(wspace=0,hspace=0)
# pyplot.savefig('E:\\Dicom\\test\\images\\'+'image.jpg')
pyplot.show()

'''
'''
pyplot.figure(dpi=300)
pyplot.axes().set_aspect('equal')
pyplot.set_cmap(pyplot.gray())
pyplot.pcolormesh(x, y, numpy.flipud(ArrayDicom[:, :, image_3]))  # 第三个维度表示现在展示的是第几层
pyplot.axis('off')
pyplot.savefig('E:\\Dicom\\test\\images\\'+'AxialSlice'+'.jpg',bbox_inches='tight',pad_inches=0.0)
pyplot.show()

pyplot.figure(dpi=300)
pyplot.axes().set_aspect('equal')
pyplot.set_cmap(pyplot.gray())
pyplot.pcolormesh(y, z, numpy.fliplr(numpy.rot90((ArrayDicom[image_1, :, :]),3)))
pyplot.axis('off')
pyplot.savefig('E:\\Dicom\\test\\images\\'+'CoronalSlice'+'.jpg',bbox_inches='tight',pad_inches=0.0)
pyplot.show()

pyplot.figure(dpi=300)
pyplot.axes().set_aspect('equal')
pyplot.set_cmap(pyplot.gray())
pyplot.pcolormesh(x, z, numpy.fliplr(numpy.rot90((ArrayDicom[:, image_2, :]),3)))
pyplot.axis('off')
pyplot.savefig('E:\\Dicom\\test\\images\\'+'SagitalSlice'+'.jpg',bbox_inches='tight',pad_inches=0.0)
pyplot.show()

'''

Array_vtk = numpy_support.numpy_to_vtk(ArrayDicom.ravel('F'), deep=True, array_type=vtk.VTK_FLOAT)
imagedata = vtk.vtkImageData()
imagedata.SetOrigin(ConstOrigin)
imagedata.SetSpacing(ConstPixelSpacing)
imagedata.SetDimensions(ConstPixelDims)
imagedata.GetPointData().SetScalars(Array_vtk)
origin = numpy.array(ConstOrigin)
ConstPixelSpacing = numpy.array(ConstPixelSpacing)
ConstPixelDims = numpy.array(ConstPixelDims)
center = origin + (ConstPixelSpacing * ConstPixelDims / 2)
DirectionCosines_x = (0, 0, 1, 0, 1, 0, -1, 0, 0)
DirectionCosines_y = (1, 0, 0, 0, 0, -1, 0, 1, 0)
DirectionCosines_z = (1, 0, 0, 0, 1, 0, 0, 0, 1)

def mip_x():
    ImageSlab = vtk.vtkImageSlabReslice()
    ImageSlab.SetInputData(imagedata)
    ImageSlab.SetResliceAxesOrigin(center)
    ImageSlab.SetResliceAxesDirectionCosines(DirectionCosines_x)
    ImageSlab.SetSlabThickness(ConstPixelSpacing[0]*ConstPixelDims[0])
    ImageSlab.SetBlendModeToMax()
    ImageSlab.SetSlabResolution(ConstPixelSpacing[0])
    ImageSlab.Update()
    image = ImageSlab.GetOutput()
    m = image.GetDimensions()
    vtk_data = image.GetPointData().GetScalars()
    arr = numpy_support.vtk_to_numpy(vtk_data).reshape(m[1], m[0])
    arr = (arr - numpy.min(arr)) / ((numpy.max(arr) - numpy.min(arr)) / 255)
    width = columns
    height = int(len(lstFilesDCM) * (ConstPixelSpacing[2] / ConstPixelSpacing[1]))
    dim = (width, height)
    resized = cv2.resize(numpy.rot90(arr, 1), dim, interpolation=cv2.INTER_AREA)
    return resized

def mip_y():
    ImageSlab = vtk.vtkImageSlabReslice()
    ImageSlab.SetInputData(imagedata)
    ImageSlab.SetResliceAxesOrigin(center)
    ImageSlab.SetResliceAxesDirectionCosines(DirectionCosines_y)
    ImageSlab.SetSlabThickness(ConstPixelSpacing[1]*ConstPixelDims[1])
    ImageSlab.SetBlendModeToMax()
    ImageSlab.SetSlabResolution(ConstPixelSpacing[1])
    ImageSlab.Update()
    image = ImageSlab.GetOutput()
    m = image.GetDimensions()
    vtk_data = image.GetPointData().GetScalars()
    arr = numpy_support.vtk_to_numpy(vtk_data).reshape(m[1], m[0])
    arr = (arr - numpy.min(arr)) / ((numpy.max(arr) - numpy.min(arr)) / 255)
    width = int(len(lstFilesDCM) * (ConstPixelSpacing[2] / ConstPixelSpacing[0]))
    height = row
    dim = (width, height)
    resized = cv2.resize(numpy.rot90(arr, -1), dim, interpolation=cv2.INTER_AREA)
    # cv2.imwrite( path +'/'+ name +'.jpg', resized)
    return resized

def mip_z():
    ImageSlab = vtk.vtkImageSlabReslice()
    ImageSlab.SetInputData(imagedata)
    ImageSlab.SetResliceAxesOrigin(center)
    ImageSlab.SetResliceAxesDirectionCosines(DirectionCosines_z)
    ImageSlab.SetSlabThickness(ConstPixelSpacing[2] * ConstPixelDims[2])
    ImageSlab.SetBlendModeToMax()
    ImageSlab.SetSlabResolution(ConstPixelSpacing[2])
    ImageSlab.Update()
    image = ImageSlab.GetOutput()
    m = image.GetDimensions()
    vtk_data = image.GetPointData().GetScalars()
    arr = numpy_support.vtk_to_numpy(vtk_data).reshape(m[1], m[0])
    arr = (arr - numpy.min(arr)) / ((numpy.max(arr) - numpy.min(arr)) / 255)
    arr = numpy.rot90(arr,-1)
    # cv2.imwrite(path+'/'+name+'.jpg', numpy.rot90(arr, -1))
    return arr

pyplot.figure(figsize=(3,1),dpi=300)
pyplot.subplot(131)
pyplot.imshow(mip_z(),cmap='gray')
pyplot.title('AxialSlice_MIP',fontsize=4,y=1.1)
pyplot.xticks([])
pyplot.yticks([])
pyplot.subplot(132)
pyplot.imshow(mip_x(),cmap='gray')
pyplot.title('CoronalSlice_MIP',fontsize=4,y=1.1)
pyplot.xticks([])
pyplot.yticks([])
pyplot.subplot(133)
pyplot.imshow(numpy.rot90(mip_y(),1),cmap='gray')
pyplot.title('SagitalSlice_MIP',fontsize=4,y=1.1)
pyplot.xticks([])
pyplot.yticks([])
pyplot.tight_layout(pad=1.3,w_pad=2)
pyplot.subplots_adjust(wspace=0,hspace=0)
# pyplot.savefig('E:\\Dicom\\test\\images\\'+'MIP_image.jpg')
pyplot.show()


import logging
from odoo import models, fields, api, tools, release, _
from odoo.exceptions import ValidationError, UserError
from .server import get_default_server
from .settings import debug

logger = logging.getLogger(__name__)

class PbxUser(models.Model):
    _name = 'asterisk_plus.user'
    _inherit = 'mail.thread'
    _description = _('Asterisk User')

    exten = fields.Char()
    user = fields.Many2one('res.users', required=True,
                           ondelete='cascade',
                           # Exclude shared users
                           domain=[('share', '=', False)])
    name = fields.Char(related='user.name', readonly=True)
    #: Server where the channel is defined.
    server = fields.Many2one('asterisk_plus.server', required=True,
                             ondelete='restrict', default=get_default_server)
    server_id = fields.Char(related='server.server_id')
    channels = fields.One2many('asterisk_plus.user_channel',
                               inverse_name='asterisk_user')
    originate_vars = fields.Text(string='Channel Variables')
    open_reference = fields.Boolean(
        default=True,
        help=_('Open reference form on incoming calls.'))
    user_call_count = fields.Integer(compute='_get_call_count', string='Calls')
    missed_calls_notify = fields.Boolean(
        default=True,
        help=_('Notify user on missed calls.'))
    call_popup_is_enabled = fields.Boolean(
        default=True,
        string='Call Popup')
    call_popup_is_sticky = fields.Boolean(
        default=True,
        string='Popup Is Sticky')

    _sql_constraints = [
        ('exten_uniq', 'unique (exten,server)',
         _('This phone extension is already used!')),
        ('user_uniq', 'unique ("user",server)',
         _('This user is already defined!')),
    ]

    @api.model
    def create(self, vals):
        user = super(PbxUser, self).create(vals)
        if user and not self.env.context.get('no_clear_cache'):
            self.pool.clear_caches()
        return user

    def write(self, vals):
        user = super(PbxUser, self).write(vals)
        if user and not self.env.context.get('no_clear_cache'):
            self.pool.clear_caches()
        return user

    @api.model
    def has_asterisk_plus_group(self):
        """Used from actions.js to check if Odoo user is enabled to
        use Asterisk applications in order to start a bus listener.
        """
        if (self.env.user.has_group('asterisk_plus.group_asterisk_admin') or
                self.env.user.has_group(
                    'asterisk_plus.group_asterisk_user')):
            return True

    def _get_originate_vars(self):
        self.ensure_one()
        try:
            if not self.originate_vars:
                return []
            return [k for k in self.originate_vars.split('\n') if k]
        except Exception:
            logger.exception('Get originate vars error:')
            return []

    def dial_user(self):
        self.ensure_one()
        self.env.user.asterisk_users[0].server.originate_call(
            self.exten, model='asterisk_plus.user', res_id=self.id)

    def open_user_form(self):
        if self.env.user.has_group('asterisk_plus.group_asterisk_admin'):
            return {
                'type': 'ir.actions.act_window',
                'res_model': 'asterisk_plus.user',
                'name': 'Users',
                'view_mode': 'tree,form',
                'view_type': 'form',
                'target': 'current',
            }
        else:
            if not self.env.user.asterisk_users:
                raise ValidationError('PBX user is not configured!')
            return {
                'type': 'ir.actions.act_window',
                'res_model': 'asterisk_plus.user',
                'res_id': self.env.user.asterisk_users.id,
                'name': 'User',
                'view_id': self.env.ref(
                    'asterisk_plus.asterisk_plus_user_user_form').id,
                'view_mode': 'form',
                'view_type': 'form',
                'target': 'current',
            }

    @api.model
    @tools.ormcache('exten', 'system_name')
    def get_res_user_id_by_exten(self, exten, system_name):
        # TODO: Is it required?
        astuser = self.search([
            ('exten', '=', exten), ('system_name', '=', system_name)], limit=1)
        debug(self, 'GET RES USER BY EXTEN {} at {}: {}'.format(
            exten, system_name, astuser))
        return astuser.user.id

    def _get_call_count(self):
        for rec in self:
            rec.user_call_count = self.env[
                'asterisk_plus.call'].sudo().search_count(
                ['|', ('calling_user', '=', rec.user.id),
                      ('called_user', '=', rec.user.id)])

    def action_view_calls(self):
        # Used from the user calls view button.
        self.ensure_one()
        return {
            'name': _("Calls"),
            'type': 'ir.actions.act_window',
            'view_mode': 'tree',
            'res_model': 'asterisk_plus.call',
            'domain': ['|', ('calling_user', '=', self.user.id),
                            ('called_user', '=', self.user.id)],
        }


from ast import Call
from re import L
from urllib.request import urlretrieve
from aiogram import Dispatcher
from aiogram.types import Message, CallbackQuery
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters import Text

import time
import os
import urllib
import requests

from markups.add_section import *
from models.user import User
from models.city import City
from models.category import Category
from models.section import Section, SectionPhoto
from states.find_section import FindSection
from utils.db_connection import create_db_session

from markups.find_section import *

from email_validator import validate_email, EmailNotValidError

async def select_city(message: Message):
    await FindSection.City.set()
    kb = await get_cities_kb(offset=0)
    chat_id = message["from"]["id"]
    await message.bot.send_message(
        text="""
        Город🏢
        ---
        Выберите город из
        предложенного списка.
    """,
        chat_id=chat_id,
        reply_markup=kb,
    )

async def save_city_value_and_select_category(call: CallbackQuery, state: FSMContext):
    chat_id = call["from"]["id"]
    async with state.proxy() as data:
        data["city"] = call.data.split("_")[1]

    await FindSection.Category.set()

    kb = await f_get_categories_kb(offset=0)
    await call.bot.send_message(
        text="""
        Категория
        ---
        Необходимо определиться с
        категорией.
        Так мы сможем релевантно
        подобрать места.💪
    """,
        chat_id=chat_id,
        reply_markup=kb,
    )

async def metro_or_district(call: CallbackQuery, state: FSMContext):
    await FindSection.MetroOrDistrict.set()
    async with state.proxy() as data:
        data["category"] = call.data.split("_")[1]

    chat_id = call["from"]["id"]
    await call.bot.send_message(
        text="""
        Выбор метро или района
        ---
        По какому параметру сузить
        поиск мест.🗺
    """,
        chat_id=chat_id,
        reply_markup=metro_or_district_kb,
    )

async def by_metro(call: CallbackQuery, state: FSMContext):
    await FindSection.Metro.set()
    async with state.proxy() as data:
        data["by_metro"] = True

        kb = await get_metros_kb(city=data["city"], offset=0)

    chat_id = call["from"]["id"]

    await call.bot.send_message(
        text="""
        Метро
        ---
        Укажите станцию метро🚇
    """,
        chat_id=chat_id,
        reply_markup=kb,
    )

async def by_district(call: CallbackQuery, state: FSMContext):
    await FindSection.District.set()
    async with state.proxy() as data:
        data["by_district"] = True
        kb = await get_districts_kb(city=data["city"], offset=0)

    chat_id = call["from"]["id"]

    await call.bot.send_message(
        text="""
        Район
        ---
        Укажите район📍
    """,
        chat_id=chat_id,
        reply_markup=kb,
    )

async def select_training(call: CallbackQuery, state: FSMContext):
    await FindSection.Trainings.set()
    async with state.proxy() as data:
        data["metro_or_district"] = call.data.split("_")[1]

    kb = await get_trainigs_kb(offset=0)
    chat_id = call["from"]["id"]
    await call.bot.send_message(
        text="""
        Вид занятий
        ---
        Это может быть все, что угодно,
        от йоги и стретчинга до бокса
        и функциональных тренировок.🏋♂
        ---
        Вы можете написать в ответ боту
        вид занятий, который вас
        интересует⤵
    """,
        chat_id=chat_id,
        reply_markup=kb,
    )

async def waiting_for_find(call: CallbackQuery, state: FSMContext):
    await FindSection.Wait.set()
    session_maker = await create_db_session()
    async with state.proxy() as data:
        data["traning"] = call.data

        category = await Category.get_category(
            session_maker=session_maker, name=data["category"]
        )
        category = category[0]
        if data.get("by_district"):
            district = await District.get_district(
                session_maker=session_maker, name=data["metro_or_district"]
            )
            district = district
            sections = await Section.find(
                session_maker=session_maker,
                city=data["city"],
                category_id=category.id,
                district_id=district[0].id,
            )
        else:
            metro = await Metro.get_metro(
                session_maker=session_maker, name=data["metro_or_district"]
            )
            sections = await Section.find(
                session_maker=session_maker,
                city=data["city"],
                category_id=category.id,
                metro_id=metro[0].id,
            )
        if sections == []:
            await call.bot.send_message(
                text="Подходящей секции не нашлось. ", chat_id=call['from']['id']
            )
        else:

            chat_id = call["from"]["id"]
            await call.bot.send_message(text="Ищем для вас места, ожидайте⏱", chat_id=chat_id)
            time.sleep(2)
            await call.bot.send_message(
                text="""
                Отлично!🏋
                Нашли для тебя места,
                формируем список ⚙
            """,
            chat_id=chat_id,
            )

            tranings = ""
            if type(sections[0].tranings) == list:
                for traning in sections[0].tranings:
                    tranings += traning + "\n"
            else:
                tranings = sections[0].tranings

            category = await Category.get_category(
                session_maker=session_maker, name=data["category"]
            )
            district = await District.get_district_by_id(
                session_maker=session_maker, id=sections[0].district_id
            )
            metro = await Metro.get_metro_by_id(
                session_maker=session_maker, id=sections[0].metro_id
            )

            data["section"] = sections[0]
            data['section_id'] = sections[0].id

            section_photo = await SectionPhoto.get_by_section_id(session_maker=session_maker, section_id=data['section'].id)

            if section_photo != []:
                photo = requests.get(section_photo[0].file_path)

                await call.bot.send_photo(
                photo=photo.content,
                caption=f"""
                    {sections[0].title}

                    Город:{sections[0].city}
                    Категория: {sections[0].category_id}
                    Адрес: {sections[0].address}
                    Район: {district[0].name}
                    Метро: {metro[0].name}

                    Виды занятий:
                    {tranings}
                """,
                chat_id=chat_id,
                reply_markup=waiting_for_find_kb,
                )
            else:
                await call.bot.send_message(
                    text=f"""
                    {sections[0].title}

                    Город:{sections[0].city}
                    Категория: {sections[0].category_id}
                    Адрес: {sections[0].address}
                    Район: {district[0].name}
                    Метро: {metro[0].name}

                    Виды занятий:
                    {tranings}
                """,
                chat_id=chat_id,
                reply_markup=waiting_for_find_kb,
                )

async def way(call: CallbackQuery, state: FSMContext):
    async with state.proxy() as data:
        lat = data['section'].geoposition.split(' ')[0]
        long = data['section'].geoposition.split(" ")[1]

    await call.bot.send_message(text=f"""
        Открыть карту
Москвы в приложении Яндекс.Карты
    """, chat_id=call['from']['id'])

async def consult(call: CallbackQuery, state: FSMContext):

    async with state.proxy() as data:
        await call.bot.send_message(
            text=f"""
            Подтвердите данные
            ---
            Место
            {data['section'].title}
            Имя
            {call['from']['first_name']}

            Телефон:

        """,
            chat_id=call["from"]["id"],
            reply_markup=consult_kb,
        )
    await call.bot.send_message(
        text = "Напишите свой номер телефона",
        chat_id = call['from']['id']
    )

    await call.bot.send_message(
        text=f"""
        Устанавливаем связь с местом
    """,
        chat_id=call["from"]["id"],
    )
    time.sleep(1)
    await call.bot.send_message(
        text=f"""
        Ваша заявка отправлена, в
        рабочее время с вами свяжется
        менеджер места и ответит на все
        вопросы
        ---
        Спасибо, что воспользовались
        подбором, будем рады, если
        поддержите наш бот ₽(рублем)
    """,
        chat_id=call["from"]["id"],
        reply_markup=consult_sent_kb,
    )

async def feedback(call: CallbackQuery, state: FSMContext):
    await call.bot.send_message(
        text="""
        Оцените место⭐
        ---
        Другие пользователи, при выборе места, будут учитывать рейтинг
    """,
        chat_id=call["from"]["id"],
        reply_markup=feedback_kb,
    )

async def feedback_text(call: CallbackQuery, state: FSMContext):

    rate = call.data.split("_")[1]
    session_maker = await create_db_session()
    async with state.proxy() as data:
        section = data["section"]
        await section.update_section_rates(session_maker=session_maker, rate=int(rate))

    await call.bot.send_message(
        text="""
        Напишите отзыв
        ---
        Вам нравится это место?
        Расскажите, почему!
    """,
        chat_id=call["from"]["id"],
    )

async def not_help(call: CallbackQuery, state: FSMContext):
    await call.bot.send_message(
        text="""
        Отлично
        Места, в которые вы отправили
        заявки можно посмотреть, отправив команду
        ---
        /listplace
    """,
        chat_id=call["from"]["id"],
    )

    time.sleep(10)
    await call.bot.send_message(
        text="""
        Привет!
        Это снова бот портала
        MestoSporta
        ---
        Скажите, связался ли с вами фитнес-клуб?
    """,
        chat_id=call["from"]["id"],
        reply_markup=yes_or_not_kb,
    )

async def yes_bot(call: CallbackQuery, state: FSMContext):
    await call.bot.send_message(
        text="""
        Спасибо за обратную связь. Хороших вам тренировок
    """,
    chat_id=call['from']['id']
    )

async def no_bot(call: CallbackQuery, state: FSMContext):
    await call.bot.send_message(
        text="""
        Спасибо за обратную связь. Мы поработаем над этим.
    """,
        chat_id=call["from"]["id"],
    )

def register_select_section(dp: Dispatcher):
    dp.register_callback_query_handler(select_city, text=["start_search"], state='*')
    dp.register_callback_query_handler(
        save_city_value_and_select_category,
        Text(startswith="city_"),
        state="*",
    )
    dp.register_callback_query_handler(
        metro_or_district, Text(startswith="findcategory_"), state=FindSection
    )
    dp.register_callback_query_handler(by_metro, text=["by_metro"], state='*')
    dp.register_callback_query_handler(
        by_district, text=["by_district"], state='*'
    )
    dp.register_callback_query_handler(
        select_training, Text(startswith="findmetro_"), state="*"
    )
    dp.register_callback_query_handler(
        select_training, Text(startswith="finddistrict_"), state='*'
    )
    dp.register_callback_query_handler(
        waiting_for_find, Text(startswith="findtraning_"), state='*'
    )

    dp.register_callback_query_handler(consult, text=["consult"], state='*')
    dp.register_callback_query_handler(feedback, text=["feedback"], state='*')
    dp.register_callback_query_handler(
        feedback_text, Text(startswith="rate_"), state='*'
    )

    dp.register_callback_query_handler(not_help, text=["not_help"], state='*')
    dp.register_callback_query_handler(yes_bot, text=["yes"], state='*')
    dp.register_callback_query_handler(no_bot, text=["no"], state='*')
    dp.register_callback_query_handler(way, text=['way'], state='*')

# def register_select_section(dp: Dispatcher):
#     dp.register_callback_query_handler(select_city, text=["start_search"])
#     dp.register_callback_query_handler(
#         save_city_value_and_select_category,
#         Text(startswith="city_"),
#         state=FindSection.City,
#     )
#     dp.register_callback_query_handler(
#         metro_or_district, Text(startswith="category_"), state=FindSection.Category
#     )
#     dp.register_callback_query_handler(by_metro, text=["by_metro"], state=FindSection)
#     dp.register_callback_query_handler(
#         by_district, text=["by_district"], state=FindSection
#     )
#     dp.register_callback_query_handler(
#         select_training, Text(startswith="metro_"), state=FindSection
#     )
#     dp.register_callback_query_handler(
#         select_training, Text(startswith="district_"), state=FindSection
#     )
#     dp.register_callback_query_handler(
#         waiting_for_find, Text(startswith="traning_"), state=FindSection
#     )

#     dp.register_callback_query_handler(consult, text=["consult"], state=FindSection)
#     dp.register_callback_query_handler(feedback, text=["feedback"], state=FindSection)
#     dp.register_callback_query_handler(
#         feedback_text, Text(startswith="rate_"), state=FindSection
#     )

#     dp.register_callback_query_handler(not_help, text=["not_help"], state=FindSection)
#     dp.register_callback_query_handler(yes_bot, text=["yes"], state=FindSection)
#     dp.register_callback_query_handler(no_bot, text=["no"], state=FindSection)
#     dp.register_callback_query_handler(way, text=['way'], state=FindSection)


from PyQt5.QtWidgets import QWidget, QAction
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, Activation, Dense, Flatten, Reshape, Dropout, Conv2DTranspose
from tensorflow.keras.callbacks import ModelCheckpoint

import configparser
import numpy as np

# Action Settings
config = configparser.ConfigParser()
config.read('config/action_settings.ini')
SEP = config['ACTION']['SEP']
ADD = config['ACTION']['ADD']
SUB = config['ACTION']['SUB']
DIV = config['ACTION']['DIV']
MUL = config['ACTION']['MUL']
SPL = config['ACTION']['SPL']
NPZ = config['ACTION']['NPZ']
MOD = config['ACTION']['MOD']
JSN = config['ACTION']['JSN']

class ModelTrain(QWidget):
    def __init__(self, nodeflow_main, n, nn, config):
        super(ModelTrain, self).__init__()

        DATASET = config.get('DATASET')
        MODEL = config.get('MODEL')
        SETTINGS = config.get('SETTINGS')

        name = nn+'Train_Name'
        dat_dir = nn+'Dataset_Dir'
        dat_ext = nn+'Dataset_Ext'
        mod_ext = nn+'Model_Ext'
        mod_dir = nn+'Model_Dir'
        set_ext = nn+'Settings_Ext'
        set_dir = nn+'Settings_Dir'

        BATCH_SIZE = 100
        EPOCHS = 60
        OPTIMIZER = 'adam'
        LOSS = 'mse'
        MONITOR = 'val_loss'
        VERBOSE = 1

        nodeflow_main.createAttribute(node=n, name='Train_Name', preset='String', socket=True, plug=True, dataType='str', dataAttr='')

        nodeflow_main.createAttribute(node=n, name='Epochs', preset='Integer', socket=True, plug=False, dataType='int', dataAttr=EPOCHS)
        nodeflow_main.createAttribute(node=n, name='Batch_Size', preset='Integer', socket=True, plug=False, dataType='int', dataAttr=BATCH_SIZE)
        nodeflow_main.createAttribute(node=n, name='Optimizer', preset='String', socket=True, plug=False, dataType='str', dataAttr=OPTIMIZER)
        nodeflow_main.createAttribute(node=n, name='Loss', preset='String', socket=True, plug=False, dataType='str', dataAttr=LOSS)
        nodeflow_main.createAttribute(node=n, name='Monitor', preset='String', socket=True, plug=False, dataType='str', dataAttr=MONITOR)
        nodeflow_main.createAttribute(node=n, name='Verbose', preset='Integer', socket=True, plug=False, dataType='int', dataAttr=VERBOSE)

        nodeflow_main.createAttribute(node=n, name='Dataset_Path', preset='Path', socket=True, plug=True, dataType='str', dataExpr=SPL + DATASET + SPL + ADD + name + ADD + NPZ)
        nodeflow_main.createAttribute(node=n, name='Model_Path', preset='Path', socket=True, plug=True, dataType='str', dataExpr=SPL + MODEL + SPL + ADD + name + ADD + MOD)
        nodeflow_main.createAttribute(node=n, name='Settings_Path', preset='Path', socket=True, plug=True, dataType='str', dataExpr=SPL + SETTINGS + SPL + ADD + name + ADD + JSN)

class ModelTrainAction(QAction):
    """Model Train"""
    def __init__(self, attrData, config):
        super(ModelTrainAction, self).__init__()

        print("Loading previously created data...")

        npz_path = attrData.get('Dataset_Path')
        data = np.load(npz_path)
        mod_path = attrData.get('Model_Path')

        dataX = "x_test"
        dataY = "y_test"

        epochs = int(attrData.get('Epochs'))
        batch_size = int(attrData.get('Batch_Size'))

        optimizer = attrData.get('Optimizer')
        loss = attrData.get('Loss')
        monitor = attrData.get('Monitor')
        verbose = int(attrData.get('Verbose'))

        input_dim = data[dataX].shape[1:]
        output_dim = data[dataY].shape[1:]

        # Building the model
        model = Sequential()

        # convolution layers
        model.add(Conv2D(1, (1, 1), data_format="channels_last", input_shape=input_dim))
        model.add(Conv2D(2, (3, 3)))
        model.add(Conv2D(3, (4, 4)))
        model.add(Dropout(.05))

        # Transpose convolution layers (Deconvolution)
        model.add(Conv2DTranspose(3, (3, 3)))
        model.add(Conv2DTranspose(2, (5, 5)))
        model.add(Conv2DTranspose(1, (8, 8)))
        model.add(Dropout(.1))

        # Fully connected layers
        model.add(Flatten())
        model.add(Dense(np.prod(output_dim)))
        model.add(Reshape(output_dim))  # scaling to the output dimension
        model.add(Activation("linear"))  # using a "soft" activation

        model.compile(optimizer=optimizer, loss=loss)
        print(model.summary())

        # fitting the model
        print("Fitting the model...")
        checkpoint = ModelCheckpoint(mod_path, monitor=monitor, verbose=verbose, save_best_only=True)
        callbacks_list = [checkpoint]

        model.fit(data["x_train"], data["y_train"],
                  batch_size=batch_size,
                  epochs=epochs,
                  validation_data=(data[dataX], data[dataY]),
                  callbacks=callbacks_list)

        model.save_weights(mod_path)
        print("Saved model to disk")
        print('######################### TRAINING COMPLETE #########################')