#!python

from typing import Dict
import sys
import json
import pathlib
from PyQt5.QtCore import QUrl, Qt, pyqtSignal, QTimer, QByteArray
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent, QMediaPlaylist
from PyQt5.QtMultimediaWidgets import QVideoWidget
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QLabel, QPushButton, QHBoxLayout, QSlider, QVBoxLayout, QFileDialog, QScrollArea, QComboBox, QKeySequenceEdit, QGridLayout, QMessageBox
from PyQt5.QtGui import QIcon, QPixmap, QCloseEvent

# 静态全局配置
DEFAULT_CONFIG = pathlib.Path.home() / ".wmask"
DEFAULT_FOLDER_PATH = ""
DEFAULT_VOLUME = 30
DEFAULT_OPACITY = 20
DEFAULT_PLAY = False
DEFAULT_ACTIVE = False

# 应用主界面
class WmaskMain(QMainWindow):
    def __init__(self):
        super().__init__()
        # 全局参数
        self.folder_path = DEFAULT_FOLDER_PATH
        self.default_volume = DEFAULT_VOLUME
        self.default_opacity = DEFAULT_OPACITY
        self.default_play = DEFAULT_PLAY
        self.default_active = DEFAULT_ACTIVE
        # 主界面保持的数据
        self.playlist = set() # 媒体路径
        self.positions: Dict[str, int] = dict() # 媒体路径->进度
        self.volumes: Dict[str, int] = dict() # 媒体路径->音量(max:100)
        self.opacitys: Dict[str, int] = dict() # 媒体路径->不透明度(max:80)
        self.plays: Dict[str, bool] = dict() # 媒体路径->是否正在播放
        self.actives: Dict[str, bool] = dict() # 媒体路径->是否处于激活状态
        # 读取配置文件
        self.openConfig()
        # 主界面持有的 wmask组件句柄、wmask窗口句柄
        self.components: Dict[str, WmaskComponent] = dict()
        self.wmasks: Dict[str, Wmask] = dict()
        # 主界面设置
        self.setWindowTitle("Wmask")
        self.setWindowIcon(ICON_FAVICON)
        self.setFixedWidth(400)
        self.resize(400, 200)
        ### 》 窗体布局
        # 按钮群
        self.newButton = QPushButton("New", parent=self) # 添加媒体
        self.newButton.clicked.connect(self.newButtonOnClicked)
        # 按钮群 水平布局
        self.buttonLayout = QHBoxLayout()
        self.buttonLayout.addWidget(self.newButton)
        # wmask组件群 垂直布局
        self.componentLayout = QVBoxLayout()
        self.componentLayout.setAlignment(Qt.AlignmentFlag.AlignTop)
        self.componentLayout.setContentsMargins(0, 0, 0, 0)
        # wmask组件群 垂直布局实体组件
        self.componentWidget = QWidget()
        self.componentWidget.setLayout(self.componentLayout)
        # wmask组件群 垂直布局实体组件 垂直滑动区域
        self.componentScroll = QScrollArea(self)
        self.componentScroll.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
        self.componentScroll.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
        self.componentScroll.setWidgetResizable(True)
        self.componentScroll.setWidget(self.componentWidget)
        # 主界面 垂直布局
        self.centralLayout = QVBoxLayout()
        self.centralLayout.setAlignment(Qt.AlignmentFlag.AlignTop)
        self.centralLayout.addLayout(self.buttonLayout)
        self.centralLayout.addWidget(self.componentScroll)
        # 主界面 垂直布局实体组件
        self.centralWidget = QWidget()
        self.centralWidget.setLayout(self.centralLayout)
        self.setCentralWidget(self.centralWidget)
        # 依此逐个载入wmask组件
        for i in self.playlist:
            self.addComponent(i)
        ### 《 窗体布局
        # 同步wmask视频进度到wmask组件进度滑动条
        self.syncPositionTimer = QTimer(parent=self)
        self.syncPositionTimer.setInterval(1000)
        self.syncPositionTimer.timeout.connect(self.syncPositionTimerOnTimeout)
        self.syncPositionTimer.start()

    def closeEvent(self, a0: QCloseEvent) -> None:
        self.saveConfig()
        playlist = self.playlist.copy()
        for i in playlist:
            self.deleteSlot(i)
        return super().closeEvent(a0)

    # 读取配置文件
    def openConfig(self, config=DEFAULT_CONFIG):
        if not pathlib.Path(config).is_file():
            return
        try:
            with open(config, "r") as fp:
                config_dict = json.load(fp)
        except:
            return
        def check(_key:str, _type:type, _default, _dict=config_dict):
            if _key in _dict and isinstance(_dict[_key], _type):
                return _dict[_key]
            else:
                return _default
        self.folder_path = check("folder_path", str, DEFAULT_FOLDER_PATH)
        self.default_volume = check("default_volume", int, DEFAULT_VOLUME)
        self.default_opacity = check("default_opacity", int, DEFAULT_OPACITY)
        self.default_play = check("default_play", bool, DEFAULT_PLAY)
        self.default_active = check("default_active", bool, DEFAULT_ACTIVE)
        playlist = check("playlist", list, [])
        def addMedia(mediaObj:dict):
            mediaPath = check("mediaPath", str, "", mediaObj)
            if mediaPath == "":
                return
            self.playlist.add(mediaPath)
            self.positions[mediaPath] = check("position", int, 0, mediaObj)
            self.volumes[mediaPath] = check("volume", int, self.default_volume, mediaObj)
            self.opacitys[mediaPath] = check("opacity", int, self.default_opacity, mediaObj)
            self.plays[mediaPath] = check("play", bool, self.default_play, mediaObj)
            self.actives[mediaPath] = check("active", bool, self.default_active, mediaObj)
        for mediaObj in playlist:
            addMedia(mediaObj)

    # 保存配置文件
    def saveConfig(self, config=DEFAULT_CONFIG):
        configObj = {}
        configObj["folder_path"] = self.folder_path
        configObj["default_volume"] = self.default_volume
        configObj["default_opacity"] = self.default_opacity
        configObj["default_play"] = self.default_play
        configObj["default_active"] = self.default_active
        configObj["playlist"] = []
        for i in self.playlist:
            mediaObj = {}
            mediaObj["mediaPath"] = i
            mediaObj["position"] = self.components[i].positionSlider.value()
            mediaObj["volume"] = self.components[i].volumeSlider.value()
            mediaObj["opacity"] = self.components[i].opacitySlider.value()
            mediaObj["play"] = self.components[i].playOn
            mediaObj["active"] = self.components[i].activeOn
            configObj["playlist"].append(mediaObj)
        with open(config, "w") as fp:
            json.dump(configObj, fp)

    ### 》 按钮群信号槽
    def newButtonOnClicked(self):
        return_lists, _ = QFileDialog.getOpenFileNames(self, "select media", self.folder_path, "Media Files (*.mp4 *.MP4 *.avi *.AVI *.mkv *.MKV *.webm *.WebM *.mov *.MOV *.flv *.FLV *.ogg *.OGG);;All Files (*.*)")
        if return_lists:
            self.folder_path = str(pathlib.Path(return_lists[-1]).parent)
        for i in return_lists:
            if i in self.playlist:
                continue
            self.playlist.add(i)
            self.positions[i] = 0
            self.volumes[i] = self.default_volume
            self.opacitys[i] = self.default_opacity
            self.plays[i] = self.default_play
            self.actives[i] = self.default_active
            self.addComponent(i)
    ### 《 按钮群信号槽

    # 添加wmask组件
    def addComponent(self, mediaPath:str):
        self.components[mediaPath] = WmaskComponent(mediaPath, self.positions[mediaPath], self.opacitys[mediaPath], self.volumes[mediaPath], self.plays[mediaPath], self.actives[mediaPath], parent=self)
        self.components[mediaPath].rateSignal.connect(self.rateSlot)
        self.components[mediaPath].playSignal.connect(self.playSlot)
        self.components[mediaPath].activeSignal.connect(self.activeSlot)
        self.components[mediaPath].deleteSignal.connect(self.deleteSlot)
        self.components[mediaPath].positionSignal.connect(self.positionSlot)
        self.components[mediaPath].volumeSignal.connect(self.volumeSlot)
        self.components[mediaPath].opactiySignal.connect(self.opacitySlot)
        if self.actives[mediaPath]:
            self.activeSlot(mediaPath, True)
        self.componentLayout.addWidget(self.components[mediaPath])

    ### 》 Wmask组件信号槽
    def rateSlot(self, mediaPath:str, value:float):
        if mediaPath in self.wmasks:
            self.wmasks[mediaPath].player.setPlaybackRate(value)

    def playSlot(self, mediaPath:str, play:bool):
        if mediaPath not in self.wmasks:
            return
        if play:
            self.wmasks[mediaPath].player.play()
        else:
            self.wmasks[mediaPath].player.pause()

    def activeSlot(self, mediaPath:str, active:bool):
        if active:
            self.wmasks[mediaPath] = Wmask(mediaPath, self.components[mediaPath].opacitySlider.value(), self.components[mediaPath].volumeSlider.value())
            self.wmasks[mediaPath].player.durationChanged.connect(lambda x: self.components[mediaPath].positionSlider.setMaximum(x) if x > 0 else None)
            self.wmasks[mediaPath].player.setPosition(self.components[mediaPath].positionSlider.value())
            self.wmasks[mediaPath].wmaskCloseSignal.connect(self.wmaskCloseSlot)
            self.wmasks[mediaPath].show()
            if self.components[mediaPath].playOn:
                self.wmasks[mediaPath].player.play()
        else:
            if mediaPath in self.wmasks:
                self.wmasks[mediaPath].deleteLater()
                del self.wmasks[mediaPath]

    def deleteSlot(self, mediaPath:str):
        if self.components[mediaPath].activeOn:
            self.components[mediaPath].activeButton.click()
        self.components[mediaPath].deleteLater()
        del self.components[mediaPath]

        self.playlist.remove(mediaPath)
        self.positions.pop(mediaPath)
        self.opacitys.pop(mediaPath)
        self.volumes.pop(mediaPath)
        self.plays.pop(mediaPath)
        self.actives.pop(mediaPath)

    def positionSlot(self, mediaPath:str, position:int):
        if mediaPath in self.components and self.components[mediaPath].activeOn:
            self.wmasks[mediaPath].player.setPosition(position)

    def volumeSlot(self, mediaPath:str, volume:int):
        if mediaPath in self.components and self.components[mediaPath].activeOn:
            self.wmasks[mediaPath].player.setVolume(volume)

    def opacitySlot(self, mediaPath:str, opacity:int):
        if mediaPath in self.components and self.components[mediaPath].activeOn:
            self.wmasks[mediaPath].setWindowOpacity(opacity / 100)
    ### 《 wmask组件信号槽

    # wmask信号槽
    def wmaskCloseSlot(self, mediaPath:str):
        if mediaPath in self.components and self.components[mediaPath].activeOn:
            self.components[mediaPath].activeButton.click()

    # 计时器信号槽
    def syncPositionTimerOnTimeout(self):
        for i in self.playlist:
            if self.components[i].activeOn and self.components[i].playOn:
                self.components[i].positionSlider.blockSignals(True)
                self.components[i].positionSlider.setValue(self.wmasks[i].player.position())
                self.components[i].positionSlider.blockSignals(False)

