pythonlistobjectinventory

How to create a list from a .txt file and then convert the list values into objects


I am a beginner in Python having trouble with a school project. I'm trying to create a library inventory management system based around a file called books.txt

First of all, here is the raw data of books.txt

Mastering Windows Server 2019 - Second Edition;Krause,Jordan;978-1789804539;005.4476/KRA;5;3;
Windows Server 2019 & PowerShell All In One For Dummies;Perrot,Sara;978-1119560715;005.4476/PER;10;2;
Windows Server Automation with PowerShell Cookbook - Fouth Edition;Lee,Thomas;978-1800568457;005.4476/LEE;3;1;
Python Cookbook: Recipes for Mastering Python 3;Beazley,David;978-1449340377;005.133/BEA;10;8;
Automate the Boring Stuff With Python;Sweigart,Al;978-1593275990;005.133/SWE;10;10;
Head First Python - 2nd Edition;Barry,Paul;978-1491919538;005.133/BAR;4;2;
Python Crash Course - 2nd Edition;Matthes,Eric;978-1593279288;005.133/MAT;12;8;
Python for Dummies;Maruch,Stef;978-0471778646;005.133/MAR;5;0;
Beginning Programming with Python for Dummies;Mueller,John Paul;978-1119457893;005.133/MUE;7;5;
Beginning COBOL for Programmers;Coughlan,Michael;978-1430262534;005.133/COU;1;0;

So what I'm trying to do here is store a list of these book objects in a variable. The aim of the program is to modify the list of book objects, rather than modifying the .txt file directly. After that's all done the user can save the changes and THEN overwrite the .txt file. Anyway, I've tried many different things and right now I feel like this function has got me closest in terms of reading and splitting the lines from the file to create a list.

#Apparently 'with open' stops you from having to close the file.
#Copy of display() for the purposes of playing around.
def inventory3():
    print("\nName \t \t Author \t \t ISBN \t \t Call Number \t \t Stock \t \t Loaned")
    with open("books.txt", "r") as inventoryfile:
        for line in inventoryfile:
            strip_lines=line.strip()
            inventory = strip_lines.split(";")
            print(inventory)

This displays all the lines in the books.txt file correctly (I don't want the square brackets to display, but that's a problem for later) and I know from testing (stuff like test = inventory[-3:]) that it functions correctly as a list. Now the aim is to "index the stored list" to create the book objects, and apparently each book object I create should be stored in a separate list. This was the example I was provided.

books.append(Book(line[0],line[1],line[2],line[3],line[4],line[5]))

And I previously created a book class, like so

class Book:

    def __init__(self, title, author, isbn, callnumber, stock, loaned):
        self.title = title
        self.author = author
        self.isbn = isbn
        self.callnumber = callnumber
        self.stock = stock
        self.loaned = loaned

    def getTitle(self):
        return self.title

    def getAuthor(self):
        return self.author

    def getISBN(self):
        return self.isbn

    def getCallNumber(self):
        return self.callnumber

    def getStock(self):
        return self.stock

    def getLoaned(self):
        return self.loaned

I'm a bit confused on how I'm meant to link these two together. I'm not seeing the progression from getting the contents of the txt file to display to suddenly converting them all into objects (that can then be individually deleted, new books added, etc). I've spent days Googling and YouTubing but found nothing, so I'm here for help. Thank you very much.


Solution

  • It seems that you want to use the lists created at inventory3 to instantiate your Book class. In this case, you can try to change your function a bit and add a return, like this:

    def inventory3():
        inventory = []
        print("\nName \t \t Author \t \t ISBN \t \t Call Number \t \t Stock \t \t Loaned")
        with open("books.txt", "r") as inventoryfile:
            for line in inventoryfile:
                strip_lines=line.strip()
                inventory_line = strip_lines.split(";")[:-1] # Use-1 to get rid of all empty double quotes ('') in the end of each list
                print(inventory_line)
                inventory.append(inventory_line)
        return inventory
    

    With this, you can do:

    inventory = inventory3()
    books = []
    for book_details in inventory:
        books.append(Book(book_details[0],book_details[1], book_details[2],book_details[3],book_details[4],book_details[5]))
    print(books)
    

    You'll see your objects created.

    And, if you really don't need the empty '' in the and of each list, as i suggested, you can do it with list unpacking, it will be more pythonic. Like this:

    inventory = inventory3()
    books = []
    for book_details in inventory:
        books.append(Book(*book_details))
    print(books)
    

    *book_details will be exactly the same as book_details[0],book_details[1], book_details[2],book_details[3],book_details[4],book_details[5].

    EDIT

    As said in comments, I'm adding an example using dataclasses.

    from dataclasses import dataclass
    
    @dataclass
    class Book:
        title:str
        author:str
        isbn:str
        callnumber:str
        stock:str
        loaned:str
    
        # Your Functions
    
        ...
    

    If you use a dataclass and print your objects you get something that can help you:

    Book(title='Mastering Windows Server 2019 - Second Edition', author='Krause,Jordan', isbn='978-1789804539', callnumber='005.4476/KRA', stock='5', loaned='3')
    

    Instead of:

    <__main__.Book object at 0x000001F1D23BFFA0>
    

    If you want something defined by yourself, you can implement the repr method of your book class:

    class Book:
        def __init__(self, title, author, isbn, callnumber, stock, loaned):
            self.title = title
            self.author = author
            self.isbn = isbn
            self.callnumber = callnumber
            self.stock = stock
            self.loaned = loaned
    
        def __repr__(self):
            return self.title + '/' + self.author
    
        # Your Functions
    
        ...