<file_sep>from GrandStand import GrandStand
from BoxStand import BoxStand
from TelescopicStand import TelescopicStand
from Pods import Pod

class Coliseum():
    
    def __init__(self, name):
        self.name = name
        self.stands = list() # A list of all stands inside the coliseum

    def get_name(self):
        """This method will return the name."""
        return self.name

    def set_name(self, name):
        """This method will change the name."""
        self.name = name

    def get_stands(self):
        """This method will return the list of stands inside the coliseum."""
        return self.stands
    
    def show_stands(self):
        """This will show all stands in the stands list."""

        for i in self.stands:
            print(i.name)
            i.show_pods()

    def add_stand_to_coliseum(self, stand):
        """This method will add a new stand inside the colisum list of stands."""
        self.stands.append(stand)

    def remove_stand_of_coliseum(self, stand_id):
        """This method will remove stand from stands list that contain all the stands objects. The parameter should be the pods id."""
        found_stand = False

        # Loop through each stand in our stands list.
        for i in self.stands:

            # If we find them, remove them from the list.
            if i.id == stand_id:
                self.stands.remove(i)
                # set our indicator to True
                found_stand = True
       
        # If we looped through our list and did not find our stand, the indicator would never get change, so return 'Pod not found!'
        if not found_stand:
            print(f'Stand not found!')



if __name__ == "__main__":

    # Create a Coliseum that will have three Stands and each
    # of them will have some pods

    # Coliseum
    coliseum_humacao = Coliseum('Coliseum of Multiple Uses from Humacao')

    # Stands
    lateral_grand_stand_west = GrandStand('Lateral Grand Stand - West', 42, 17, 3)
    lateral_grand_stand_east = GrandStand('Lateral Grand Stand - East', 42, 17, 3)
    telescopic_stand_bottom = TelescopicStand('Telescopic Stand - South', 28, 11, 2)

    # Pods
    lateral_grand_stand_west.create_pod()
    lateral_grand_stand_west.create_pod()
    lateral_grand_stand_west.create_pod()

    lateral_grand_stand_east.create_pod()
    lateral_grand_stand_east.create_pod()
    lateral_grand_stand_east.create_pod()

    telescopic_stand_bottom.create_pod()
    telescopic_stand_bottom.create_pod()
    telescopic_stand_bottom.create_pod()

    # Cheking for pods...
    # print(f'{lateral_grand_stand_west.get_name()}')
    # lateral_grand_stand_west.show_pods()
    # print(f'{lateral_grand_stand_east.get_name()}')
    # lateral_grand_stand_east.show_pods()
    # print(f'{telescopic_stand_bottom.get_name()}')
    # telescopic_stand_bottom.show_pods()

    # Adding stands to stadium
    coliseum_humacao.add_stand_to_coliseum(lateral_grand_stand_west)
    coliseum_humacao.add_stand_to_coliseum(lateral_grand_stand_east)
    coliseum_humacao.add_stand_to_coliseum(telescopic_stand_bottom)

    # Cheking of what the stadium is made of
    coliseum_humacao.show_stands()<file_sep>import numpy
import math
import helper_module


