from odoo import api, Command, fields, models, _

class MailActivity(models.Model):
    _inherit = 'mail.activity'

    attachment_files = fields.Many2many('ir.attachment', string='Attachments',
                                        relation='operation_activity_attachment_rel')
    date_deadlinee = fields.Date(default=lambda self: fields.Date.today(), string='Due Date')
    assigned_user_ids = fields.Many2many(
        'res.users',
        'assigned_users_rel',
        'activity_id',
        'user_id',
        string="Assigned Users"
    )
    cc_user_ids = fields.Many2many(
        'res.users',
        'cc_users_rel',
        'activity_id',
        'user_id',
        string="CC"
    )

    activity_body = fields.Text()

    def send_user_email(self):
        template_id = self.env.ref('operation.mail_template_user')
        for email in self.assigned_user_ids:
            template_id.write({'email_to': email.email})
            if self.cc_user_ids:
                cc_emails = [cc.email for cc in self.cc_user_ids]
                template_id.write({'email_cc': ','.join(cc_emails)})

            if template_id:
                template_id.send_mail(self.id, force_send=True)
                self.action_close_dialog()


import os
import unittest
from os import environ
from unittest import mock

from pythonforandroid.bootstrap import Bootstrap
from pythonforandroid.distribution import Distribution
from pythonforandroid.recipe import Recipe
from pythonforandroid.build import Context
from pythonforandroid.util import BuildInterruptingException
from pythonforandroid.archs import (
    Arch,
    ArchARM,
    ArchARMv7_a,
    ArchAarch_64,
    Archx86,
    Archx86_64,
)
from pythonforandroid.androidndk import AndroidNDK

expected_env_gcc_keys = {
    "CFLAGS",
    "LDFLAGS",
    "CXXFLAGS",
    "CC",
    "CXX",
    "LDSHARED",
    "STRIP",
    "MAKE",
    "READELF",
    "BUILDLIB_PATH",
    "PATH",
    "ARCH",
    "NDK_API",
}

class ArchSetUpBaseClass(object):
    """
    An class object which is intended to be used as a base class to configure
    an inherited class of `unittest.TestCase`. This class will override the
    `setUp` method.
    """

    ctx = None
    expected_compiler = ""

    TEST_ARCH = 'armeabi-v7a'

    def setUp(self):
        self.ctx = Context()
        self.ctx.ndk_api = 21
        self.ctx.android_api = 27
        self.ctx._sdk_dir = "/opt/android/android-sdk"
        self.ctx._ndk_dir = "/opt/android/android-ndk"
        self.ctx.ndk = AndroidNDK(self.ctx._ndk_dir)
        self.ctx.setup_dirs(os.getcwd())
        self.ctx.bootstrap = Bootstrap().get_bootstrap("sdl2", self.ctx)
        self.ctx.bootstrap.distribution = Distribution.get_distribution(
            self.ctx,
            name="sdl2",
            recipes=["python3", "kivy"],
            archs=[self.TEST_ARCH],
        )
        self.ctx.python_recipe = Recipe.get_recipe("python3", self.ctx)
        # Here we define the expected compiler, which, as per ndk >= r19,
        # should be the same for all the tests (no more gcc compiler)
        self.expected_compiler = (
            f"/opt/android/android-ndk/toolchains/"
            f"llvm/prebuilt/{self.ctx.ndk.host_tag}/bin/clang"
        )

class TestArch(ArchSetUpBaseClass, unittest.TestCase):
    """
    An inherited class of `ArchSetUpBaseClass` and `unittest.TestCase` which
    will be used to perform tests for the base class
    :class:`~pythonforandroid.archs.Arch`.
    """

    def test_arch(self):
        arch = Arch(self.ctx)
        self.assertEqual(arch.__str__(), arch.arch)
        self.assertEqual(arch.target, "None21")
        self.assertIsNone(arch.command_prefix)
        self.assertIsInstance(arch.include_dirs, list)

class TestArchARM(ArchSetUpBaseClass, unittest.TestCase):
    """
    An inherited class of `ArchSetUpBaseClass` and `unittest.TestCase` which
    will be used to perform tests for :class:`~pythonforandroid.archs.ArchARM`.
    """

    @mock.patch("shutil.which")
    @mock.patch("pythonforandroid.build.ensure_dir")
    def test_arch_arm(self, mock_ensure_dir, mock_shutil_which):
        """
        Test that class :class:`~pythonforandroid.archs.ArchARM` returns some
        expected attributes and environment variables.

        .. note::
            Here we mock two methods:

                - `ensure_dir` because we don't want to create any directory
                - `shutil.which` because otherwise we will
                  get an error when trying to find the compiler (we are setting
                  some fake paths for our android sdk and ndk so probably will
                  not exist)

        """
        mock_shutil_which.return_value = self.expected_compiler
        mock_ensure_dir.return_value = True

        arch = ArchARM(self.ctx)
        self.assertEqual(arch.arch, "armeabi")
        self.assertEqual(arch.__str__(), "armeabi")
        self.assertEqual(arch.command_prefix, "arm-linux-androideabi")
        self.assertEqual(arch.target, "armv7a-linux-androideabi21")
        arch = ArchARM(self.ctx)

        # Check environment flags
        env = arch.get_env()
        self.assertIsInstance(env, dict)
        self.assertEqual(
            expected_env_gcc_keys, set(env.keys()) & expected_env_gcc_keys
        )

        # check shutil.which calls
        mock_shutil_which.assert_called_once_with(
            self.expected_compiler, path=environ["PATH"]
        )

        # check gcc compilers
        self.assertEqual(env["CC"].split()[0], self.expected_compiler)
        self.assertEqual(env["CXX"].split()[0], self.expected_compiler + "++")
        # check android binaries
        self.assertEqual(
            env["STRIP"].split()[0],
            os.path.join(
                self.ctx._ndk_dir,
                f"toolchains/llvm/prebuilt/{self.ctx.ndk.host_tag}/bin",
                "llvm-strip",
            )
        )
        self.assertEqual(
            env["READELF"].split()[0],
            os.path.join(
                self.ctx._ndk_dir,
                f"toolchains/llvm/prebuilt/{self.ctx.ndk.host_tag}/bin",
                "llvm-readelf",
            )
        )

        # check that cflags are in gcc
        self.assertIn(env["CFLAGS"], env["CC"])

        # check that flags aren't in gcc and also check ccache
        self.ctx.ccache = "/usr/bin/ccache"
        env = arch.get_env(with_flags_in_cc=False)
        self.assertNotIn(env["CFLAGS"], env["CC"])
        self.assertEqual(env["USE_CCACHE"], "1")
        self.assertEqual(env["NDK_CCACHE"], "/usr/bin/ccache")

        # Check exception in case that CC is not found
        mock_shutil_which.return_value = None
        with self.assertRaises(BuildInterruptingException) as e:
            arch.get_env()
        self.assertEqual(
            e.exception.args[0],
            "Couldn't find executable for CC. This indicates a problem "
            "locating the {expected_compiler} executable in the Android "
            "NDK, not that you don't have a normal compiler installed. "
            "Exiting.".format(expected_compiler=self.expected_compiler),
        )

class TestArchARMv7a(ArchSetUpBaseClass, unittest.TestCase):
    """
    An inherited class of `ArchSetUpBaseClass` and `unittest.TestCase` which
    will be used to perform tests for
    :class:`~pythonforandroid.archs.ArchARMv7_a`.
    """

    @mock.patch("shutil.which")
    @mock.patch("pythonforandroid.build.ensure_dir")
    def test_arch_armv7a(
        self, mock_ensure_dir, mock_shutil_which
    ):
        """
        Test that class :class:`~pythonforandroid.archs.ArchARMv7_a` returns
        some expected attributes and environment variables.

        .. note::
            Here we mock the same functions than
            :meth:`TestArchARM.test_arch_arm`.
            This has to be done because here we tests the `get_env` with clang

        """
        mock_shutil_which.return_value = self.expected_compiler
        mock_ensure_dir.return_value = True

        arch = ArchARMv7_a(self.ctx)
        self.assertEqual(arch.arch, "armeabi-v7a")
        self.assertEqual(arch.__str__(), "armeabi-v7a")
        self.assertEqual(arch.command_prefix, "arm-linux-androideabi")
        self.assertEqual(arch.target, "armv7a-linux-androideabi21")

        env = arch.get_env()
        # check shutil.which calls
        mock_shutil_which.assert_called_once_with(
            self.expected_compiler, path=environ["PATH"]
        )

        # check clang
        self.assertEqual(
            env["CC"].split()[0],
            "{ndk_dir}/toolchains/llvm/prebuilt/"
            "{host_tag}/bin/clang".format(
                ndk_dir=self.ctx._ndk_dir, host_tag=self.ctx.ndk.host_tag
            ),
        )
        self.assertEqual(
            env["CXX"].split()[0],
            "{ndk_dir}/toolchains/llvm/prebuilt/"
            "{host_tag}/bin/clang++".format(
                ndk_dir=self.ctx._ndk_dir, host_tag=self.ctx.ndk.host_tag
            ),
        )

        # For armeabi-v7a we expect some extra cflags
        self.assertIn(
            " -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -mthumb",
            env["CFLAGS"],
        )

class TestArchX86(ArchSetUpBaseClass, unittest.TestCase):
    """
    An inherited class of `ArchSetUpBaseClass` and `unittest.TestCase` which
    will be used to perform tests for :class:`~pythonforandroid.archs.Archx86`.
    """

    @mock.patch("shutil.which")
    @mock.patch("pythonforandroid.build.ensure_dir")
    def test_arch_x86(self, mock_ensure_dir, mock_shutil_which):
        """
        Test that class :class:`~pythonforandroid.archs.Archx86` returns
        some expected attributes and environment variables.

        .. note::
            Here we mock the same functions than
            :meth:`TestArchARM.test_arch_arm` plus `glob`, so we make sure that
            the glob result is the expected even if the folder doesn't exist,
            which is probably the case. This has to be done because here we
            tests the `get_env` with clang
        """
        mock_shutil_which.return_value = self.expected_compiler
        mock_ensure_dir.return_value = True

        arch = Archx86(self.ctx)
        self.assertEqual(arch.arch, "x86")
        self.assertEqual(arch.__str__(), "x86")
        self.assertEqual(arch.command_prefix, "i686-linux-android")
        self.assertEqual(arch.target, "i686-linux-android21")

        env = arch.get_env()
        # check shutil.which calls
        mock_shutil_which.assert_called_once_with(
            self.expected_compiler, path=environ["PATH"]
        )

        # For x86 we expect some extra cflags in our `environment`
        self.assertIn(
            " -march=i686 -mssse3 -mfpmath=sse -m32",
            env["CFLAGS"],
        )

class TestArchX86_64(ArchSetUpBaseClass, unittest.TestCase):
    """
    An inherited class of `ArchSetUpBaseClass` and `unittest.TestCase` which
    will be used to perform tests for
    :class:`~pythonforandroid.archs.Archx86_64`.
    """

    @mock.patch("shutil.which")
    @mock.patch("pythonforandroid.build.ensure_dir")
    def test_arch_x86_64(
        self, mock_ensure_dir, mock_shutil_which
    ):
        """
        Test that class :class:`~pythonforandroid.archs.Archx86_64` returns
        some expected attributes and environment variables.

        .. note::
            Here we mock the same functions than
            :meth:`TestArchARM.test_arch_arm` plus `glob`, so we make sure that
            the glob result is the expected even if the folder doesn't exist,
            which is probably the case. This has to be done because here we
            tests the `get_env` with clang
        """
        mock_shutil_which.return_value = self.expected_compiler
        mock_ensure_dir.return_value = True

        arch = Archx86_64(self.ctx)
        self.assertEqual(arch.arch, "x86_64")
        self.assertEqual(arch.__str__(), "x86_64")
        self.assertEqual(arch.command_prefix, "x86_64-linux-android")
        self.assertEqual(arch.target, "x86_64-linux-android21")

        env = arch.get_env()
        # check shutil.which calls
        mock_shutil_which.assert_called_once_with(
            self.expected_compiler, path=environ["PATH"]
        )

        # For x86_64 we expect some extra cflags in our `environment`
        mock_shutil_which.assert_called_once()
        self.assertIn(
            " -march=x86-64 -msse4.2 -mpopcnt -m64", env["CFLAGS"]
        )