# wmask组件
class WmaskComponent(QWidget):
    # 信号
    rateSignal = pyqtSignal(str, float)
    playSignal = pyqtSignal(str, bool)
    activeSignal = pyqtSignal(str, bool)
    deleteSignal = pyqtSignal(str)
    positionSignal = pyqtSignal(str, int)
    volumeSignal = pyqtSignal(str, int)
    opactiySignal = pyqtSignal(str, int)

    def __init__(self, mediaPath:str, position:int, opacity:int, volume:int, play:bool, active:bool, parent):
        super().__init__(parent)
        self.mediaPath = mediaPath
        # 名称标签
        self.nameLabel = QLabel(pathlib.Path(mediaPath).name, parent=self)
        self.nameLabel.setToolTip(self.mediaPath)
        # 播放速度下拉列表框
        self.rateComboBox = QComboBox(parent=self)
        self.rateComboBox.setFixedWidth(80)
        self.rateComboBox.addItems(["0.25", "0.5", "1.0", "1.25", "1.5"])
        self.rateComboBox.setCurrentText("1.0")
        self.rateComboBox.currentTextChanged.connect(self.rateComboBoxOnCurrentTextChanged)
        # 播放/暂停键
        self.playOn = play
        self.playButton = QPushButton(parent=self)
        self.playButton.setFixedWidth(30)
        self.playButton.setIcon(ICON_MEDIA_PLAYBACK_PAUSE if play else ICON_MEDIA_PLAYBACK_START)
        self.playButton.clicked.connect(self.playButtonOnClicked)
        # 激活/关闭键
        self.activeOn = active
        self.activeButton = QPushButton(parent=self)
        self.activeButton.setFixedWidth(30)
        self.activeButton.setIcon(ICON_SYSTEM_SHUTDOWN if active else ICON_SYSTEM_RUN)
        self.activeButton.clicked.connect(self.activeButtonOnClicked)
        # 删除键
        self.deleteButton = QPushButton(parent=self)
        self.deleteButton.setFixedWidth(30)
        self.deleteButton.setIcon(ICON_WINDOW_CLOSE)
        self.deleteButton.clicked.connect(self.deleteButtonOnClicked)
        # 上面四个组件 水平布局
        self.hlayout = QHBoxLayout()
        self.hlayout.addWidget(self.nameLabel)
        self.hlayout.addWidget(self.rateComboBox)
        self.hlayout.addWidget(self.playButton)
        self.hlayout.addWidget(self.activeButton)
        self.hlayout.addWidget(self.deleteButton)
        # 进度
        self.positionLabel = QLabel("progress", parent=self)
        self.positionLabel.setFixedWidth(80)
        self.positionSlider = QSlider(Qt.Orientation.Horizontal, parent=self)
        self.positionSlider.setMinimum(0)
        self.positionSlider.setMaximum(2 * position)
        self.positionSlider.setSingleStep(1000)
        self.positionSlider.setValue(position)
        self.positionSlider.valueChanged.connect(lambda x: self.positionSignal.emit(self.mediaPath, x))
        # 进度 水平布局
        self.h1layout = QHBoxLayout()
        self.h1layout.addWidget(self.positionLabel)
        self.h1layout.addWidget(self.positionSlider)
        # 音量
        self.volumeLabel = QLabel("volume", parent=self)
        self.volumeLabel.setFixedWidth(80)
        self.volumeSlider = QSlider(Qt.Orientation.Horizontal, parent=self)
        self.volumeSlider.setMinimum(0)
        self.volumeSlider.setMaximum(100)
        self.volumeSlider.setSingleStep(1)
        self.volumeSlider.setValue(volume)
        self.volumeSlider.valueChanged.connect(lambda x: self.volumeSignal.emit(self.mediaPath, x))
        # 音量 水平布局
        self.h2layout = QHBoxLayout()
        self.h2layout.addWidget(self.volumeLabel)
        self.h2layout.addWidget(self.volumeSlider)
        # 不透明度
        self.opacityLabel = QLabel("opacity", parent=self)
        self.opacityLabel.setFixedWidth(80)
        self.opacitySlider = QSlider(Qt.Orientation.Horizontal, parent=self)
        self.opacitySlider.setMinimum(0)
        self.opacitySlider.setMaximum(80)
        self.opacitySlider.setSingleStep(1)
        self.opacitySlider.setValue(opacity)
        self.opacitySlider.valueChanged.connect(lambda x: self.opactiySignal.emit(self.mediaPath, x))
        # 不透明度 水平布局
        self.h3layout = QHBoxLayout()
        self.h3layout.addWidget(self.opacityLabel)
        self.h3layout.addWidget(self.opacitySlider)
        # 总 垂直布局
        self.vlayout = QVBoxLayout()
        self.vlayout.addLayout(self.hlayout)
        self.vlayout.addLayout(self.h1layout)
        self.vlayout.addLayout(self.h2layout)
        self.vlayout.addLayout(self.h3layout)
        self.setLayout(self.vlayout)
        # 窗体尺寸
        self.setFixedHeight(120)
        self.setFixedWidth(parent.width()-40)

        self.rateComboBox.setEnabled(self.activeOn)
        self.playButton.setEnabled(self.activeOn)

    ### 《 转发信号
    def rateComboBoxOnCurrentTextChanged(self, value:str):
        if not self.activeOn:
            return
        self.rateSignal.emit(self.mediaPath, float(value))

    def playButtonOnClicked(self):
        if not self.activeOn:
            return
        self.playButton.setIcon(ICON_MEDIA_PLAYBACK_START if self.playOn else ICON_MEDIA_PLAYBACK_PAUSE)
        self.playOn ^= True
        self.playSignal.emit(self.mediaPath, self.playOn)

    def activeButtonOnClicked(self):
        self.activeButton.setIcon(ICON_SYSTEM_RUN if self.activeOn else ICON_SYSTEM_SHUTDOWN)
        self.activeOn ^= True
        self.rateComboBox.setEnabled(self.activeOn)
        self.playButton.setEnabled(self.activeOn)
        self.activeSignal.emit(self.mediaPath, self.activeOn)

    def deleteButtonOnClicked(self):
        self.deleteSignal.emit(self.mediaPath)
    ### 》 转发信号

# wmask窗体
class Wmask(QWidget):
    wmaskCloseSignal = pyqtSignal(str)

    def __init__(self, mediaPath:str, opacity:int, volume:int):
        super().__init__()
        self.mediaPath = mediaPath
        # 设置全屏
        desktop = QApplication.desktop()
        screen_size = desktop.screenGeometry(desktop.screenNumber(self))
        self.resize(screen_size.width(), screen_size.height())
        # 窗体属性
        self.setWindowOpacity(opacity / 100) # 不透明度
        self.setAttribute(Qt.WidgetAttribute.WA_TransparentForMouseEvents, True) # 鼠标事件穿透
        self.setAttribute(Qt.WidgetAttribute.WA_OpaquePaintEvent) # 视频循环播放时，播完到重新开始不重绘，以防止闪屏
        self.flags = Qt.WindowType.FramelessWindowHint | Qt.WindowType.BypassWindowManagerHint | Qt.WindowType.WindowStaysOnTopHint # 无边框 | 键盘鼠标事件穿透 | 置顶窗体
        self.setWindowFlags(self.flags)
        # 视频输出组件
        self.video_widget = QVideoWidget(parent=self)
        self.video_widget.resize(self.width(), self.height())
        # 播放列表（其实只有单一视频，但为了循环播放，需要设置一个播放列表）
        self.playlist = QMediaPlaylist(parent=self)
        self.playlist.addMedia(QMediaContent(QUrl.fromLocalFile(self.mediaPath)))
        self.playlist.setPlaybackMode(QMediaPlaylist.Loop)
        # 播放器
        self.player = QMediaPlayer(parent=self)
        self.player.setPlaylist(self.playlist)
        self.player.setVideoOutput(self.video_widget)
        self.player.setVolume(volume)

    def closeEvent(self, a0: QCloseEvent) -> None:
        self.wmaskCloseSignal.emit(self.mediaPath)
        return super().closeEvent(a0)

# base64字符串转QIcon
def base64ToQIcon(_base64:bytes):
    qpixmap = QPixmap()
    qpixmap.loadFromData(QByteArray.fromBase64(_base64))
    return QIcon(qpixmap)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    # favicon
    ICON_FAVICON = base64ToQIcon(b"iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAAAAAAAAQCEeRdzAAACKklEQVR4nO2ZvUoDQRDHJzZqSh/AwhiNirWf2PoMVtr7GgE1aPQFLPyGdFa+gIUPYGXjJyRgDIIiaDQ6w87hJrlNNuvt3UbuDz849obN7Gbmn2UDECtWrFj/UQNIFikzWR4LKt66KIEq8s1UeSyoeOsqS8l4lAOMt66uX0DXl9AkUkE+mAqP6cQ70cQbyB0yjKT4OdciPscxKfuptVcGxC5uI31MnscyLeLzHBupEsghUkJmpXF6LvK7hE98sSE+Ms2ASOYI6ZHGVYmqFhaJvFJ5QsZ83jeWSrvSCl3UgLfIJqh3U25WneYOVeQ89yCcRyU5aaedRyW5bJxyngMQzjOnEe81rjPOMw0imWOodx6VnFoAff1bIJxnXDPeqRLynIcWoePjzjXxOrR3HllO2ego8ojsgF4ZOPVDRuWyD/rO49xRwtR5nDjM0VdPxwUT53HiOD2E3ICZ86gUqiOtIQ9g5jwqheZII/DrPP0a8brlEYojUbnsgXCeec34ThrUuiNN8QecwN+cRyWrjiQ7z4RmvElJWHMkcp5rnjgo51EpMEeiJl0FcVj7Ql5AlJFK8g2zzmWWSt4R5QLZRRaRXoN5YAlE0t51Xw05BXX9B3U9uII8S/NQ2S4bzANn0Hzh+gnCSv3kd0H7ilx2SMVnnqtuWsC7zzxvJguIqoQK0LyAgsE8dU1MO0kNNdgiPqi/idLIOYgNq/Fz2mCeSJVEFphkxLnEihXLpn4AChIW6yQNMxgAAAAASUVORK5CYII=")
    # 媒体播放键
    ICON_MEDIA_PLAYBACK_START = base64ToQIcon(b"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAATdEVYdFRpdGxlAE9wdGljYWwgRHJpdmU+Z7oMAAABg0lEQVQ4jcWTS0tCURDH5+jJezNNLKpv0AOKHlK0CVwFtesjRAs3PWgTtHKhmwiCFi1amASCLSRLK2+ZFhmtSoWgWhdooPgI70O795x2YaZluGhgFgPz//GfYQZRSqGRUDWkBgBcXoQuT28pAQ6rGLvZbJb+7IAQYurp7l0BtfwcDHMzdVmglH7mWeiEyrJMRVGgD0/30vkFdxMMHvWV91TmFweSJIGiyJDJpqGzo4sxDY+Ns1pd7Jg73AoEAq2/jsDzPBBCQCyK8JpKQjqbQgP9g8zI0KhFpqUXt8c1CwDoR4BCFJCKEmCMAavVIIg86PV69dTkdGuTCu84drcnyjW4EkAIAYwxMBoGmlkt6Fr0kM/nlf2wR8hlc0uL88uRmgCBFwAhBCzDgtHQBrJMqM/vLSUSSUcBi6vWBetb5Q6+OWA0LBgN7XAduSpG49FoURTmbLa1x2oLrAqIxaPvPv9BThAFy8b6preWsCpAhdCde8/F5TIFu9PprOsS0b8/U8OAD1i6yfAlA768AAAAAElFTkSuQmCC")
    # 媒体暂停键
    ICON_MEDIA_PLAYBACK_PAUSE = base64ToQIcon(b"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAATdEVYdFRpdGxlAE9wdGljYWwgRHJpdmU+Z7oMAAAA7ElEQVQ4jdWTwUoDMRRFz3sTZvoH6beIKIOFfpsLcSfoj4hYqFj8FWlcqMvJTJO4GA2t2lEYN75N8g7kcO8iklJizOio138hMNvLYnmzTilaABV1J/V8ulher1PCAoiom9Xz6V5BStHWRzNAWN7f2p5hDw+OERFWD3d2sELXdQC4p8d870/h5fU5s70C7z0hRpq2wXufmYhQlVVmA4KWEDY0vsH7NjMVoSyrzIYThIAxZieBqlJVk28TmM8CYCduLyhQ1d9U+Og7+ZIgxvhzgrDp3OXVhQUoCuMAYgju7PzUAph3tj3y///CaMEbabKLq8akpOcAAAAASUVORK5CYII=")
    # 媒体激活建
    ICON_SYSTEM_RUN = base64ToQIcon(b"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAABN0RVh0VGl0bGUAT3B0aWNhbCBEcml2ZT5nugwAAABgUExURf///wAAAP///4CAgFhbV1hbVp+gnXN0ca6uq3N1ca2trK+wrcfIxlVXU0JDQVVXU1VXU1ZYVGxuaoiKhcXFxM/PzuHh4OLi4O7u7PHx8fLz8vf39/j4+Pv7+/z8+/7+/mcCE4sAAAAQdFJOUwABAQKzt/b6+vv7+/z9/v7YPlFDAAAAdUlEQVQYlXWOWQ6AIAwFAfeVQl1QVO5/SxsTAUN8f22mb8qYDyKyOJk2OotmMe5uH0Xg9dZW7ab9FRrXiMYZ/CU+HY9PAVlAeR/MK+3XGV5WLsdlr2ORoe0sh/Ksi+CzwMFOPCWSDtqQRZCl67vH4v/IeQ6K3yejC9e2pE6uAAAAAElFTkSuQmCC")
    # 媒体失活键
    ICON_SYSTEM_SHUTDOWN = base64ToQIcon(b"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAANhQTFRFnZ2dnp6eoKCgn5+fnZ2dnJyc0NDQ09PTAAAABQUFDxAPJicmQ0RBX2BdYGFgaGhodHR0e314iIqFiYmJjpCLj5GMm5ubsbKwsrKys7Ozu7u7vL+4vb68wMDAxMTExcfCxsjDyMjIzMzMz8/P0dHR1dXV1tbW19fX2NjY2dnZ3d3d3t7e39/f4ODg4eHh4+Pj5OTk5eXl5ubm5+fn6Ojo6enp6urq6+vr7Ozs7e3t7u7u7+/v8PDw8fHx8vLy8/Pz9PT09vb2+vr6+/v7/Pz8/f39/v7+////R6AftQAAAAh0Uk5TGqamp/n6/f1ShpYZAAAAqUlEQVQYV12Pu41CQRAEu3dm3xNIGDznQjiPECB3QsDHIQAQAsQdOx+MBQzaLJVKakLKEu+dwpWylg/wbYhuzjYCQKZf7r8HnaRNj+zC7CSTAiVt90hwWLEAChSLVguiRXbAdFZA3IPd8GAl8j+sdqM5fwDc3IZutNARgIa9GhZcKIyRvUFP2TeouHUA43gNFLEEoMeQ+WU+/AmlLSSOLHVd3t8Q28bv+09M609MRKtpUAAAAABJRU5ErkJggg==")
    # wmask组件删除键
    ICON_WINDOW_CLOSE = base64ToQIcon(b"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAALpQTFRF////YWRfYGNgX19dX2FdYWFdXmBcYGNcYGReYmRgYWNfYGJeYGJcYGJeYmReYmRgYWNdYmRgYGJeYGReYmReYWNfX2FdYGJeYWJfY2VgYmRgY2ZhYmReY2ZhZGZhYGRffH55enx2en13e313fH55f4F8gIJ9gIJ+g4WAhIaBio2Gi42IfH55fYB6gYN9gYR9g4WAhYeChomDio2IsLOrsbSsuby0ur21ur62wMS8wcS8wsa+w8a+x8vDi9cj2gAAADR0Uk5TAG5vdnZ2d3d4eHl6fX19fX5/gICAhIaSmdnd3eDh4uTs7e3t7e3t7e3t7e3u7u7u7u7u7ttMubAAAABxSURBVBiVY2AgC4jJc4IoZnlRqICUqa4QAwOPkokkVIBF11xPiEfJVIURpkfAwNJIzVSHA2GKoLGVmT4XkrH82jYWquwIPp+mrZaGqSJchFXd2lCEV9lUkQkqIGemIQy0VsFUBiogIcsNotikxcnzGAAVDQmLdEUqbgAAAABJRU5ErkJggg==")
    wmask_main = WmaskMain()
    wmask_main.show()
    sys.exit(app.exec_())


