Learn Python3 Intermediate: The Great Robot Race


I am having issues with the exercise contained in the link, https://www.codecademy.com/courses/learn-intermediate-python-3/projects/the-great-robot-race-python-project. I am new to Python, and have been building my knowledge through the Codecademy Learn Python3 courses.

After completing Task 9, the following error message for the robot_race_functions.py appears:

Traceback (most recent call last):
File “robot_race.py”, line 21, in
robot_moves.append(rr.compute_robot_logic(walls, goal, bots))
File “/home/ccuser/workspace/the-great-robot-race-python-project-workspace/robot_race_functions.py”, line 62, in compute_robot_logic
dist = calc_manhattan_dist(bot.calc_x + move[0], bot.calc_y + move[1], goal.x, goal.y)
AttributeError: ‘list’ object has no attribute ‘calc_x’

I am not sure how to resolve the error, given that the project requires changes to be made to the robot_race.py file, and not the the robot_race_functions.py file.

Any help, tips, or recommendations to resolve the error would be greatly appreciated! (+ anything else that looks amiss with my code :blush:)

Please see below for the edits I have made to the robot_race.py file up to Task 9:

import robot_race_functions as rr from collections import deque, Counter, namedtuple from time import time, sleep maze_file_name = 'maze_data_1.csv' seconds_between_turns = 0.3 max_turns = 35 # Initialize the robot race maze_data = rr.read_maze(maze_file_name) rr.print_maze(maze_data) walls, goal, bots = rr.process_maze_init(maze_data) # Populate a deque of all robot commands for the provided maze robot_moves = deque() num_of_turns = 0 while not rr.is_race_over(bots) and num_of_turns < max_turns: # For every bot in the list of bots, if the bot has not reached the end, add a new move to the robot_moves deque # Add your code below! for bot in bots: robot_moves.append(rr.compute_robot_logic(walls, goal, bots)) num_of_turns += 1 # Count the number of moves based on the robot names # Add your code below! move_count = Counter(move[0] for move in robot_moves) print(move_count) # Count the number of collisions by robot name # Add your code below collision_count = Counter(move[0] for move in robot_moves if has_collided == True) print(collision_count) # Create a namedtuple to keep track of our robots' points # Add your code below! BotScoreData = namedtuple('BotScoreData', ['name', 'num_moves', 'num_collisions', 'score']) # Calculate the scores (moves + collisions) for each robot and append it to bot_scores bot_scores = [] # Add your code below! for robot in bots: bot_score = BotScore_Data(bot.name, move_count, collision_count, move_count + collision_count) bot_scores.append(bot_score) print(bot_scores) # Populate a dict to keep track of the robot movements bot_data = {} # Add your code below! for robot in bots: bot_data[bot.name] = bot # Move the robots and update the map based on the moves deque while len(robot_moves) > 0: # Make sure to pop moves from the front of the deque # Add your code below! # Update the maze characters based on the robot positions and print it to the console rr.update_maze_characters(maze_data, bots) rr.print_maze(maze_data) sleep(seconds_between_turns - time() % seconds_between_turns) # Print out the results! #rr.print_results(bot_scores)

You should run this locally and set a breakpoint().
When it says list object has no attribute calc_x, it’s because whatever is being .calc_x is already a list by then (and lists don’t have that method). You might have mistakenly re-assigned bot to be a list instead of a bot class.
What is calc_x? Is it a class data member or method? If it’s a method it should be called with parenthesis to signify you want to invoke the method.

@toastedpitabread thank you for your reply.

I haven’t edited the robot_race_functions file which contains calc_x, defined as follows:

class Robot: def __init__(self, x, y, name): self.x = x self.calc_x = x self.y = y self.calc_y = y self.has_finished = False self.remove = False self.name = name def process_move(self, direction): if direction == 'left': self.x += -1 if direction == 'right': self.x += 1 if direction == 'up': self.y += 1 if direction == 'down': self.y += -1 if direction == 'finished': self.remove = True

calc_x is not called directly within the robot_race.py file, and I do not think I am assigning bot to be a list, so am quite puzzled as to how to approach this error.


Regardless of what we may think what happened, the interpretor error is clear: AttributeError: ‘list’ object has no attribute ‘calc_x’

So highly suggest putting that breakpoint before it hits that line and see what is happening.