class TestArchAArch64(ArchSetUpBaseClass, unittest.TestCase):
    """
    An inherited class of `ArchSetUpBaseClass` and `unittest.TestCase` which
    will be used to perform tests for
    :class:`~pythonforandroid.archs.ArchAarch_64`.
    """

    @mock.patch("shutil.which")
    @mock.patch("pythonforandroid.build.ensure_dir")
    def test_arch_aarch_64(
        self, mock_ensure_dir, mock_shutil_which
    ):
        """
        Test that class :class:`~pythonforandroid.archs.ArchAarch_64` returns
        some expected attributes and environment variables.

        .. note::
            Here we mock the same functions than
            :meth:`TestArchARM.test_arch_arm` plus `glob`, so we make sure that
            the glob result is the expected even if the folder doesn't exist,
            which is probably the case. This has to be done because here we
            tests the `get_env` with clang
        """
        mock_shutil_which.return_value = self.expected_compiler
        mock_ensure_dir.return_value = True

        arch = ArchAarch_64(self.ctx)
        self.assertEqual(arch.arch, "arm64-v8a")
        self.assertEqual(arch.__str__(), "arm64-v8a")
        self.assertEqual(arch.command_prefix, "aarch64-linux-android")
        self.assertEqual(arch.target, "aarch64-linux-android21")

        env = arch.get_env()
        # check shutil.which calls
        mock_shutil_which.assert_called_once_with(
            self.expected_compiler, path=environ["PATH"]
        )

        # For x86_64 we expect to find an extra key in`environment`
        for flag in {"CFLAGS", "CXXFLAGS", "CC", "CXX"}:
            self.assertIn("-march=armv8-a", env[flag])


#
# Author: Fabrício G. M. C - Ph.D

# The internal state corresponds to
# temperature history.
# The environment model is expressed
# in the conditiion-action rules

class ModelBasedReflexAgent:
    def __init__(self, temp):
        # internal state
        self.last_temp = temp

    def select_action(self, temp):
        if (temp - self.last_temp) > 0:
            temp_increase = True
        else:
            temp_increase = False
        # internal state update:
        if temp_increase and temp > 37.5:
            return "Strong medication"
        elif not temp_increase and temp > 37.5:
            return "Mild medication"
        elif temp <= 37.5:
            return "No medication"

# This agent has no internal state
# (i.e.: memory) nor environment model.
class ReflexAgent:
    def __init__(self):
        pass
    def select_action(self,temp):
        if temp > 37.5:
            return "Mild medication"
        else:
            return "No medication"


# -*- coding: utf-8 -*-
"""
nim.py
============
Module containing functions necessary for nim game.

@author: hrishit chaudhuri
@github: https://www.github.com/hrishitchaudhuri
"""
import sys
import time

import nimClass as nc

def endMessage(game):
    """
    Print message at end of game.

    Parameters
    ----------
    game : nimGame
        Game initizalized with user specifications.

    Returns
    -------
    None.

    """

    if game.player_turn == "y":
        restart=input_start("You lost :(\nWould you like to play again? [Y/N] ")
        if restart=='y':
            startGame()
        else:
            sys.exit(0)

    else:
        restart=input_start("You won :)\nWould you like to play again? [Y/N] ")
        if restart=='y':
            startGame()
        else:
            sys.exit(0)

def int_error(func, *args):
    """
    Handle ValueErrors in int-returning functions.

    Parameters
    ----------
    func : function
        Function for which a ValueError has to be handled.
    *args : tuple
        Arguments to the function.

    Returns
    -------
    None.

    """

    print("Please enter a valid integer.")
    return func(*args)

def input_heaps():
    """
    Return user-input for setting number of nim-heaps.

    Returns
    -------
    a : int
        Number of heaps in nim-game set by user.

    """

    try:
        a=int(input("Enter number of heaps: "))
        while a<=0:
            a=int(input("Enter valid number of heaps: "))

    except ValueError:
        a=int_error(input_heaps)

    finally:
        return a

def input_heapsizes(a):
    """
    Return user-input for setting size of each nim-heap.

    Parameters
    ----------
    a : int
        Number of heaps in nim-game.

    Returns
    -------
    heaps : list
        Array containing height of each nim-heap.

    """

    try:
        heaps=[]
        for i in range(a):
            ip=int(input("Enter size of heap %d: " % i))
            while ip <= 0:
                ip=int(input("Enter valid size of heap %d: " % i))
            heaps.append(ip)

    except ValueError:
        heaps=int_error(input_heapsizes, a)

    finally:
        return heaps

def input_start(ipstring):
    """
    Return user response to [Y/N] question.

    Parameters
    ----------
    ipstring : str
        [Y/N] question to be asked to user.

    Returns
    -------
    player_turn : str
        [Y/N] response given by user.

    """

    try:
        player_turn=input(ipstring)
        while player_turn.lower() not in ["y", "n"]:
            player_turn=input("Please enter a valid response. [Y/N]? ")

    except ValueError:
        player_turn=input_start("Please enter valid string. [Y/N]" )

    finally:
        return player_turn

def heap_choice(game):
    """
    Return user-input to choose heap to play in.

    Parameters
    ----------
    game : nimGame
        Game initialized with user specifications.

    Returns
    -------
    heap : int
        Heap which user chooses to draw coins from.

    """

    try:
        heap=int(input("Enter heap number to remove coins from: "))
        while heap not in range(0, len(game.heaps)) or game.heaps[heap] <= 0:
            heap=int(input("Enter valid heap number: "))

    except ValueError:
        heap=int_error(heap_choice, game)

    finally:
        return heap

def count_choice(heap, game):
    """
    Return user-input to choose number of coins to draw from heap.

    Parameters
    ----------
    heap : int
        Heap which user chooses to draw coins from.
    game : nimGame
        Game initialized with user specifications.

    Returns
    -------
    count : int
        Number of coins user chooses to draw from heap.

    """

    try:
        count=int(input("Enter number of coins to remove: "))
        while count not in range(1, game.heaps[heap]+1):
            count=int(input("Enter number in range: "))

    except ValueError:
        count=int_error(count_choice, heap, game)

    finally:
        return count

def getPlayer_turn(game):
    """
    Obtain and return user play.

    Parameters
    ----------
    game : nimGame
        Game initialized with user specifications.

    Returns
    -------
    list
        List containing player turn.

    """

    heap=heap_choice(game)
    count=count_choice(heap, game)

    return [heap, count]

def init_menu():
    """
    Set up menu for initializing nim game.

    Returns
    -------
    game : nimGame
        Game initialized with user specifications.

    """

    a=input_heaps()
    print("")

    heaps=input_heapsizes(a)
    print("")

    player_turn=input_start("Would you like to start? [Y/N]? ")
    print("")

    game=nc.nimGame(heaps, player_turn.lower())
    return game

def play_turn(game):
    """
    Instruct computer or player to play respective turn.

    Parameters
    ----------
    game : nimGame
        Game initialized with user specifications.

    Returns
    -------
    None.

    """

    if game.isEndgame():
        endMessage(game)

    if game.player_turn == "y":
        turn=getPlayer_turn(game)
        game.heaps[turn[0]]-=turn[1]
        print("You removed", turn[1], "from heap", turn [0])
        game.player_turn="n"

    else:
        turn=game.bestPlay()
        game.heaps[turn[0]]-=turn[1]
        print("\nComputer thinking...")
        time.sleep(2)
        print("Computer removed", turn[1], "from heap", turn[0])
        game.player_turn="y"

def draw_game(game):
    """
    Print current game state.

    Parameters
    ----------
    game : nimGame
        Game initialized with user specifications.

    Returns
    -------
    None.

    """

    print("Current game state: " + str(list(map(lambda x: "Heap " + str(x) +
                                                " (*" + str(game.heaps[x]) +")",
                                                [x for x in range(len(game.heaps))]))))

def startGame():
    """
    Start new nim game.

    Returns
    -------
    None.

    """

    game=init_menu()
    game.max_height=max(game.heaps)
    while True:
        draw_game(game)
        play_turn(game)


# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        max_depth = 0
        if(root is None):
            return max_depth
        queue = [root]
        while(queue):
            max_depth += 1
            for i in range(len(queue)):
                root = queue.pop(0)
                if(root.left):
                    queue.append(root.left)
                if(root.right):
                    queue.append(root.right)
        return max_depth

Python/104. Maximum Depth of Binary Tree.py


import os
import copy

from google.appengine.api import users
from google.appengine.ext import ndb
from google.appengine.ext.ndb import msgprop
from protorpc import messages

from google.appengine.api import mail

from jinja2 import Environment, FileSystemLoader
import webapp2

debug = os.environ.get('SERVER_SOFTWARE', '').startswith('Dev')

JINJA_ENVIRONMENT = Environment(
#    loader=PackageLoader('estimate', 'templates'),
    loader=FileSystemLoader(os.path.dirname(__file__)),
    extensions=['jinja2.ext.autoescape'],
    autoescape=True)

def format_currency(value):
    return "${:,.2f}".format(value)

JINJA_ENVIRONMENT.filters.update({
    'format_currency': format_currency,
})

def extra_context(handler, context=None):
    """
    Adds extra context.
    """

    context = context or {}

    return dict({'request': handler.request}, **context)

class Shape(messages.Enum):
    L = 10
    U = 20
    R = 30
    O = 0

class CountertopMaterial(ndb.Model):
    type = ndb.StringProperty(indexed=False)
    cost_per_slab = ndb.FloatProperty(indexed=False)
    color = ndb.StringProperty()
    slab_size_sqft = ndb.FloatProperty(indexed=False)
    date_created = ndb.DateTimeProperty(auto_now_add=True)
    labor_cost_per_sqft = ndb.FloatProperty(indexed=False)
    image_filename = ndb.StringProperty(indexed=False)