import os,traceback,requests,time,json
from datetime import datetime,timedelta
from tqdm import tqdm
import settings
from saveLastChaeck import saveLastCheck
from .parser import ParseOuestfrance
from HttpRequest.uploader import AsyncKafkaTopicProducer
cpath =os.path.dirname(__file__) or "."
kafkaTopicName = settings.KAFKA_OUESTFRANCE
commanPattern =settings.KAFKA_COMMON_PATTERN
website= "ouestfrance-immo.com"
commonIdUpdate = f"activeid-{website}"
class OuestFranceScraper:
    def __init__(self,paremeter,timeout = 5) -> None:
        self.logfile = open(f"{cpath}/error.log",'a')
        self.timeout = timeout
        self.headers = {
            "Connection": "keep-alive",
            "sec-ch-ua": '"Chromium";v="106", "Google Chrome";v="106", "Not;A=Brand";v="99"',
            "Accept": "application/json, text/plain, */*",
            "sec-ch-ua-mobile": "?0",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36",
            "sec-ch-ua-platform": "Windows",
            "Origin": "https://www.ouestfrance-immo.com",
            "Sec-Fetch-Site": "same-site",
            "Sec-Fetch-Mode": "cors",
            "Sec-Fetch-Dest": "empty",
            "Referer": "https://www.ouestfrance-immo.com/",
            "Accept-Encoding": "gzip, deflate, br",
            "Accept-Language": "en-US,en;q=0.9,hi;q=0.8",
        }
        self.paremeter = paremeter
        self.size=100
        self.producer = AsyncKafkaTopicProducer()
        self.searchurl = "https://www-api.ouestfrance-immo.com/api/annonces/"
        self.session = requests.Session()
    def init_session(self):
        self.session.close()
        self.session = requests.Session()
    def fetch(self,url,method = "get",sid=0,retry=0,**kwargs):
        kwargs['headers'] = self.headers
        try:
            if method=="post":
                r = self.session.post(url,timeout=self.timeout,**kwargs)
            else:
                r = self.session.get(url,timeout=self.timeout,**kwargs)
            # print(f"{r.status_code} : response status")
        except Exception as e:
            traceback.print_exc(file=self.logfile)
            print(e)
            time.sleep(1)
            self.init_session()
            if retry<10:
                retry+=1
                return self.fetch(url,method=method,sid=sid,retry=retry,**kwargs)
            else:return None
        if r.status_code not in [200,404,400]:
            print(url)
            print(method)
            print(kwargs)
            self.init_session(sid=sid)
            if retry<10:
                retry+=1
                return self.fetch(url,method=method,sid=sid,retry=retry,**kwargs)
            else:return None
        return r
    def save(self,adslist,onlyid=False):
        if onlyid:
            # now = datetime.now()
            ads = [ParseOuestfrance(ad) for ad in adslist]
            # ads = [{"id":"quest-"+str(ad.get("id")), "last_checked": now.isoformat(),"available":True} for ad in adslist]
            self.producer.PushDataList_v1(commonIdUpdate,ads)
        else:
            self.producer.PushDataList(kafkaTopicName,adslist)
            adslist = [ParseOuestfrance(ad) for ad in adslist]
            self.producer.PushDataList(commanPattern,adslist)
        # data = ""
        # for ad in adslist:
        #     data += json.dumps(ad)+"\n"
        # with open(f"{cpath}/out.json","a") as file:
        #     file.write(data)
        # parseAdList = [ParseLogicImmo(ad) for ad in adslist]
        # self.producer.PushDataList(commonTopicName,parseAdList)
        # self.producer.PushDataList(nortifyTopic,parseAdList)
    def Crawlparam(self,param,allPage = True,first=False,save=True,onlyid=False):
        # input()
        response = self.fetch(self.searchurl, method = "get", params=param,)
        if not response:
            return 0
        # print(response.status_code,"+++++++++")
        res = response.json()
        pagesize = param["limit"]
        ads = res['data']
        fetchedads = ads
        if save:self.save(fetchedads,onlyid=onlyid)
        if first:
            return fetchedads[0]
        if allPage:
            totalpage = res["count"]
            # input()
            print(len(ads),"_total ads+++++++++++++")
            totalpage = int(totalpage/pagesize)+1
            print(f"total page {totalpage}")
            for i in tqdm(range(2,totalpage)):
                param["page"] = i
                self.Crawlparam(param,allPage=False,onlyid=onlyid)
                # break
        else:
            return fetchedads
    def getTotalResult(self,dic):
        dic = {
            **dic,
            "limit":1
        }
        response = self.fetch(self.searchurl, method = "get", params=dic)
        res = response.json()
        count = res["count"]
        return count
    def getMax(self,dic,max="prix"):
        dic = {
            **dic,
            "tri":f"{max}_desc",
            f"{max}_min":1,
            "limit":1
        }
        response = self.fetch(self.searchurl, method = "get", params=dic)
        res = response.json()
        maxval = res["data"][0][max]
        return maxval
    def genFilter(self,parameter={},onlyid=False,low="prix_min",max="prix_max"):
        if parameter:
            dic = parameter.copy()
        else:dic = self.paremeter.copy()
        # totalresult = getTotalResult(session,dic)
        # acres = totalresult
        # dic['recherche[produit]']=typ
        if low=="prix_min":
            # iniinterval =[98976, 98989]
            iniinterval = [0,1000]
            maxprize = self.getMax(dic.copy())
        else:
            maxprize = self.getMax(dic.copy(),max="surface")
            iniinterval =[0,1]
        # maxprize = getMaxPrize(session,dic)
        maxresult = 4999
        filterurllist = ""
        finalresult = 0
        nooffilter = 0
        while iniinterval[1]<=maxprize:
            dic[low],dic[max] = iniinterval
            totalresult = self.getTotalResult(dic)
            if totalresult <= maxresult and totalresult>0:
                # print("condition is stisfy going to next interval",totalresult)
                # print(iniinterval,">apending")
                filterurllist += json.dumps(iniinterval) + "/n/:"
                # FetchFilter(dic,onlyid,session2)
                self.CrawlOuestfrance(dic.copy(),onlyid)
                print("going to next")
                iniinterval[0] = iniinterval[1]+1
                iniinterval[1] = iniinterval[0]+int(iniinterval[0]/2)
                finalresult +=totalresult
                nooffilter +=1
            # elif acres-finalresult<4800 and acres-finalresult>0:
            #     print(maxresult, acres , maxresult-acres)
            #     # input()
            #     # print("elif 1")
            #     last = 10
            #     iniinterval[1] = maxprize
            elif totalresult == 0:
                # print("elif 1",iniinterval)
                last = 10
                iniinterval[0] = iniinterval[1]
                iniinterval[1] = iniinterval[0] + (int(iniinterval[1]/last) or 1)
                # iniinterval[0] = iniinterval[1]
                # iniinterval[1] +=1
            elif iniinterval[1]-iniinterval[0] <=2 and totalresult>maxresult and low=="prix_min":
                finalresult +=totalresult
                self.genFilter(dic.copy(),onlyid,"surface_min","surface_max")
                iniinterval[0] = iniinterval[1]
                iniinterval[1]+=1
            elif totalresult>maxresult:
                # print("elif 2",iniinterval)
                last = -5
                dif = iniinterval[1]-iniinterval[0]
                iniinterval[1] = iniinterval[1] + int(dif/-2)
                if iniinterval[0]>iniinterval[1]:
                    iniinterval[1] = iniinterval[0]+1
            # retrydic[iniinterval[0]] +=1
            print(f"\r{totalresult}-{maxresult}:::: of  {finalresult}==>{iniinterval} {maxprize} {low} no of filter",end="")
            # print(totalresult,"-",maxresult,"::::",acres ," of ", finalresult,"==>",iniinterval)
        self.CrawlOuestfrance(dic.copy(),onlyid)

    def getLastUpdate(self):
        try:
            with open(f"{cpath}/lastUpdate.json",'r') as file:
                data = json.load(file)
            return data
        except:
            return {}
    def getTimeStamp(self,strtime):
        formate = '%Y-%m-%d %H:%M:%S'
        # 2022-06-19 05:26:55
        try:
            t = datetime.strptime(strtime,formate)
        except:return strtime
        return t.timestamp()
    def getUpdateDicFromAd(self,ad):
        nowtime  = datetime.now()
        upd={
                "timestamp": nowtime.timestamp(),
                "lastupdate": self.getTimeStamp(ad.get('date_deb_aff')),
                "Rlastupdate": ad.get('date_deb_aff'),
                "created": self.getTimeStamp(ad.get('date_creation')),
                "rcreated": ad.get('date_creation'),
            }
        return upd
    def getAdStatus(self,id):
        url = f"{self.searchurl}{id}"
        r = self.fetch(url)
        data = r.json()
        if data["data"]:return True
        else:False
    def getlatestAd(self):
        param = self.paremeter
        param["limit"] = 1
        data = self.Crawlparam(param,allPage=False,first=True)
        param["limit"] = self.size
        return data
    def createNewUpdate(self,latestad=None):
        lastupd = self.getLastUpdate()
        if not latestad:
            latestad = self.getlatestAd()
        lastupd=self.getUpdateDicFromAd(latestad)
        with open(f"{cpath}/lastUpdate.json",'w') as file:
            file.write(json.dumps(lastupd))
    def CrawlOuestfrance(self,param=None,onlyid=False):
        if not param:
            param = self.paremeter.copy()
        if not onlyid:self.createNewUpdate(latestad=None)
        self.Crawlparam(param,onlyid=onlyid)
    def updateLatestAd(self):
        updates = self.getLastUpdate()
        if updates:
            param = self.paremeter
            updated = False
            first = True
            page =1
            adcount = 0
            page = 1
            while not updated:
                param["page"] = page
                # res = self.fetch(searchurl, method = "post", json=param)
                ads = self.Crawlparam(param,False,False,False)
                updatedads = []
                updatetimestamp = updates["lastupdate"]
                for ad in ads:
                    # ad = self.GetAdInfo(ad['id'])
                    adtimestamp = self.getTimeStamp(ad["date_deb_aff"])
                    print(f"   {adtimestamp}> {updatetimestamp}====>",adtimestamp>updatetimestamp)
                    if adtimestamp>updatetimestamp:
                        if first:
                            self.createNewUpdate(ad)
                            first=False
                        updatedads.append(ad)
                        adcount+=1
                    else:
                        print(f"{adcount} new ads scraped ")
                        updated = True
                        break
                self.save(updatedads)
                page+=1
        else:
            print("there is no update available")
