'''
File containing the PlottingCalculator class
'''
import numpy as np
import math
from pyrigee.orbit import *

'''
The PlottingCalculator class contains functions that calculate coordinates for plotting
things. Used to reduce the amount of code in the OrbitPlotter class.
'''
class PlottingCalculator:
    # The number of divisions in wireframe plots for bodies
    __PLANET_DIVS = 9j

    # The number of divisions in orbit plots
    __ORBIT_DIVS = 61

    def __init__(self, t):
        self.__tick_value = t

    '''
    Calculates the x, y, z coordinates of a sphere. Used to plot the body defined by the user. Takes
    the scaled radius, or the radius of the body scaled to the graph's tick units
    '''
    def calculate_body_coords(self, scaled_radius):
        # Create theta and phi values that run from 0 to 2pi and 0 to pi, respectively
        theta, phi = np.mgrid[0:2 * np.pi:self.__PLANET_DIVS, 0:np.pi:self.__PLANET_DIVS]

        '''
        Calculate x, y, and z of sphere given theta and phi ranges. Divide each radius by tick value to make sure
        that the units are correct when displayed
        '''
        x = scaled_radius * np.cos(theta) * np.sin(phi)
        y = scaled_radius * np.sin(theta) * np.sin(phi)
        z = scaled_radius * np.cos(phi)

        return (x, y, z)

    '''
    Calculates the coordinates of an elliptical orbit. Takes the orbits inclination, eccentricty, and semi-major axis.
    The transfer flag indicates whether or not this is a transfer orbit, in which case only half the orbit will be
    calculated. negative indicates whether or not the orbit should be flipped. Returns the x, y, z coords of the
    elliptical orbit scaled by __tick_value
    '''
    def calculate_elliptical_orbit_coords(self, inclination, eccentricity, semi_major_axis, transfer, negative):
        # Number to multiply by pi by when bounding np.linepace. Default is -2 to plot an entire polar coordinate
        pi_multiplier = -2

        # If user only wants to plot half the orbit, change pi multiplier to -1, so that np.linspace goes from 0 to pi
        if transfer:
            pi_multiplier = -1

        theta = np.linspace(pi_multiplier * np.pi, 0, self.__ORBIT_DIVS)

        # Convert inclination to radians
        inclination = np.radians(inclination)

        # Polar equation of ellipse
        r = (semi_major_axis * (1 - eccentricity**2)) / (1 - eccentricity * np.cos((theta)))

        # Flip orbit if negative flag is true
        if negative:
            r *= -1

        # Convert polar equations to cartesean coords based on the given orbital inclination
        x = r * np.cos(theta) * np.cos(inclination)
        y = r * np.sin(theta)
        z = x * np.tan(inclination)

        # Return the scaled coordinates of the elliptical orbit
        return self.calculate_scaled_coords(x, y, z)

    '''
    Calculates the coordinates of a parabolic orbit. Takes an orbit object representing the orbit and the radius of the
    body being orbited. Returns the x, y, z coords of the orbit scaled by __tick_value
    '''
    def calculate_parabolic_orbit_coords(self, orbit, body_radius):
        # Create theta value for periodic plotting
        theta = np.linspace(0, 2 * np.pi, self.__ORBIT_DIVS)

        # Polar equation of ellipse
        r = ((orbit.perigee) * 2 + (body_radius * 2)) / (1 - np.cos(theta))

        # Convert polar equations to cartesean coords based on the given orbital inclination
        x = r * np.cos(theta) * np.cos(np.radians(orbit.inclination))
        y = r * np.sin(theta)
        z = r * np.sin(np.radians(orbit.inclination)) * np.cos(theta)

        # Return the scaled coordinates of the parabolic orbit
        return self.calculate_scaled_coords(x, y, z)

    '''
    Calculates the coordinates of the ascending node. Takes the radius of the body being orbited, the orbits
    inclination, the apogee, and the perigee/ Returns the coordinates scaled by __tick_value
    '''
    def calculate_ascending_node_coords(self, body_radius, inclination, apogee, perigee):
        # Calculate the apoapsis/periapsis (distances from center of mass) of target orbit where inclination arrow will be plotted
        apoapsis = apogee + body_radius
        periapsis = perigee + body_radius

        # Calculate ascending node height
        ascending_node_height = math.sqrt(apoapsis * periapsis)

        # Return the scaled coordinates of the inclination change arrow
        return self.calculate_scaled_coords(0, -ascending_node_height, 0)

    '''
    Calculates the coordinates of the apogee text annotation. Takes the x, y, and z coordinates of the orbit, each
    as a list of numbers
    '''
    def calculate_apogee_text_coords(self, x, y, z):
        # Get coordinates of apogee text
        apogee_x = x[0]
        apogee_y = y[0]
        apogee_z = z[0]

        return (apogee_x, apogee_y, apogee_z)

    '''
    Calculates the coordinates of the perigee text annotation. Takes the x, y, and z coordinates of the orbit, each
    as a list of numbers
    '''
    def calculate_perigee_text_coords(self, x, y, z):
        # Index of orbit coordinates of the orbit's perigee
        perigee_coord_index = int(x.size / 2)

        # Get coordinates of perigee text
        perigee_x = x[perigee_coord_index]
        perigee_y = y[perigee_coord_index]
        perigee_z = z[perigee_coord_index]

        return (perigee_x, perigee_y, perigee_z)

    '''
    Takes three lists, each representing x, y, and z coordinates, respectively. Returns these coordinates scaled
    by __tick_value
    '''
    def calculate_scaled_coords(self, x, y, z):
        return (x / self.__tick_value, y / self.__tick_value, z / self.__tick_value)

    '''
    Calculates the orbit, eccentricity, and semi-major axis of the transfer orbit. The transfer orbit is the elliptical
    orbit that transitions from one circular orbit to another. Takes the initial orbit, the target orbit, and the radius
    of the body being orbited
    '''
    def calculate_transfer_orbit_elements(self, initial_orbit, target_orbit, body_radius):
        # Calculate apogee, perigee, apoapsis, and periapsis of the transfer orbit
        transfer_apogee = target_orbit.apogee
        transfer_perigee = initial_orbit.perigee
        transfer_apoapsis = transfer_apogee + body_radius
        transfer_periapsis = transfer_perigee + body_radius

        # Calculate semi-major axis of transfer orbit
        transfer_semi_major_axis = (transfer_apoapsis + transfer_periapsis) / 2

        # Calculate eccentricity of transfer orbit
        transfer_eccentricity = (transfer_apoapsis - transfer_periapsis) / (transfer_apoapsis + transfer_periapsis)

        # Variable to hold the inclination of the transfer orbit
        transfer_inclination = 0

        '''
        Determine whether the initial or target orbit is the higher one, and set the transfer inclination as needed.
        The transfer orbit will be plotted to show path taken either before or after an inclination change, whichever
        is most efficient
        '''
        if initial_orbit.apogee > target_orbit.apogee:
            transfer_inclination = target_orbit.inclination
        else:
            transfer_inclination = initial_orbit.inclination

        # If the transfer apogee < transfer perigee (such as when maneuvering from higher orbit to a lower orbit), flip the values
        if transfer_apogee < transfer_perigee:
            temp = transfer_apogee
            transfer_apogee = transfer_perigee
            transfer_perigee = temp

        # Return a new orbit that represents the elliptical transfer orbit, the transfer eccentricity, and the transfer semi-major axis
        return (Orbit(transfer_apogee, transfer_perigee, transfer_inclination), transfer_eccentricity, transfer_semi_major_axis)

    '''
    Calculates the orbit, eccentricity, and semi-major axis of the in-between orbit. The in-between orbit is the orbit the
    spacecraft will be in after an inclination change to show how the spacecraft will transition between inclination changes
    and Hohmann transfer orbits. Takes the initial orbit, the target orbit, and the radius of the body being orbited
    '''
    def calculate_in_between_orbit_elements(self, initial_orbit, target_orbit, body_radius):
        # Variables to hold in-between apogee and perigee
        in_between_apogee = 0
        in_between_perigee = 0

        # Variable to hold inclination of the in-between orbit
        in_between_inclination = 0

        # If maneuver shrinks the orbit
        if initial_orbit.apogee > target_orbit.apogee:
            in_between_apogee = initial_orbit.apogee
            in_between_perigee = initial_orbit.perigee
            in_between_inclination = target_orbit.inclination

        # If the maneuver expands the orbit
        else:
            in_between_apogee = target_orbit.apogee
            in_between_perigee = target_orbit.perigee
            in_between_inclination = initial_orbit.inclination

        # Calculate in-between orbit apsis
        in_between_apoapsis = in_between_apogee + body_radius
        in_between_periapsis = in_between_perigee + body_radius

        # Calculate eccentricity of in-between orbit
        in_between_eccentricity = (in_between_apoapsis - in_between_periapsis) / (in_between_apoapsis + in_between_periapsis)

        # Calculate semi-major axis of in-between orbit
        in_between_semi_major_axis = (in_between_apoapsis + in_between_periapsis) / 2

        # Return a new orbit that represents the in-between orbit, the in-between eccentricity, and the in-between semi-major axis
        return (Orbit(in_between_apogee, in_between_perigee, in_between_inclination), in_between_eccentricity, in_between_semi_major_axis)