"""
# Group 1
cm1 = CountertopMaterial()
cm1.populate(type="granite", cost_per_slab=800, color="Cecilia Light", slab_size_sqft=45, labor_cost_per_sqft=50, image_filename="group1_cecilia_light.JPG")
cm1.put()

cm2 = CountertopMaterial()
cm2.populate(type="granite", cost_per_slab=800, color="Fiorito", slab_size_sqft=45, labor_cost_per_sqft=50, image_filename="group1_fiorito.JPG")
cm2.put()

cm3 = CountertopMaterial()
cm3.populate(type="granite", cost_per_slab=800, color="Ouro Brazil", slab_size_sqft=45, labor_cost_per_sqft=50, image_filename="group1_ouro_brazil.JPG")
cm3.put()

cm4 = CountertopMaterial()
cm4.populate(type="granite", cost_per_slab=800, color="Tan Brown", slab_size_sqft=45, labor_cost_per_sqft=50, image_filename="group1_tan_brown.JPG")
cm4.put()

# Group 2
cm5 = CountertopMaterial()
cm5.populate(type="granite", cost_per_slab=1100, color="Giblee", slab_size_sqft=45, labor_cost_per_sqft=50, image_filename="group2_giblee.JPG")
cm5.put()

cm6 = CountertopMaterial()
cm6.populate(type="granite", cost_per_slab=1100, color="Juparana Wave", slab_size_sqft=45, labor_cost_per_sqft=50, image_filename="group2_juparana_wave.JPG")
cm6.put()

cm7 = CountertopMaterial()
cm7.populate(type="granite", cost_per_slab=1100, color="Kashmire Cream", slab_size_sqft=45, labor_cost_per_sqft=50, image_filename="group2_kashmire_cream.JPG")
cm7.put()

cm8 = CountertopMaterial()
cm8.populate(type="granite", cost_per_slab=1100, color="Sapphire", slab_size_sqft=45, labor_cost_per_sqft=50, image_filename="group2_sapphire.JPG")
cm8.put()

# Group 3
cm9 = CountertopMaterial()
cm9.populate(type="granite", cost_per_slab=1900, color="Copenhagen", slab_size_sqft=45, labor_cost_per_sqft=50, image_filename="group3_copenhagen.JPG")
cm9.put()

cm10 = CountertopMaterial()
cm10.populate(type="granite", cost_per_slab=1900, color="Golden Crystal", slab_size_sqft=45, labor_cost_per_sqft=50, image_filename="group3_golden_crystal.JPG")
cm10.put()

cm11 = CountertopMaterial()
cm11.populate(type="granite", cost_per_slab=1900, color="Thyphoon Bordeaux", slab_size_sqft=45, labor_cost_per_sqft=50, image_filename="group3_thyphoon_bordeaux.JPG")
cm11.put()

cm12 = CountertopMaterial()
cm12.populate(type="granite", cost_per_slab=1900, color="White Ice", slab_size_sqft=45, labor_cost_per_sqft=50, image_filename="group3_white_ice.JPG")
cm12.put()
"""

class Client(ndb.Model):
    email = ndb.StringProperty(indexed=False)
    phone = ndb.StringProperty(indexed=False)
    street1 = ndb.StringProperty(indexed=False)
    street2 = ndb.StringProperty(indexed=False)
    zipcode = ndb.StringProperty(indexed=False)
    city = ndb.StringProperty(indexed=False)
    name = ndb.StringProperty(indexed=False)
    message = ndb.TextProperty(indexed=False)
    date_created = ndb.DateTimeProperty(auto_now_add=True)

class CountertopShape(ndb.Model):
    A = ndb.FloatProperty(indexed=False)
    B = ndb.FloatProperty(indexed=False)
    C = ndb.FloatProperty(indexed=False)
    D = ndb.FloatProperty(indexed=False)
    E = ndb.FloatProperty(indexed=False)
    F = ndb.FloatProperty(indexed=False)
    shape = msgprop.EnumProperty(Shape, required=True)
    sqft = ndb.ComputedProperty(lambda self: self.compute_sqft())

    def compute_sqft(self):
        if self.shape == Shape.L:
            return (self.A * self.B + self.C * self.D) / 144.0
        if self.shape == Shape.U:
            return (self.A * self.B + self.F * (self.C - self.E) + self.C * self.D) / 144.0
        if self.shape == Shape.R:
            return (self.A * self.B) / 144.0
        return 0

    def get_sides(self):
        if self.shape == Shape.L:
            return (self.A, self.B, self.C, self.D)
        elif self.shape == Shape.R:
            return (self.A, self.B)
        elif self.shape == Shape.U:
            return (self.A, self.B, self.C, self.D, self.E, self.F)
        return ()

    def get_name(self):
        if self.shape == Shape.L:
            return 'L-shape'
        elif self.shape == Shape.U:
            return 'U-shape'
        elif self.shape == Shape.R:
            return 'R-shape'
        return 'Shape: other'

    def get_path(self):
        if self.shape == Shape.L:
            return '/lshape'
        if self.shape == Shape.U:
            return '/ushape'
        if self.shape == Shape.R:
            return '/rshape'
        return '/contact'

class Estimate(ndb.Model):
    """Sub model for representing an author."""
    client = ndb.StructuredProperty(Client)
    countertop_shapes = ndb.StructuredProperty(CountertopShape, repeated = True)
    total_sqft = ndb.FloatProperty(indexed=False)
    total_price = ndb.FloatProperty(indexed=False)
    date_created = ndb.DateTimeProperty(auto_now_add=True)
    need_attention = ndb.BooleanProperty()
    ip = ndb.StringProperty(indexed=False)
    labor_cost = ndb.FloatProperty(indexed=False)
    material = ndb.StructuredProperty(CountertopMaterial) # one for all pieces
    material_cost = ndb.FloatProperty(indexed=False)

    def compute_total_sqft(self):
        total = 0
        for shape in self.countertop_shapes:
            total += shape.sqft
        return total

    def compute_material_cost(self):
        return (int(self.compute_total_sqft() / self.material.slab_size_sqft) + 1) * self.material.cost_per_slab

    def compute_total_price(self):
        return self.compute_material_cost() + self.compute_labor_cost()

    def compute_labor_cost(self):
        return self.compute_total_sqft() * self.material.labor_cost_per_sqft

    def compute_number_of_slabs(self):
        return int(self.compute_total_sqft() / self.material.slab_size_sqft) + 1

class Order(ndb.Model):
    client = ndb.StructuredProperty(Client)
    estimate = ndb.StructuredProperty(Estimate)
    date_created = ndb.DateTimeProperty(auto_now_add=True)

class MainPage(webapp2.RequestHandler):

    def get(self):
        # estimates = Estimate.query().order(-Estimate.date_created)
        """
        user = users.get_current_user()
        if user:
            url = users.create_logout_url(self.request.uri)
            url_linktext = 'Logout'
        else:
            url = users.create_login_url(self.request.uri)
            url_linktext = 'Login'
        """
        template = JINJA_ENVIRONMENT.get_template('index.html')
        self.response.write(template.render(**extra_context(self)))

class TempPage(webapp2.RequestHandler):

    def get(self):
        # estimates = Estimate.query().order(-Estimate.date_created)
        """
        user = users.get_current_user()
        if user:
            url = users.create_logout_url(self.request.uri)
            url_linktext = 'Logout'
        else:
            url = users.create_login_url(self.request.uri)
            url_linktext = 'Login'
        """
        template = JINJA_ENVIRONMENT.get_template('temp.html')
        self.response.write(template.render(**extra_context(self)))

class ShapeRevertHandler(webapp2.RequestHandler):

    def get(self):
        eid = self.request.get('eid')
        if not eid:
            self.redirect('/')

        key = ndb.Key(urlsafe=eid)
        estimate = key.get()

        if len(estimate.countertop_shapes) > 0:
            path = estimate.countertop_shapes[-1].get_path()
            new_shapes = copy.copy(estimate.countertop_shapes[:-1])
            estimate.countertop_shapes = new_shapes
            estimate.put()

            self.redirect('%s?eid=%s' % (path, estimate.key.urlsafe()))
        else:
            self.redirect('/')

class ShapeHandler(webapp2.RequestHandler):
    SHAPED = {'/lshape': 'lshape.html', '/rshape': 'rshape.html', '/ushape': 'ushape.html'}

    def get(self):
        name = self.request.path
        template = JINJA_ENVIRONMENT.get_template(self.SHAPED.get(name))
        self.response.write(template.render(**extra_context(self)))

    def get_shape(self):
        if self.request.path == '/lshape':
            return Shape.L
        if self.request.path == '/rshape':
            return Shape.R
        if self.request.path == '/ushape':
            return Shape.U
        return Shape.O

    def post(self):
        side_A = self.request.get('side_A')
        side_B = self.request.get('side_B')
        side_C = self.request.get('side_C')
        side_D = self.request.get('side_D')
        side_E = self.request.get('side_E')
        side_F = self.request.get('side_F')
        eid = self.request.get('eid')
        shape = self.get_shape()

        def _do_redirect():
            self.redirect( "{0}?eid={1}&side_A={2}&side_B={3}&side_C={4}&side_D={5}".
                           format(self.request.path, eid, side_A, side_B, side_C, side_D, side_E, side_F))

        if not unicode.isdigit(side_A) or not unicode.isdigit(side_B):
            _do_redirect()
            return

        if shape == Shape.L or shape == Shape.U:
            if not unicode.isdigit(side_C) or not unicode.isdigit(side_D):
                _do_redirect()

        if shape == Shape.U:
            if not unicode.isdigit(side_E) or not unicode.isdigit(side_F):
                _do_redirect()

        # everything is fine
        if eid:
            key = ndb.Key(urlsafe=eid)
            estimate = key.get()
        else:
            estimate = Estimate()

        # estimate.material = CountertopMaterial.query()[0]
        piece = CountertopShape(shape=shape)
        # material = CountertopMaterial().query(CountertopMaterial.color == 'black').fetch(1)[0]
        # estimate.material = material
        if side_A: piece.A = float(side_A)
        if side_B: piece.B = float(side_B)
        if side_C: piece.C = float(side_C)
        if side_D: piece.D = float(side_D)
        if side_E: piece.E = float(side_E)
        if side_F: piece.F = float(side_F)

        estimate.countertop_shapes.append(piece)
        estimate.total_sqft = estimate.compute_total_sqft()
        # estimate.labor_cost = estimate.compute_labor_cost()
        # estimate.total_price = estimate.compute_total_price()
        estimate.ip = self.request.remote_addr
        estimate.put()
        self.redirect('/material?eid=%s' % estimate.key.urlsafe())

class TotalHandler(webapp2.RequestHandler):
    def get(self):
        template = JINJA_ENVIRONMENT.get_template('total.html')
        eid = ndb.Key(urlsafe=self.request.get('eid'))
        mid = ndb.Key(urlsafe=self.request.get('mid'))
        estimate = eid.get()
        material = mid.get()
        estimate.material = material
        estimate.put()
        template_values = { 'estimate': estimate }

        self.response.write(template.render(**extra_context(self, template_values)))

    def post(self):
        side_A = self.request.get('side_A')
        side_B = self.request.get('side_B')
        side_C = self.request.get('side_C')
        side_D = self.request.get('side_D')
        eid = self.request.get('eid')
        key = ndb.Key(urlsafe=eid)

        if not unicode.isdigit(side_A) or not unicode.isdigit(side_B) or\
        not unicode.isdigit(side_C) or not unicode.isdigit(side_D):
            self.redirect('/lshape?eid=%s&side_A=%s&side_B=%s&side_C=%s&side_D=%s' % (eid, side_A, side_B, side_C, side_D))
            return

        # everything is fine
        if key:
            estimate = key.get()
        else:
            estimate = Estimate()

        # estimate.material = CountertopMaterial.query()[0]
        shape = CountertopShape(shape=Shape.L)
        # material = CountertopMaterial().query(CountertopMaterial.color == 'black').fetch(1)[0]
        # estimate.material = material
        shape.A = float(side_A)
        shape.B = float(side_B)
        shape.C = float(side_C)
        shape.D = float(side_D)

        estimate.countertop_shapes.append(shape)
        estimate.total_sqft = estimate.compute_total_sqft()
        # estimate.labor_cost = estimate.compute_labor_cost()
        # estimate.total_price = estimate.compute_total_price()
        estimate.ip = self.request.remote_addr
        estimate.put()
        self.redirect('/material?eid=%s' % estimate.key.urlsafe())