def CheckId(id):
    ob = OuestFranceScraper(data)
    found= ob.getAdStatus(id)
    ob.__del__()
    return found
def main_scraper(payload,update=False):
    adtype = payload.get("real_state_type")
    """
    typIds
        201 : for vente
        214 : for location
        216 : for location
    """
    data = {
        "limit":200,
        "tri":"date_desc",
        # "typIds":"201,214,216"
    }
    if adtype == "Updated/Latest Ads" or update:
        ob = OuestFranceScraper(data,timeout=10)
        print("updateing latedst ads")
        ob.updateLatestAd()
    elif payload.get("real_state_type") == "deletedCheck":
        rescrapActiveId()
    else:
        ob = OuestFranceScraper(data,timeout=30)
        ob.genFilter()
def rescrapActiveIdbyType():
    """
    typIds
        201 : for vente
        207 : for vente
        208 : for vente
        209 : for vente
        210 : for vente
        213 : for location
        214 : for location
        216 : for location
    """
    data = {
        "limit":208,
        "tri":"date_desc",
        # "typIds":"201,214,216"
    }
    ob = OuestFranceScraper(data,timeout=30)
    ob.genFilter(data,onlyid=True)
def rescrapActiveId():
    nowtime = datetime.now()
    nowtime = nowtime - timedelta(hours=1)
    rescrapActiveIdbyType()
    # main("buy",True)
    # with concurrent.futures.ThreadPoolExecutor(max_workers=10) as excuter:
    #     futures = [excuter.submit(rescrapActiveIdbyType, i) for i in ["rental","sale"]]
    #     for f in futures:print(f)
    # rescrapActiveIdbyType("rental")
    # print("complited")
    saveLastCheck(website,nowtime.isoformat())
if __name__ == "__main__":
    """
    typIds
        201 : for vente
        214 : for location
        216 : for location
    """
    data = {
        "limit":200,
        "tri":"date_desc",
        # "typIds":"201,214,216"
    }
    ob = OuestFranceScraper(data,timeout=30)
    ob.CrawlOuestfrance()
    # ob.updateLatestAd()

#parms ?limit=2&tri=date_decroissant&balcon=1&criteres_or=1&hasPhoto=1&idslieu=33540&isNeuf=0&limit=10&terrasse=1&tra=V&typIds=201&veranda=1&prix_min=199290&page=1&prix_max=200000


from socket import *

try:

    soc = socket(AF_INET, SOCK_STREAM)

    soc.bind(('192.168.0.101', 4000))
    soc.listen(1)

    while True:
        c_sock, c_addr = soc.accept()

        c_message = c_sock.recv(1000).decode()
        print(c_addr, ': ', c_message)

        message = input("message: ")
        if message == 'quit':
            c_sock.close()
            break
        c_sock.send(message.encode())

        c_sock.close()

finally:
    c_sock.close()
    soc.close()


"""
    1st: line sweep

    Time    O(RlogR ClogC)
    Space   O(RC)
    LTE 48/40 testcases
"""
class Solution:
    def isRectangleCover(self, rectangles: List[List[int]]) -> bool:
        linesweep2D = defaultdict(Counter)
        for r1, c1, r2, c2 in rectangles:
            for i in range(r1, r2):
                linesweep2D[i][c1] += 1
                linesweep2D[i][c2] -= 1

        rows = sorted(linesweep2D.keys())
        prev_width = None
        prev_r = None
        for r in rows:

            if prev_r == None:
                prev_r = r
            elif prev_r+1 != r:
                return False
            prev_r = r

            col_idxs = sorted(linesweep2D[r].keys())

            pfs = 0
            back2zero = False
            for c in col_idxs:
                pfs += linesweep2D[r][c]
                if pfs == 0:
                    if back2zero:
                        return False
                    back2zero = True
                elif pfs > 1:
                    return False
            width = col_idxs[-1] - col_idxs[0]

            if prev_width == None:
                prev_width = width
            elif width != prev_width:
                return False
        return True

"""
    2nd: math
    - 4 corners of the combined rectangle must appear once. But corners of other rectangles must appear even number of times
    - sum of the areas must be equal to the area of the combined rectangle
"""
class Solution:
    def isRectangleCover(self, rectangles: List[List[int]]) -> bool:
        corners = set()
        area_sum = 0
        for x1, y1, x2, y2 in rectangles:
            corners ^= {(x1, y1), (x1, y2), (x2, y2), (x2, y1)}
            area_sum += (x2 - x1) * (y2 - y1)
        # check the corners
        if len(corners) != 4:
            return False
        # check area with the remaining corners
        left, bottom = 2**32, 2**32
        right, top = -(2**32), -(2**32)
        for x, y in corners:
            left = min(left, x)
            bottom = min(bottom, y)
            right = max(right, x)
            top = max(top, y)
        if (right - left) * (top - bottom) != area_sum:
            return False
        return True


from .kickers import FastKickerController
from .mint import XFELMachineInterface
from .screens import ScreenService
from .tds import TransverseDeflectors
from .sbunches import SpecialBunchesControl, DiagnosticRegion

class BunchLengthMachine:
    def __init__(self, kickerop: FastKickerController,
                 sservice: ScreenService,
                 deflectors: TransverseDeflectors,
                 initial_location=None,
                 mi=None) -> None:
        initial_location = initial_location if initial_location else DiagnosticRegion("I1")
        self.kickerop = kickerop
        self.screens = sservice
        self.deflectors = deflectors
        self.sbunches = SpecialBunchesControl()
        self.set_measurement_location(initial_location)
        mi = mi if mi else XFELMachineInterface()

    def set_kicker_for_screen(self, screen_name: str) -> None:
        kicker_setpoints = self.screens.get_fast_kicker_setpoints_for_screen(screen_name)
        for setpoint in kicker_setpoints:
            self.kickerop.apply_fast_kicker_setpoint(setpoint)
        # self.sbunches.write_kicker

    def set_measurement_location(self, location: DiagnosticRegion):
        self.sbunches.location = location
        self.screens.location = location
        self.deflectors.location = location


"""
total_connect_client package

TotalConnectClient is the main class for the Total Connect interface.

Its accessors may return instances of TotalConnectLocation, TotalConnectPartition,
and TotalConnectZone (from .location, .partition, and .zone respectively), but
users of this interface never create those themselves.
"""

from . import client, zone, const

TotalConnectClient = client.TotalConnectClient
ArmingHelper = client.ArmingHelper

ZoneStatus = zone.ZoneStatus
ZoneType = zone.ZoneType
ArmingState = const.ArmingState
ArmType = const.ArmType
ResultCode = const._ResultCode

__all__ = [
    'TotalConnectClient', 'ArmType', 'ArmingState', 'ArmingHelper',
    'ZoneType', 'ZoneStatus',
]


from pprint import pprint
import json
from copy import deepcopy
file_open = open('data.csv','r')
file_read = file_open.read()
count = 0
timetable=[]
dictionary={
        'day':'RK',
        'prof':'RK',
        'subject':'RK',
        'subject_number':'RK',
        'time':'RK',
        'room':'RK',
}
counter=0
new_word=''
word_list=[]
for letter in file_read:
	if(letter==',' or letter=="\n"):
		word_list.append(new_word)
		new_word=''

	else:
		new_word=new_word+letter

with open('data.json','w') as file:
		timelist=[]
		for word in word_list:
			if(count==0):
				dictionary['day']=word
			if(count==1):
				dictionary['prof']=word
			if(count==2):
				dictionary['subject']=word
			if(count==3):
				dictionary['subject_number']=word
			if(count==4):
				dictionary['time']=word
			if(count==5):
				dictionary['room']=word
				count=-1
				timetable.append(deepcopy(dictionary))
			count=count+1
		json.dump(timetable, file)


import Yard
import random

class Chicken:

    def __init__(self, yard: Yard, name, color, x, y):
        self.yard = yard
        self.name = name
        self.color = color
        self.x = x
        self.y = y

    def __str__(self):
        return self.name + '(' + str(self.x) + ',' + str(self.y) + ')'

    def step(self):
        xMove = random.randint(-1, 1)
        yMove = random.randint(-1, 1)
        self.x += xMove
        self.y += yMove

        if self.x < 0:
            self.x = 0
        elif self.x > self.yard.width:
            self.x = self.yard.width

        if self.y < 0:
            self.y = 0
        elif self.y > self.yard.lenght:
            self.y = self.yard.lenght

    def getSamePositionChickens(self):
        samePositionChickens = []
        for chick in self.yard.chickens:
            if chick != self and chick.x == self.x and chick.y == self.y and type(chick) is Chicken:
                samePositionChickens.append(chick)
        return samePositionChickens


#!/bin/python3

import math
import os
import random
import re
import sys

#
# Complete the 'marsExploration' function below.
#
# The function is expected to return an INTEGER.
# The function accepts STRING s as parameter.
#

def marsExploration(s):
    # Write your code here
    num_errors = 0

    for i, char in enumerate(s):
        if i % 3 == 1:
            if char != "O":
                num_errors += 1
        else:
            if char != "S":
                num_errors += 1

    return num_errors

if __name__ == '__main__':
    fptr = open(os.environ['OUTPUT_PATH'], 'w')

    s = input().strip()

    result = marsExploration(s)

    fptr.write(str(result) + '\n')

    fptr.close()

Algorithms/03 - Strings/Mars Exploration.py


def check(a,b,c):
    isA = 0
    isB = 0
    isC = 0
    if a**2 + b**2 != c**2:
        isC = 1
    if b**2 + c**2 != a**2:
        isA = 1
    if a**2 + c**2 != b**2:
        isB = 1
    if isA + isB + isC == 3:
        return print("wrong")
    return print("right")

while True:
    a,b,c = list(map(int,input().split()))
    if a == 0 and b == 0 and c == 0 :
        break
    check(a,b,c)


import simpy
import random
import sys

from gvas.config import settings
from gvas.base import Process, NamedProcess
from gvas.base import Simulation
from gvas.cluster import *
from gvas.cluster.network import Message, Address
from gvas.dynamo import Uniform

##########################################################################
# Simulation Configuration
##########################################################################

CLUSTER_SIZE    = settings.defaults.cluster.size
RACK_SIZE       = settings.defaults.rack.size
NODE_CPUS       = settings.defaults.node.cpus
NODE_MEMORY     = settings.defaults.node.memory

NODE_COUNT      = settings.simulations.simple.node_count
START_COUNT     = settings.simulations.simple.start_team_size
MIN_MSG_SIZE    = settings.simulations.simple.min_msg_size
MAX_MSG_SIZE    = settings.simulations.simple.max_msg_size
MIN_MSG_VALUE   = settings.simulations.simple.min_msg_value
MAX_MSG_VALUE   = settings.simulations.simple.max_msg_value

##########################################################################
# Classes
##########################################################################

