Project Name: ASPP+pelita
Language: Python
Statement Type: Assignment

Source Code:
def parse_layout(layout_str):
    """Parse a layout string

    Return a dict
        {'walls': list_of_wall_coordinates,
         'food' : list_of_food_coordinates,
         'bot'  : list_of_4_bot_coordinate}

    A layout string is composed of wall characters '#', food characters '.', and
    bot characters '0', '1', '2', and '3'.

    Valid layouts must be enclosed by walls and be of rectangular shape. Example:

     ########
     #0  .  #
     #2    1#
     #  .  3#
     ########


    If items are overlapping, several layout strings can be concateneted:
     ########
     #0  .  #
     #     1#
     #  .  3#
     ########
     ########
     #2  .  #
     #     1#
     #  .  3#
     ########

     In this case, bot '0' and bot '2' are on top of each other at position (1,1)
    """
    layout_list = []
    start = False
    for i, line in enumerate(layout_str.splitlines()):
        row = line.strip()
        if not row:
            # ignore emptylines
            continue
        if not start:
            # start a new layout
            # check that row is a valid opening string
            if row.count('#') != len(row):
                raise ValueError(f"Layout does not start with a row of walls (line: {i})!")
            current_layout = [row]
            start = True
            continue
        # we are in the middle of a layout, just append to the current
        # layout unless we detect the closing string
        current_layout.append(row)
        if row.count('#') == len(row):
            # this is a closing string
            # append the layout to tha layout list
            layout_list.append('\n'.join(current_layout))
            start = False

    if start:
        # the last layout has not been closed, complain here!
        raise ValueError(f"Layout does not end with a row of walls (line: {i})!")

    # initialize walls, food and bots from the first layout
    out = parse_single_layout(layout_list.pop(0))
    for layout in layout_list:
        items = parse_layout(layout)
        # walls should always be the same
        if items['walls'] != out['walls']:
            raise ValueError('Walls are not equal in all layouts!')
        # add the food, removing duplicates
        out['food'] = list(set(out['food'] + items['food']))
        # add the bots
        for bot_idx, bot_pos in enumerate(items['bots']):
            if bot_pos:
                # this bot position is not None, overwrite whatever we had before
                out['bots'][bot_idx] = bot_pos

    return out

parse_layout(layout_str='\n        ##################\n        #. ... .##.     3#\n        # # #  .  .### #1#\n        # # ##.   .      #\n        #      .   .## # #\n        #0# ###.  .  # # #\n        #2     .##. ... .#\n        ################## ')

Selected Statement: current_layout = [row]

Function Input:
layout_str: '\n        ##################\n        #. ... .##.     3#\n        # # #  .  .### #1#\n        # # ##.   .      #\n        #      .   .## # #\n        #0# ###.  .  # # #\n        #2     .##. ... .#\n        ################## '

Variable Values Before Statement:
row: '##################'

Value After Statement Execution: ##################

Variable States During Runtime (line, value):
layout_str: 1
'\n        ##################\n        #. ... .##.     3#\n        # # #  .  .### #1#\n        # # ##.   .      #\n        #      .   .## # #\n        #0# ###.  .  # # #\n        #2     .##. ... .#\n        ################## '
layout_list: 35
56
##################
#. ... .##.     3#
# # #  .  .### #1#
# # ##.   .      #
#      .   .## # #
#0# ###.  .  # # #
#2     .##. ... .#
##################
64
start: 36
False
48
True
57
False
i: 37
0
37
1
37
2
37
3
37
4
37
5
37
6
37
7
37
8
line: 37
''
37
'        ##################'
37
'        #. ... .##.     3#'
37
'        # # #  .  .### #1#'
37
'        # # ##.   .      #'
37
'        #      .   .## # #'
37
'        #0# ###.  .  # # #'
37
'        #2     .##. ... .#'
37
'        ################## '
row: 38
''
38
'##################'
38
'#. ... .##.     3#'
38
'# # #  .  .### #1#'
38
'# # ##.   .      #'
38
'#      .   .## # #'
38
'#0# ###.  .  # # #'
38
'#2     .##. ... .#'
38
'##################'
current_layout: 47
##################
52
##################, #. ... .##.     3#
52
##################, #. ... .##.     3#, # # #  .  .### #1#
52
##################, #. ... .##.     3#, # # #  .  .### #1#, # # ##.   .      #
52
##################, #. ... .##.     3#, # # #  .  .### #1#, # # ##.   .      #, #      .   .## # #
52
##################, #. ... .##.     3#, # # #  .  .### #1#, # # ##.   .      #, #      .   .## # #, #0# ###.  .  # # #
52
##################, #. ... .##.     3#, # # #  .  .### #1#, # # ##.   .      #, #      .   .## # #, #0# ###.  .  # # #, #2     .##. ... .#
52
##################, #. ... .##.     3#, # # #  .  .### #1#, # # ##.   .      #, #      .   .## # #, #0# ###.  .  # # #, #2     .##. ... .#, ##################
out: 64
{'walls': [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (1, 0), (1, 7), (2, 0), (2, 2), (2, 3), (2, 5), (2, 7), (3, 0), (3, 7), (4, 0), (4, 2), (4, 3), (4, 5), (4, 7), (5, 0), (5, 3), (5, 5), (5, 7), (6, 0), (6, 5), (6, 7), (7, 0), (7, 7), (8, 0), (8, 1), (8, 6), (8, 7), (9, 0), (9, 1), (9, 6), (9, 7), (10, 0), (10, 7), (11, 0), (11, 2), (11, 7), (12, 0), (12, 2), (12, 4), (12, 7), (13, 0), (13, 2), (13, 4), (13, 5), (13, 7), (14, 0), (14, 7), (15, 0), (15, 2), (15, 4), (15, 5), (15, 7), (16, 0), (16, 7), (17, 0), (17, 1), (17, 2), (17, 3), (17, 4), (17, 5), (17, 6), (17, 7)], 'food': [(1, 1), (3, 1), (4, 1), (5, 1), (6, 3), (7, 1), (7, 2), (7, 4), (7, 5), (7, 6), (10, 1), (10, 2), (10, 3), (10, 5), (10, 6), (11, 4), (12, 6), (13, 6), (14, 6), (16, 6)], 'bots': [(1, 5), (16, 2), (1, 6), (16, 1)]}