class MaterialHandler(webapp2.RequestHandler):
    def get(self):
        template = JINJA_ENVIRONMENT.get_template('material.html')
        l = CountertopMaterial.query()
        template_values = { 'materials': l }

        self.response.write(template.render(**extra_context(self, template_values)))
        return

class EstimateHandler(webapp2.RequestHandler):
    def get(self):
        template = JINJA_ENVIRONMENT.get_template('estimate.html')
        self.response.write(template.render(**extra_context(self)))

class AboutHandler(webapp2.RequestHandler):
    def get(self):
        template = JINJA_ENVIRONMENT.get_template('about.html')
        self.response.write(template.render(**extra_context(self)))

class AdminHandler(webapp2.RequestHandler):
    def get(self):
        estimates = Estimate.query(Estimate.need_attention == True)

        user = users.get_current_user()
        if not user:
            url = users.create_login_url(self.request.uri)
            self.redirect(url)
            return

        """
        if user.nickname() != "admin@admin.com":
            self.response.write("Not authorized")
            return
        """

        url = users.create_logout_url(self.request.uri)
        url_linktext = 'Logout'

        template_values = {
            'user': user,
            'estimates': estimates,
            'url': url,
            'url_linktext': url_linktext,
            'user': user
        }
        template = JINJA_ENVIRONMENT.get_template('admin.html')
        self.response.write(template.render(template_values))

class ContactHandler(webapp2.RequestHandler):
    def get(self):
        template = JINJA_ENVIRONMENT.get_template('contact_other.html')
        self.response.write(template.render(**extra_context(self)))

    def post(self):
        name = self.request.get('name')
        phone = self.request.get('phone')
        email = self.request.get('email')
        message = self.request.get('message')
        eid = self.request.get('eid')

        client = Client()
        client.name = name
        client.email = email
        client.phone = phone
        client.message = message
        client.put()

        if eid:
            key = ndb.Key(urlsafe=eid)

            estimate = key.get()
            estimate.client = client
            estimate.need_attention = True
            estimate.total_price = estimate.compute_total_price()
            estimate.total_sqft = estimate.compute_total_sqft()
            estimate.material_cost = estimate.compute_material_cost()
            estimate.labor_cost = estimate.compute_labor_cost()

            estimate.put()

            template = JINJA_ENVIRONMENT.get_template('email.html')
            template_values = {
                               'client': client,
                               'estimate': estimate }
            html = template.render(**extra_context(self, template_values))
        else:
            template = JINJA_ENVIRONMENT.get_template('client_details.html')
            template_values = { 'client': client }

            html = template.render(**extra_context(self, template_values))

        message = mail.EmailMessage(sender="grybkin@gmail.com",
                            subject="New Client")

        message.to = "sergey@domus-surfaces.com"
        message.cc = "sergek@russianamericanmedia.com"
        message.html = html
        message.send()

        self.redirect('/thankyou')

class ThankyouHandler(webapp2.RequestHandler):
    def get(self):
        template = JINJA_ENVIRONMENT.get_template('thankyou.html')
        self.response.write(template.render(**extra_context(self)))

application = webapp2.WSGIApplication([
#    ('/', TempPage),
    ('/', MainPage),
    ('/estimate', EstimateHandler),
    ('/about', AboutHandler),
    ('/lshape', ShapeHandler),
    ('/ushape', ShapeHandler),
    ('/rshape', ShapeHandler),
    ('/shape', ShapeRevertHandler),
    ('/contact', ContactHandler),
    ('/admin', AdminHandler),
    ('/material', MaterialHandler),
    ('/total', TotalHandler),
    ('/thankyou', ThankyouHandler),
#    ('/rest/.*', rest.Dispatcher),
], debug=debug)

# configure the rest dispatcher to know what prefix to expect on request urls
# rest.Dispatcher.base_url = "/rest"

# add all models from the current module, and/or...
# rest.Dispatcher.add_models_from_module(__name__)
# add all models from some other module, and/or...
# rest.Dispatcher.add_models_from_module(my_model_module)
# add specific models
"""
rest.Dispatcher.add_models({
#  "estimate": Estimate,
  "material": CountertopMaterial})
# add specific models (with given names) and restrict the supported methods

rest.Dispatcher.add_models({
  'material' : (CountertopMaterial, rest.READ_ONLY_MODEL_METHODS),
#  'estimate' : (Estimate, ['GET', 'POST', 'PUT']),
#  'cache' : (CacheModel, ['GET_METADATA', 'GET', 'DELETE']
})

# optionally use custom authentication/authorization
# rest.Dispatcher.authenticator = MyAuthenticator()
# rest.Dispatcher.authorizer = MyAuthorizer()

"""


lados = []

for lado in range(0, 3):
    lados.append(int(input('Entre com o tamanho do {}o. lado: '.format(lado + 1))))

if(lados[0] == lados[1] and lados[1] == lados[2]):
    print('Triângulo equilátero')
elif(lados[0] == lados[1] or lados[1] == lados[2] or lados[0] == lados[2]):
    print('Triângulo isósceles')
else:
    print('Triângulo escaleno')


from flask import Flask, render_template, request
from WDS import WDSWrapper
import json

app = Flask(__name__)

# Initialise WDS wrapper
with open('wds_credentials.json') as creds:
    wds_credentials = json.load(creds)
    wds = WDSWrapper(wds_credentials)

@app.route('/', methods=['GET'])
@app.route('/search', methods=['GET'])
def index():
    return render_template('search.html')

@app.route('/results', methods=['POST'])
def get_results():

    # Validate the query string
    # length? special characters?
    query = request.form.get('natural_language_query')

    # Run query
    print('Query: ' + request.form.get('natural_language_query'))
    results = wds.query(natural_language_query=query, max_docs=10)

    # Format results
    # get doc title, passage(s), page numbers?
    # format into appropriate dictionary
    # display_results = {}
    # for result in results['results']:

    # Render template ... with fields: title + passage for documents, original search query should be in search box (different colour or something)

    return render_template('results.html', results=results['results'])

if __name__=='__main__':
    app.run(debug=True)


from typing import List  # noqa: F401

from libqtile import bar, layout, widget
from libqtile.config import Click, Drag, Group, Key, Match, Screen
from libqtile.lazy import lazy
import os
import subprocess
from libqtile import hook

mod = "mod4"
alt = "mod1"
terminal = "alacritty"
cs = 'one_dark' #colorscheme

colors = {
            'one_dark': {
                'soft_blue': '61AFEF',
                'light_slate_grey': '778899',
                'black': '282C34',
                'green': '98c379',
                'pink': 'C678DD',
                'red': 'E06C75',
                'yellow': 'E5C07B'

            },
            'gruvbox': {
                'bg': '282828',
                'fg0': 'fbf1c7',
                'fg': 'ebdbb2',
                'fg4': 'a89984',
                'red0': 'cc241d',
                'red1': 'fb4934',
                'green0': '98971a',
                'green1': 'b8bb26',
                'yellow0': 'd79921',
                'yellow1': 'fabd2f',
                'blue0': '458588',
                'blue1': '83a598',
                'purple0': 'b16286',
                'purple1': 'd3869b',
                'aqua0': '689d6a',
                'aqua1': '8ec07c',
                'grey0': 'a89984',
                'grey1': '928374'

            },
            'dark_grayish_blue': '979FAD',
         }
border_width = 2
gap = 10
right_widgets_padding = 10

keys = [
    # Switch between windows
    Key([mod], "h", lazy.layout.left(), desc="Move focus to left"),
    Key([mod], "l", lazy.layout.right(), desc="Move focus to right"),
    Key([mod], "j", lazy.layout.down(), desc="Move focus down"),
    Key([mod], "k", lazy.layout.up(), desc="Move focus up"),
    Key([mod], "space", lazy.layout.next(), desc="Move window focus to other window"),
    # Move windows between left/right columns or move up/down in current stack.
    # Moving out of range in Columns layout will create new column.
    Key([mod, "shift"], "h", lazy.layout.shuffle_left(), desc="Move window to the left"),
    Key([mod, "shift"], "l", lazy.layout.shuffle_right(), desc="Move window to the right"),
    Key([mod, "shift"], "j", lazy.layout.shuffle_down(), desc="Move window down"),
    Key([mod, "shift"], "k", lazy.layout.shuffle_up(), desc="Move window up"),
    # Grow windows. If current window is on the edge of screen and direction
    # will be to screen edge - window would shrink.
    Key([mod, "control"], "h", lazy.layout.grow_left(), desc="Grow window to the left"),
    Key([mod, "control"], "l", lazy.layout.grow_right(), desc="Grow window to the right"),
    Key([mod, "control"], "j", lazy.layout.grow_down(), desc="Grow window down"),
    Key([mod, "control"], "k", lazy.layout.grow_up(), desc="Grow window up"),
    Key([mod], "n", lazy.layout.normalize(), desc="Reset all window sizes"),
    # Key bindings  specific to MonadTall layout starts
    Key([mod], "o", lazy.layout.grow()), # "o" for outwards
    Key([mod], "i", lazy.layout.shrink()), # 'i' for inwards
    # this will toggle between max and min
    Key([mod], "m", lazy.layout.maximize()),
    # Key bindings  specific to MonadTall layout ends

    # Toggle between split and unsplit sides of stack.
    # Split = all windows displayed
    # Unsplit = 1 window displayed, like Max layout, but still with
    # multiple stack panes
    Key(
        [mod, "shift"],
        "Return",
        lazy.layout.toggle_split(),
        desc="Toggle between split and unsplit sides of stack",
    ),
    Key([mod], "Return", lazy.spawn(terminal), desc="Launch terminal"),
    # Toggle between different layouts as defined below
    Key([mod], "Tab", lazy.next_layout(), desc="Toggle between layouts"),
    Key([mod], "w", lazy.window.kill(), desc="Kill focused window"),
    Key([mod, "control"], "r", lazy.reload_config(), desc="Reload the config"),
    Key([mod, "shift"], "r", lazy.restart(), desc="Restart the Qtile"),
    Key([mod, "control"], "q", lazy.shutdown(), desc="Shutdown Qtile"),

    # Volume binding starts
    Key([], "XF86AudioLowerVolume", lazy.spawn("amixer -q sset Master 5%-"), desc="decrease volume"),
    Key([], "XF86AudioRaiseVolume", lazy.spawn("amixer -q sset Master 5%+"), desc="increase volume"),
    # Volume binding ends

    Key([mod], "space", lazy.spawn("rofi -show drun -show-icons"), desc="Spawn a command using a prompt widget"),
    Key([alt], "Tab", lazy.spawn("rofi -show window"), desc="Spawn a command using a prompt widget"),
]

groups = [Group(i) for i in "123456789"]

for i in groups:
    keys.extend(
        [
            # mod1 + letter of group = switch to group
            Key(
                [mod],
                i.name,
                lazy.group[i.name].toscreen(),
                desc="Switch to group {}".format(i.name),
            ),
            # mod1 + shift + letter of group = switch to & move focused window to group
            Key(
                [mod, "shift"],
                i.name,
                lazy.window.togroup(i.name, switch_group=True),
                desc="Switch to & move focused window to group {}".format(i.name),
            )
        ]
    )

layouts = [
    layout.MonadTall(border_focus = colors['gruvbox']['purple0'], border_normal = colors['gruvbox']['grey0'],
        border_width = border_width, max_ratio = 0.9, margin = gap)
        #  border_width = border_width, max_ratio = 0.9, margin = gap, single_margin = [50, 200, 50, 200]),
]

widget_defaults = dict(
    font="Caskaydia Cove Nerd Font",
    fontsize=12,
    padding=3,
)
extension_defaults = widget_defaults.copy()