class SimpleSimulation(Simulation):

    def __init__(self, *args, **kwargs):
        super(SimpleSimulation, self).__init__(*args, **kwargs)

        self.cluster = None
        self.record_proc = self.env.process(self.record())
        self.diary.configuration = settings.simulations.simple

    def record(self):
        """
        Process method to record the state of the networks once per cycle.
        """
        while True:
            # self.diary.update('message_count', self._message_count)
            # self.diary.update('message_size', self._message_size)
            # self.diary.update('avg_bandwidth', self._avg_bandwidth)
            # self.diary.update('Congestion', self._avg_used_bandwidth)
            msg_size  = float(self._message_size)
            msg_count = float(self._message_count)
            avg_msg   = msg_size / msg_count if msg_count > 0 else 0.0

            self.diary.update('Number of Messages', msg_count)
            self.diary.update('Mean Message Size', avg_msg)
            self.diary.update('Mean Latency', self._avg_latency)
            yield self.env.timeout(1)

    @property
    def _message_size(self):
        """
        Returns total size of message traffic on all of the racks.
        """
        size = 0
        for r in self.cluster.racks.itervalues():
            size += r.network.traffic
        return size

    @property
    def _message_count(self):
        """
        Returns total number of messages in-flight on all of the racks.
        """
        return sum([r.network.message_count for r in self.cluster.racks.itervalues()])

    @property
    def _avg_bandwidth(self):
        """
        Returns average bandwidth of all the racks.
        """
        bandwidth = sum([r.network.bandwidth for r in self.cluster.racks.itervalues()])
        return bandwidth / len(self.cluster.racks)

    @property
    def _avg_used_bandwidth(self):
        """
        Returns used bandwidth of all the racks.
        """
        bandwidth = sum([r.network.bandwidth for r in self.cluster.racks.itervalues()])
        capacity = sum([r.network.capacity for r in self.cluster.racks.itervalues()])

        congestion = capacity - bandwidth
        return congestion / len(self.cluster.racks)

    @property
    def _avg_latency(self):
        """
        Returns average latency of all the racks.
        """
        latency = sum([r.network.latency for r in self.cluster.racks.itervalues()])
        return latency / len(self.cluster.racks)

    def script(self):
        rack_options = {
            'size': RACK_SIZE
        }
        node_options = {
            'cpus': NODE_CPUS,
            'memory': NODE_MEMORY
        }
        gen = Cluster.create(
            self.env,
            size=CLUSTER_SIZE,
            rack_options=rack_options,
            node_options=node_options,
        )
        cluster = gen.next()
        self.cluster = cluster

        # create program generator
        pgen = PingProgram.create(self.env, cpus=1, memory=4, ports=[3333, 4444])

        # create nodes using cluster's node generator
        nodes = [cluster.add() for i in range(NODE_COUNT)]

        # assign new programs to each node
        for n in nodes:
            n.assign(pgen.next())

        # set some programs to start working instead of waiting
        starters = random.sample(nodes, START_COUNT)
        work_maker = Uniform(10, 50, 'int')
        for n in starters:
            p = n.programs[n.programs.keys()[0]]
            p.work_queue.append(work_maker.next())

class PingProgram(Program):

    def __init__(self, env, *args, **kwargs):
        self.work_queue = []
        self.message_size_gen = Uniform(MIN_MSG_SIZE, MAX_MSG_SIZE, 'int')
        self.message_value_gen = Uniform(MIN_MSG_VALUE, MAX_MSG_VALUE, 'int')
        self.msg_received = env.event()

        super(PingProgram, self).__init__(env, *args, **kwargs)

    def recv(self, message):
        # print "Program {}: received a message with value {} at {}\n".format(self.id, value, self.env.now)
        self.work_queue.append(message.value)
        self.msg_received.succeed()
        self.msg_received = self.env.event()

    def wait(self):
        """
        Wait until we get a new message
        """
        # print "Program {}: waiting for recv at {}\n".format(self.id, self.env.now)
        yield self.msg_received
        # print "Program {}: received message! {}\n".format(self.id, self.env.now)

    def work(self):
        """
        Simulate work by going to sleep according to the oldest value in the
        work queue.
        """
        # print "Program {}: starting work at {}\n".format(self.id, self.env.now)
        yield self.env.timeout(self.work_queue.pop(0))
        # print "Program {}: done working at {}\n".format(self.id, self.env.now)

    def send(self):
        """
        Send a message to another node with varying size and value.  The value
        of the message will be used by the recipient computer as the amount of
        time to "work".
        """
        # print "Program {}: sending at {}\n".format(self.id, self.env.now)
        yield self.env.timeout(1)

        # find other node and send the message
        recip = self.node.rack.cluster.random(
            lambda n: n.id != self.node.id and n.programs
        )

        self.node.send(
            dst=recip.address._replace(port=3333),
            size=self.message_size_gen.next(),
            value=self.message_value_gen.next()
        )

        # print "Program {}: done sending at {}\n".format(self.id, self.env.now)

    def run(self):
        """
        Kicks off execution of a simulated program. This method contains a loop
        to cycle through specific behaviors such as:
            - wait for recv
            - sleep for random time
            - does a send to one or more other Programs/Nodes
            - repeat
        """
        while True:
            if not self.work_queue:
                waiting = self.env.process(self.wait())
                yield waiting

            working = self.env.process(self.work())
            yield working

            sending = self.env.process(self.send())
            yield sending

##########################################################################
# Execution
##########################################################################

if __name__ == '__main__':
    s = SimpleSimulation()
    s.run()


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

import logging

import networkx as nx

log = logging.getLogger()

def _find_src_nodes(Gt):
    src_list = []
    for node in Gt.nodes():
        predecessors = list(Gt.predecessors(node))
        if not predecessors:
            src_list.append(node)
    return src_list

def _find_dst_nodes(Gt):
    dst_list = []
    for node in Gt.nodes():
        successors = list(Gt.successors(node))
        if not successors:
            dst_list.append(node)
    return dst_list

def has_simple_path(G, src, dst):
    all_path = list(nx.all_simple_paths(G, src, dst))
    return len(all_path) > 0

def find_all_simple_path(G):
    """
    Generate all simple paths in the graph G from source to target.
    Args:
        G (nx.DiGraph)
    Returns:
        src_list (list of str): source nodes
        dst_list (list of str): dstination nodes
        all_paths (list of list(str)): all simple paths of nodes' names
    """
    src_list = _find_src_nodes(G)
    dst_list = _find_dst_nodes(G)
    log.info('find all path from {} to {}'.format(src_list, dst_list))
    all_paths = []
    for src in src_list:
        for dst in dst_list:
            paths = list(nx.all_simple_paths(G, src, dst))
            log.info('found path: {}'.format(paths))
            all_paths += paths
    return src_list, dst_list, all_paths


print('Maior número:')

valor1 = input('Digite o primeiro valor: ')
valor2 = input('Digite o segundo valor: ')
valor3 = input('Digite o terceiro valor: ')

a = float(valor1)
b = float(valor2)
c = float(valor3)

maior = 0
if a >= b and a >= c:
    maior = a
elif b >= a and b >= c:
    maior = b
elif c >= a and c >= b:
    maior = c

print(f'O maior valor é: {maior}')


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

import math
import random

import tensorflow as tf

from tensorflow.contrib.tensor_forest.python.ops import inference_ops
from tensorflow.contrib.tensor_forest.python.ops import training_ops

# If tree[i][0] equals this value, then i is a leaf node.
LEAF_NODE = -1

# A convenience class for holding random forest hyperparameters.
#
# To just get some good default parameters, use:
#   hparams = ForestHParams(num_classes=2, num_features=40).fill()
#
# Note that num_classes can not be inferred and so must always be specified.
# Also, either num_splits_to_consider or num_features should be set.
#
# To override specific values, pass them to the constructor:
#   hparams = ForestHParams(num_classes=5, num_trees=10, num_features=5).fill()
#
# TODO(thomaswc): Inherit from tf.HParams when that is publicly available.
class ForestHParams(object):
  """A base class for holding hyperparameters and calculating good defaults."""

  def __init__(self, num_trees=100, max_nodes=10000, bagging_fraction=1.0,
               max_depth=0, num_splits_to_consider=0,
               feature_bagging_fraction=1.0,
               max_fertile_nodes=0, split_after_samples=250,
               valid_leaf_threshold=1, **kwargs):
    self.num_trees = num_trees
    self.max_nodes = max_nodes
    self.bagging_fraction = bagging_fraction
    self.feature_bagging_fraction = feature_bagging_fraction
    self.max_depth = max_depth
    self.num_splits_to_consider = num_splits_to_consider
    self.max_fertile_nodes = max_fertile_nodes
    self.split_after_samples = split_after_samples
    self.valid_leaf_threshold = valid_leaf_threshold

    for name, value in kwargs.items():
      setattr(self, name, value)

  def values(self):
    return self.__dict__

  def fill(self):
    """Intelligently sets any non-specific parameters."""
    # Fail fast if num_classes or num_features isn't set.
    _ = getattr(self, 'num_classes')
    _ = getattr(self, 'num_features')

    self.training_library_base_dir = getattr(
        self, 'training_library_base_dir', '')
    self.inference_library_base_dir = getattr(
        self, 'inference_library_base_dir', '')

    self.bagged_num_features = int(self.feature_bagging_fraction *
                                   self.num_features)

    self.bagged_features = None
    if self.feature_bagging_fraction < 1.0:
      self.bagged_features = [random.sample(
          range(self.num_features),
          self.bagged_num_features) for _ in range(self.num_trees)]

    self.regression = getattr(self, 'regression', False)

    # Num_outputs is the actual number of outputs (a single prediction for
    # classification, a N-dimenensional point for regression).
    self.num_outputs = self.num_classes if self.regression else 1

    # Add an extra column to classes for storing counts, which is needed for
    # regression and avoids having to recompute sums for classification.
    self.num_output_columns = self.num_classes + 1

    # Allow each tree to be unbalanced by up to a factor of 2.
    self.max_depth = (self.max_depth or
                      int(2 * math.ceil(math.log(self.max_nodes, 2))))

    # The Random Forest literature recommends sqrt(# features) for
    # classification problems, and p/3 for regression problems.
    # TODO(thomaswc): Consider capping this for large number of features.
    self.num_splits_to_consider = (
        self.num_splits_to_consider or
        max(10, int(math.ceil(math.sqrt(self.num_features)))))

    # max_fertile_nodes doesn't effect performance, only training speed.
    # We therefore set it primarily based upon space considerations.
    # Each fertile node takes up num_splits_to_consider times as much
    # as space as a non-fertile node.  We want the fertile nodes to in
    # total only take up as much space as the non-fertile nodes, so
    num_fertile = int(math.ceil(self.max_nodes / self.num_splits_to_consider))
    # But always use at least 1000 accumulate slots.
    num_fertile = max(num_fertile, 1000)
    self.max_fertile_nodes = self.max_fertile_nodes or num_fertile
    # But it also never needs to be larger than the number of leaves,
    # which is max_nodes / 2.
    self.max_fertile_nodes = min(self.max_fertile_nodes,
                                 int(math.ceil(self.max_nodes / 2.0)))

    # We have num_splits_to_consider slots to fill, and we want to spend
    # approximately split_after_samples samples initializing them.
    num_split_initializiations_per_input = max(1, int(math.floor(
        self.num_splits_to_consider / self.split_after_samples)))
    self.split_initializations_per_input = getattr(
        self, 'split_initializations_per_input',
        num_split_initializiations_per_input)

    # If base_random_seed is 0, the current time will be used to seed the
    # random number generators for each tree.  If non-zero, the i-th tree
    # will be seeded with base_random_seed + i.
    self.base_random_seed = getattr(self, 'base_random_seed', 0)

    return self

