<file_sep>"""Window module"""

import time
import tkinter
from typing import Tuple
from boid import Boid
from vector import Vector

HEIGHT = 1000
WIDTH = 1000

class Window:
    """The main window in which the process will be hosted"""
    def __init__(self):
        self.window = tkinter.Tk()
        self.canvas = tkinter.Canvas(self.window, height=HEIGHT, width=WIDTH)
        self.canvas.pack()
        self.last_time = time.monotonic()
        self.boids = []

    def update(self):
        """Event loop body"""
        delta_time = time.monotonic() - self.last_time
        for boid in self.boids:
            #TODO: the rotation is purely part of the boid's internal calculations and needs to be moved out somehow
            # possibly delta_time needs to be moved to the main loop and shared
            boid.rotation += boid.torque * delta_time
            delta = self.bounced_velocity(delta_time, boid)
            boid.x_position += delta[0]
            boid.y_position += delta[1]
            self.canvas.delete(boid.canvas_handle)
            boid.canvas_handle = self.canvas.create_polygon(boid.points())
        self.last_time = time.monotonic()
        self.window.update()

    def unconstrained_velocity(self, delta_time: float, boid: Boid) -> Tuple[float, float]:
        """Returns the x and y movements as they are"""
        delta_x = boid.x_velocity * delta_time
        delta_y = boid.y_velocity * delta_time
        return (delta_x, delta_y)

    def constrained_velocity(self, delta_time: float, boid: Boid) -> Tuple[float, float]:
        """Returns the x and y movements constrained as though the window edges were a wall"""
        delta_x = boid.x_velocity * delta_time
        delta_y = boid.y_velocity * delta_time
        if self.on_border(boid, delta_x, delta_y):
            return (0, 0)
        else:
            return (delta_x, delta_y)

    def bounced_velocity(self, delta_time: float, boid: Boid) -> Tuple[float, float]:
        """Returns the x and y movements, if these would take the boid outside of the window
        boundary then (0, 0) is returned and the boid is rotated 180 degrees"""
        delta_x = boid.x_velocity * delta_time
        delta_y = boid.y_velocity * delta_time
        if self.on_border(boid, delta_x, delta_y):
            boid.rotation += 3.14
            return (0, 0)
        else:
            return (delta_x, delta_y)

    def reflected_velocity(self, delta_time: float, boid: Boid) -> Tuple[float, float]:
        """Returns the x and y movements, if these would take the boid outside of the window
        boundary then (0, 0) is returned and the velocity is reflected"""
        x_velocity = boid.x_velocity
        y_velocity = boid.y_velocity
        delta_x = x_velocity * delta_time
        delta_y = y_velocity * delta_time
        if self.on_border(boid, delta_x, delta_y):
            if self.on_vertical_border(boid, delta_y):
                x_velocity = -x_velocity
            if self.on_horizontal_border(boid, delta_x):
                y_velocity = -y_velocity
            rotation = Vector(x_velocity, y_velocity).rotation_normalized() * 3.14
            if x_velocity < 0:
                boid.rotation = rotation
            else:
                boid.rotation = -rotation
            return (0, 0)
        else:
            return (delta_x, delta_y)

    def on_border(self, boid: Boid, delta_x: float, delta_y: float) -> bool:
        """Return true if the movement would take the boid outside of the boundary of the window"""
        return (delta_x > 0 and boid.x_position >= WIDTH or delta_x < 0 and boid.x_position < 0 or  
                delta_y > 0 and boid.y_position >= HEIGHT or delta_y < 0 and boid.y_position < 0)

    def on_vertical_border(self, boid: Boid, delta_y: float) -> bool:
        """Return true if the movement would take the boid out of the top or bottom border"""
        return delta_y > 0 and boid.y_position >= HEIGHT or delta_y < 0 and boid.y_position < 0

    def on_horizontal_border(self, boid: Boid, delta_x: float) -> bool:
        """Return true if the movement would take the boid out of the left or right border"""
        return delta_x > 0 and boid.x_position >= WIDTH or delta_x < 0 and boid.x_position < 0

    def add_boid(self, boid: Boid):
        """Add a boid to the canvas"""
        boid.canvas_handle = self.canvas.create_polygon(boid.points())
        self.boids.append(boid)
<file_sep>import time
import tkinter

window = tkinter.Tk()
canvas = tkinter.Canvas(window, height=1000, width=1000)
canvas.pack()

bottom_y = 600
triangle = canvas.create_polygon(400, 400, 600, 400, 500, 600)

for i in range(1, 200):
    window.update()
    bottom_y += 1
    canvas.delete(triangle)
    triangle = canvas.create_polygon(400, 400, 600, 400, 500, bottom_y)
    time.sleep(0.1)
<file_sep>from vector import Vector