# BAR TODO: bold fonts, right widgets need to be underlined, rounded corners for bar.
screens = [
    Screen(
        bottom=bar.Bar(
            [
                widget.GroupBox(highlight_method = 'line'
                    , inactive = colors['gruvbox']['fg4'], highlight_color = [colors['gruvbox']['bg'],
                        colors['gruvbox']['bg']], borderwidth = 3),
                widget.Spacer(),
                widget.Clock(format="%Y-%m-%d %a %H:%M", foreground=colors['gruvbox']['red0']),
                widget.Spacer(),
                widget.CPU(format='{load_percent}%', foreground = colors['gruvbox']['green0'],
                     #  border_color=colors['gruvbox']['green0']
                    ),
                widget.ThermalSensor(foreground=colors['gruvbox']['green0']),
                widget.Spacer(length=10),
                widget.Sep(foreground=colors['gruvbox']['green0']),
                widget.Spacer(length=10),
                widget.Memory(foreground=colors['gruvbox']['yellow1'], format = '{MemUsed:.0f}{mm}/{MemTotal:.0f}{mm}'),
                widget.Spacer(length=10),
                widget.Sep(foreground=colors['gruvbox']['yellow1']),
                widget.Systray(),
                widget.Spacer(length=10),
                widget.TextBox("Vol:", foreground=colors['gruvbox']['purple0']),
                widget.Volume(foreground=colors['gruvbox']['purple0']),
                widget.Spacer(length=5),
            ],
            24,
            margin = [0,700,5,700],
            background = colors['gruvbox']['bg'],
        ),
    ),
]

# Drag floating layouts.
mouse = [
    Drag([mod], "Button1", lazy.window.set_position_floating(), start=lazy.window.get_position()),
    Drag([mod], "Button3", lazy.window.set_size_floating(), start=lazy.window.get_size()),
    Click([mod], "Button2", lazy.window.bring_to_front()),
]

dgroups_key_binder = None
dgroups_app_rules = []  # type: List
follow_mouse_focus = True
bring_front_click = False
cursor_warp = False
floating_layout = layout.Floating(
    float_rules=[
        # Run the utility of `xprop` to see the wm class and name of an X client.
        *layout.Floating.default_float_rules,
        Match(wm_class="confirmreset"),  # gitk
        Match(wm_class="makebranch"),  # gitk
        Match(wm_class="maketag"),  # gitk
        Match(wm_class="ssh-askpass"),  # ssh-askpass
        Match(title="branchdialog"),  # gitk
        Match(title="pinentry"),  # GPG key password entry
    ]
)
auto_fullscreen = True
focus_on_window_activation = "smart"
reconfigure_screens = True

# If things like steam games want to auto-minimize themselves when losing
# focus, should we respect this or not?
auto_minimize = True

# XXX: Gasp! We're lying here. In fact, nobody really uses or cares about this
# string besides java UI toolkits; you can see several discussions on the
# mailing lists, GitHub issues, and other WM documentation that suggest setting
# this string if your java app doesn't work correctly. We may as well just lie
# and say that we're a working one by default.
#
# We choose LG3D to maximize irony: it is a 3D non-reparenting WM written in
# java that happens to be on java's whitelist.
wmname = "LG3D"

@hook.subscribe.startup_once
def autostart():
    home = os.path.expanduser('~/configs/autostart.sh')
    subprocess.run([home])


from app.models.address_record import AddressRecord
from app.models.dol_disclosure_job_order import DolDisclosureJobOrder  # noqa
from app.models.employer_record_address_link import EmployerRecordAddressLink  # noqa
from app.tests.base_test_case import BaseTestCase

class TestAddressRecord(BaseTestCase):
    use_session = False

    def test_to_string(self):
        test_address = AddressRecord(
            address_1='Address line 1',
            address_2='Address line 2',
            city='City',
            state='NC',
            postal_code='27701',
            country='USA'
        )
        self.assertEqual("Address line 1 Address line 2, City, NC 27701 USA", str(test_address))
        test_address = AddressRecord(
            address_1='Address line 1',
            address_2='Address line 2',
            city=None,
            state=None,
            postal_code=None,
            country='USA'
        )
        self.assertEqual("Address line 1 Address line 2 USA", str(test_address))
        test_address = AddressRecord(
            address_1='Address line 1',
            address_2='Address line 2',
            city='Boulder',
            state='CO',
            postal_code='12345',
            country='USA'
        )
        self.assertEqual("Address line 1 Address line 2, Boulder, CO 12345 USA", str(test_address))

    def test_geocode_hash(self):
        test_address = AddressRecord(
            address_1='Address line 1',
            address_2='Address line 2',
            city='City',
            state='NC',
            postal_code='27701',
            country='USA'
        )
        test_address_2 = AddressRecord(
            address_1='Address line 1 - v2',
            address_2='Address line 2',
            city='City',
            state='NC',
            postal_code='27701',
            country='USA'
        )
        self.assertNotEqual(test_address.get_geocode_hash(), test_address_2.get_geocode_hash())

    def test_clean_method(self):
        test_address = AddressRecord(
            address_1=' Address LINE 1 ',
            address_2=' address line 2  ',
            city=None,
            state='north carolina',
            postal_code='27701 ',
            country=None
        )
        test_address.clean()
        self.assertEqual(test_address.address_1,'Address Line 1')
        self.assertEqual(test_address.address_2,'Address Line 2')
        self.assertIsNone(test_address.city)
        self.assertEqual(test_address.state,'NC')
        self.assertEqual(test_address.postal_code,'27701')
        self.assertEqual(test_address.country,'UNITED STATES OF AMERICA')

    def test_not_null_method(self):
        test_address = AddressRecord(
            address_1=' Address LINE 1 ',
            address_2=' address line 2  ',
            city=None,
            state='north carolina',
            postal_code='27701 ',
            country=None
        )
        self.assertFalse(test_address.is_null())
        test_address = AddressRecord(
        )
        self.assertTrue(test_address.is_null())


import numpy as np
import pandas as pd
import math
from numpy import mean
from numpy import std
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegression
from sklearn.impute import KNNImputer
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.pipeline import Pipeline
from matplotlib import pyplot
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, f1_score, confusion_matrix,  plot_confusion_matrix, classification_report, roc_auc_score, roc_curve

"""
#################################
###-----Data imputation----- ####
#################################
"""
#function to choose the number of k for knn imputation
def choose_k_for_knn_imputation(X, y):
    # evaluate each strategy on the dataset
    results = list()
    strategies = [str(i) for i in [1,3,5,7,9,15,18,21]]
    for s in strategies:
        # create the modeling pipeline
        pipeline = Pipeline(steps=[('scale', StandardScaler()),('i', KNNImputer(n_neighbors=int(s))), ('m', LogisticRegression())])
        # evaluate the model
        cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
        scores = cross_val_score(pipeline, X, y, scoring='accuracy', cv=cv, n_jobs=-1)
        # store results
        results.append(scores)
        print('>%s %.3f (%.3f)' % (s, mean(scores), std(scores)))
    # plot model performance for comparison
    pyplot.boxplot(results, labels=strategies, showmeans=True)
    pyplot.show()

#imputation using knn
def imputation_with_knn(data, nb):
    #--define imputer
    imputer = KNNImputer(n_neighbors=nb)
    #--fit on the dataset
    imputer.fit(data)
    #--transform the dataset
    imputed_data = imputer.transform(data)
    #--print total missing
    print('Missing values in the imputed dataset: %d' % sum(np.isnan(imputed_data).flatten()))
    #--transform to dataframe
    imputed_data = pd.DataFrame(imputed_data, columns = data.columns)
    return imputed_data

"""
#################################
###-----Data splitting----- ####
#################################
"""
#--split into training and test set
def train_split_test(input_data, y_data, indata_labels):
    X_train, X_test, y_train, y_test = train_test_split(
           input_data, y_data, test_size=0.3,
           stratify=y_data, random_state=0
    )
    print("X_train", X_train.shape)
    print("y_train", y_train.shape)
    print("X_test", X_test.shape)
    print("y_test", y_test.shape)
    #transform the Target data into 'int'/binary
    y_train = y_train.astype("int")
    y_test = y_test.astype("int")
    #from numpy to dataframe
    X_train = pd.DataFrame(X_train, columns =indata_labels)
    X_test = pd.DataFrame(X_test, columns =indata_labels)

    return X_train, X_test, y_train, y_test

"""
#########################################
###-----Evaluation of ML models----- ####
#########################################
"""
#function to compute the evaluation metrics as: accuracy, precision, recall, etc.
def Print_confusion_matrix(cm, auc, heading): #cm for confusion matrix, heading is the title.
    print('\n', heading)
    true_negative  = cm[0,0]
    true_positive  = cm[1,1]
    false_negative = cm[1,0]
    false_positive = cm[0,1]
    total          = true_negative + true_positive + false_negative + false_positive
    accuracy       = (true_positive + true_negative)/total
    precision      = (true_positive)/(true_positive + false_positive)
    recall         = (true_positive)/(true_positive + false_negative)
    misclassification_rate = (false_positive + false_negative)/total
    F1             = (2*true_positive)/(2*true_positive + false_positive + false_negative)
    mcc            = (true_positive*true_negative - false_positive*false_negative) / math.sqrt((true_positive+false_positive)*(true_positive+false_negative)*(true_negative+false_positive)*(true_negative+false_negative))
    print('accuracy.................%7.4f' % accuracy)
    print('precision................%7.4f' % precision)
    print('recall...................%7.4f' % recall)
    print('F1.......................%7.4f' % F1)
    print('auc......................%7.4f' % auc)
    print('mcc......................%7.4f' % mcc)

#function to plot the ROC curve
def plotROC(tpr, fpr, roc_auc, dataset, label=''):
    """
    Plot ROC curve from tpr and fpr.
    """
    lw = 2
    plt.figure(figsize=(5, 5))
    plt.plot(fpr, tpr, color='darkorange',
             lw=lw, label='%s ROC curve (area = %0.2f)' % (label,roc_auc))
    plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')
    plt.xlim([0.0, 1.0])
    plt.ylim([0.0, 1.05])
    plt.xlabel('False Positive Rate')
    plt.ylabel('True Positive Rate')
    plt.title('Receiver operating characteristic of the %s set' % dataset)
    plt.legend(loc="lower right")
    plt.show()

#function to evaluate the model by plotting the confusion matrix, the classification report and ROC curve of the input dataset.
def evaluate_your_model_metrics(best_model, X_train, y_train, dataset_label):
    y_predicted_train = best_model.predict(X_train)
    probabilities_train = best_model.predict_proba(X_train)
    plot_confusion_matrix(best_model, X_train, y_train)
    plt.show()
    # plot the confusion matrix of the training set
    cm_train = confusion_matrix(y_train, y_predicted_train)
    auc_train = roc_auc_score(y_train, y_predicted_train)
    Print_confusion_matrix(cm_train, auc_train, '***Evaluation of the %s dataset***\n' %dataset_label)
    #plot the ROC curve
    fpr_train, tpr_train, th_train = roc_curve(y_train, probabilities_train[:, 1])
    plotROC(tpr_train, fpr_train, auc_train, '%s' %dataset_label, label='')
    #print the classification report
    c_report = classification_report(y_train, y_predicted_train)
    print('\nClassification report:\n', c_report)


from nervaluate import Evaluator