# A simple container to hold the training variables for a single tree.
class TreeTrainingVariables(object):
  """Stores tf.Variables for training a single random tree.

  Uses tf.get_variable to get tree-specific names so that this can be used
  with a tf.learn-style implementation (one that trains a model, saves it,
  then relies on restoring that model to evaluate).
  """

  def __init__(self, params, tree_num, training):
    self.tree = tf.get_variable(
        name=self.get_tree_name('tree', tree_num), dtype=tf.int32,
        initializer=tf.constant(
            [[-1, -1]] + [[-2, -1]] * (params.max_nodes - 1)))
    self.tree_thresholds = tf.get_variable(
        name=self.get_tree_name('tree_thresholds', tree_num),
        shape=[params.max_nodes],
        initializer=tf.constant_initializer(-1.0))
    self.tree_depths = tf.get_variable(
        name=self.get_tree_name('tree_depths', tree_num),
        shape=[params.max_nodes],
        dtype=tf.int32,
        initializer=tf.constant_initializer(1))
    self.end_of_tree = tf.get_variable(
        name=self.get_tree_name('end_of_tree', tree_num),
        dtype=tf.int32,
        initializer=tf.constant([1]))

    if training:
      self.non_fertile_leaves = tf.get_variable(
          name=self.get_tree_name('non_fertile_leaves', tree_num),
          dtype=tf.int32,
          initializer=tf.constant([0]))
      self.non_fertile_leaf_scores = tf.get_variable(
          name=self.get_tree_name('non_fertile_leaf_scores', tree_num),
          initializer=tf.constant([1.0]))

      self.node_to_accumulator_map = tf.get_variable(
          name=self.get_tree_name('node_to_accumulator_map', tree_num),
          shape=[params.max_nodes],
          dtype=tf.int32,
          initializer=tf.constant_initializer(-1))

      self.candidate_split_features = tf.get_variable(
          name=self.get_tree_name('candidate_split_features', tree_num),
          shape=[params.max_fertile_nodes, params.num_splits_to_consider],
          dtype=tf.int32,
          initializer=tf.constant_initializer(-1))
      self.candidate_split_thresholds = tf.get_variable(
          name=self.get_tree_name('candidate_split_thresholds', tree_num),
          shape=[params.max_fertile_nodes, params.num_splits_to_consider],
          initializer=tf.constant_initializer(0.0))

    # Statistics shared by classification and regression.
    self.node_sums = tf.get_variable(
        name=self.get_tree_name('node_sums', tree_num),
        shape=[params.max_nodes, params.num_output_columns],
        initializer=tf.constant_initializer(0.0))

    if training:
      self.candidate_split_sums = tf.get_variable(
          name=self.get_tree_name('candidate_split_sums', tree_num),
          shape=[params.max_fertile_nodes, params.num_splits_to_consider,
                 params.num_output_columns],
          initializer=tf.constant_initializer(0.0))
      self.accumulator_sums = tf.get_variable(
          name=self.get_tree_name('accumulator_sums', tree_num),
          shape=[params.max_fertile_nodes, params.num_output_columns],
          initializer=tf.constant_initializer(-1.0))

      # Regression also tracks second order stats.
      if params.regression:
        self.node_squares = tf.get_variable(
            name=self.get_tree_name('node_squares', tree_num),
            shape=[params.max_nodes, params.num_output_columns],
            initializer=tf.constant_initializer(0.0))

        self.candidate_split_squares = tf.get_variable(
            name=self.get_tree_name('candidate_split_squares', tree_num),
            shape=[params.max_fertile_nodes, params.num_splits_to_consider,
                   params.num_output_columns],
            initializer=tf.constant_initializer(0.0))

        self.accumulator_squares = tf.get_variable(
            name=self.get_tree_name('accumulator_squares', tree_num),
            shape=[params.max_fertile_nodes, params.num_output_columns],
            initializer=tf.constant_initializer(-1.0))

      else:
        self.node_squares = tf.constant(
            0.0, name=self.get_tree_name('node_squares', tree_num))

        self.candidate_split_squares = tf.constant(
            0.0, name=self.get_tree_name('candidate_split_squares', tree_num))

        self.accumulator_squares = tf.constant(
            0.0, name=self.get_tree_name('accumulator_squares', tree_num))

  def get_tree_name(self, name, num):
    return '{0}-{1}'.format(name, num)

class ForestStats(object):

  def __init__(self, tree_stats, params):
    """A simple container for stats about a forest."""
    self.tree_stats = tree_stats
    self.params = params

  def get_average(self, thing):
    val = 0.0
    for i in range(self.params.num_trees):
      val += getattr(self.tree_stats[i], thing)

    return val / self.params.num_trees

class TreeStats(object):

  def __init__(self, num_nodes, num_leaves):
    self.num_nodes = num_nodes
    self.num_leaves = num_leaves

class ForestTrainingVariables(object):
  """A container for a forests training data, consisting of multiple trees.

  Instantiates a TreeTrainingVariables object for each tree. We override the
  __getitem__ and __setitem__ function so that usage looks like this:

    forest_variables = ForestTrainingVariables(params)

    ... forest_variables.tree ...
  """

  def __init__(self, params, device_assigner, training=True,
               tree_variable_class=TreeTrainingVariables):
    self.variables = []
    for i in range(params.num_trees):
      with tf.device(device_assigner.get_device(i)):
        self.variables.append(tree_variable_class(params, i, training))

  def __setitem__(self, t, val):
    self.variables[t] = val

  def __getitem__(self, t):
    return self.variables[t]

class RandomForestDeviceAssigner(object):
  """A device assigner that uses the default device.

  Write subclasses that implement get_device for control over how trees
  get assigned to devices.  This assumes that whole trees are assigned
  to a device.
  """

  def __init__(self):
    self.cached = None

  def get_device(self, unused_tree_num):
    if not self.cached:
      dummy = tf.constant(0)
      self.cached = dummy.device

    return self.cached

class RandomForestGraphs(object):
  """Builds TF graphs for random forest training and inference."""

  def __init__(self, params, device_assigner=None, variables=None,
               tree_graphs=None,
               t_ops=training_ops,
               i_ops=inference_ops):
    self.params = params
    self.device_assigner = device_assigner or RandomForestDeviceAssigner()
    tf.logging.info('Constructing forest with params = ')
    tf.logging.info(self.params.__dict__)
    self.variables = variables or ForestTrainingVariables(
        self.params, device_assigner=self.device_assigner)
    tree_graph_class = tree_graphs or RandomTreeGraphs
    self.trees = [
        tree_graph_class(
            self.variables[i], self.params,
            t_ops.Load(self.params.training_library_base_dir),
            i_ops.Load(self.params.inference_library_base_dir), i)
        for i in range(self.params.num_trees)]

  def _bag_features(self, tree_num, input_data):
    split_data = tf.split(1, self.params.num_features, input_data)
    return tf.concat(1, [split_data[ind]
                         for ind in self.params.bagged_features[tree_num]])

  def training_graph(self, input_data, input_labels):
    """Constructs a TF graph for training a random forest.

    Args:
      input_data: A tensor or placeholder for input data.
      input_labels: A tensor or placeholder for labels associated with
        input_data.

    Returns:
      The last op in the random forest training graph.
    """
    tree_graphs = []
    for i in range(self.params.num_trees):
      with tf.device(self.device_assigner.get_device(i)):
        seed = self.params.base_random_seed
        if seed != 0:
          seed += i
        # If using bagging, randomly select some of the input.
        tree_data = input_data
        tree_labels = input_labels
        if self.params.bagging_fraction < 1.0:
          # TODO(thomaswc): This does sampling without replacment.  Consider
          # also allowing sampling with replacement as an option.
          batch_size = tf.slice(tf.shape(input_data), [0], [1])
          r = tf.random_uniform(batch_size, seed=seed)
          mask = tf.less(r, tf.ones_like(r) * self.params.bagging_fraction)
          gather_indices = tf.squeeze(tf.where(mask), squeeze_dims=[1])
          # TODO(thomaswc): Calculate out-of-bag data and labels, and store
          # them for use in calculating statistics later.
          tree_data = tf.gather(input_data, gather_indices)
          tree_labels = tf.gather(input_labels, gather_indices)
        if self.params.bagged_features:
          tree_data = self._bag_features(i, tree_data)

        tree_graphs.append(
            self.trees[i].training_graph(tree_data, tree_labels, seed))
    return tf.group(*tree_graphs)

  def inference_graph(self, input_data):
    """Constructs a TF graph for evaluating a random forest.

    Args:
      input_data: A tensor or placeholder for input data.

    Returns:
      The last op in the random forest inference graph.
    """
    probabilities = []
    for i in range(self.params.num_trees):
      with tf.device(self.device_assigner.get_device(i)):
        tree_data = input_data
        if self.params.bagged_features:
          tree_data = self._bag_features(i, input_data)
        probabilities.append(self.trees[i].inference_graph(tree_data))
    with tf.device(self.device_assigner.get_device(0)):
      all_predict = tf.pack(probabilities)
      return tf.reduce_sum(all_predict, 0) / self.params.num_trees

  def average_size(self):
    """Constructs a TF graph for evaluating the average size of a forest.

    Returns:
      The average number of nodes over the trees.
    """
    sizes = []
    for i in range(self.params.num_trees):
      with tf.device(self.device_assigner.get_device(i)):
        sizes.append(self.trees[i].size())
    return tf.reduce_mean(tf.pack(sizes))

  def average_impurity(self):
    """Constructs a TF graph for evaluating the leaf impurity of a forest.

    Returns:
      The last op in the graph.
    """
    impurities = []
    for i in range(self.params.num_trees):
      with tf.device(self.device_assigner.get_device(i)):
        impurities.append(self.trees[i].average_impurity())
    return tf.reduce_mean(tf.pack(impurities))

  def get_stats(self, session):
    tree_stats = []
    for i in range(self.params.num_trees):
      with tf.device(self.device_assigner.get_device(i)):
        tree_stats.append(self.trees[i].get_stats(session))
    return ForestStats(tree_stats, self.params)