from random import random

def check(number,list):
    if number in list:
        return False
    else:
         return True
list =[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
def func(i,list):
    index = int(random()*10)
    if index <= len(list)-1:
        cleaner = list[i]
        list[i]= list[index]
        list[index]=cleaner

for i in list:
     func(i,list)

print(list)


from sklearn.cluster import KMeans
import numpy as np
import matplotlib.pyplot as plt

# X = np.array([[1, 2], [1, 4], [1, 0], [10, 2], [10, 4], [10, 0]])
X = np.array(np.random.random((100, 2)))
kmeans = KMeans(n_clusters=2).fit(X)
print('Labels')
print(kmeans.labels_)
result = kmeans.predict([[0, 0], [12, 3]])
print('result')
print(result)
print('clusters')
print(kmeans.cluster_centers_)

plt.scatter(X[:, 0], X[:, 1], c=kmeans.labels_)
plt.xlabel("X")
plt.ylabel("Y")
plt.show()


import math
import numpy as np

PSI = (math.sqrt(5) - 1) / 2
PSI_2 = 1 - PSI
TOL = 1.e-5

class Triangle:
    def __init__(self, v1, v2, v3):
        self.v1 = v1
        self.v2 = v2
        self.v3 = v3

    def path(self, opacity, fill_color):
        side_l, side_r = self.v2 - self.v1, self.v3 - self.v2

        # MOVE TO
        d = "m {}, {} ".format(self.v1[0], self.v1[1])
        # LINE TO
        d += "l {}, {} ".format(side_l[0], side_l[1])
        d += "l {}, {} ".format(side_r[0], side_r[1])
        # LINE TO, CLOSE PATH
        d += "l {}, {}z".format(-side_l[0], -side_l[1])

        return '<path fill="{}" opacity="{}" d="{}"/>'.format(fill_color, opacity, d)

    def dotted(self, stroke_width, stroke_color="black", tile_color="black", radius=0.1):
        svg_circle = lambda point: '<circle cx="{}" cy="{}" r="{}" stroke="{}" stroke-width="{}" fill="{}" />\n'.format(point[0], point[1], radius, stroke_color, stroke_width, tile_color)

        side_l, side_r = self.v2 - self.v1, self.v3 - self.v2

        d = svg_circle(self.v1)
        d += svg_circle(side_l)
        d += svg_circle(side_r)
        d += svg_circle(-side_l)

        return d

    @property
    def center(self):
        return (self.v1 + self.v3)/2

    def mirror(self):
        v1 = np.array([self.v1[0], -self.v1[1]])
        v2 = np.array([self.v2[0], -self.v2[1]])
        v3 = np.array([self.v3[0], -self.v3[1]])
        return self.__class__(v1, v2, v3)

class Fatty(Triangle):

    def split(self):
        s1 = PSI_2 * self.v1 + PSI * self.v3
        s2 = PSI_2 * self.v1 + PSI * self.v2

        return (Fatty(s1, s2, self.v1),
                Tiny(s2, s1, self.v2),
                Fatty(self.v3, s1, self.v2))

class Tiny(Triangle):

    def split(self):
        s1 = PSI * self.v1 + PSI_2 * self.v2

        return (Tiny(s1, self.v3, self.v1),
                Fatty(self.v3, s1, self.v2))

class Tiling:
    def __init__(self, initial=None, depth = 5, scale = 100, mirror=True):
        """Tiling manager class.

        Args:
            initial (list of `Triangle`, optional): The initial tiling. Defaults to None.
        """
        if initial is None or initial == "rombus":
            theta = 2 * math.pi / 5
            rot = np.array([math.cos(theta), math.sin(theta)])
            v1 = np.array([-scale / 2, 0])
            v2 = scale / 2 * rot
            v3 = np.array([scale / 2 / PSI, 0])
            initial = [Fatty(v1, v2, v3)]

        elif initial == "hexagon":
            theta = math.pi / 5
            alpha = math.cos(theta)
            rot = np.array([math.cos(theta), math.sin(theta)])
            v1 = np.array([scale, 0])
            c = np.array([0, 0])
            u1 = u2 = np.array([v1[0]*rot[0]-v1[1]*rot[1], v1[0]*rot[1]+v1[1]*rot[0]])
            v2 = v3 = np.array([u1[0]*rot[0]-u1[1]*rot[1], u1[0]*rot[1]+u1[1]*rot[0]])
            u3 = u4 = np.array([v3[0]*rot[0]-v3[1]*rot[1], v3[0]*rot[1]+v3[1]*rot[0]])
            v4 = v5 = np.array([u4[0]*rot[0]-u4[1]*rot[1], u4[0]*rot[1]+u4[1]*rot[0]])
            u5 = -v1

            initial = [
                Tiny(v1, c, u1),
                Tiny(v2, c, u2),
                Tiny(v3, c, u3),
                Tiny(v4, c, u4),
                Tiny(v5, c, u5)
            ]

        self.tiling = initial

        self.depth = depth
        self.mirror = mirror
        self.scale = scale

        self._create(depth, mirror)

    def _create(self, depth, mirror):
        # Cut the tiles recursively
        for _ in range(depth):
            new_tiling = []
            for tile in self.tiling:
                new_tiling.extend(tile.split())
            self.tiling = new_tiling

        # Mirror the tiling along the x-Axis
        if mirror:
            self.tiling.extend([tile.mirror() for tile in self.tiling])

    def to_svg(self, filepath, dotted=False, width=0.005, margin=1.05, fill_color="white", stroke_color="black", radius=.0005):
        stroke_width = str(PSI ** self.depth * self.scale * width)

        # Create viewport
        xmin = ymin = - self.scale * margin
        width =  height = 2 * self.scale * margin
        viewbox ='{} {} {} {}'.format(xmin, ymin, width, height)

        svg = ['<?xml version="1.0" encoding="utf-8"?>']
        svg.append('<svg width="100%" height="100%" viewBox="{}"'.format(viewbox))
        svg.append(' preserveAspectRatio="xMidYMid meet" version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">')

        # Elements container
        svg.append('<g style="stroke:{}; stroke-width: {};">'.format(stroke_color, stroke_width))

        # Generates elements
        if dotted:
            for tile in self.tiling:
                svg.append(tile.dotted(stroke_width, stroke_color, fill_color, .0005))
        else:
            for tile in self.tiling:
                svg.append(tile.path(1, fill_color))

        svg.append('</g>\n</svg>')
        svg = '\n'.join(svg)

        filepath = "{}_{}_{}".format(filepath, self.depth, width)
        with open(filepath, 'w') as fo:
            fo.write(svg)

if __name__ == "__main__":
    t1 = Tiling(initial="hexagon", depth=8, scale=400)
    t1.to_svg("output/rose", fill_color="pink", dotted=True, width=0.4)

    # print_svg("penrose_2_3.svg", intial_tiling=t2, depth=2, base_width=.3)
    # print_svg_dotted("penrose_dotted_9_3.svg", intial_tiling=t2, scale=scale, depth=9, base_width=.05)


import collections
import random
import unittest

import mock

from cardboard import card as c, events, zone as z
from cardboard.tests.util import GameTestCase
from cardboard.util import ANY

ENTER, LEAVE = events.ENTERED_ZONE, events.LEFT_ZONE

class ZoneTest(GameTestCase):

    card = mock.Mock(spec=c.Card)

    def setUp(self):
        super(ZoneTest, self).setUp()
        self.u = z.UnorderedZone(
            name="Emerald Hill", game=self.game, contents=self.library,
        )

        self.o = z.OrderedZone(
            name="Casino Night", game=self.game, contents=self.library,
        )

class TestZones(ZoneTest):
    def test_name(self):
        self.assertEqual(self.u.name, "Emerald Hill")
        self.assertEqual(self.o.name, "Casino Night")

    def test_ordered(self):
        self.assertFalse(self.u.ordered)
        self.assertTrue(self.o.ordered)

    def test_str_repr(self):
        self.assertEqual(str(self.u), "Emerald Hill")
        self.assertEqual(str(self.o), "Casino Night")

        self.assertEqual(repr(self.u), "<Zone: Emerald Hill>")
        self.assertEqual(repr(self.o), "<Zone: Casino Night>")

    def test_contains(self):
        for i in self.library:
            self.assertIn(i, self.u)
            self.assertIn(i, self.o)

        self.assertNotIn(object(), self.u)
        self.assertNotIn(object(), self.o)

    def test_iter(self):
        self.assertEqual(set(self.u), set(self.library))
        self.assertEqual(list(self.o), self.library)

    def test_len(self):
        self.assertEqual(len(self.u), len(self.library))
        self.assertEqual(len(self.o), len(self.library))

    def test_add(self):
        with self.assertTriggers(event=ENTER, card=30, zone=self.u):
            self.u.add(30)

        with self.assertTriggers(event=ENTER, card=30, zone=self.o):
            self.o.add(30)

        self.assertEqual(set(self.u), set(self.library) | {30})
        self.assertEqual(list(self.o), self.library + [30])

    def test_add_already_contains(self):
        NO_OWNER, OWNER = "on the {}", "in {}'s {}"
        u, o = self.u.name, self.o.name

        n = mock.Mock()
        self.u.add(n)
        self.o.add(n)

        self.resetEvents()

        with self.assertRaisesRegexp(ValueError, NO_OWNER.format(u)):
            self.u.add(n)

        with self.assertRaisesRegexp(ValueError, NO_OWNER.format(o)):
            self.o.add(n)

        with self.assertRaisesRegexp(ValueError, OWNER.format(n.owner, u)):
            self.u.owner = n.owner
            self.u.add(n)

        with self.assertRaisesRegexp(ValueError, OWNER.format(n.owner, o)):
            self.o.owner = n.owner
            self.o.add(n)

        # wasn't added twice nor removed
        self.assertIn(self.library[0], self.u)
        self.assertEqual(self.o.count(self.library[0]), 1)

        self.assertFalse(self.events.trigger.called)

    def test_add_owner_redirection(self):
        """
        Adding a card with a different owner than the zone's redirects.

        """

        card = mock.Mock()

        self.u.name, self.o.name = "foo", "bar"
        self.u.owner, self.o.owner = mock.Mock(), mock.Mock()

        self.u.add(card)
        self.o.add(card)

        card.owner.foo.add.assert_called_once_with(card)
        card.owner.bar.add.assert_called_once_with(card)

    def test_move(self):
        self.o.add(self.card)
        self.card.zone = self.o  # on actual cards this is a property

        with self.assertTriggers(event=ENTER, card=self.card, zone=self.u):
            self.u.move(self.card)
            self.card.zone = self.u

        self.assertIn(self.card, self.u)

        with self.assertTriggers(event=ENTER, card=self.card, zone=self.o):
            self.o.move(self.card)

        self.assertIn(self.card, self.o)

    def test_move_to_self(self):
        self.resetEvents()

        # shouldn't even be checking library[0].zone
        with self.assertRaises(ValueError):
            self.u.move(self.library[0])

        with self.assertRaises(ValueError):
            self.o.move(self.library[0])

        # wasn't added twice nor removed
        self.assertIn(self.library[0], self.u)
        self.assertEqual(self.o.count(self.library[0]), 1)

        self.assertFalse(self.events.trigger.called)

    def test_pop(self):
        self.resetEvents()
        e = self.u.pop()
        self.assertLastEventsWere([dict(event=LEAVE, card=e, zone=self.u)])

        self.resetEvents()
        f = self.o.pop()
        self.assertLastEventsWere([dict(event=LEAVE, card=f, zone=self.o)])

        self.assertEqual(set(self.u), set(self.library) - {e})
        self.assertEqual(list(self.o), self.library[:-1])

    def test_remove(self):
        e = self.library[-7]
        self.library.remove(e)

        with self.assertTriggers(event=LEAVE, card=e, zone=self.u):
            self.u.remove(e)

        with self.assertTriggers(event=LEAVE, card=e, zone=self.o):
            self.o.remove(e)

        self.assertEqual(set(self.u), set(self.library))
        self.assertEqual(list(self.o), self.library)

        self.assertRaises(ValueError, self.u.remove, object())
        self.assertRaises(ValueError, self.o.remove, object())

    def test_update(self):
        self.u.update(range(4))

        for i in range(4):
            self.assertIn(i, self.u)

        self.assertEqual(len(self.u), len(self.library) + 4)

        evs = [dict(event=ENTER, card=i, zone=self.u) for i in range(4)]
        self.assertLastEventsWere(evs)

        self.resetEvents()

        self.o.update(range(4))
        self.assertEqual(self.o[-4:], range(4))

        self.assertEqual(len(self.o), len(self.library) + 4)

        evs = [dict(event=ENTER, card=i, zone=self.o) for i in range(4)]
        self.assertLastEventsWere(evs)

    def test_silent(self):
        self.o.add(self.card)
        self.card.zone = self.o
        self.resetEvents()

        self.u.add(20, silent=True)
        self.o.add(20, silent=True)

        self.u.remove(self.library[0], silent=True)
        self.o.remove(self.library[0], silent=True)

        self.u.pop(silent=True)
        self.o.pop(silent=True)

        self.u.move(self.card, silent=True)
        self.card.zone = self.u
        self.o.move(self.card, silent=True)

        self.u.update(range(10), silent=True)
        self.o.update(range(10), silent=True)

        self.assertFalse(self.events.trigger.called)

    def test_iterable(self):
        i = range(10)

        # TODO: This is incomplete, all the methods don't take iterables
        o = z.OrderedZone(game=None, name="Emerald Hill", contents=i)
        u = z.UnorderedZone(game=None, name="Emerald Hill", contents=i)

        i.pop()

        self.assertEqual(list(o), range(10))
        self.assertEqual(list(u), range(10))

class TestOrderedZone(ZoneTest):
    def test_reversed(self):
        self.assertEqual(list(reversed(self.o)), list(reversed(self.library)))

    def test_getitem(self):
        for i, e in enumerate(self.library):
            self.assertEqual(self.o[i], e)

        self.assertEqual(self.o[2:7:2], self.library[2:7:2])

    def test_set_del_item(self):
        self.assertRaises(AttributeError, getattr, self.o, "__setitem__")
        self.assertRaises(AttributeError, getattr, self.o, "__delitem__")

    def test_count(self):
        o = z.OrderedZone(game=None, name="Emerald Hill",
                          contents=[1, 1, 1, 2, 2, 3])

        for i, e in enumerate(range(3, 0, -1), 1):
            self.assertEqual(o.count(e), i)

    def test_index(self):
        e = self.library[4]
        self.assertEqual(self.o.index(e), 4)

    def test_pop_index(self):
        e1 = self.o.pop(0)
        e2 = self.o.pop(4)

        self.library.pop(0)
        self.library.pop(4)

        self.assertEqual(list(self.o), self.library)
        self.assertLastEventsWere([
            {"event" : LEAVE, "card" : e1, "zone" : self.o},
            {"event" : LEAVE, "card" : e2, "zone" : self.o},
        ])

    def test_reverse(self):
        self.o.reverse()
        self.assertEqual(list(self.o), list(reversed(self.library)))

    def test_shuffle(self):
        with mock.patch("cardboard.zone.random.shuffle") as shuffle:
            self.o.shuffle()

        shuffle.assert_called_once_with(self.o._order)

class TestZone(unittest.TestCase):
    def test_zone(self):
        c = mock.Mock()

        for zone in ["battlefield", "exile", "hand"]:
            n = z.zone[zone](game=None, contents=[c])
            self.assertIsInstance(n, z.UnorderedZone)
            self.assertEquals(n.name, zone)
            self.assertIn(c, n)

        for zone in ["graveyard", "library", "stack"]:
            n = z.zone[zone](game=None, contents=[c])
            self.assertIsInstance(n, z.OrderedZone)
            self.assertEquals(n.name, zone)
            self.assertIn(c, n)


from math import ceil
import time

def add_up_version1(list_numbers, number):
    half = ceil(number/2)
    pairs = []

    for item in range(half):
        temp = []
        temp.append(item)
        temp.append(number - item)
        pairs.append(temp)

    for item in pairs:
        if item[0] in list_numbers and item[1] in list_numbers:
            return True

    return False

def add_up_version2(list_numbers, number):

    for item in range(len(list_numbers)):
        temp_list = list_numbers.copy()
        temp_number = temp_list.pop(item)

        for num in temp_list:
            if temp_number + num == number:
                return True

    return False

def main():

    start_time = time.time()
    print(add_up_version1([10, 15, 3, 7], 17))
    print(add_up_version1([1, 2, 3, 4], 3))
    print(add_up_version1([1, 2, 3, 4], 4))
    print(add_up_version1([1, 2, 3, 4], 10))
    end_time = time.time()
    print(end_time - start_time)

    start_time = time.time()
    print(add_up_version2([10, 15, 3, 7], 17))
    print(add_up_version2([1, 2, 3, 4], 3))
    print(add_up_version2([1, 2, 3, 4], 4))
    print(add_up_version2([1, 2, 3, 4], 10))
    end_time = time.time()
    print(end_time - start_time)

if __name__ == "__main__":
    main()


"""
Implements the baseclasses for all Component types in Lumen.

The base classes implement the core validation logic and the ability
to dynamically resolve Source and Variable references.
"""
from __future__ import annotations

import warnings

from functools import partial
from typing import (
    Any, ClassVar, Dict, List, Tuple, Type,
)

import pandas as pd
import panel as pn
import param  # type: ignore

from panel.io.cache import _container_hash, _hash_funcs
from panel.util import classproperty
from typing_extensions import Literal

from .state import state
from .util import (
    VARIABLE_RE, cleanup_expr, is_ref, resolve_module_reference,
)
from .validation import (
    ValidationError, match_suggestion_message, reverse_match_suggestion,
    validate_parameters,
)

class Component(param.Parameterized):
    """
    Baseclass for all Lumen component types including Source, Filter,
    Transform, Variable and View types. Components must implement
    serialization and deserialization into a specification dictionary
    via the `from_spec` and `to_spec` protocol. Additonally they
    should implement validation.
    """

    __abstract = True

    # Whether the component allows references
    _allows_refs: ClassVar[bool] = True

    # Parameters that are computed internally and are not part of the
    # component specification
    _internal_params: ClassVar[List[str]] = ['name']

    # Deprecated parameters that are still allowed as spec keys
    _legacy_params: ClassVar[List[str]] = []

    # Keys that must be declared declared as a list of strings or
    # tuples of strings if one of multiple must be defined.
    _required_keys: ClassVar[List[str | Tuple[str, ...]]] = []

    # Keys that are valid to define
    _valid_keys: ClassVar[List[str] | Literal['params'] | None] = None

    # Whether to enforce parameter validation in specification
    _validate_params: ClassVar[bool] = False

    def __init__(self, **params):
        self._refs = params.pop('refs', {})
        expected = list(self.param)
        validate_parameters(params, expected, type(self).name)
        if self._allows_refs:
            params = self._extract_refs(params, self._refs)
        super().__init__(**params)
        for p, ref in self._refs.items():
            if isinstance(state.variables, dict):
                continue
            elif isinstance(ref, str) and '$variables' in ref:
                ref_vars = VARIABLE_RE.findall(ref)
                state.variables.param.watch(partial(self._update_ref, p, ref), ref_vars)
                if '.' not in p and p not in params:
                    self._update_ref(p, ref)

    def _extract_refs(self, params: Dict[str, Any], refs: Dict[str, Any]):
        from .variables import Variable
        processed = {}
        for pname, pval in params.items():
            if is_ref(pval):
                refs[pname] = pval
            elif isinstance(pval, (pn.widgets.Widget, param.Parameter, Variable)):
                var = state.variables.add_variable(pval)
                processed[pname] = var.value
                refs[pname] = f'$variables.{var.name}'
                continue
            elif isinstance(pval, dict):
                subrefs = {}
                processed[pname] = self._extract_refs(pval, subrefs)
                for subkey, subref in subrefs.items():
                    refs[f'{pname}.{subkey}'] = subref
                continue
            else:
                processed[pname] = pval
        return processed

    def _update_ref(self, pname: str, ref: str, *events: param.parameterized.Event):
        """
        Component should implement appropriate downstream events
        following a change in a variable.
        """
        expr = cleanup_expr(ref)
        new_value = pd.eval(expr, local_dict=dict(state.variables), engine='python')
        if '.' in pname:
            pname, *keys = pname.split('.')
            old = getattr(self, pname)
            current = new = old.copy()
            for k in keys[:-1]:
                current = current[k]
            current[keys[-1]] = new_value
        else:
            new = new_value
        self.param.update({pname: new})

    def _sync_refs(self, trigger: bool = True):
        updates = []
        for p, ref in self._refs.items():
            if isinstance(state.variables, dict):
                continue
            elif isinstance(ref, str) and '$variables' in ref:
                with param.discard_events(self):
                    self._update_ref(p, ref)
                    pname, *_ = p.split('.')
                    updates.append(pname)
        if trigger:
            self.param.trigger(*updates)

    ##################################################################
    # Validation API
    ##################################################################

    @classproperty
    def _valid_keys_(cls) -> List[str] | None:
        if cls._valid_keys == 'params':
            valid = [p for p in cls.param if p not in cls._internal_params]
        else:
            valid = cls._valid_keys
        return valid if valid is None else valid + cls._legacy_params

    @classmethod
    def _validate_keys_(cls, spec: Dict[str, Any]):
        valid_keys = cls._valid_keys_
        for key in spec:
            if valid_keys is None or key in valid_keys:
                continue
            msg = f'{cls.__name__} component specification contained unknown key {key!r}.'
            msg = match_suggestion_message(key, cls._valid_keys_ or [], msg)
            raise ValidationError(msg, spec, key)

    @classmethod
    def _validate_required_(
        cls, spec: Dict[str, Any], required: List[str | Tuple[str, ...]] | None = None
    ):
        if required is None:
            required_keys = cls._required_keys
        else:
            required_keys = required
        for key in required_keys:
            if isinstance(key, str):
                if key in spec:
                    continue
                msg = f'The {cls.__name__} component requires {key!r} parameter to be defined.'
                msg, attr = reverse_match_suggestion(key, list(spec), msg)
                raise ValidationError(msg, spec, attr)
            elif isinstance(key, tuple):
                if any(f in spec for f in key):
                    continue
                skey = sorted(key)
                key_str = "', '".join(skey[:-1]) + f"' or '{skey[-1]}"
                msg = f"{cls.__name__} component requires one of '{key_str}' to be defined."
                for f in key:
                    msg, attr = reverse_match_suggestion(f, list(spec), msg)
                    if attr:
                        break
                raise ValidationError(msg, spec, attr)

    @classmethod
    def _validate_list_subtypes(
        cls, key: str, subtype: Type[Component], subtype_specs: List[Dict[str, Any] | str],
        spec: Dict[str, Any], context: Dict[str, Any], subcontext: List[Dict[str, Any] | str] | None = None
    ):
        if not isinstance(subtype_specs, list):
            raise ValidationError(
                f'{cls.__name__} component {key!r} key expected list type but got {type(subtype_specs).__name__}. '
                "This could be because of a missing dash in the yaml file.",
                spec, key
            )
        subtypes = []
        for subtype_spec in subtype_specs:
            subtype_spec = subtype.validate(subtype_spec, context)
            subtypes.append(subtype_spec)
            if subcontext is not None:
                subcontext.append(subtype_spec)
        return subtypes

    @classmethod
    def _validate_dict_subtypes(
        cls, key: str, subtype: Type[Component], subtype_specs: Dict[str, Dict[str, Any] | str],
        spec: Dict[str, Any], context: Dict[str, Any], subcontext: Dict[str, Any] | None = None
    ):
        if not isinstance(subtype_specs, dict):
            raise ValidationError(
                f'{cls.__name__} component {key!r} key expected dict type but got {type(subtype_specs).__name__}.',
                spec, key
            )
        subtypes = {}
        for subtype_name, subtype_spec in subtype_specs.items():
            subtypes[subtype_name] = subtype.validate(subtype_spec, context)
            if subcontext is not None:
                subcontext[subtype_name] = subtypes[subtype_name]
        return subtypes

    @classmethod
    def _validate_str_or_spec(
        cls, key: str, subtype: Type[Component], subtype_spec: Dict[str, Any] | str,
        spec: Dict[str, Any], context: Dict[str, Any]
    ):
        if isinstance(subtype_spec, str):
            if subtype_spec not in context[f'{key}s']:
                msg = f'{cls.__name__} component specified non-existent {key} {subtype_spec!r}.'
                msg = match_suggestion_message(subtype_spec, list(context[key]), msg)
                raise ValidationError(msg, spec, subtype_spec)
            return subtype_spec
        return subtype.validate(subtype_spec, context)

    @classmethod
    def _validate_dict_or_list_subtypes(
        cls, key: str, subtype: Type[Component], subtype_specs: Dict[str, Dict[str, Any] | str] | List[Dict[str, Any] | str],
        spec: Dict[str, Any], context: Dict[str, Any], subcontext: Dict[str, Any] | List[Dict[str, Any] | str] | None = None
    ):
        if isinstance(subtype_specs, list):
            assert subcontext is None or isinstance(subcontext, list)
            return cls._validate_list_subtypes(key, subtype, subtype_specs, spec, context, subcontext)
        else:
            assert subcontext is None or isinstance(subcontext, dict)
            return cls._validate_dict_subtypes(key, subtype, subtype_specs, spec, context, subcontext)

    @classmethod
    def _deprecation(
        cls, msg: str, key: str, spec: Dict[str, Any], update: Dict[str, Any]
    ):
        warnings.warn(msg, DeprecationWarning)
        if key not in spec:
            spec[key] = {}
        spec[key].update(update)

    @classmethod
    def _validate_ref(
        cls, key: str, value: Any, spec: Dict[str, Any], context: Dict[str, Any]
    ):
        refs = value[1:].split('.')
        if refs[0] == 'variables':
            if refs[1] not in context.get('variables', {}):
                msg = f'{cls.__name__} component {key!r} references undeclared variable {value!r}.'
                msg = match_suggestion_message(refs[1], list(context.get('variables', {})), msg)
                raise ValidationError(msg, spec, refs[1])
        elif refs[0] not in context.get('sources', {}):
            msg = f'{cls.__name__} component {key!r} references undeclared source {value!r}.'
            msg = match_suggestion_message(refs[1], list(context.get('sources', {})), msg)
            raise ValidationError(msg, spec, refs[1])

    @classmethod
    def _validate_param(cls, key: str, value: Any, spec: Dict[str, Any]):
        pobj = cls.param[key]
        try:
            if isinstance(pobj, param.Selector) and pobj.names and value in pobj.names:
                return
            pobj._validate(value)
        except Exception as e:
            msg = f"{cls.__name__} component {key!r} value failed validation: {str(e)}"
            raise ValidationError(msg, spec, key)

    @classmethod
    def _is_component_key(cls, key: str) -> bool:
        if key not in cls.param:
            return False
        pobj = cls.param[key]
        return (
            isinstance(pobj, param.ClassSelector) and
            isinstance(pobj.class_, type) and
            issubclass(pobj.class_, Component)
        )

    @classmethod
    def _is_list_component_key(cls, key: str) -> bool:
        if key not in cls.param:
            return False
        pobj = cls.param[key]
        return (
            isinstance(pobj, param.List) and
            isinstance(pobj.item_type, type) and
            issubclass(pobj.item_type, Component)
        )

    @classmethod
    def _validate_spec_(
        cls, spec: Dict[str, Any], context: Dict[str, Any] | None = None
    ) -> Dict[str, Any]:
        validated: Dict[str, Any] = {}
        if context is None:
            context = validated

        for key in (cls._valid_keys_ or list(spec)):
            if key not in spec:
                continue
            val = spec[key]
            if is_ref(val) and not cls._allows_refs:
                raise ValidationError(
                    f'{cls.__name__} component does not allow references but {key} '
                    f'value ({val!r}) is a reference.', spec, val
                )
            if hasattr(cls, f'_validate_{key}'):
                val = getattr(cls, f'_validate_{key}')(val, spec, context)
            elif cls._is_component_key(key):
                val = cls.param[key].class_.validate(val, context)
            elif cls._is_list_component_key(key):
                val = cls._validate_list_subtypes(
                    key, cls.param[key].item_type, val, spec, context
                )
            elif is_ref(val):
                cls._validate_ref(key, val, spec, context)
            elif key in cls.param:
                if isinstance(val, str) and val.startswith('@'):
                    continue
                cls._validate_param(key, val, spec)
            validated[key] = val
        return validated

    ##################################################################
    # Public API
    ##################################################################

    @property
    def refs(self) -> List[str]:
        return [v for k, v in self._refs.items() if v.startswith('$variables.')]

    @classmethod
    def from_spec(cls, spec: Dict[str, Any] | str) -> 'Component':
        """
        Creates a Component instance from a specification.

        Parameters
        ----------
        spec : dict or str
            Specification declared as a dictionary of parameter values
            or a string referencing a source in the sources dictionary.

        Returns
        -------
        Resolved and instantiated Component object
        """
        if isinstance(spec, str):
            raise ValueError(
                "Component cannot be materialized by reference. Please pass "
                "full specification for the component."
            )
        return cls(**spec)

    def to_spec(self, context: Dict[str, Any] | None = None) -> Dict[str, Any]:
        """
        Exports the full specification to reconstruct this component.

        Parameters
        ----------
        context: Dict[str, Any]
          Context contains the specification of all previously serialized components,
          e.g. to allow resolving of references.

        Returns
        -------
        Declarative specification of this component.
        """
        spec = {}
        for p, value in self.param.values().items():
            if p in self._internal_params or value == self.param[p].default:
                continue
            elif self._is_component_key(p):
                pspec = value.to_spec(context=context)
                if not pspec:
                    continue
                value = pspec
            elif self._is_list_component_key(p):
                value = [
                    None if v is None else v.to_spec(context=context)
                    for v in value
                ]
            spec[p] = value
        if context is not None:
            spec.update(self._refs)
        return spec

    @classmethod
    def validate(
        cls, spec: Dict[str, Any] | str, context: Dict[str, Any] | None = None
    ) -> Dict[str, Any] | str:
        """
        Validates the component specification given the validation context.

        Arguments
        -----------
        spec: dict | str
          The specification for the component being validated (or a referene to the component)
        context: dict
          Validation context contains the specification of all previously validated components,
          e.g. to allow resolving of references.

        Returns
        --------
        Validated specification.
        """
        if isinstance(spec, str):
            return spec
        context = {} if context is None else context
        cls._validate_keys_(spec)
        cls._validate_required_(spec)
        return cls._validate_spec_(spec, context)

class MultiTypeComponent(Component):
    """
    MultiComponentType is the baseclass for extensible Lumen components.

    A `MultiTypeComponent` can be resolved using the `_get_type` method
    either by the name declared in the `<component>_type` attribute,
    where the name of the component represent the immediate subclasses
    of MultiTypeComponent. For example `class View(MultiTypeComponent)`
    should define `view_type` for all its descendants to override.

    Just as any other Component, `MultiTypeComponent` implements
    methods to construct an instance from a specification, export the
    specification of a component and the ability to validate a
    component.
    """

    __abstract = True

    _required_keys: ClassVar[List[str | Tuple[str, ...]]] = ['type']

    @classproperty
    def _valid_keys_(cls) -> List[str | Tuple[str, ...]] | None:
        if cls._valid_keys is None:
            valid = None
        elif cls._valid_keys == 'params':
            valid = list(cls.param)
        elif 'params' in cls._valid_keys:
            valid = cls._valid_keys.copy()
            valid.extend(list(cls.param))
        else:
            valid = cls._valid_keys.copy()

        if valid is not None and 'type' not in valid:
            valid.append('type')
        return valid if valid is None else valid + cls._legacy_params

    @classproperty
    def _base_type(cls):
        if cls is MultiTypeComponent:
            return
        return cls.__mro__[cls.__mro__.index(MultiTypeComponent)-1]

    @classproperty
    def _component_type(cls) -> str:
        component_type = getattr(cls, f'{cls._base_type.__name__.lower()}_type')
        if component_type is not None:
            return component_type
        return f'{cls.__module__}.{cls.__name__}'

    @classmethod
    def _import_module(cls, component_type: str):
        base_type = cls._base_type
        try:
            import_name = f'lumen.{base_type.__name__.lower()}s.{component_type}'
            __import__(import_name)
        except ImportError as e:
            if e.name != import_name:
                msg = (
                    f"In order to use the {base_type.__name__.lower()} "
                    f"component '{component_type}', the '{e.name}' package "
                    "must be installed."
                )
                raise ImportError(msg)

    @classmethod
    def _get_type(
        cls, component_type: str, spec: Dict[str, Any] | None = None
    ) -> Type['MultiTypeComponent']:
        base_type = cls._base_type
        if component_type is None:
            raise ValidationError(
                f"No 'type' was provided during instantiation of {base_type.__name__} component.",
                spec
            )
        if '.' in component_type:
            return resolve_module_reference(component_type, base_type)

        cls._import_module(component_type)

        subcls_types = set()
        for subcls in param.concrete_descendents(cls).values():
            subcls_type = subcls._component_type
            if subcls_type is None:
                continue
            subcls_types.add(subcls_type)
            if subcls_type == component_type:
                return subcls

        msg = f"{base_type.__name__} component specification declared unknown type '{component_type}'."
        msg = match_suggestion_message(component_type, list(subcls_types), msg)
        raise ValidationError(msg, spec, component_type)

    ##################################################################
    # Public API
    ##################################################################

    @classmethod
    def from_spec(cls, spec: Dict[str, Any] | str) -> 'MultiTypeComponent':
        if isinstance(spec, str):
            raise ValueError(
                "MultiTypeComponent cannot be materialized by reference. Please pass "
                "full specification for the MultiTypeComponent."
            )
        spec = dict(spec)
        component_cls = cls._get_type(spec.pop('type'), spec)
        return component_cls(**spec)

    def to_spec(self, context: Dict[str, Any] | None = None) -> Dict[str, Any]:
        """
        Exports the full specification to reconstruct this component.

        Returns
        -------
        Resolved and instantiated Component object
        """
        spec = super().to_spec(context=context)
        spec['type'] = self._component_type
        return spec

    @classmethod
    def validate(
        cls, spec: Dict[str, Any] | str, context: Dict[str, Any] | None = None
    ) -> Dict[str, Any] | str:
        """
        Validates the component specification given the validation context and the path.

        Arguments
        -----------
        spec: dict | str
          The specification for the component being validated or a reference to the component.
        context: dict
          Validation context contains the specification of all previously validated components,
          e.g. to allow resolving of references.

        Returns
        --------
        Validated specification.
        """
        if isinstance(spec, str):
            return spec
        context = {} if context is None else context
        if 'type' not in spec:
            msg = f'{cls.__name__} component specification did not declare a type.'
            msg, attr = reverse_match_suggestion('type', list(spec), msg)
            raise ValidationError(msg, spec, attr)
        component_cls = cls._get_type(spec['type'], spec)
        component_cls._validate_keys_(spec)
        component_cls._validate_required_(spec)
        return component_cls._validate_spec_(spec, context)

_hash_funcs[Component] = lambda component: _container_hash(component.to_spec())


"""def reverse(a):
	while a:
	#for i in a:
		if a != " ":
			b = a[::-1]
			print("Reversed string is: ", b)
			if b == a:
				print("Works")
			else:
				print("Bummer!")
		return

reverse("roor")"""

"""prefixes = 'JKLMNOPQ'
suffix = 'ack'
#i = 0
for letter in prefixes:
	if letter == 'O':
		letter = letter + 'u'
		print(letter + suffix)
	elif letter == 'Q':
		letter = letter + 'u'
		print(letter + suffix)
	else:
		print(letter + suffix)
	#i = i + 1
	"""

"""a = "fruit"
print(a[:])"""

def find(word, letter, index):
	#index = 0
	while index < len(word):
		if word[index] == letter:
			return index
		index = index + 1
	return -1

print(find("aderinsola", "a", 0))

"""def count(word, letter):
	count = 0
	a = []
	b = 0
	for a in word:
		if letter == a[b]:
			count = count + 1
	print(count, end="")

count("abracadabra", "a")"""

"""def count(word, letter):
	count = 0
	a = []
	b = 0
	#c = b
	for a in word:
		if letter == a[b]:
			count = count + 1
	print(count, end="")

count("abracadabra", "a")"""

"""def count(word, letter):
	count = 0
	a = []
	b = 0
	#c = 0
	#while c <= b:
	#while word != " ":
	#	c = 0
	for a in word:
		if letter == a[b]:
			count = count + 1
		#c = c + 1
	print(count, end="")
	#c = c + 1

count("abracadabra", "a")"""

"""a = "rood"
b = []
while a:
	c = 0
	for i in a:
		if a != " ":
			b = a[::-1]
			print(b, end="")
		break
	c = c + 1"""
	#print(a)
	#b = a[::-1]
	#print(b)
"""if b == a:
	print("Works!")
else:
	print("Ouch! That sucks!")"""

"""def any_lowercase(s):
	for c in s:
		if c.islower():
			#b = c
			return True	#if lowercase in the middle, this doesn't
		else:			#perform as it should
			return False

def any_lowercase2(s):
	for c in s:
		if 'c'.islower():
			return 'True'
		else:
			return 'False'

def any_lowercase3(s):
		for c in s:
			flag = c.islower()
		return flag

def any_lowercase4(s):
	flag = False
	for c in s:
		flag = flag or c.islower()
	return flag

def any_lowercase5(s):
	for c in s:
		if not c.islower():
			return False		#This works well!
	return True

#print(any_lowercase2("ADERINSOLA"))

def rotate_word(s, i):
	holder = ""
	for v in s:
		c = ord(v)
		if c >= ord('a') and c <= ord('z'):
			if c > ord('m'):
				c -= i
			else:
				c += i
		elif c >= ord('A') and c <= ord('Z'):
			if c > ord ('M'):
				c -= i
			else:
				c += i
		holder += chr(c)
	return holder

print(rotate_word("The Quick Brown Fox Jumps Over The Lazy Dog", 13))"""


#!/usr/bin/python
# -*- coding: UTF-8 -*-
import re,os,sys
import random
import argparse

parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('--per', dest='per', type=int, default=10, help='ratio of test set (%)')
parser.add_argument('--file', dest='file', type=str, default='data_from_USPTO_utf8_converted_clear', help='input file')
args = parser.parse_args()
params = vars(args)
print(params)
file = params['file']
test_percent = params['per']

# select n% as test set
def select_file(fin,test_p):
	lines = open(fin,'r+').readlines()[1:] #remove the first title line and the last blank line
	writer1= open(fin+'_train', 'w')
	writer2= open(fin+'_test', 'w')
	all_num = len(lines)
	test_num = int(all_num*(test_p*0.01))

	print('all num: %d' %all_num)
	print('test num: %d' %test_num)
	print('train num: %d' %(all_num-test_num))
	print('slecting...')
	test_set = random.sample(lines, test_num)
	for item in test_set:
		lines.remove(item)
	print('selected')

	writer1.writelines(lines)
	writer2.writelines(test_set)

select_file(file, test_percent)


#if an element in an m x n matrix is 0, it's entire
#row and column are set to zero

#O(m*n) solution: loops through matrix twice,
#first time to find the rows and columns with zeros
#in them, and second time to assign each value in those
#rows cols to zero
def zero_matrix(m):
    row = {}
    col = {}
    for i in range(len(m)):
        for j in range(len(m[0])):
            if(m[i][j] == 0):
                if(i not in row):
                    row[i] = 1
                if(j not in col):
                    col[j] = 1

    #set all vals in row to zero
    for i in row:
        for j in range(len(m[0])):
            m[i][j] = 0

    #set all vals in col to zero
    for j in col:
        for i in range(len(m)):
            m[i][j] = 0

    return(m)

m = [[1,0,1,1],[1,1,1,1],[0,1,1,0],[1,1,1,1]]
print(zero_matrix(m))


import time
import os

from richxerox import *
from tinydb import TinyDB, where

HOME_DIR = 'static/db'
# Create directory if it doesn't exist
os.system("mkdir %s" % HOME_DIR)
db = TinyDB('%s/db.json' % HOME_DIR)
currently_found_in_clipboard = paste(format='text')
while True:
    time.sleep(0.1) # one tenth of a second
    if paste(format='text') != currently_found_in_clipboard:
        currently_found_in_clipboard = paste(format='text')
        # When the user hits CMD+C store the clipboard in a file and take a screenshot of the screen
        created_at = time.time()
        entry = { 'content': pasteall(), 'created_at': int(created_at),}
        entry['screenshot'] = '%s/screen%s.png' % (HOME_DIR, created_at)
        os.system("screencapture %s" % entry['screenshot'])
        db.insert(entry)


import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
import math
from detectron2.detectron2.layers import FrozenBatchNorm2d, ShapeSpec, get_norm
_NORM = 'BN'

class Conv2d_BN(nn.Module):
    """Convolution with BN module."""
    def __init__(
            self,
            in_ch,
            out_ch,
            kernel_size=1,
            stride=1,
            pad=0,
            dilation=1,
            groups=1,
            bn_weight_init=1,
            act_layer=None,
    ):
        super().__init__()
        self.in_ch = in_ch
        self.out_ch = out_ch
        self.conv = torch.nn.Conv2d(in_ch,
                                    out_ch,
                                    kernel_size,
                                    stride,
                                    pad,
                                    dilation,
                                    groups,
                                    bias=False
        )
        self.bn = get_norm(_NORM, out_ch)
        torch.nn.init.constant_(self.bn.weight, bn_weight_init)
        torch.nn.init.constant_(self.bn.bias, 0)
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                # Note that there is no bias due to BN
                fan_out = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
                m.weight.data.normal_(mean=0.0, std=np.sqrt(2.0 / fan_out))

        self.act_layer = act_layer() if act_layer is not None else nn.Identity()

    def forward(self, x):
        # ain = self.in_ch
        # aout = self.out_ch

        x = self.conv(x)
        x = self.bn(x)
        x = self.act_layer(x)

        return x

class Dila_PRM(nn.Module):
    def __init__(self,in_embed,out_embed,kernel_size=4,downsample_ratio=1,dilations=[2,4,6],
                 fusion='cat'):
        super().__init__()

        self.dilations = dilations
        self.in_embed = in_embed
        # self.in_embeds=[self.in_embed,self.in_embed//2,self.in_embed//4]
        # self.out_embeds=[self.in_embed,self.in_embed//2,self.in_embed//4]
        self.out_embed = out_embed
        self.fusion = fusion
        self.kernel_size = kernel_size
        self.stride = downsample_ratio
        #self.out_size = img_size//downsample_ratio

        self.convs = nn.ModuleList(
            [
                nn.Sequential(
                    nn.Conv2d(
                        in_channels=self.in_embed,
                        out_channels=self.in_embed,
                        kernel_size=self.kernel_size,
                        stride=self.stride,
                        # padding=math.ceil(((self.kernel_size-1)*self.dilations[idx] + 1 - self.stride) / 2),
                        padding=math.ceil(((self.kernel_size-1)*self.dilations[idx])/2),
                        dilation=self.dilations[idx]),
                    # nn.BatchNorm2d(self.in_embed),
                    nn.GELU()
                ) for idx in range(len(self.dilations))
            ]
        )

        if self.fusion == 'cat':
            self.outchans = self.in_embed * len(self.dilations)
            '''这里可以改一改，不同尺度的特征维度尽量少'''
            #self.aggerate = Conv2d_BN(self.in_embed*len(self.dilations),self.in_embed,act_layer=nn.Hardswish)
            self.aggerate = Conv2d_BN(self.in_embed*len(self.dilations),self.out_embed,act_layer=nn.Hardswish)

    def forward(self,x):
        B,C,H,W = x.shape   #1,3,320,320

        out = self.convs[0](x).unsqueeze(dim=-1)
        for i in range(1,len(self.dilations)):
            cur_out = self.convs[i](x).unsqueeze(dim=-1)

            out = torch.cat((cur_out,out),dim=-1)

        B, C, W, H, N = out.shape
        #cur_size = (W,H)
        if self.fusion=='cat':
            out = out.permute(0,4,1,2,3).reshape(B,N*C,W,H)
            out = self.aggerate(out)
            # out = out.flatten(2).transpose(1,2) #B,N,C

        return out


def solution(box):
    maxBox = max(box)
    if maxBox == box[0]:
        return box[0]
    start, end = 0, maxBox
    answer = maxBox
    while start <= end:
        mid = (start + end) // 2

        crit = 0
        for b in box:
            crit += b - mid
            if crit > 0:
                start = mid + 1
                break

        if crit <= 0: #
            end = mid - 1
            answer = min(answer, mid)

        else:
            start = mid + 1

    return answer

print(solution([500, 999, 400]))

프로그래머스 문제/파이썬/2022 카카오 채용연계형 겨울 테크 인턴십 코딩테스트/3.py


from random import randint

de = randint(1,6)
print(de)

secret = randint(0,1000)
for essai in range(10):
    print("Devinez mon nombre secret :")
    nombreSaisi = int(input())
    if nombreSaisi == secret:
        print("Bravo, vous êtes perspicace.")
        break
    else:
        print("Et non, bien tenté.")