def test_loaders_produce_the_same_results():
    true_list = [
        ["O", "O", "O", "O", "O", "O"],
        ["O", "O", "B-ORG", "I-ORG", "O", "O"],
        ["O", "O", "B-MISC", "I-MISC", "O", "O"],
        ["B-MISC", "I-MISC", "I-MISC", "I-MISC", "I-MISC", "I-MISC"],
    ]

    pred_list = [
        ["O", "O", "B-PER", "I-PER", "O", "O"],
        ["O", "O", "B-ORG", "I-ORG", "O", "O"],
        ["O", "O", "B-MISC", "I-MISC", "O", "O"],
        ["B-MISC", "I-MISC", "I-MISC", "I-MISC", "I-MISC", "I-MISC"],
    ]

    true_conll = (
        "word\tO\nword\tO\nword\tO\nword\tO\nword\tO\nword\tO\n\n"
        "word\tO\nword\tO\nword\tB-ORG\nword\tI-ORG\nword\tO\nword\tO\n\n"
        "word\tO\nword\tO\nword\tB-MISC\nword\tI-MISC\nword\tO\nword\tO\n\n"
        "word\tB-MISC\nword\tI-MISC\nword\tI-MISC\nword\tI-MISC\nword\tI-MISC\nword\tI-MISC\n"
    )

    pred_conll = (
        "word\tO\nword\tO\nword\tB-PER\nword\tI-PER\nword\tO\nword\tO\n\n"
        "word\tO\nword\tO\nword\tB-ORG\nword\tI-ORG\nword\tO\nword\tO\n\n"
        "word\tO\nword\tO\nword\tB-MISC\nword\tI-MISC\nword\tO\nword\tO\n\n"
        "word\tB-MISC\nword\tI-MISC\nword\tI-MISC\nword\tI-MISC\nword\tI-MISC\nword\tI-MISC\n"
    )

    true_prod = [
        [],
        [{"label": "ORG", "start": 2, "end": 3}],
        [{"label": "MISC", "start": 2, "end": 3}],
        [{"label": "MISC", "start": 0, "end": 5}],
    ]

    pred_prod = [
        [{"label": "PER", "start": 2, "end": 3}],
        [{"label": "ORG", "start": 2, "end": 3}],
        [{"label": "MISC", "start": 2, "end": 3}],
        [{"label": "MISC", "start": 0, "end": 5}],
    ]

    evaluator_list = Evaluator(true_list, pred_list, tags=["PER", "ORG", "MISC"], loader="list")

    evaluator_conll = Evaluator(true_conll, pred_conll, tags=["PER", "ORG", "MISC"], loader="conll")

    evaluator_prod = Evaluator(true_prod, pred_prod, tags=["PER", "ORG", "MISC"])

    _, _ = evaluator_list.evaluate()
    _, _ = evaluator_prod.evaluate()
    _, _ = evaluator_conll.evaluate()

    assert evaluator_prod.pred == evaluator_list.pred == evaluator_conll.pred
    assert evaluator_prod.true == evaluator_list.true == evaluator_conll.true


from __future__ import print_function
from sys import stdin, stderr, argv, exit
import random

if len(argv) not in [5, 6]:
    print("python %s maxAge indivs startGen endGen [lp]" % (argv[0],))
    print("indivs can be ALL")
    exit(-1)

maxAge = int(argv[1])
if argv[2] == "ALL":
    nindivs = None  # Actually we stop at 200
    maxInds = 200
else:
    nindivs = int(argv[2])
startGen = int(argv[3])
endGen = int(argv[4])
lp = len(argv) == 6

l = stdin.readline()

# currGen = cfg.startSave
currGen = 0

def getIndivs(ageInds):
    indivs = []
    maxIndsPerCohort = min([len(x) for x in list(ageInds.values())])
    for age, inds in list(ageInds.items()):
        indivs.extend(random.sample(inds, maxIndsPerCohort))
    return indivs

ageCnt = {}
indivsAge = {}
while l != "":
    toks = l.rstrip().split(" ")
    rep = int(float(toks[1]))
    if rep > 0:
        break
    gen = int(float(toks[0]))
    id = int(float(toks[2]))
    sex = int(float(toks[3]))
    father = int(float(toks[4]))
    mother = int(float(toks[5]))
    age = int(float(toks[6]))

    if gen > currGen:
        if currGen >= startGen:
            indivs = getIndivs(indivsAge)
            if nindivs:
                print(currGen, random.sample(indivs, nindivs))
            else:
                if len(indivs) > maxInds:
                    print(currGen, random.sample(indivs, maxInds))
                else:
                    print(currGen, indivs)
            if lp:
                if nindivs:
                    print(random.sample(indivs, nindivs))
                else:
                    if len(indivs) > maxInds:
                        print(random.sample(indivs, maxInds))
                    else:
                        print(indivs)
        indivsAge = {}
        currGen = gen
        if currGen > endGen:
            break

    if age <= maxAge:
        ageCnt[age] = ageCnt.get(age, 0) + 1
        indivsAge.setdefault(age, []).append(id)
    l = stdin.readline()
if currGen <= endGen:
    indivs = getIndivs(indivsAge)
    if nindivs:
        print(currGen, random.sample(indivs, nindivs))
    else:
        if len(indivs) > maxInds:
            print(currGen, random.sample(indivs, maxInds))
        else:
            print(currGen, indivs)
    if lp:
        if nindivs:
            print(random.sample(indivs, nindivs))
        else:
            if len(indivs) > maxInds:
                print(random.sample(indivs, maxInds))
            else:
                print(indivs)


from wikidata.client import Client

client = Client()  # doctest: +SKIP

entity = client.get('Q20145', load=True)

data = entity.data

claims = data['claims']

for clm in claims:
    # print(clm)
    if clm in ('P106', 'P136'):
        qvalue = claims[clm][0]['mainsnak']['datavalue']['value']
        qid_entity = client.get(qvalue['id'], load=True)
        print(qid_entity.description)

# print(entity.description)


import scrapy

class ScrapingSpider(scrapy.Spider):
    name = 'scraping'

    def start_requests(self):
        start_urls = [
                    'https://www.kaggle.com/aakashverma8900'
                ]
        for url in start_urls:
            yield scrapy.Request(url=url, callback=self.parse)

    def parse(self, response):
        item = {}
        title = response.css('title::text').get()
        item['title'] = title
        yield item


from django.shortcuts import get_object_or_404, redirect, render
from taggit.models import Tag
from django.urls import reverse
import json
from django.contrib.auth.models import User
from questions.models import Questions,Comments
from django.utils import timezone

# Create your views here.

def first_login(request):
    if request.user.is_authenticated and request.user.profile.first_login == True:
        if request.method == "POST":
            tags = json.loads(request.POST["tags"])
            print(tags)
            for tag in tags:
                request.user.profile.following.add(tag)
            request.user.profile.first_login = False
            request.user.profile.save()
            return redirect(reverse("home:home"))
        else:
            tags = Tag.objects.all()
            if len(tags)>=50:
                l = list([str(tag) for tag in tags[50:]])
                json_optional_tags = json.dumps(l)
                return render(request,'userProfile/interest.html',{'tags':tags[:50],'json_optional_tags':json_optional_tags})
            return render(request, 'userProfile/interest.html', {'tags': tags})
    else:
        return redirect(reverse("accounts:login"))

def profile(request,username):
    user = get_object_or_404(User,username = username)
    if request.user.username == username:
        if request.method == "POST":
            request.user.profile.bio=request.POST['new-bio-tt']
            request.user.profile.save()
            return redirect(reverse("profile:profile", args=[request.user]))
        else:
            bio = user.profile.bio
            questions = Questions.objects.filter(author = user)
            answers = Comments.objects.filter(cmnt_author = user)
            following = user.profile.following.names()
            content={
                "user":user,
                "bio":bio,
                "questions":questions,
                "answers":answers,
                "following":following,
            }
            return render(request,"userProfile/profile.html",content)
    else:
        bio = user.profile.bio
        questions = Questions.objects.filter(author=user)
        answers = Comments.objects.filter(cmnt_author=user)
        following = user.profile.following.names()
        content = {
            "user": user,
            "bio": bio,
            "questions": questions,
            "answers": answers,
            "following": following,
        }
        return render(request, "userProfile/profile_notuser.html", content)
        #show details only
    #if invalid username return 404


#defining of function

def paridhi_circle(radius):
    pi = 3.14
    paridhi = 2 * pi * radius
    return(paridhi)

my_paridhi = paridhi_circle(5.5)
print(my_paridhi)
print("function call end here")


from typing import List
from direction import Direction
from orientation import Orientation
from pos import Pos

class Brick:

    def __init__(self, pos: Pos):
        self.pos = pos

    def next_pos(self, direction: Direction) -> Pos:
        """
        Find and return next position in the given direction.
        This function does NOT check for the validity of the move.
        :param direction: Direction of the move (left, right, up, down)
        :return: Brick's next position/orientation in the given direction.
        """

        # nextpos based on current position params.
        nextpos = Pos(self.pos.x, self.pos.y, self.pos.orientation)

        # Update nextpos position object params based on current orientation and the direction of next move.
        # In a Pos object:
        # x value always points to the left block for horizontal lying brick.
        # y value always points to the upper block for vertical lying brick.
        if self.pos.orientation is Orientation.STANDING:
            if direction is Direction.UP:
                nextpos.y -= 2
                nextpos.orientation = Orientation.VERTICAL_LYING
            if direction is Direction.DOWN:
                nextpos.y += 1
                nextpos.orientation = Orientation.VERTICAL_LYING
            if direction is Direction.LEFT:
                nextpos.x -= 2
                nextpos.orientation = Orientation.HORIZONTAL_LYING
            if direction is Direction.RIGHT:
                nextpos.x += 1
                nextpos.orientation = Orientation.HORIZONTAL_LYING

        elif self.pos.orientation is Orientation.HORIZONTAL_LYING:
            if direction is Direction.UP:
                nextpos.y -= 1
            if direction is Direction.DOWN:
                nextpos.y += 1
            if direction is Direction.LEFT:
                nextpos.x -= 1
                nextpos.orientation = Orientation.STANDING
            if direction is Direction.RIGHT:
                nextpos.x += 2
                nextpos.orientation = Orientation.STANDING

        elif self.pos.orientation is Orientation.VERTICAL_LYING:
            if direction is Direction.UP:
                nextpos.y -= 1
                nextpos.orientation = Orientation.STANDING
            if direction is Direction.DOWN:
                nextpos.y += 2
                nextpos.orientation = Orientation.STANDING
            if direction is Direction.LEFT:
                nextpos.x -= 1
            if direction is Direction.RIGHT:
                nextpos.x += 1

        return nextpos

    def move(self, next_pos: Pos):
        """
        Move the brick to the given position.
        :param next_pos: Position object.
        """
        self.pos = next_pos

    def get_blocks_occupied(self) -> List[List[int]]:
        """
        Find the blocks occupied by the brick.
        :return: A list containing 1 or more elements,
         where each list element contains a block's x,y coordinates.
        """

        # occupies 1 block in standing position
        if self.pos.orientation is Orientation.STANDING:
            return [[self.pos.x, self.pos.y]]

        # occupies 2 blocks along y axis in vertical pos.
        if self.pos.orientation is Orientation.VERTICAL_LYING:
            return [[self.pos.x, self.pos.y], [self.pos.x, self.pos.y + 1]]

        # occupies 2 blocks along x axis in horizontal pos.
        if self.pos.orientation is Orientation.HORIZONTAL_LYING:
            return [[self.pos.x, self.pos.y], [self.pos.x + 1, self.pos.y]]


import torch