class Pod():
    """This class will create seats for people to sit down. Those seats are going to be called 'Pods'."""

    def __init__(self, row, column):
        """This constructur will create and store the attribute for a pod."""

        self.pod = self.create_pod(row, column)
        self.id = helper_module.generate_id()

    def show_pod(self):
        """This will display this pod."""

        print(self.pod)

    def create_pod(self, pod_row, pod_column):
        """It takes in two integer values; the number of rows and columns for the desire pod. Returns a matrix which have '0' where avaiable seats are and '2' where buffer seats are.'"""

        # Creating a matrix that represent the seats on a pod
        pod = numpy.zeros(shape=(pod_row, pod_column), dtype=int)

        # Total available rows in the pod where people can sit. It round the value to the greatest integer.
        total_avaliable_rows = math.ceil(pod_row/3)

        # Here it will be save the a row that will represent a buffer marker. A buffer marker is important because it will denote where a two buffer rows will start.
        buffer_row_marker = list()
        # Here it will be store in a list the actual number of the rows people can sit in the pot.
        actual_rows_people_sit = list()

        # This for loop will run the amount of total avaliable rows and each time it will store a row that represent a buffer marker to one list and the actual rows people can sit in the other list.
        # The 3*row represent sequence jump.
        # The specific reason why the jump is 3*row is because the distance from where the person sit and the next person sits is a little bit over the 6ft. recommended for social distance.
        # Each seat is 20in the leg room is also 20in so with two rows in between that adds up to eight feet and four inches. A row less and it will be just 5 feets.
        # ***THE VALUES HERE FOR THE ROW ARE THE INDEXES. STARTING FROM 0.***
        for row in range(total_avaliable_rows):
            # The plus 1 is because the first row is always going to be avaliable. 
            buffer_row_marker.append(1+(3*row))
            actual_rows_people_sit.append(3*row)

        # Changing the values from zero to 2's for the Buffer Rows
        for row in buffer_row_marker:
            for column in range(pod_column):

                # This run in the special case where the program can't add two buffer rows because there is just one row left.
                # The minus one is because the pod_row represent the actual number of rows. Meaning it doesn't represent the index. 
                if row == pod_row-1: 
                    pod[row][column] = 2

                # This run in the special case where the program can't add two buffer rows because there is no row left.
                # The break is to ignore adding the buffer rows and jump outside the elif and for loop.
                elif row == pod_row:
                    break

                # This run for everytime there is two rows that can be set as buffers.
                else:
                    pod[row][column] = 2
                    pod[row+1][column] = 2

        return pod

    def sitting_people(self, amount_people_sitting):
        """This function will deside where to sit people on the pod. The amount of people is an integer and the pod needs to be an object type matrix. After seatting everyone it will set some buffer seats for social distance."""



        # Finding the rows people can actually sit.
        total_avaliable_rows = math.ceil(len(self.pod)/3)
        actual_rows_people_sit = list()
        for row in range(total_avaliable_rows):
            actual_rows_people_sit.append(3*row)
        
        # Finding the amount of rows and columns the pod have.
        pod_num_column = len(self.pod[0]) 

        # Creating a variable that is goint to be use to know how many sits the row have left to allow some desition making.
        seats_left = pod_num_column

        # There is a social distance recommended by the CDC of 6 feets, considering that each seat is 20x20 inches and each
        # seat are side by side to satisfy this recommendation we need at least four seats in between the groups.
        social_distance_buffer_seats = 4

        # The reason why I went with this function is to have the ability of stopping all loops after sitting everyone. Break didn't work as intended and had to refactor the code.
        pod = self.sitting_logistic(amount_people_sitting, self.pod, actual_rows_people_sit, seats_left, social_distance_buffer_seats)

        self.pod = pod   

        return pod
 
    def sitting_logistic(self, amount_people_sitting, pod, actual_rows_people_sit, seats_left, social_distance_buffer_seats): 
        """This function is the one that is going to decide where to sit everyone."""

        for row in actual_rows_people_sit: # This goes through all rows people can sit.
            
            avaliable_seats_row = self.get_avaliable_seats_row(pod[row])
            occupied_seats = self.get_occupied_seats_row(pod[row])
            buffer_seats = self.get_buffer_seats_row(pod[row])
            avaliable_seats_pod = self.get_seats_avaliable_pod()

            # If avaliable seats are enough for the amount of people sitting and the buffer seats this will run.
            if avaliable_seats_row >= (amount_people_sitting + social_distance_buffer_seats):
                # This will run over each avaliable seat and change the value to represent is ocuppied '1' and to next amount of social_distance_buffer_seats as buffer seats '2'
                if pod[row][0] == 0: # This will mean the row is empty

                    # Loop over as many times needed to sit everyone using the avaliable_seat value as an index.
                    self.sit_people_empty_row(pod, row, amount_people_sitting)

                    # Loop over as many times needed to satisfy the social distance buffer seats amount.           
                    self.set_buffer_seat_empty_row(social_distance_buffer_seats, amount_people_sitting, pod, row)

                # This run when the row is not empty
                else: 

                    # Loop over as many times needed to sit everyone using the avaliable_seat value as an index.                  
                    self.sit_people_row(pod, row, occupied_seats,buffer_seats, amount_people_sitting)

                    # Updating the new ocuppied seats that have been set in the function from above.
                    occupied_seats += amount_people_sitting
                    
                    # Loop over as many times needed to satisfy the social distance buffer seats amount.
                    self.set_buffer_seat(social_distance_buffer_seats, occupied_seats, buffer_seats, pod,row)

                return pod

            # This will run when the avaliable sit are less than the people seatting plus the buffer seats.
            else:
                # This code cover the case when the people trying to sit get to the edge of the pod. The buffer seats will be ommited because the stair will work as the buffer.
                if avaliable_seats_row == amount_people_sitting:

                    # This run when the row is empty.
                    if pod[row][0] == 0:
                        self.sit_people_empty_row(pod, row, amount_people_sitting)

                        return pod

                    # This run where the row is not empty.
                    else:
                        self.sit_people_row(pod, row, occupied_seats, buffer_seats, amount_people_sitting)

                        return pod

                # This will run when there are not enough seats in the row but the amount people that want to be seated is less or equal that the actual seats in the whole row.
                elif avaliable_seats_row < amount_people_sitting and amount_people_sitting <= len(pod[0]):
                    # This will run when the pod is full. Meaning the group is to big for the avaliable seats.
                    if amount_people_sitting > avaliable_seats_pod:
                        print(f'The pod is full. This last group of {amount_people_sitting} can\'t be seated to big for the avaliable seats.')

                        return self.pod

                    # This code will run when there are no more row left to seat people. Is going to update that there is not enough space.
                    if (pod[row] == self.pod[-2]).all():
                        print('This group is to large for the amount of seats in any of the rows.')
                        print(f'There is still {avaliable_seats_pod} seats scatter through the pod but there is no {amount_people_sitting}\nseats side by side empty.')

                        return self.pod


                    # This pass will allow the program to jump for the next row and check for avaliable seats.
                    pass

                # This will run if the people that want to be seatted is larger that actual row length.
                elif amount_people_sitting > len(pod[0]):
                    print(f'The amount of people to be seatted is larger than the actual row.')
                    return pod
                
                # This will run when less than the actual amount for the social distance buffer seats are needed. 
                else: 
                    seats_left = self.get_avaliable_seats_row(pod[row])

                    # This statement will verify if the difference of the seat left and the people who want to sit is a positive number. The value that this difference will give back is the amount of buffer seats that are needed.
                    if (seats_left - amount_people_sitting) > 0:
                        # Seating people
                        self.sit_people_row(pod, row, occupied_seats, buffer_seats, amount_people_sitting)

                        # Updating the new ocuppied seats that have been set in the function from above.
                        occupied_seats += amount_people_sitting

                        # Calculating how many buffers are needed and then setting the seats as buffers.
                        buffer_seats_needed = seats_left - amount_people_sitting
                        self.set_buffer_seat(buffer_seats_needed, occupied_seats, buffer_seats, pod, row)

                        return pod

    def sitting_people_from_terminal(self, amount_people_sitting, terminal):
        """This function will deside where to sit people on the pod. The amount of people is an integer and the pod needs to be an object type matrix. After seatting everyone it will set some buffer seats for social distance."""



        # Finding the rows people can actually sit.
        total_avaliable_rows = math.ceil(len(self.pod)/3)
        actual_rows_people_sit = list()
        for row in range(total_avaliable_rows):
            actual_rows_people_sit.append(3*row)
        
        # Finding the amount of rows and columns the pod have.
        pod_num_column = len(self.pod[0]) 

        # Creating a variable that is goint to be use to know how many sits the row have left to allow some desition making.
        seats_left = pod_num_column

        # There is a social distance recommended by the CDC of 6 feets, considering that each seat is 20x20 inches and each
        # seat are side by side to satisfy this recommendation we need at least four seats in between the groups.
        social_distance_buffer_seats = 4

        # The reason why I went with this function is to have the ability of stopping all loops after sitting everyone. Break didn't work as intended and had to refactor the code.
        response = self.sitting_logistic_from_terminal(amount_people_sitting, self.pod, actual_rows_people_sit, seats_left, social_distance_buffer_seats, terminal)

        if response is None:
            pass
            
        else:
            self.pod = response   

    def sitting_logistic_from_terminal(self, amount_people_sitting, pod, actual_rows_people_sit, seats_left, social_distance_buffer_seats, terminal): 
        """This function is the one that is going to decide where to sit everyone."""

        for row in actual_rows_people_sit: # This goes through all rows people can sit.
            
            avaliable_seats_row = self.get_avaliable_seats_row(pod[row])
            occupied_seats = self.get_occupied_seats_row(pod[row])
            buffer_seats = self.get_buffer_seats_row(pod[row])
            avaliable_seats_pod = self.get_seats_avaliable_pod()

            # If avaliable seats are enough for the amount of people sitting and the buffer seats this will run.
            if avaliable_seats_row >= (amount_people_sitting + social_distance_buffer_seats):
                # This will run over each avaliable seat and change the value to represent is ocuppied '1' and to next amount of social_distance_buffer_seats as buffer seats '2'
                if pod[row][0] == 0: # This will mean the row is empty

                    # Loop over as many times needed to sit everyone using the avaliable_seat value as an index.
                    self.sit_people_empty_row(pod, row, amount_people_sitting)

                    # Loop over as many times needed to satisfy the social distance buffer seats amount.           
                    self.set_buffer_seat_empty_row(social_distance_buffer_seats, amount_people_sitting, pod, row)

                # This run when the row is not empty
                else: 

                    # Loop over as many times needed to sit everyone using the avaliable_seat value as an index.                  
                    self.sit_people_row(pod, row, occupied_seats,buffer_seats, amount_people_sitting)

                    # Updating the new ocuppied seats that have been set in the function from above.
                    occupied_seats += amount_people_sitting
                    
                    # Loop over as many times needed to satisfy the social distance buffer seats amount.
                    self.set_buffer_seat(social_distance_buffer_seats, occupied_seats, buffer_seats, pod,row)

                return pod

            # This will run when the avaliable sit are less than the people seatting plus the buffer seats.
            else:
                # This code cover the case when the people trying to sit get to the edge of the pod. The buffer seats will be ommited because the stair will work as the buffer.
                if avaliable_seats_row == amount_people_sitting:

                    # This run when the row is empty.
                    if pod[row][0] == 0:
                        self.sit_people_empty_row(pod, row, amount_people_sitting)

                        return pod

                    # This run where the row is not empty.
                    else:
                        self.sit_people_row(pod, row, occupied_seats, buffer_seats, amount_people_sitting)

                        return pod

                # This will run when there are not enough seats in the row but the amount people that want to be seated is less or equal that the actual seats in the whole row.
                elif avaliable_seats_row < amount_people_sitting and amount_people_sitting <= len(pod[0]):
                    # This will run when the pod is full. Meaning the group is to big for the avaliable seats.
                    if amount_people_sitting > avaliable_seats_pod:
                        #print(f'The pod is full. This last group of {amount_people_sitting} can\'t be seated to big for the avaliable seats.')
                        
                        terminal.jump_to_next_pod = True

                        return 

                    # This code will run when there are no more row left to seat people. Is going to update that there is not enough space.
                    if (pod[row] == self.pod[-2]).all():
                        #print('This group is to large for the amount of seats in any of the rows.')
                        #print(f'There is still {avaliable_seats_pod} seats scatter through the pod but there is no {amount_people_sitting}\nseats side by side empty.')

                        terminal.jump_to_next_pod = True

                        return 


                    # This pass will allow the program to jump for the next row and check for avaliable seats.
                    pass

                # This will run if the people that want to be seatted is larger that actual row length.
                elif amount_people_sitting > len(pod[0]):
                    #print(f'The amount of people to be seatted is larger than the actual row.')
                    return pod # PUEDES DEVOLVER QUE BRINQUE A LA PROXIMA SECCION  terminal.jump_to_next_pod = True
                
                # This will run when less than the actual amount for the social distance buffer seats are needed. 
                else: 
                    seats_left = self.get_avaliable_seats_row(pod[row])

                    # This statement will verify if the difference of the seat left and the people who want to sit is a positive number. The value that this difference will give back is the amount of buffer seats that are needed.
                    if (seats_left - amount_people_sitting) > 0:
                        # Seating people
                        self.sit_people_row(pod, row, occupied_seats, buffer_seats, amount_people_sitting)

                        # Updating the new ocuppied seats that have been set in the function from above.
                        occupied_seats += amount_people_sitting

                        # Calculating how many buffers are needed and then setting the seats as buffers.
                        buffer_seats_needed = seats_left - amount_people_sitting
                        self.set_buffer_seat(buffer_seats_needed, occupied_seats, buffer_seats, pod, row)

                        return pod

    def get_id(self):
        """This method will return the id number."""
        return self.id

    def set_buffer_seat_empty_row(self, num_buffer_seats, amount_people_sitting, pod, row):
        """This function will set buffer seats as meany times passed for an empty row."""

        for i in range(num_buffer_seats): 
            # buffer_seat_index will start at the next seat after everyone is seated instead of starting at zero
            buffer_seat_index = amount_people_sitting + i 
            pod[row][buffer_seat_index] = 2

    def set_buffer_seat(self, num_buffer_seats, occupied_seats, buffer_seats, pod, row):
        """This function will set buffer seats as meany times passed for rows that are not empty."""

        for i in range(num_buffer_seats):
            # This seat_skip function like the one before. Is a jump to start on the next seat after the occupied and buffer seats.
            seat_skip = occupied_seats + buffer_seats
            buffer_seat_index = seat_skip + i
            pod[row][buffer_seat_index] = 2

    def sit_people_empty_row(self, pod, row, amount_people_sitting):
        """This function will sit people on an empty row."""

        # Loop over as many times needed to sit everyone using the avaliable_seat value as an index.
        for avaliable_seat in range(amount_people_sitting): 
            pod[row][avaliable_seat] = 1
        
        return pod

    def sit_people_row(self, pod, row, occupied_seats, buffer_seats, amount_people_sitting):
        """This function will sit people on the rows which are not already empty."""

        for avaliable_seat in range(amount_people_sitting):
            # This seat_skip is because we are not on an empty row so we have to account for the seats already taken and the ones that functions as buffers.
            seat_skip = occupied_seats + buffer_seats
            pod[row][seat_skip+avaliable_seat] = 1

    def get_seats_avaliable_pod(self):
        """This function return the amount of seats left in the entire pod."""

        # Finding the rows people can actually sit.
        total_avaliable_rows = math.ceil(len(self.pod)/3)
        actual_rows_people_sit = list()
        for row in range(total_avaliable_rows):
            actual_rows_people_sit.append(3*row)
            
        # Looking inside each row where people can actually sit and see the amount of places people can sit..
        avaliable_seats = 0
        for row in actual_rows_people_sit:
            for seat in self.pod[row]:
                if seat == 0:
                    avaliable_seats += 1
        
        return avaliable_seats

    def get_seats_occupied_pod(self):
        """This function return the amount of seats occupied in the entire pod."""

        # Finding the rows people can actually sit.
        total_avaliable_rows = math.ceil(len(self.pod)/3)
        actual_rows_people_sit = list()
        for row in range(total_avaliable_rows):
            actual_rows_people_sit.append(3*row) 

        # Looking inside each row where people can actually sit and see the amount of places people can sit..
        occupied_seats = 0
        for row in actual_rows_people_sit:
            for seat in self.pod[row]:
                if seat == 1: # People are seated there.
                    occupied_seats += 1
                if seat == 2: # This are seats that are buffer seats.
                    occupied_seats += 1
        
        return occupied_seats

    def get_people_on_seats(self):
        """This method will return the amount of people seated in the pod."""

        # Finding the rows people can actually sit.
        total_avaliable_rows = math.ceil(len(self.pod)/3)
        actual_rows_people_sit = list()
        for row in range(total_avaliable_rows):
            actual_rows_people_sit.append(3*row) 

        # Looking inside each row where people can actually sit and see the amount of places people can sit..
        people_seated = 0
        for row in actual_rows_people_sit:
            for seat in self.pod[row]:
                if seat == 1: # People are seated there.
                    people_seated += 1
        
        return people_seated

    def get_buffer_seats_pod(self):
        """This method will return the buffer seats in the entire pod but just the ones inside the rows people can sit."""

        # Finding the rows people can actually sit.
        total_avaliable_rows = math.ceil(len(self.pod)/3)
        actual_rows_people_sit = list()
        for row in range(total_avaliable_rows):
            actual_rows_people_sit.append(3*row) 

        # Looking inside each row where people can actually sit and see the amount of places people can sit..
        buffer_seats = 0
        for row in actual_rows_people_sit:
            for seat in self.pod[row]:
                if seat == 2: # This are seats that are buffer seats.
                    buffer_seats += 1
        
        return buffer_seats

    def get_total_buffer_seats_pod(self):
        """This method will return the value of buffer seats includding the rows that are mark as buffers."""

        # Looking inside each row where people can actually sit and see the amount of places people can sit..
        buffer_seats = 0
        for row in range(len(self.pod)):
            for seat in self.pod[row]:
                if seat == 2: # This are seats that are buffer seats.
                    buffer_seats += 1
        
        return buffer_seats 

    def get_total_seat_capacity_pod(self):
        """This method will return the amount of seats in the pod. Independently if they are occupied."""

        # Looking inside each row where people can actually sit and see the amount of places people can sit..
        seat_capacity = 0
        for row in range(len(self.pod)):
            for seat in self.pod[row]:
                if seat == 0: # This are seats that are empty seats.
                    seat_capacity += 1
                if seat == 1: # This are seats that are taken seats.
                    seat_capacity += 1
                if seat == 2: # This are seats that are buffer seats.
                    seat_capacity += 1
        
        return seat_capacity      

    def get_avaliable_seats_row(self, row):
        """This function will return the amount of avaliable seats in the row. The paramater is a row from the pod."""

        avaliable_seats = 0

        for seat in row:
            # This will add up; every avaliable seat, occupied seat and buffer seat. 
            if seat == 0:
                avaliable_seats += 1

        return avaliable_seats

    def get_occupied_seats_row(self, row):
        """This function will return the amount of occupied seats in the row. The paramater is a row from the pod."""

        occupied_seats = 0

        for seat in row:
            # This will add up; every avaliable seat, occupied seat and buffer seat. 
            if seat == 1:
                occupied_seats += 1

        return occupied_seats

    def get_buffer_seats_row(self, row):
        """This function will return the amount of buffer seats in the row. The paramater is a row from the pod."""

        buffer_seats = 0

        for seat in row:
            # This will add up; every avaliable seat, occupied seat and buffer seat. 
            if seat == 2:
                buffer_seats += 1

        return buffer_seats