class RandomTreeGraphs(object):
  """Builds TF graphs for random tree training and inference."""

  def __init__(self, variables, params, t_ops, i_ops, tree_num):
    self.training_ops = t_ops
    self.inference_ops = i_ops
    self.variables = variables
    self.params = params
    self.tree_num = tree_num

  def _gini(self, class_counts):
    """Calculate the Gini impurity.

    If c(i) denotes the i-th class count and c = sum_i c(i) then
      score = 1 - sum_i ( c(i) / c )^2

    Args:
      class_counts: A 2-D tensor of per-class counts, usually a slice or
        gather from variables.node_sums.

    Returns:
      A 1-D tensor of the Gini impurities for each row in the input.
    """
    smoothed = 1.0 + tf.slice(class_counts, [0, 1], [-1, -1])
    sums = tf.reduce_sum(smoothed, 1)
    sum_squares = tf.reduce_sum(tf.square(smoothed), 1)

    return 1.0 - sum_squares / (sums * sums)

  def _weighted_gini(self, class_counts):
    """Our split score is the Gini impurity times the number of examples.

    If c(i) denotes the i-th class count and c = sum_i c(i) then
      score = c * (1 - sum_i ( c(i) / c )^2 )
            = c - sum_i c(i)^2 / c
    Args:
      class_counts: A 2-D tensor of per-class counts, usually a slice or
        gather from variables.node_sums.

    Returns:
      A 1-D tensor of the Gini impurities for each row in the input.
    """
    smoothed = 1.0 + tf.slice(class_counts, [0, 1], [-1, -1])
    sums = tf.reduce_sum(smoothed, 1)
    sum_squares = tf.reduce_sum(tf.square(smoothed), 1)

    return sums - sum_squares / sums

  def _variance(self, sums, squares):
    """Calculate the variance for each row of the input tensors.

    Variance is V = E[x^2] - (E[x])^2.

    Args:
      sums: A tensor containing output sums, usually a slice from
        variables.node_sums.  Should contain the number of examples seen
        in index 0 so we can calculate expected value.
      squares: Same as sums, but sums of squares.

    Returns:
      A 1-D tensor of the variances for each row in the input.
    """
    total_count = tf.slice(sums, [0, 0], [-1, 1])
    e_x = sums / total_count
    e_x2 = squares / total_count

    return tf.reduce_sum(e_x2 - tf.square(e_x), 1)

  def training_graph(self, input_data, input_labels, random_seed):
    """Constructs a TF graph for training a random tree.

    Args:
      input_data: A tensor or placeholder for input data.
      input_labels: A tensor or placeholder for labels associated with
        input_data.
      random_seed: The random number generator seed to use for this tree.  0
        means use the current time as the seed.

    Returns:
      The last op in the random tree training graph.
    """
    # Count extremely random stats.
    (node_sums, node_squares, splits_indices, splits_sums,
     splits_squares, totals_indices, totals_sums,
     totals_squares, input_leaves) = (
         self.training_ops.count_extremely_random_stats(
             input_data, input_labels, self.variables.tree,
             self.variables.tree_thresholds,
             self.variables.node_to_accumulator_map,
             self.variables.candidate_split_features,
             self.variables.candidate_split_thresholds,
             num_classes=self.params.num_output_columns,
             regression=self.params.regression))
    node_update_ops = []
    node_update_ops.append(
        tf.assign_add(self.variables.node_sums, node_sums))

    splits_update_ops = []
    splits_update_ops.append(self.training_ops.scatter_add_ndim(
        self.variables.candidate_split_sums,
        splits_indices, splits_sums))
    splits_update_ops.append(self.training_ops.scatter_add_ndim(
        self.variables.accumulator_sums, totals_indices,
        totals_sums))

    if self.params.regression:
      node_update_ops.append(tf.assign_add(self.variables.node_squares,
                                           node_squares))
      splits_update_ops.append(self.training_ops.scatter_add_ndim(
          self.variables.candidate_split_squares,
          splits_indices, splits_squares))
      splits_update_ops.append(self.training_ops.scatter_add_ndim(
          self.variables.accumulator_squares, totals_indices,
          totals_squares))

    # Sample inputs.
    update_indices, feature_updates, threshold_updates = (
        self.training_ops.sample_inputs(
            input_data, self.variables.node_to_accumulator_map,
            input_leaves, self.variables.candidate_split_features,
            self.variables.candidate_split_thresholds,
            split_initializations_per_input=(
                self.params.split_initializations_per_input),
            split_sampling_random_seed=random_seed))
    update_features_op = tf.scatter_update(
        self.variables.candidate_split_features, update_indices,
        feature_updates)
    update_thresholds_op = tf.scatter_update(
        self.variables.candidate_split_thresholds, update_indices,
        threshold_updates)

    # Calculate finished nodes.
    with tf.control_dependencies(splits_update_ops):
      children = tf.squeeze(tf.slice(self.variables.tree, [0, 0], [-1, 1]),
                            squeeze_dims=[1])
      is_leaf = tf.equal(LEAF_NODE, children)
      leaves = tf.to_int32(tf.squeeze(tf.where(is_leaf), squeeze_dims=[1]))
      finished = self.training_ops.finished_nodes(
          leaves, self.variables.node_to_accumulator_map,
          self.variables.accumulator_sums,
          num_split_after_samples=self.params.split_after_samples)

    # Update leaf scores.
    # TODO(gilberth): Optimize this. It currently calculates counts for
    # every non-fertile leaf.
    with tf.control_dependencies(node_update_ops):
      def dont_update_leaf_scores():
        return self.variables.non_fertile_leaf_scores

      def update_leaf_scores_regression():
        sums = tf.gather(self.variables.node_sums,
                         self.variables.non_fertile_leaves)
        squares = tf.gather(self.variables.node_squares,
                            self.variables.non_fertile_leaves)
        new_scores = self._variance(sums, squares)
        return tf.assign(self.variables.non_fertile_leaf_scores, new_scores)

      def update_leaf_scores_classification():
        counts = tf.gather(self.variables.node_sums,
                           self.variables.non_fertile_leaves)
        new_scores = self._weighted_gini(counts)
        return tf.assign(self.variables.non_fertile_leaf_scores, new_scores)

      # Because we can't have tf.self.variables of size 0, we have to put in a
      # garbage value of -1 in there.  Here we check for that so we don't
      # try to index into node_per_class_weights in a tf.gather with a negative
      # number.
      update_nonfertile_leaves_scores_op = tf.cond(
          tf.less(self.variables.non_fertile_leaves[0], 0),
          dont_update_leaf_scores,
          update_leaf_scores_regression if self.params.regression else
          update_leaf_scores_classification)

    # Calculate best splits.
    with tf.control_dependencies(splits_update_ops):
      split_indices = self.training_ops.best_splits(
          finished, self.variables.node_to_accumulator_map,
          self.variables.candidate_split_sums,
          self.variables.candidate_split_squares,
          self.variables.accumulator_sums,
          self.variables.accumulator_squares,
          regression=self.params.regression)

    # Grow tree.
    with tf.control_dependencies([update_features_op, update_thresholds_op]):
      (tree_update_indices, tree_children_updates,
       tree_threshold_updates, tree_depth_updates, new_eot) = (
           self.training_ops.grow_tree(
               self.variables.end_of_tree, self.variables.tree_depths,
               self.variables.node_to_accumulator_map, finished, split_indices,
               self.variables.candidate_split_features,
               self.variables.candidate_split_thresholds))
      tree_update_op = tf.scatter_update(
          self.variables.tree, tree_update_indices, tree_children_updates)
      threhsolds_update_op = tf.scatter_update(
          self.variables.tree_thresholds, tree_update_indices,
          tree_threshold_updates)
      depth_update_op = tf.scatter_update(
          self.variables.tree_depths, tree_update_indices, tree_depth_updates)

    # Update fertile slots.
    with tf.control_dependencies([update_nonfertile_leaves_scores_op,
                                  depth_update_op]):
      (node_map_updates, accumulators_cleared, accumulators_allocated,
       new_nonfertile_leaves, new_nonfertile_leaves_scores) = (
           self.training_ops.update_fertile_slots(
               finished, self.variables.non_fertile_leaves,
               self.variables.non_fertile_leaf_scores,
               self.variables.end_of_tree, self.variables.tree_depths,
               self.variables.accumulator_sums,
               self.variables.node_to_accumulator_map,
               max_depth=self.params.max_depth,
               regression=self.params.regression))

    # Ensure end_of_tree doesn't get updated until UpdateFertileSlots has
    # used it to calculate new leaves.
    gated_new_eot, = tf.tuple([new_eot], control_inputs=[new_nonfertile_leaves])
    eot_update_op = tf.assign(self.variables.end_of_tree, gated_new_eot)

    updates = []
    updates.append(eot_update_op)
    updates.append(tree_update_op)
    updates.append(threhsolds_update_op)
    updates.append(tf.assign(
        self.variables.non_fertile_leaves, new_nonfertile_leaves,
        validate_shape=False))
    updates.append(tf.assign(
        self.variables.non_fertile_leaf_scores,
        new_nonfertile_leaves_scores, validate_shape=False))

    updates.append(tf.scatter_update(
        self.variables.node_to_accumulator_map,
        tf.squeeze(tf.slice(node_map_updates, [0, 0], [1, -1]),
                   squeeze_dims=[0]),
        tf.squeeze(tf.slice(node_map_updates, [1, 0], [1, -1]),
                   squeeze_dims=[0])))

    cleared_and_allocated_accumulators = tf.concat(
        0, [accumulators_cleared, accumulators_allocated])
    # Calculate values to put into scatter update for candidate counts.
    # Candidate split counts are always reset back to 0 for both cleared
    # and allocated accumulators. This means some accumulators might be doubly
    # reset to 0 if the were released and not allocated, then later allocated.
    split_values = tf.tile(
        tf.expand_dims(tf.expand_dims(
            tf.zeros_like(cleared_and_allocated_accumulators, dtype=tf.float32),
            1), 2),
        [1, self.params.num_splits_to_consider, self.params.num_output_columns])
    updates.append(tf.scatter_update(
        self.variables.candidate_split_sums,
        cleared_and_allocated_accumulators, split_values))
    if self.params.regression:
      updates.append(tf.scatter_update(
          self.variables.candidate_split_squares,
          cleared_and_allocated_accumulators, split_values))

    # Calculate values to put into scatter update for total counts.
    total_cleared = tf.tile(
        tf.expand_dims(
            tf.neg(tf.ones_like(accumulators_cleared, dtype=tf.float32)), 1),
        [1, self.params.num_output_columns])
    total_reset = tf.tile(
        tf.expand_dims(
            tf.zeros_like(accumulators_allocated, dtype=tf.float32), 1),
        [1, self.params.num_output_columns])
    accumulator_updates = tf.concat(0, [total_cleared, total_reset])
    updates.append(tf.scatter_update(
        self.variables.accumulator_sums,
        cleared_and_allocated_accumulators, accumulator_updates))
    if self.params.regression:
      updates.append(tf.scatter_update(
          self.variables.accumulator_squares,
          cleared_and_allocated_accumulators, accumulator_updates))

    # Calculate values to put into scatter update for candidate splits.
    split_features_updates = tf.tile(
        tf.expand_dims(
            tf.neg(tf.ones_like(cleared_and_allocated_accumulators)), 1),
        [1, self.params.num_splits_to_consider])
    updates.append(tf.scatter_update(
        self.variables.candidate_split_features,
        cleared_and_allocated_accumulators, split_features_updates))

    return tf.group(*updates)

  def inference_graph(self, input_data):
    """Constructs a TF graph for evaluating a random tree.

    Args:
      input_data: A tensor or placeholder for input data.

    Returns:
      The last op in the random tree inference graph.
    """
    return self.inference_ops.tree_predictions(
        input_data, self.variables.tree, self.variables.tree_thresholds,
        self.variables.node_sums,
        valid_leaf_threshold=self.params.valid_leaf_threshold)

  def average_impurity(self):
    """Constructs a TF graph for evaluating the average leaf impurity of a tree.

    If in regression mode, this is the leaf variance. If in classification mode,
    this is the gini impurity.

    Returns:
      The last op in the graph.
    """
    children = tf.squeeze(tf.slice(self.variables.tree, [0, 0], [-1, 1]),
                          squeeze_dims=[1])
    is_leaf = tf.equal(LEAF_NODE, children)
    leaves = tf.to_int32(tf.squeeze(tf.where(is_leaf), squeeze_dims=[1]))
    counts = tf.gather(self.variables.node_sums, leaves)
    impurity = self._weighted_gini(counts)
    return tf.reduce_sum(impurity) / tf.reduce_sum(counts + 1.0)

  def size(self):
    """Constructs a TF graph for evaluating the current number of nodes.

    Returns:
      The current number of nodes in the tree.
    """
    return self.variables.end_of_tree - 1

  def get_stats(self, session):
    num_nodes = self.variables.end_of_tree.eval(session=session) - 1
    num_leaves = tf.where(
        tf.equal(tf.squeeze(tf.slice(self.variables.tree, [0, 0], [-1, 1])),
                 LEAF_NODE)).eval(session=session).shape[0]
    return TreeStats(num_nodes, num_leaves)


def solution(targets):
    answer = 0
    targets.sort(key=lambda x: (x[1], x[0]))
    a = 0
    for s, e in targets:
        if a <= s:
            a = e
            answer += 1

    return answer

[2차]요격 시스템.py


# python3
import socket
import datetime
import re

