0

I need to query the table, and create an instance of a class Car for each row in the database. I have reached to this point, but I am getting an error

return [Car(*row) for row in rows] TypeError: init() takes 1 positional argument but 7 were given... There are 6 attributes to the cars table...oy vey!

import sqlite3 as lite

def db_connect():
        con = lite.connect('ins.sqlite')

    with con:
        cur = con.cursor()
        cur.execute('select * from cars;')
        rows = cur.fetchall()
        for row in rows:
            #return (row) #Use list comprehension to get all rows
            return [Car(*row) for row in rows]



class Car:
    def car_info(self):
        'Add all the necessary methods and properties you want'
        a = db_connect()
        return a 

   def __init__(self, **kwargs):
    self.variables = kwargs

def main():
    x = Car() #Create a Object x
    a = x.car_info() 
    ok = tuple(map(str, a)) #convert float data into string
    print ('Make           Model          Model     Displacement     
            Power  Luxury')
    print ('        '.join(ok))

main()

1 Answer 1

1

This is clearly not right:

for row in rows:
    #return (row) #Use list comprehension to get all rows
    return [Car(*row) for row in cur]

I think that should probably be

return [Car(*row) for row in rows]

Do you understand why this is? rows has been set to all the data pulled from the database (all the rows). The "list comprehension" will then call Car() on each row to convert it to an instance of Car. There is an implicit loop in the list comprehension, so you don't put that in a for loop.

Another major problem: you need to write some code for Car.__init__() to actually make a Car instance from a row. The __init__() function in the Car class needs to take a series of arguments, the same data that will appear in each row from the database, and then needs to store each argument inside of self.

This is pretty clearly for a class project. You should design your Car class however the teacher wants it done. But I would normally suggest that the car_info() function shouldn't be inside the class; the class should just implement Car. So the class should have a __init__() function to create a class instance, a __str__() function for producing a nice output string representing a class instance, and other method functions as appropriate; then you can have a function that goes to the database, and pulls all the rows and makes Car instances from each row. Alternatively, if you want a class function that pulls rows, then all the database code should be inside the class. As the design is currently, it just seems weird that db_connect() is an ordinary function but car_info() is a method function... but it's a method function that doesn't do anything with the self value, so it isn't really a good method function; it should really be a class function. But as I said, if your teacher wants it done this way, do it this way.

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

4 Comments

ok, i see what you mean....so i edited the code above with the init, now, I am getting an error return [Car(*row) for row in rows] TypeError: __init__() takes 1 positional argument but 7 were given
I discussed this in the fourth paragraph: "Another major problem: you need to write some code for Car.__init__() to actually make a Car instance from a row. The __init__() function in the Car class needs to take a series of arguments, the same data that will appear in each row from the database, and then needs to store each argument inside of self."
you are correct it is for a class project, however, i am very new at python, so my code structure is not the best in this language. i appreciate your constructive criticism, it is very helpful. I am figuring this out as I go...so once I have a good working code, I will clean it up I guess. ...so you think that my __init__() where it takes kwargs, cannot work with this....do I need to specify the arguments in order to create the instances?
When you get a row from the database, it will just be a series of values. kwargs needs values in the format name=value. It is certainly not wrong to have kwargs if you want that, but if you want to be able to do Car(*row) you will need to make an __init__() function that accepts parameters that have the same order as the values in the row. That way each value in turn from the row will line up with each parameter in turn from the function. See section 4.7.4 here: docs.python.org/2/tutorial/…

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.