if __name__ == '__main__':
    pass    
    # test = numpy.zeros(shape=(10, 10), dtype=int)

    # print(test)
    # print("\t\t\t\t\t" + str(test).replace('\n','\n\t\t\t\t\t'))


    # grand_stand_pod_left = Pod(17,15)

    # grand_stand_pod_left.sitting_people(5)


    # grand_stand_pod_left.show_pod()
    # # print()

    # people = list()
    # for i in range(20):
    #     people.append(i)
    # people.append(5)


    # for i in people:
    #     print()
    #     print(i)
    #     print()

    #     # print('before')
    #     # print(grand_stand_pod_left.pod)
    #     print(grand_stand_pod_left.sitting_people(i))
    #     # print('after')
    #     # print(grand_stand_pod_left.pod)


    # print(len(grand_stand_pod_left.pod))
    # print(grand_stand_pod_left.pod[16])
    # print(grand_stand_pod_left.pod[-1])
    

    # x = numpy.array([[10, 5], [10, 6]])

    # print((x[-1] == x[0]).all())



    # grand_stand_pod_left.show_pod()<file_sep>from abc import ABC
from Pods import Pod
from helper_module import print_newline

class Stand(ABC):

    def __init__(self, name, row, column, num_pods):
        self.name = name
        self.row = row # All the rows that it has with counting different pods
        self.column = column # All the columns
        self.num_pods = num_pods # Quantity of pods wanted for the stand.
        self.pod_rows = row
        self.pod_columns = int(self.column / self.num_pods) 
        self.pods = list() # A list of all pods inside the stand

    def create_pod(self):
        """This method will create and store pods inside the stand list."""
        
        pod = Pod(self.pod_rows, self.pod_columns)
        self.add_pod_to_stand(pod)
        
        return pod

    def get_pods(self):
        """This method will return a list of the pods for this stand."""
        
        return self.pods

    def show_pods(self):
        """This method will show all pods in the pods list."""

        for i in self.pods:
            i.show_pod()  
            print_newline()  

    def get_name(self):
        """This method will return the name."""
        return self.name

    def set_name(self, name):
        """This method will let you change the name."""
        self.name = name

    def get_row(self):
        """This method will return the row number."""
        return self.row

    def set_row(self, row):
        """This method will let you change the row number"""
        self.row = row

    def get_column(self):
        """This method will return the column number."""
        return self.column
 
    def set_column(self, column):
        """This method will let you change the column number"""
        self.row = column

    def get_num_pods(self):
        """This method will return the number of pods in this specific stand."""
        return self.num_pods

    def set_num_pods(self, num_pods):
        """This method will let you change the number of pods in this specific stand."""
        self.num_pods = num_pods

    def add_pod_to_stand(self, pod):
        """This method will add a pod to the stand list that contain all the pods objects."""
        self.pods.append(pod)

    def remove_pod_from_stand(self, pod_id):
        """This method will remove pod from stand list that contain all the pods objects. The parameter should be the pods id."""
        found_pod = False

        # Loop through each pod in our pods list.
        for i in self.pods:

            # If we find them, remove them from the list.
            if i.id == pod_id:
                self.pods.remove(i)
                # set our indicator to True
                found_pod = True
       
        # If we looped through our list and did not find our pod, the indicator would never get change, so return 'Pod not found!'
        if not found_pod:
            print(f'Pod not found!')