vector = Vector(0, -1)
print(vector.rotation_normalized())
vector = Vector(0, 1)
print(vector.rotation_normalized())
vector = Vector(1, 0)
print(vector.rotation_normalized())
vector = Vector(-1, 0)
print(vector.rotation_normalized())
vector = Vector(4, 1)
print(vector.rotation_normalized())<file_sep>import tkinter
import time
top = tkinter.Tk()
canvas = tkinter.Canvas(top, bg = 'grey', height = 1000, width = 1000)
canvas.pack()

coords = 10,50,240,210
arc = canvas.create_arc(coords, start = 0, extent = 150, fill = 'red')

while True:
    #time.sleep(1)
    canvas.move(arc, 10, 0)
    top.update()
#top.mainloop()<file_sep>import time

clock = time.monotonic()
print(clock)

time.sleep(5)

clock = time.monotonic()
print(clock)<file_sep>"""
Boids module
The three critical rules governing boid behaviour are
1. Separation: Steer away from individual boids
2. Alignment: Steer in a similar direction of local boids
3. Cohesion: Steer toward the center of mass of local boids
"""
from typing import List
from vector import Vector

TRIANGLE_POINTS = (Vector(0, -5), Vector(5, 5), Vector(-5, 5))
VISION_ANGLE = -0.6
SPEED = 50

class Boid:
    """Simple Automaton"""
    def __init__(self, radius: float, vision_radius: float,
                 x_position: float, y_position: float, rotation: float):
        self.radius = radius
        self.vision_radius = vision_radius
        self.vision_radius_squared = vision_radius ** 2
        self.x_position = x_position
        self.y_position = y_position
        self.rotation = rotation
        self.torque = 0
        self.x_velocity = 0
        self.y_velocity = 0

    def bounding_box(self) -> tuple:
        """OBSOLETE: The boid is now represented by a triangle
        Returns the x,y coords of the top-left and bottom right corners of the bounding box"""
        upper_left_x = self.x_position - self.radius
        upper_left_y = self.y_position + self.radius
        bottom_right_x = self.x_position + self.radius
        bottom_right_y = self.y_position - self.radius
        return (upper_left_x, upper_left_y, bottom_right_x, bottom_right_y)

    def points(self) -> tuple:
        points = []
        for point in TRIANGLE_POINTS:
            rotated_point = point.rotate(self.rotation)
            points.append(rotated_point.x_val + self.x_position)
            points.append(rotated_point.y_val + self.y_position)
        return tuple(points)

    def update(self, boids: List['Boid']):
        """Adjusts the boid's velocity depending on neighbouring boids"""
        local_boids = self.find_neighbouring_boids(boids)
        direction = Vector(0, -1).rotate(self.rotation)
        self.x_velocity = direction.x_val * SPEED
        self.y_velocity = direction.y_val * SPEED
        if local_boids.__len__() == 0:
            self.torque = 0
            return
        separation = self.separation_velocity(local_boids).rotate(-self.rotation)
        alignment = self.alignment_velocity(local_boids).rotate(-self.rotation)
        cohesion = self.cohesion_velocity(local_boids).rotate(-self.rotation)
        total_rotation = (separation + alignment + cohesion).normalized()
        if total_rotation.x_val < 0:
            self.torque = -total_rotation.rotation_normalized()
        else:
            self.torque = total_rotation.rotation_normalized()

    def velocity(self) -> Vector:
        return Vector(self.x_velocity, self.y_velocity)

    def separation_velocity(self, local_boids: List['Boid']) -> Vector:
        """Calculates the velocity to avoid local boids"""
        locals_to_self_x = 0
        locals_to_self_y = 0
        for boid in local_boids:
            locals_to_self_x += self.x_position - boid.x_position
            locals_to_self_y += self.y_position - boid.y_position
        return Vector(locals_to_self_x, locals_to_self_y).normalized()

    def alignment_velocity(self, local_boids: List['Boid']) -> Vector:
        """Calculates the average velocity of all local boids"""
        local_velocity_x = 0
        local_velocity_y = 0
        for boid in local_boids:
            local_velocity_x += boid.x_velocity
            local_velocity_y += boid.y_velocity
        return Vector(local_velocity_x, local_velocity_y).normalized()

    def cohesion_velocity(self, local_boids: List['Boid']) -> Vector:
        """Calculates the direction towards the center of mass of all local boids"""
        position_x = 0
        position_y = 0
        boid_count = local_boids.__len__()
        for boid in local_boids:
            position_x += boid.x_position
            position_y += boid.y_position
        position_x /= boid_count
        position_y /= boid_count
        return Vector(position_x - self.x_position, position_y - self.y_position).normalized()

    def find_neighbouring_boids(self, boids: List['Boid']) -> List['Boid']:
        """Find all boids within the self's range of vision"""
        local_boids = []
        for boid in boids:
            if boid == self:
                continue
            if (self.in_range(boid.x_position, boid.y_position) and
                    not self.in_blind_spot(boid.x_position, boid.y_position)):
                local_boids.append(boid)
        return local_boids

    def in_range(self, x_val: float, y_val: float) -> bool:
        """Return true if the position is within the vision range"""
        distance_squared = (self.x_position - x_val) ** 2
        distance_squared += (self.y_position - y_val) ** 2
        return distance_squared <= self.vision_radius_squared

    def in_blind_spot(self, x_val: float, y_val: float) -> bool:
        """Return true if the position is in the boids blind spot"""
        self_to_boid = Vector(x_val - self.x_position, y_val - self.y_position).rotate(self.rotation)
        rotation = self_to_boid.rotation()
        return rotation < VISION_ANGLE
