36

The error says:

AttributeError: 'list' object has no attribute 'cost' 

I am trying to get a simple profit calculation to work using the following class to handle a dictionary of bicycles:

class Bike(object):
    def __init__(self, name, weight, cost):
        self.name = name
        self.weight = weight
        self.cost = cost

bikes = {
    # Bike designed for children"
    "Trike": ["Trike", 20, 100],
    # Bike designed for everyone"
    "Kruzer": ["Kruzer", 50, 165]
    }

When I try to calculate profit with my for statement, I get the attribute error.

# Markup of 20% on all sales
margin = .2
# Revenue minus cost after sale
for bike in bikes.values():
    profit = bike.cost * margin

First, I don't know why it is referring to a list, and everything seems to be defined, no?

1
  • 1
    You are not creating Bike objects with the [] syntax. You are creating lists. Commented Mar 29, 2015 at 22:04

4 Answers 4

26

Consider:

class Bike(object):
    def __init__(self, name, weight, cost):
        self.name = name
        self.weight = weight
        self.cost = cost

bikes = {
    # Bike designed for children"
    "Trike": Bike("Trike", 20, 100),      # <--
    # Bike designed for everyone"
    "Kruzer": Bike("Kruzer", 50, 165),    # <--
    }

# Markup of 20% on all sales
margin = .2
# Revenue minus cost after sale
for bike in bikes.values():
    profit = bike.cost * margin
    print(profit)

Output:

33.0
20.0

The difference is that in your bikes dictionary, you're initializing the values as lists [...]. Instead, it looks like the rest of your code wants Bike instances. So create Bike instances: Bike(...).

As for your error

AttributeError: 'list' object has no attribute 'cost'

this will occur when you try to call .cost on a list object. Pretty straightforward, but we can figure out what happened by looking at where you call .cost -- in this line:

profit = bike.cost * margin

This indicates that at least one bike (that is, a member of bikes.values() is a list). If you look at where you defined bikes you can see that the values were, in fact, lists. So this error makes sense.

But since your class has a cost attribute, it looked like you were trying to use Bike instances as values, so I made that little change:

[...] -> Bike(...)

and you're all set.

Sign up to request clarification or add additional context in comments.

2 Comments

This would be a better answer if you explained the difference between your code and OP's.
@Kevin edited it after I posted it -- actually going to revise it again to explain the initial error.
6

They are lists because you type them as lists in the dictionary:

bikes = {
    # Bike designed for children"
    "Trike": ["Trike", 20, 100],
    # Bike designed for everyone"
    "Kruzer": ["Kruzer", 50, 165]
    }

You should use the bike-class instead:

bikes = {
    # Bike designed for children"
    "Trike": Bike("Trike", 20, 100),
    # Bike designed for everyone"
    "Kruzer": Bike("Kruzer", 50, 165)
    }

This will allow you to get the cost of the bikes with bike.cost as you were trying to.

for bike in bikes.values():
    profit = bike.cost * margin
    print(bike.name + " : " + str(profit))

This will now print:

Kruzer : 33.0
Trike : 20.0

Comments

5

You need to pass the values of the dict into the Bike constructor before using like that. Or, see the namedtuple -- seems more in line with what you're trying to do.

Comments

-2
from gettext import install
from sys import argv
import nmap
# Crear un objeto de escaneo
scanner = nmap.PortScanner()


host = argv.host

# Validar si el host es válido
if not host:
    print("ingrese un host.")
    try:
        # Permitir al usuario elegir el rango de puertos
        begin = int(input("puerto inicial: ")) - 1
        end = 1023

        mensaje = f"Escaneando {host}  puerto {begin} al {end}...\n"
        print(mensaje)
        
        # Almacenar los resultados en el archivo
        with open ("nombre_archivo", 'w') as archivo:
            archivo.write("\n" + "*" * 50 + "\n")
            archivo.write(mensaje)

        for i in range (begin, end + 1):
            res = scanner.scan (host, str(i))
            estado_puerto = res['scan'][host]['tcp'][i]['state']

            # Si el puerto está abierto, obtener datos
            servicio = res['scan'][host]['tcp'][i].get('nombre', 'desconocido')
            resultado = f'Puerto ({i+1}) está {estado_puerto}. Servicio: {servicio}\n'
            print(resultado)
            archivo.write(resultado)

    except KeyboardInterrupt:
        print("\nEscaneo cancelado por el usuario.")
        exit()

2 Comments

This looks to be a port scanning app written in python. Might you please edit your answer to include some explanation as to how this works and answers the question, which is about resolving an AttributeError: 'list' object has no attribute 'cost' error when trying to get a simple profit calculation to work using the following class to handle a dictionary of bicycles as indicated in the question? Thanks!
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.