def make_subtiles(x: torch.Tensor, h: int, w: int) -> torch.Tensor:
    """ Reshape a 3D or 4D tensor into a new 4D with the dimension 0 used to index the subtiles (and batch)
    Inputs:
     x: tensor to split into subtiles of size h, w. Size of x: (C,H,W) or (N,C,H,W)
     h: int indicating the height of the subtile
     w: int indicating the width of the subtile to use

    Output:
     Torch tensor of shape (N,C,H,W) with N = the total number of subtiles created.
    """
    if x.dim() == 3:
        x = x.unsqueeze(0)
    elif x.dim() != 4:
        raise ValueError(f'Input dimension must be either 3 or 4. {x.dim} dimensions provided')

    b, c, m, n = x.shape

    if m // h != m / h:
        raise ValueError(f'Required subtile size of {h} for tensor size of {m}, does not create an exact number of subtiles. Use padding or change subtile size.')
    elif n // w != n / w:
        raise ValueError(f'Required subtile size of {w} for tensor size of {n}, does not create an exact number of subtiles. Use padding or change subtile size.')

    return x.reshape(b, c, m // h, h, n // w, w).permute(2, 4, 0, 1, 3, 5).reshape(-1, c, h, w)

def unmake_subtiles(x: torch.Tensor, m: int, n: int) -> torch.Tensor:
    """ Reshape the subtiles created by make_subtiles into a tensor of the original size

    Inputs:
     x: torch tensor with 4D with structure (N,C,H,W)
     m: int of the origial height of the image (height to recreate)
     n: into f the original width of the image (width to recreate)
    """
    if x.dim() == 3:
        x = x.unsqueeze(0)
    elif x.dim() != 4:
        raise ValueError(f'Input dimension must be either 3 or 4. {x.dim} dimensions provided')

    c, h, w = x.shape[-3:]
    b = x.shape[0] // ((m // h) * (n // w))

    if m // h != m / h:
        raise ValueError(f'Required larger torch of size {m} while subtiles are of size {h} this does not work.')
    elif n // w != n / w:
        raise ValueError(f'Required larger torch of size {n} while subtiles are of size {w} this does not work.')

    return x.reshape(m // h, n // w, b, c, h, w).permute(2, 3, 0, 4, 1, 5).reshape(b, c, m, n)


from django.core.management.base import BaseCommand
from rooms.models import Amenity

class Command(BaseCommand):
    help = "this command that auto-create amenities"

    def handle(self, *args, **options):
        amenities = [
            "Bed sheets",
            "Body Cleanser",
            "Coffee Maker",
            "Dishes",
            "Facial Cleanser",
            "Hair Dryer",
            "Hangers",
            "Iron",
            "Lockbox",
            "Microwave",
            "Oil",
            "Pans",
            "Pepper",
            "Pots",
            "Salt",
            "Shampoo",
            "Silverware",
            "Soap",
            "Toilet Paper",
            "Towels",
        ]

        for a in amenities:
            Amenity.objects.create(name=a)

        self.stdout.write(self.style.SUCCESS("Amenities Created!"))


# 1166번
import sys
input=sys.stdin.readline

n,*arr=map(int,input().split())
start=0
end=min(arr)
for _ in range(60):
    mid=(start+end)/2
    k=(arr[0]//mid)*(arr[1]//mid)*(arr[2]//mid)
    if n<=k:
        start=mid
    else:
        end=mid
print(end)


import os
from re import I
import numpy as np
from torch.utils.data import Dataset, DataLoader
import torchvision.transforms as transforms
import albumentations as A
import tifffile as tiff
import json
import cv2
import torch
import argparse
import matplotlib.pyplot as plt

from PIL import Image
from sklearn.model_selection import train_test_split

label_dict = {0:"background", 1:"stas"}

transforms_test =   transforms.Compose([
                    transforms.ToTensor(),
                    transforms.Normalize((0.827, 0.621, 0.769), (0.168, 0.302, 0.190)),])

class cancer_seg_semi_data(Dataset):
    def __init__(self, args, data, isTrain=True):
        self.data = data
        self.semi = args.semi
        self.root = args.root
        self.isTrain = isTrain
        self.image_size = args.img_size

        self.data_info = []

        if isTrain:
            self.transform = A.Compose([
                                A.RandomCrop(width=self.image_size[0], height=self.image_size[1]),
                                A.HorizontalFlip(p=0.5),
                                A.VerticalFlip(p=0.5),
                                # A.RandomRotate90(p=0.5),
                                # A.Transpose(p=0.5),
                                A.RandomBrightnessContrast(brightness_limit=0.3, contrast_limit=0.3, p=0.3),
                                A.ShiftScaleRotate(p=0.5)
                            ])
        else:
            self.transform = None

        for image_name in self.data:
            points = []
            label_name = image_name[:-4] + '.json'

            with open(os.path.join(self.root, 'Train_Annotations_SEG', label_name)) as f:
                info = json.load(f)
            label_info = info['shapes']
            for label in label_info:
                tmp_points = np.array(label['points']).astype(np.int)
                points.append(tmp_points)
            image_path = os.path.join(self.root, 'Train_Images', image_name[:-4] + '.jpg')

            self.data_info.append([image_path, points, 'normal'])
        if isTrain:
            for image_name in os.listdir(os.path.join(self.root, 'Public_Image')):
                image_path = os.path.join(self.root, 'Public_Image', image_name)
                mask_path = os.path.join('./semi', image_name[:-4] + '.png')

                self.data_info.append([image_path, mask_path, 'semi'])

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

    def __getitem__(self, index):
        image_path, points, train_type = self.data_info[index]

        image = cv2.imread(image_path)
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # (H, W, 3)

        height, width, _  = image.shape

        if train_type == 'normal':
            mask = np.zeros((height, width, 1))
            for pts in points:
                cv2.fillPoly(mask, [pts], color=1)
        else:
            mask = cv2.imread(points, 0)
            mask = mask[:,:,np.newaxis] / 255.0

        # self.visualization(image, mask)

        if self.transform:
            transformed = self.transform(image=image, mask=mask)
            image, mask = transformed["image"], transformed["mask"]

        image = image.transpose((2, 0, 1)) # (3, H, W)
        mask = mask.transpose((2, 0, 1)) # (1, H, W)

        image = torch.from_numpy((image.copy()))
        image = image.float() / 255.0
        mean = torch.as_tensor([0.827, 0.621, 0.769], dtype=image.dtype, device=image.device)
        std = torch.as_tensor([0.168, 0.302, 0.190], dtype=image.dtype, device=image.device)
        if mean.ndim == 1:
            mean = mean.view(-1, 1, 1)
        if std.ndim == 1:
            std = std.view(-1, 1, 1)
        image.sub_(mean).div_(std)
        mask = torch.from_numpy((mask.copy()))

        return image, mask

class cancer_seg_data(Dataset):
    def __init__(self, args, data, isTrain=True):
        self.data = data
        self.root = args.root
        self.isTrain = isTrain
        self.image_size = args.img_size

        self.data_info = []

        if isTrain:
            self.transform = A.Compose([
                                A.RandomCrop(width=self.image_size[0], height=self.image_size[1]),
                                A.HorizontalFlip(p=0.3),
                                A.VerticalFlip(p=0.3),
                                # A.RandomRotate90(p=0.3),
                                # A.Transpose(p=0.3),
                                A.RandomBrightnessContrast(brightness_limit=0.3, contrast_limit=0.3, p=0.3),
                                A.ShiftScaleRotate(p=0.3)
                            ])
        else:
            self.transform = None

        for image_name in self.data:
            points = []
            label_name = image_name[:-4] + '.json'

            with open(os.path.join(self.root, 'Train_Annotations_SEG', label_name)) as f:
                info = json.load(f)
            label_info = info['shapes']
            for label in label_info:
                tmp_points = np.array(label['points']).astype(np.int)
                points.append(tmp_points)
            image_path = os.path.join(self.root, 'Train_Images', image_name[:-4] + '.jpg')

            self.data_info.append([image_path, points])

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

    def __getitem__(self, index):
        image_path, points = self.data_info[index]

        image = cv2.imread(image_path)
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # (H, W, 3)

        height, width, _  = image.shape

        mask = np.zeros((height, width, 1))
        for pts in points:
            cv2.fillPoly(mask, [pts], color=1)

        # self.visualization(image, mask)

        if self.transform:
            transformed = self.transform(image=image, mask=mask)
            image, mask = transformed["image"], transformed["mask"]

        image = image.transpose((2, 0, 1)) # (3, H, W)
        mask = mask.transpose((2, 0, 1)) # (1, H, W)

        image = torch.from_numpy((image.copy()))
        image = image.float() / 255.0
        mean = torch.as_tensor([0.827, 0.621, 0.769], dtype=image.dtype, device=image.device)
        std = torch.as_tensor([0.168, 0.302, 0.190], dtype=image.dtype, device=image.device)
        if mean.ndim == 1:
            mean = mean.view(-1, 1, 1)
        if std.ndim == 1:
            std = std.view(-1, 1, 1)
        image.sub_(mean).div_(std)
        mask = torch.from_numpy((mask.copy()))

        return image, mask
    def visualization(self, image, mask):
        transform = A.RandomCrop(width=1280, height=900)(image=image, mask=mask)
        image_crop, mask_crop = transform["image"], transform["mask"]

        transform = A.HorizontalFlip(p=1)(image=image_crop, mask=mask_crop)
        hor_image, hor_mask = transform["image"], transform["mask"]

        transform = A.VerticalFlip(p=1)(image=image_crop, mask=mask_crop)
        ver_image, ver_mask = transform["image"], transform["mask"]

        transform = A.RandomBrightnessContrast(brightness_limit=0.15, contrast_limit=0.15, p=1)(image=image_crop, mask=mask_crop)
        bright_image, bright_mask = transform["image"], transform["mask"]

        transform = A.RandomRotate90(p=1)(image=image_crop, mask=mask_crop)
        rotate_image, rotate_mask = transform["image"], transform["mask"]

        transform = A.Transpose(p=1)(image=image_crop, mask=mask_crop)
        transpose_image, transpose_mask = transform["image"], transform["mask"]

        transform = A.ShiftScaleRotate(p=1)(image=image_crop, mask=mask_crop)
        shift_image, shift_mask = transform["image"], transform["mask"]

        plt.figure(figsize=(18,12))
        plt.subplot(4,4,1)
        plt.title("image_ori")
        plt.imshow(image)
        plt.axis('off')
        plt.subplot(4,4,2)
        plt.title("mask_ori")
        plt.imshow(mask)
        plt.axis('off')
        plt.subplot(4,4,3)
        plt.title("image_cropped")
        plt.imshow(image_crop)
        plt.axis('off')
        plt.subplot(4,4,4)
        plt.title("mask_cropped")
        plt.imshow(mask_crop)
        plt.axis('off')
        plt.subplot(4,4,5)
        plt.title("image_vertial_flip")
        plt.imshow(ver_image)
        plt.axis('off')
        plt.subplot(4,4,6)
        plt.title("mask_vertial_flip")
        plt.imshow(ver_mask)
        plt.axis('off')
        plt.subplot(4,4,7)
        plt.title("image_horizontal_flip")
        plt.imshow(hor_image)
        plt.axis('off')
        plt.subplot(4,4,8)
        plt.title("mask_horizontal_flip")
        plt.imshow(hor_mask)
        plt.axis('off')
        plt.subplot(4,4,9)
        plt.title("image_rotate")
        plt.imshow(rotate_image)
        plt.axis('off')
        plt.subplot(4,4,10)
        plt.title("mask_rotate")
        plt.imshow(rotate_mask)
        plt.axis('off')
        plt.subplot(4,4,11)
        plt.title("image_rotateshift")
        plt.imshow(shift_image)
        plt.axis('off')
        plt.subplot(4,4,12)
        plt.title("mask_rotateshift")
        plt.imshow(shift_mask)
        plt.axis('off')
        plt.subplot(4,4,13)
        plt.title("image_bright")
        plt.imshow(bright_image)
        plt.axis('off')
        plt.subplot(4,4,14)
        plt.title("mask_bright")
        plt.imshow(bright_mask)
        plt.axis('off')
        plt.subplot(4,4,15)
        plt.title("image_transpose")
        plt.imshow(transpose_image)
        plt.axis('off')
        plt.subplot(4,4,16)
        plt.title("mask_transpose")
        plt.imshow(transpose_mask)
        plt.axis('off')
        plt.show()

class cancer_public_seg_data(Dataset):
    def __init__(self, root):
        self.root = root
        self.data_info = []
        for data in ['Public_Image']:
            for image_name in os.listdir(os.path.join(self.root, data)):
                self.data_info.append([os.path.join(self.root, data, image_name), image_name])

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

    def __getitem__(self, index):
        image_path, image_name = self.data_info[index]

        image = Image.open(image_path).convert("RGB")
        return transforms_test(image), image_name

if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description='Train the UNet on images and target masks',
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument('--root', type=str, default='../../dataset', help='Number of epochs')
    parser.add_argument('--epochs', type=int,default=5, help='Number of epochs')
    parser.add_argument('--img_size', type=int,default=896, help='size of image')
    parser.add_argument('--batch_size', type=int, default=1, help='Batch size')
    parser.add_argument('--learning_rate', type=float, default=0.0001, help='Learning rate')
    parser.add_argument('--load', type=str, default=False, help='Load model from a .pth file')
    parser.add_argument('--scale', type=float, default=0.5, help='Downscaling factor of the images')
    parser.add_argument('--validation', type=float, default=0.1,help='Percent of the data that is used as validation (0-100)')
    parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
    parser.add_argument('--split_seed', type=int, default=2022, help='')
    args = parser.parse_args()
    data_list = os.listdir(os.path.join(args.root, 'Train_Images'))
    train_data_list, valid_data_list = train_test_split(data_list, random_state=args.split_seed, test_size=args.validation)

    mean = torch.as_tensor([0.827, 0.621, 0.769])
    std = torch.as_tensor([0.168, 0.302, 0.190])
    if mean.ndim == 1:
        mean = mean.view(-1, 1, 1)
    if std.ndim == 1:
        std = std.view(-1, 1, 1)

    valid_data = cancer_seg_data(args, train_data_list, isTrain=True)
    valid_loader = DataLoader(valid_data, batch_size=1, num_workers=0, shuffle=True, pin_memory=True)
    for image, mask in valid_loader:
        mask = mask[:,0,:,:]
        image = image.cpu().detach()
        image = ((image * std) + mean) * 255
        image = image.numpy()
        image = image.astype(np.uint8)
        # for batch_size in range(len(image)):
        #     plt.figure(figsize=(18,12))
        #     plt.subplot(1,2,1)
        #     plt.title("image")
        #     plt.imshow(image[batch_size].transpose((1, 2, 0)))
        #     plt.subplot(1,2,2)
        #     plt.title("label")
        #     plt.imshow(mask[batch_size])
        #     plt.show()

    # data_loader = DataLoader(data, batch_size=2, shuffle=True, drop_last=False)
    # iter_data = iter(data_loader)
    # image, mask = iter_data.next()
    # print(image.shape, mask.shape)


# Copyright 2020-2021 AstroLab Software
# Author: Marco Leoni, Julien Peloton
#
# Licensed under the MIT License;
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      https://opensource.org/licenses/mit-license.php
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import numpy as np

from scipy.optimize import least_squares
from sklearn.metrics import mean_squared_error

__all__ = ['delta_t', 'fsigmoid', 'errfunc_sigmoid', 'fit_sigmoid', 'compute_mse']

def delta_t(time_index: np.array) -> np.array:
    """ Re-index an index relatively to the first data point.

    Parameters
    ----------
    time_index : np.array

    Returns
    -------
    relative_time : np.array
        time relative to the first
        data point in the dataframe
    """

    relative_time = time_index - time_index[0]

    return relative_time

def fsigmoid(x: np.array, a: float, b: float, c: float) -> np.array:
    """Sigmoid function

    Parameters
    ---------
    x: np.array
    a: float
    b: float
    c: float

    Returns
    -------
    sigmoid: np.array
        fit with a sigmoid function
    """

    sigmoid = c / (1.0 + np.exp(-a * (x - b)))

    return np.array(sigmoid)

def errfunc_sigmoid(params: list, time: np.array, flux: np.array) -> float:
    """ Absolute difference between theoretical and measured flux.

    Parameters
    ----------
    params : list of float
        light curve parameters: (a, b, t0, tfall, trise)
    time : array_like
        exploratory variable (time of observation)
    flux : array_like
        response variable (measured flux)

    Returns
    -------
    diff : float
        absolute difference between theoretical and observed flux

    """
    return abs(flux - fsigmoid(time, *params))

def fit_sigmoid(time: np.array, flux: np.array) -> list:
    """ Find best-fit parameters using scipy.least_squares.

    Parameters
    ----------
    time : array_like
        exploratory variable (time of observation)
    flux : array_like
        response variable (measured flux)

    Returns
    -------
    result : list of float
        best fit parameter values
    """
    flux = np.asarray(flux)
    t0 = time[flux.argmax()] - time[0]
    if t0 > 0:
        dt = time[flux.argmax()] - time[flux.argmin()]
        slope = (flux.argmax() - flux.argmin()) / dt
    else:
        slope = 1.
    if flux[0] > 0:
        f0 = flux[0]
    else:
        f0 = 0

    aguess = slope
    cguess = np.max(flux)

    if f0 != 0 and cguess / f0 != 1.:
        bguess = np.log(cguess / f0 - 1.) / aguess
    else:
        bguess = 1.0

    guess = [aguess, bguess, cguess]
    result = least_squares(errfunc_sigmoid, guess, args=(time, flux))

    return result.x

def compute_mse(f_obs: np.array, f_exp: np.array) -> float:
    """ Compute mean squared error.

    Parameters
    ----------
    f_obs: np.array
        observed data points
    f_exp: np.array
        fitted (predicted) data points

    Returns
    -------
    test_mse: float
        mse between fitted and observed
    """

    test_mse = mean_squared_error(f_obs, f_exp)

    return test_mse

def main():
    return None

if __name__ == '__main__':
    main()


#!/usr/bin/env python
# coding: utf-8

# ## Iteradores e iterables

# 1) A partir de una lista vacía, utilizar un ciclo while para cargar allí números negativos del -15 al -1

# In[1]:

lista = []
n = -15
while (n < 0):
    lista.append(n)
    n += 1
print(lista)

# 2) ¿Con un ciclo while sería posible recorrer la lista para imprimir sólo los números pares?

# In[3]:

n = 0
while (n < len(lista)):
    if (lista[n] % 2 == 0):
        print(lista[n])
    n += 1

# 3) Resolver el punto anterior sin utilizar un ciclo while

# In[4]:

for elemento in lista:
    if (elemento % 2 == 0):
        print(elemento)

# 4) Utilizar el iterable para recorrer sólo los primeros 3 elementos

# In[7]:

for elemento in lista[:3]:
    print(elemento)

# 5) Utilizar la función **enumerate** para obtener dentro del iterable, tambien el índice al que corresponde el elemento

# In[9]:

for i, e in enumerate(lista):
    print(i, e)

# 6) Dada la siguiente lista de números enteros entre 1 y 20, crear un ciclo donde se completen los valores faltantes: lista = [1,2,5,7,8,10,13,14,15,17,20]

# In[10]:

lista = [1,2,5,7,8,10,13,14,15,17,20]

# In[11]:

n = 1
while(n <= 20):
    if (not(n in lista)):
        lista.insert((n-1), n)
    n += 1
print(lista)

# 7) La sucesión de Fibonacci es un listado de números que sigue la fórmula:

# n0 = 0

# n1 = 1

# ni = ni-1 + ni-2

# Crear una lista con los primeros treinta números de la sucesión.

# In[23]:

fibo = [0,1]
n = 2
while(n < 30):
    fibo.append(fibo[n-1]+fibo[n-2])
    n += 1
print(fibo)

# 8) Realizar la suma de todos elementos de la lista del punto anterior

# In[24]:

sum(fibo)

# 9) La proporción aurea se expresa con una proporción matemática que nace el número irracional Phi= 1,618… que los griegos llamaron número áureo. El cuál se puede aproximar con la sucesión de Fibonacci. Con la lista del ejercicio anterior, imprimir el cociente de los últimos 5 pares de dos números contiguos:

# Donde i es la cantidad total de elementos

# ni-1 / ni

# ni-2 / ni-1

# ni-3 / ni-2

# ni-4 / ni-3

# ni-5 / ni-4

#

# In[38]:

primeros = 15
n = primeros - 5
while(n < primeros):
    print(fibo[n]/fibo[n-1])
    n += 1

# 10) A partir de la variable cadena ya dada, mostrar en qué posiciones aparece la letra "n"

# cadena = 'Hola Mundo. Esto es una practica del lenguaje de programación Python'

# In[39]:

cadena = 'Hola Mundo. Esto es una practica del lenguaje de programación Python'
for i, c in enumerate(cadena):
    if c == 'n':
        print(i)

# 11) Crear un diccionario e imprimir sus claves utilizando un iterador

# In[40]:

dicc = {  'Ciudad': ['Buenos Aires','Caracas','Bogotá','Lisboa','Roma'],
'País': ['Argentina','Venezuela','Colombia','Portugal','Italia'],
'Continente' : ['América','América','América','Europa','Europa']}
for i in dicc:
    print(i)

# 12) Convertir en una lista la variable "cadena" del punto 10 y luego recorrerla con un iterador

# In[41]:

cadena = 'Hola Mundo. Esto es una practica del lenguaje de programación Python'
print(type(cadena))
cadena = list(cadena)
print(type(cadena))

# In[45]:

recorre = iter(cadena)
largo = len(cadena)
for i in range(0, largo):
    print(next(recorre))

# 13) Crear dos listas y unirlas en una tupla utilizando la función zip

# In[48]:

lis1 = ['run','fly','sleep']
lis2 = ['correr','volar','dormir']
lisz = zip(lis1, lis2)
print(type(lisz))
print(list(lisz))

# 14) A partir de la siguiente lista de números, crear una nueva sólo si el número es divisible por 7

# lis = [18,21,29,32,35,42,56,60,63,71,84,90,91,100]

# In[49]:

lis = [18,21,29,32,35,42,56,60,63,71,84,90,91,100]
lis2 = [i for i in lis if i % 7 == 0]
print(lis2)

# 15) A partir de la lista de a continuación, contar la cantidad total de elementos que contiene, teniendo en cuenta que un elemento de la lista podría ser otra lista:

# lis = [[1,2,3,4],'rojo','verde',[True,False,False],['uno','dos','tres']]

# In[56]:

lis = [[1,2,3,4],'rojo','verde',[True,False,False],['uno','dos','tres']]

# In[51]:

type(lis)

# In[57]:

cantidad = 0
for elemento in lis:
    if (type(elemento) == list):
        cantidad += len(elemento)
    else:
        cantidad += 1
print('La cantidad total de elementos es', cantidad)

# 16) Tomar la lista del punto anterior y convertir cada elemento en una lista si no lo es

# In[58]:

for indice, elemento in enumerate(lis):
    if (type(elemento) != list):
        lis[indice]=[elemento]
print(lis)