def request(client):
    buf = client.recv(1024)
    print(buf)
    if buf:
        res = re.findall(r'GET (/.*)HTTP', buf.decode())[0]
    # if res == '/favicon.ico':
    #     return
    else:
        res = 'what?'
    print(res)

    day = datetime.datetime.now()
    day_str = str(day).split('.')[0].encode()
    client.send('HTTP/1.1 200 OK\r\n\r\n'.encode('utf-8') + '
hello world!
'.encode('utf-8') + day_str +
                '
访问链接：'.encode('gbk') + res.encode())
    return buf or 'nothong'

def main(ip='0.0.0.0', port=8000):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind((ip, port))
    sock.listen(5)
    cout = 1
    while cout > 0:
        con, add = sock.accept()
        request(con)
        cout += 1
        con.close()

if __name__ == '__main__':
    main(port=80)


import pyPdf

def tryPasswd(path, pwds):
	fp = file(path, "rb")
	pdf = pyPdf.PdfFileReader(fp)
	ret = 0
	for p in pwds:
		try:
			ret = pdf.decrypt(p)
		except:
			pass
		if ret==1:
			return p
	return None

def getInfo(path, pwd):
	content = ""
	num_pages = 1
	p = file(path, "rb")
	pdf = pyPdf.PdfFileReader(p)
	try:
		ret = pdf.decrypt(pwd)
	except:
		#return '"'+path+'",'+'Unicode error '+pwd
		return '',
	if ret == 0:
		#return '"'+path+'",'+'Invalid password '+pwd
		return '',
	#print pdf.getDocumentInfo()
	#print pdf.getPage(3)
	voda_details = pdf.getPage(2).extractText().encode("ascii", "ignore")
	#print pwd,path
	#print 'pg[2]',pdf.getPage(2).extractText().encode("ascii", "ignore")
	return '"'+path+'",'+parse_voda2(voda_details)

def getAmount(pdf_file):
	p = file(pdf_file, "rb")
	pdf = pyPdf.PdfFileReader(p)
	airtel_details = pdf.getPage(0).extractText().encode("ascii", "ignore")
	#print '"'+pdf_file+'",'+airtel_details
	return parse_airtel(airtel_details)

import re
def parse_airtel(text):
	#airtel_re = 'Near Bridge(.+)security'
	airtel_re = 'amount due on or=\+-(.+)Near Bridge(\d{10})(\d+)(\d\d-...-\d\d\d\d)(\d+\.\d\d)(\d+\.\d\d)(\d+\.\d\d)(\d+\.\d\d)(\d+\.\d\d)(\d\d-...-\d\d\d\d)to(\d+)monthly charges(\d\d-...-\d\d\d\d).+Nivaata.+(\d\d-...-\d\d\d\d)`  ([0-9,\.]+)'
	#airtel_re = 'this month\'s charges.+`([\d,\.]+).+monthly charges(..-...-....)airtel number(\d+).+Limited(..-...-....)'
	match = re.search(airtel_re, text, flags=re.DOTALL)
	if match is not None:
		csv = match.groups()
		strn = str(csv)
		return strn[1:-1]
		#return '"'+csv[0]+'","'+csv[1]+'",'+csv[2]
	return 'Invalid Bill'

def parse_voda2(text):
	voda_re = 'details(.+?)Vodafone no.(\d+).+Total([\d\.]+)Note'
	match = re.search(voda_re, text)
	if match is not None:
		csv = match.groups()
		#strn = str(csv)
		return '"'+csv[0]+'","'+csv[1]+'",'+csv[2]
	return 'Invalid Bill'


import os
import asyncio
import logging
from aiogram import Bot
from aiogram.dispatcher import Dispatcher
from aiogram.utils.executor import start_webhook

BOT_TOKEN = os.environ.get('TOKEN')
WEBHOOK_HOST = "https://android-expert-bot.herokuapp.com"
WEBHOOK_PATH = '/webhook'
WEBHOOK_URL = f"{WEBHOOK_HOST}{WEBHOOK_PATH}"

WEBAPP_HOST = '0.0.0.0'
WEBAPP_PORT = os.environ.get('PORT')

bot = Bot(BOT_TOKEN, parse_mode="HTML")
dp = Dispatcher(bot)

async def on_startup(dp):
    await bot.set_webhook(WEBHOOK_URL)

async def on_shutdown(dp):
    logging.warning('Shutting down..')
    await bot.delete_webhook()
    await dp.storage.close()
    await dp.storage.wait_closed()

    logging.warning('Bye!')

if __name__ == '__main__':
    from handlers import dp

    start_webhook(
        dispatcher=dp,
        webhook_path=WEBHOOK_PATH,
        on_startup=on_startup,
        on_shutdown=on_shutdown,
        host=WEBAPP_HOST,
        port=WEBAPP_PORT)


from posixpath import normpath

def main():

    while True:

        print("welcome to my game!")
        player_name = input(" what is your name ")
        print(" hi " + player_name)
        life_counter = 3

        Backpack = []

        print(f" you have   {life_counter}   remaining ")
        print("you can go in 1 of 4 directions, North, East, South, West")

        while True:

            player_Direction = input("which direction would you like to go in?")

            if player_Direction == "North":
                print("you went North")
                # i am trying to fail in puzzle, lose life
                PuzzleGuessNorth = input("what is 10+10")
                if PuzzleGuessNorth == "20":
                    print("correct")
                    Backpack.append("key 1")  # <--- this is how the key is stored in the backpack

                else:
                    print("incorrect")
                    life_counter -= 1
                    print(f"you have lost a life, you now have  {life_counter}  remaining ")

            elif player_Direction == "East":
                print("you went East")
                # repeat of the code above
                PuzzleGuessEast = input("what was the name of the man that made the tesla coil ")
                if PuzzleGuessEast == "Nikola tesla":
                    print("correct")
                    Backpack.append("key 2")

                else:
                    print("incorrect")
                    life_counter -= 1
                    print(f"you have lost a life, you now have {life_counter} remianing")

            elif player_Direction == "South":
                print("you went South")
                # repeat of North
                print("A: going to the pub, B: getting food, C: getting girls or D: all of the above")
                PuzzleGuessSouth = input("what is Kian Smith known for?")
                if PuzzleGuessSouth == "all of the above":
                    print("correct")
                    Backpack.append("key 3")

                else:
                    print("incorrect")
                    life_counter -= 1
                    print(f"you have lost a life, you now have {life_counter} remaining")

            elif player_Direction == "West":
                print("you went West")
                #
                PuzzlegameWest = input("was this a good game")
                if PuzzlegameWest == "No":
                    print("thank you for your honesty")
                    Backpack.append("key 4")
                else:
                    print("your lying")

            else:
                print("sorry not recognised")

            if ("key 1" in Backpack) and ("key 2" in Backpack) and ("key 3" in Backpack) and ("key 4" in Backpack):
                print("door open! Win game!")

            if life_counter == 0:
                print("you have died, try again")
                break
        exit()

main()


from app_init import db
from controllers.server import server_fields
from controllers.server_queries import (
    current_user_in_server,
    get_server_by_id,
    is_valid_server_invite,
)

from flask_jwt_extended import current_user, jwt_required
from flask_restful import abort, marshal_with, reqparse, Resource

parser = reqparse.RequestParser()
parser.add_argument("server_id")
parser.add_argument("code")

class AccountServersResource(Resource):
    @jwt_required()
    @marshal_with(server_fields)
    def put(self, account_id):
        args = parser.parse_args()
        server_id = args["server_id"]

        server = get_server_by_id(server_id)
        if server is None:
            abort(404, message=f"Server {server_id} doesn't exist")

        # Having an ID of 0 means apply to current user
        if account_id == 0:
            account_id = current_user.id

        if current_user.id != account_id:
            abort(403, message="You must use an invite code on yourself")

        if current_user_in_server(server_id):
            abort(422, message="You are already in this server")

        code = args["code"]

        if not is_valid_server_invite(server_id, code):
            abort(403, message="Invalid server invite")

        current_user.servers.append(server)
        db.session.add(current_user)
        db.session.commit()

        return current_user.servers


from queue import PriorityQueue

leftQ=PriorityQueue()
leftQA=PriorityQueue()
rightQ=PriorityQueue()
rightQA=PriorityQueue()
n = int(input())
l = int(input())

for _ in range(l):
    x, y, imp = map(float, input().split())
    leftQ.put((y,x,int(imp)))
    leftQA.put((x,y,int(imp)))

r = int(input())
for _ in range(r):
	x, y, imp = map(float, input().split())
	rightQ.put((y,x,int(imp)))

counter=0

while not leftQ.empty() and not rightQ.empty():
	left=leftQ.get()
	right=rightQ.get()
	leftX=left[0]
	rightX=right[0]

	if(leftX>rightX):
		leftQ.put(left)
		imp=right[2]+counter
		x=float(right[0])
		y=float(right[1])
		rightQA.put((y,x,imp))

	elif(leftX<rightX):
		counter+=1
		rightQ.put(right)

if leftQ.empty() and not rightQ.empty():
	while not rightQ.empty():
		right=rightQ.get()
		imp=right[2]+counter
		x=float(right[0])
		y=float(right[1])
		rightQA.put((y,x,imp))

#Print the results

while not leftQA.empty():
    next_item = leftQA.get()
    print(int(next_item[2]))

while not rightQA.empty():
    next_item = rightQA.get()
    print(next_item[2])


cnt = 0

def solution(numbers, target) :
    # DFS 재귀 함수
    def DFS(I, L) :
        global cnt
        # numbers의 모든 수를 다 탐색한 경우
        if I==len(numbers) :
            # 모든 수 탐색 결과, L이 타겟 넘버와 같다면 경우의 수 + 1
            if L==target :
                cnt += 1
                return
        # numbers의 모든 수를 탐색하는 과정
        else :
            DFS(I+1, L+numbers[I]) # I번째 수를 더하는 경우
            DFS(I+1, L-numbers[I]) # I번째 수를 빼는 경우

    # 함수 run
    DFS(0, 0)

    return cnt


"""
Django settings for antyc_website project.
"""

from os import path
import platform

# Django

BASE_DIR = path.dirname(path.dirname(__file__))

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'antyc',
    'pipeline',
)

MIDDLEWARE_CLASSES = (
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'pipeline.middleware.MinifyHTMLMiddleware',
)

TEMPLATE_CONTEXT_PROCESSORS = (
    'django.contrib.auth.context_processors.auth',
    'django.template.context_processors.debug',
    'django.template.context_processors.i18n',
    'django.template.context_processors.media',
    'django.template.context_processors.static',
    'django.template.context_processors.tz',
    'django.contrib.messages.context_processors.messages',
    'antyc_website.context_processors.site',
)

ROOT_URLCONF = 'antyc_website.urls'

WSGI_APPLICATION = 'antyc_website.wsgi.application'

# Internationalization
LANGUAGE_CODE = 'en-ca'
TIME_ZONE = 'America/Edmonton'
USE_I18N = True
USE_L10N = True
USE_TZ = True

# Static files (CSS, JavaScript, Images)
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR + '/static/'
STATICFILES_DIRS = (
    path.join(BASE_DIR, "assets"),
)

# Media files (user uploaded)
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR + '/media/'

LOGIN_REDIRECT_URL = '/'
LOGIN_URL = '/login/'

# Email
SERVER_EMAIL = 'Antyc Solutions <root@antyc.ca>'
EMAIL_USE_TLS = True

# Third party

# Django Pipeline
STATICFILES_STORAGE = 'pipeline.storage.PipelineCachedStorage'
require_js = '2.2.0'
PIPELINE = {
    'STYLESHEETS': {
        'index': {
            'source_filenames': (
                'css/sticky-footer.css',
                'css/index.css',
            ),
            'output_filename': 'css/index_all.css',
        },
    },
    'JAVASCRIPT': {
        'index': {
            'source_filenames': (
                'js/require_setup.js',
            ),
            'output_filename': 'js/index_all.js',
            'template_name': 'antyc/pipeline_js.html',
            'extra_context': {
                'src':
                    '//cdnjs.cloudflare.com/ajax/libs/require.js/' +
                    require_js + '/require.min.js',
                'async': True,
            },
        },
    },
}
system = platform.system()
if system == 'Windows':
    yuglify = 'yuglify.cmd'
elif system == 'Linux':
    yuglify = 'yuglify'
else:
    raise Exception('Unknown platform.system')
PIPELINE['YUGLIFY_BINARY'] = (
    path.normpath(
        path.join(BASE_DIR, '../node_modules/.bin/' + yuglify)
    )
)

# Project

VERSIONS = {
    'bootswatch_simplex_css': '3.3.6',
    # 'bootstrap_js': '3.3.6', # see require_setup.js
    'html5shiv_js': '3.7.3',
    'respond_js': '1.4.2',
    'font_awesome_css': '4.6.3',
    'require_js': require_js,  # see above
    # 'jquery_js': '2.2.4', # see require_setup.js
}

if path.isfile(path.join(BASE_DIR, "../prod")):
    from .configs.prod_settings import *

    PIPELINE['JAVASCRIPT']['index']['source_filenames'] += \
        ('antyc/google_analytics.js',)
elif path.isfile(path.join(BASE_DIR, "../test")):
    from .configs.test_settings import *
elif path.isfile(path.join(BASE_DIR, "../devl")):
    from .configs.devl_settings import *

    INSTALLED_APPS += ('debug_toolbar',)

    MIDDLEWARE_CLASSES = list(MIDDLEWARE_CLASSES)
    MIDDLEWARE_CLASSES.insert(
        5, 'debug_toolbar.middleware.DebugToolbarMiddleware'
    )
    MIDDLEWARE_CLASSES = tuple(MIDDLEWARE_CLASSES)
else:
    raise Exception("Please create a settings decision file.")


# Python Online Marathon
# sprint 08
# practical tasks

########################################## 3 ##########################################
# Write the function quadratic_equation with arguments a, b ,c that solution to quadratic equation without a complex solution.

# Write unit tests for this function with QuadraticEquationTest class

# Minimum 3 tests: discriminant < 0, discriminant > 0, discriminant = 0

################################ PASSED ################################
import unittest
import math

def quadratic_equation(a, b, c):
    try:
        discriminant = (b**2)-(4*a*c)
        if discriminant < 0:
            return(None)
        x1 = (-b+math.sqrt(discriminant))/(2*a)
        x2 = (-b-math.sqrt(discriminant))/(2*a)
        if x1 == x2:
            return x1
        else:
            return(x1, x2)
    except ZeroDivisionError:
        raise ValueError

test_data_with_positive_discriminant = (2, 1, -1)
test_data_with_negative_discriminant = (-2, 1, -1)

class NormInstances:
    type_int = 5
    type_float = 5.0

class QuadraticEquationTest(unittest.TestCase):

    def test_positive_discriminant(self):
        discriminant = ((test_data_with_positive_discriminant[1]) ** 2) - (4 * test_data_with_positive_discriminant[0] * test_data_with_positive_discriminant[2])
        expected = discriminant > 0
        self.assertTrue(expected, msg="Discriminant is NOT greater than 0")

    def test_negative_discriminant(self):
        discriminant = ((test_data_with_negative_discriminant[1]) ** 2) - (4 * test_data_with_negative_discriminant[0] * test_data_with_negative_discriminant[2])
        expected = discriminant < 0
        self.assertTrue(expected, msg="Discriminant is NOT less than 0")

    def test_zero_discriminant(self):
        with self.assertRaises(ZeroDivisionError):
            0 / 0

    def test_a_b_c_type(self):
        checked_object = NormInstances()
        msg = "checked_object is not an integer nor a float"
        self.assertIsInstance(checked_object, NormInstances, msg)

######################### tests #########################

# print(quadratic_equation(2, 1, -1))

# print(quadratic_equation(1, -4, 4))

# print(quadratic_equation(4, 1, 2))

# try:
#     quadratic_equation(0, 0, 0)
# except ValueError:
#     print('error')

# print(count_tests > 3)

# print(failures)

# print(errors)

# print(cheater)

# print(skipped)

# print(expectedFailures)