<file_sep>"""Program entry point"""

import random
import typing
from boid import Boid
import window

FLOCK = typing.List[Boid]
ITERATIONS = 0

def random_flock(size: int) -> FLOCK:
    flock: FLOCK = []
    rng = random.Random()
    for i in range(size):
        x_pos = rng.randrange(100, 900)
        y_pos = rng.randrange(100, 900)
        rot = (rng.random() -0.5) * 3.14
        flock.append(Boid(5, 100, x_pos, y_pos, rot))
    return flock

window = window.Window()
# flock: FLOCK = [
#     Boid(5, 100, 500, 500, 3.14),
#     #Boid(5, 100, 550, 500, 0)
#     #Boid(5, 100, 550, 500, 1.5),
#     #Boid(5, 100, 480, 500, -1.5),
#     #Boid(5, 100, 500, 520, 3.14),
#     #Boid(5, 100, 500, 430, 3.14)
# ]

#flock[0].torque = 1.5

flock = random_flock(100)

for boid in flock:
    window.add_boid(boid)

while True:
    for boid in flock:
        boid.update(flock)
    window.update()
    ITERATIONS += 1
    print(ITERATIONS)
<file_sep>"""Vector module"""
from math import sqrt, sin, cos

class Vector:
    """2D Vector with operations useful to the program"""
    def __init__(self, x: float, y: float):
        self.x_val = x
        self.y_val = y

    def __add__(self, other: 'Vector'):
        return Vector(self.x_val + other.x_val, self.y_val + other.y_val)

    def __sub__(self, other: 'Vector'):
        return Vector(self.x_val - other.x_val, self.y_val - other.y_val)

    def __mul__(self, other: float):
        return Vector(self.x_val * other, self.y_val * other)

    def negative(self) -> 'Vector':
        return Vector(-self.x_val, -self.y_val)

    def magnitude(self) -> float:
        return sqrt(self.x_val ** 2 + self.y_val ** 2)

    def normalized(self) -> 'Vector':
        if self.x_val == 0 and self.y_val == 0:
            return Vector(0, 0)
        magnitude = self.magnitude()
        return Vector(self.x_val / magnitude, self.y_val / magnitude)

    def rotate(self, rotation: float) -> 'Vector':
        """Rotate the vector counter-clockwise by the rotation specified in radians"""
        x_val = self.x_val * cos(rotation) - self.y_val * sin(rotation)
        y_val = self.x_val * sin(rotation) + self.y_val * cos(rotation)
        return Vector(x_val, y_val)

    def rotation(self) -> float:
        """Calculates the cosine of the angle of the vector from (0, 1),
        a vector of (0, 0) will return 0"""
        #Method: Simplification of the dot product where vector b = (0, 1) becomes
        if self.x_val == 0 and self.y_val == 0:
            return 0
        return self.y_val / self.magnitude()

    def rotation_normalized(self) -> float:
        """Calculates the cosine as above and then normalises it from (1, -1) to (0, 1)"""
        cos_val = self.rotation()
        return (-cos_val + 1) / 2

    def str(self) -> str:
        return '(' + str(self.x_val) + ', ' + str(self.y_val) + ')'
<file_sep>import threading
import time

class Proclaimer (threading.Thread):
    def __init__(self, proclamation):
        self.proclamation = proclamation
        threading.Thread.__init__(self)
    def run(self):
        proclaim_eternally(self.proclamation)

def proclaim(proclamation):
    """Proclaim"""
    world_list = []
    for word in proclamation.split(' '):
        world_list.append(word.capitalize())
    print(' '.join(world_list) + '!')

def proclaim_eternally(proclamation):
    """Proclaim Eternally(every two seconds)"""
    while True:
        proclaim(proclamation)
        time.sleep(2)

one = Proclaimer('praise kek')
two = Proclaimer('sieg heil')
three = Proclaimer('hail satan')
four = Proclaimer('maga')
five = Proclaimer('long live the king')

one.start()
two.start()
three.start()
four.start()
five.start()<file_sep>def double(number):
    return number * 2

capitalise = lambda word: word.capitalize()

print(capitalise('SOMETHING SOMETHING'))