if __name__ == "__main__":  
    pass<file_sep>from Stand import Stand

class BoxStand(Stand):
    
    def __init__(self, name, row, column, num_pods):

        super().__init__(name, row, column, num_pods)
        self.stand_category = 'Box Stand'



if __name__ == "__main__":
    pass<file_sep>from Stand import Stand

class TelescopicStand(Stand):
    
    def __init__(self, name, row, column, num_pods):

        super().__init__(name, row, column, num_pods)
        self.stand_category = 'Telescopic Stand'



if __name__ == "__main__":
    pass<file_sep># Assigning Seats COVID

## Table of Content
* [Introduction](#Introduction)
* [Motivation](#Motivation)
* [Implementation](#Implementation)
    * [Assumed measurements](#Assume-measurements)
    * [Classes](#Classes)
* [Illustrations](#Illustrations)
    * [Coliseum](#Coliseum)
    * [Stands](#Stands)
* [Technologies](#Technologies)
* [Project Status](#Project-Status)


## Introduction
The objective of this project is to automate the decision making of sitting people on a coliseum. The catch is that people need to be seated 6 feet apart, as recommended by the World Health Organization (WHO) and the Center of Disease Control and Prevention (CDC). In the case there is a group of people that want to be seated they all are going to be seated together and the next group or person is going to be 6 feet apart.

## Motivation
The motivation came from two places:
* This project was my last assignment of the CS 1.1 - Object Oriented Programming (OOP) class. I had the liberty of choosing anything to work on but I needed to implement an OOP design.
* Little before starting CS 1.1 I was talking with a friend and this idea came of sitting people on a coliseum with 6 feet apart of each other. He don't have the knowledge to program the solution and I just didn't had enough time. Then this opportunity where I can test my skills and also do something meaningful came. So, I took the challenge!

## Implementation
I'm sure there are countless ways to approach this problem, but I went with an Object Oriented Program (OOP) design. There are several classes, that are going to be explain briefly further down, which manipulate different pieces of the program.

To approach the problem I decided that there are going to be what I called buffer rows. This buffer rows just represent individual rows that are not going to be occupied because a distance of 6 feet will be needed. In this project I assume some measurements, shown further down, to complete the project.

From this measurements we can conclude that the buffers rows that are going to be needed are 3. Also, we can conclude that 4 seats are going to be needed to separate one person or group from another in the same row.


### Assumed measurements:
* Seats: 
    * 20x20 inches
* Legroom:
    * 20 inches

### Classes:
* Terminal
    * Manage everything from sitting the people to creating a coliseum, stands or pods. It has also features like getting reports of the entire coliseum.
* Coliseum
    * A Coliseum will have instances of other classes, classes that will represent stands. This is better know as composition. 
* Stand
    * The Stand is an abstract class. An abstract class can't be instantiated. A programmer can only create other classes that inherit from an abstract class and those classes can be instantiate. This class is to honor the DRY principle (Don't Repeat Yourself).
    * Classes that inherit from Stand:
        * BoxStand
        * GrandStand
        * TelescopicStand
* Pods
    * Pods are the name that I choose to give to the group of seats. The way I choose to represent each seat was as matrixes but there is a drawback when the stands in a coliseum are not rectangular or squares. A drawback that I need a solution but for now the code is good enough, just for now.


## Illustrations
### Coliseum
Using this coliseum I model the program and found problems and solutions. As I said before, there are some problems I have to find solutions but as of right now the program can create a coliseum, stands and sit people but the stands have to have a rectangular shape.

<img width="757" alt="Coliseum - Seats Configuration" src="https://user-images.githubusercontent.com/69913812/102847466-50269680-440a-11eb-8712-f9e1aac165b9.png">

### Stands
After creating stands and pods like "Pod #1", in the image below. The program will set some rows as Buffer Rows as seen in "Pod #2". After all this depending on the amount of people that want to be seated together, as a group. The program will seat them and seat the next group with 6 feet apart as seen in "Pod #1".

![Lateral Grand Stand](https://user-images.githubusercontent.com/69913812/102842837-cd98d980-43ff-11eb-9f8f-9b403cca3346.jpg)



## Technologies
* Python 3.8

## Project Status
The project right now is on standby, but I do planned to keep innovating it. 

Add more features like storing the coliseum, report to the person using the terminal the actual seats used to seat the person or group and work with the "irregular" stands, the ones that are not rectangular or square's shape.<file_sep>from random import randint

def generate_id():
    """Helper function that return a eight digit random number which is going to be of type string."""
    id_number = ""
    for _ in range(3):
        id_number += str(randint(0,9))

    return id_number

def print_newline():
    """Helper function that just add a new empty line."""

    print("")<file_sep>from Coliseum import Coliseum
from Stand import Stand
from GrandStand import GrandStand
from BoxStand import BoxStand
from TelescopicStand import TelescopicStand
from Pods import Pod
from helper_module import print_newline

class Terminal():

    def __init__(self, name):   
        self.name = name
        self.jump_to_next_pod = False

    def create_coliseum(self):
        """This method will create a new coliseum and return it. Name must be a string."""
        
        name = input('Whats the name for the Coliseum?\n- ')
        return Coliseum(name)

    def show_coliseum_report(self, coliseum):
        """This method will print and extensive report of the coliseum."""

        quantity_stands = 0
        quantity_pods = 0
        quantitiy_avaliable_seats_people_can_sit_coliseum = 0
        quantity_seats_occupied_coliseum = 0
        quantity_people_seated_coliseum = 0
        quantity_buffer_seats_for_rows_people_sit = 0
        full_seat_coliseum_capacity = 0 # This is the seat capacity for the rows people can actually seat of the whole coliseum. Independently if they are occupied or not.
        buffer_seats_coliseum = 0

        for stand in coliseum.stands:
            quantity_stands += 1
            for pod in stand.pods:
                quantity_pods += 1
                quantitiy_avaliable_seats_people_can_sit_coliseum += pod.get_seats_avaliable_pod()
                quantity_seats_occupied_coliseum += pod.get_seats_occupied_pod()
                quantity_people_seated_coliseum += pod.get_people_on_seats()
                quantity_buffer_seats_for_rows_people_sit += pod.get_buffer_seats_pod() 
                full_seat_coliseum_capacity += pod.get_total_seat_capacity_pod()
                buffer_seats_coliseum += pod.get_total_buffer_seats_pod()

        print(f'The {coliseum.name} have:\n')
        print(f'\tSTANDS:')
        print(f'\t\tQuantity of Stands:\t\t\t\t\t{quantity_stands}\n')
        print(f'\tPODS:')
        print(f'\t\tQuantity of Pods:\t\t\t\t\t{quantity_pods}')
        print(f'\tSEATS:')
        print(f'\t\tColiseum Capacity (Including Buffer Rows):\t\t{full_seat_coliseum_capacity}')
        print(f'\t\tBuffer Seats (Including Buffer Rows):\t\t\t{buffer_seats_coliseum}')
        print(f'\t\tAvaliable Seats:\t\t\t\t\t{quantitiy_avaliable_seats_people_can_sit_coliseum}')
        print(f'\t\tPeople Seated:\t\t\t\t\t\t{quantity_people_seated_coliseum}')
        print(f'\t\tBuffer Seats (Excluding Buffer Rows):\t\t\t{quantity_buffer_seats_for_rows_people_sit}')
        print(f'\t\tOccupied Seats:\t\t\t\t\t\t{quantity_seats_occupied_coliseum}')

    def show_coliseum_layout(self, coliseum):
        """This method will display a more readable layout of the coliseum"""

        quantity_stands = 0

        quantitiy_avaliable_seats_people_can_sit_coliseum = 0
        quantity_seats_occupied_coliseum = 0
        quantity_people_seated_coliseum = 0

        quantity_buffer_seats_for_rows_people_sit = 0 # Buffer Seats (Excluding Buffer Rows)
        buffer_seats_coliseum = 0

        # Collecting Information
        for stand in coliseum.stands:
            quantity_stands += 1
            for pod in stand.pods:
                quantitiy_avaliable_seats_people_can_sit_coliseum += pod.get_seats_avaliable_pod()
                quantity_seats_occupied_coliseum += pod.get_seats_occupied_pod()
                quantity_people_seated_coliseum += pod.get_people_on_seats()
                quantity_buffer_seats_for_rows_people_sit += pod.get_buffer_seats_pod() 
                buffer_seats_coliseum += pod.get_total_buffer_seats_pod()

        # Displaying Information
        print(f'Coliseum: {coliseum.name}')
        print(f'\tStands: {quantity_stands}')
        for stand in coliseum.stands:
            print(f'\t\tCategory: {stand.stand_category}')
            print(f'\t\t\tName: {stand.name}')
            for pod in stand.pods:
                print(f'\t\t\t\tPod Id: {pod.get_id()}')
                print("\t\t\t\t\t" + str(pod.pod).replace('\n','\n\t\t\t\t\t'))

    def seatting_people(self, coliseum, amount_people_sitting):
        """This method will sit people inside the coliseum."""

        for stand in coliseum.stands:
            for pod in stand.pods:

                self.jump_to_next_pod = False

                # Here we are passing the terminal object to manipulate the attribute jump_to_next_pod from inside the method of the Pod type object.
                pod.sitting_people_from_terminal(amount_people_sitting, self)
                
                # In the case the pod was full this value was going to be changed inside sitting_people_from_terminal() and allow the program to move to the next pod.
                if self.jump_to_next_pod == True:
                    pass
                
                else:
                    if amount_people_sitting > 1:
                        print(f'The group of {amount_people_sitting} is seated.')

                    elif amount_people_sitting == 1:
                        print(f'The person was seated.')

                    print_newline()

                    return

        print(f'Is not possible to sit {amount_people_sitting} in the entire coliseum!')

    def create_grand_stand(self):
        """This method will prompt user to create a GrandStand object and return it."""
        
        name = input('Whats the name for the GrandStand?\n- ')
        row = int(input('How many rows the entire stand will have?\n- '))
        column = int(input('How many columns the entire stand will have?\n- '))
        num_pods = int(input('How many pods you want?\n- '))
        return GrandStand(name, row, column, num_pods)

    def create_box_stand(self):
        """This method will promt user to create a BoxStand object and return it."""

        name = input('Whats the name for the BoxStand?\n- ')
        row = int(input('How many rows the entire stand will have?\n- '))
        column = int(input('How many columns the entire stand will have?\n- '))
        num_pods = int(input('How many pods you want?\n- '))
        return BoxStand(name, row, column, num_pods)

    def create_telescopic_stand(self):
        """This method will promt user to create a TelescopicStand object and return it."""

        name = input('Whats the name for the TelescopicStand?\n- ')
        row = int(input('How many rows the entire stand will have?\n- '))
        column = int(input('How many columns the entire stand will have?\n- '))
        num_pods = int(input('How many pods you want?\n- '))
        return TelescopicStand(name, row, column, num_pods)

    def create_pod(self, row, column):
        """This method will create a new pod and return it."""

        # row = int(input('How many rows the Pod will have?\n- '))
        row = row
        # column = int(input('How many column the Pod will have?\n- '))
        column = column
        
        return Pod(row, column)

    def built_coliseum(self):
        """This method will prompt to built an entire coliseum and return it."""

        print(f'Lets built the Coliseum...')
        coliseum = self.create_coliseum()

        print(f'So, now...')
        amount = int(input((f'How many GrandStand you want?\n- ')))
        for _ in range(amount):
            # Creating and appending the grand stand to the coliseum.
            grand_stand = self.create_grand_stand()
            coliseum.add_stand_to_coliseum(grand_stand)

            # Creating and appending the pods to the grand stand.
            amount = grand_stand.num_pods
            for _ in range(amount):
                pod = self.create_pod(grand_stand.pod_rows, grand_stand.pod_columns)
                grand_stand.add_pod_to_stand(pod)    
        
        amount = int(input((f'How many BoxStand you want?\n- ')))
        for _ in range(amount):
            # Creating and appending the box stand to the coliseum.            
            box_stand = self.create_box_stand()
            coliseum.add_stand_to_coliseum(box_stand)

            # Creating and appending the pods to the box stand.
            amount = box_stand.num_pods
            for _ in range(amount):
                pod = self.create_pod(box_stand.pod_rows, box_stand.pod_columns)
                box_stand.add_pod_to_stand(pod)

        amount = int(input((f'How many TelescopicStand you want?\n- ')))
        for _ in range(amount):
            # Creating and appending the telescopic stand to the ccoliseum.
            telescopic_stand = self.create_telescopic_stand()
            coliseum.add_stand_to_coliseum(telescopic_stand)

            # Creating and appending the pods to the telescopic stand.
            amount = telescopic_stand.num_pods
            for _ in range(amount):
                pod = self.create_pod(telescopic_stand.pod_rows, telescopic_stand.pod_columns)
                telescopic_stand.add_pod_to_stand(pod)

        return coliseum



if __name__ == "__main__":
    
    # Creating a terminal.
    terminal_001 = Terminal('Terminnal 001')


    # Creating a coliseum.
    humacao_arena = terminal_001.built_coliseum()

    print(f'The coliseum has been created. Now you can start sitting people.\n\n\n')

    # Loop that only stop when user wants to quit.
    quit_terminal = False
    while quit_terminal == False:

        user_response = int(input(f'[1]\tFull Report\t\t[2]\tColiseum Layout\t\t[3]\tSeating People\t\t[9]\tQuit Terminal\n- '))

        # Show Full Report
        if user_response == 1:
            terminal_001.show_coliseum_report(humacao_arena)

        # Show Coliseum Layout
        elif user_response == 2:
            terminal_001.show_coliseum_layout(humacao_arena)

        # Seating People
        elif user_response == 3:
            amount_people_sitting = int(input(f'Whats the amount of people you want to sit?\n- '))
            terminal_001.seatting_people(humacao_arena, amount_people_sitting)

        # This will run when user wants to quit program.
        elif user_response == 9:
            quit_terminal = True

        # More space, more readable.
        print('\n\n\n')<file_sep>from Stand import Stand
from Pods import Pod

class GrandStand(Stand):

    def __init__(self, name, row, column, num_pods):

        super().__init__(name, row, column, num_pods)
        self.stand_category = 'Grand Stand'



if __name__ == "__main__":
    
    lateral_grand_stand_west = GrandStand('Lateral Grand Stand - West', 42, 17, 3)
    print(lateral_grand_stand_west.get_name())

    lateral_grand_stand_west_pod_1 = Pod(lateral_grand_stand_west.pod_rows,lateral_grand_stand_west.pod_columns)
    lateral_grand_stand_west_pod_2 = Pod(lateral_grand_stand_west.pod_rows,lateral_grand_stand_west.pod_columns)
    lateral_grand_stand_west_pod_3 = Pod(lateral_grand_stand_west.pod_rows,lateral_grand_stand_west.pod_columns)


    lateral_grand_stand_west.add_pod_to_stand(lateral_grand_stand_west_pod_1)
    lateral_grand_stand_west.add_pod_to_stand(lateral_grand_stand_west_pod_2)
    lateral_grand_stand_west.add_pod_to_stand(lateral_grand_stand_west_pod_3)

    lateral_grand_stand_west.remove_pod_from_stand(lateral_grand_stand_west_pod_3.get_id())

    for i in lateral_grand_stand_west.get_pods():
        print(i.pod)