TypeError: Log.__init__() takes 1 positional argument but 5 were given

Hi!
I need to write a basic task in python like a movie library. It should ask continously for the option and the options are three . 1. add new movie, 2. see movie list, 3. exit

I wrote this code based on my python courses until now but i get an error when i am trying to add a movie. I tought based on lessons learned before the program should contain a classes.py with init and str for return to store movie title, year, genre, and imdb_link and also based on lessons learned until now i would use pickle.load and pickle.dump.
Here is the code:

import os
import pickle
from classes import Log


if os.path.exists("db.pkl"):
    with open("db.pkl", "rb") as file:
        movies = pickle.load(file)

movies = []

loop = True
while loop:
    command = input("\nWhat do you want to do next?\nAdd new movie(1)\nSee movies list(2)\nexit(3)\n")
    if command == "1":
        title = input("\nAdd movie title: \n")
        release_year = int(input("\nEnter release year: \n"))
        genre = input("\nEnter genre title: \n")
        imdb_url = input("\nEnter imdb url: \n")
        movie = Log(title, release_year, genre, imdb_url)
        movies.append(movie)
        with open("db.pkl", "wb") as file:
            pickle.dump(movies, file)
    elif command == "2":
        if len(movies) <= 0:
            print("\nNo movie in the list.\n")
        else:
            print("\nAll movie list: ")
            with open("db.pkl", "rb") as file:
                pickle.load(movies, file)
            for i in range(len(movies)):
                print(i)
            print("\n")
    elif command == "3":
        print("\nHave a nice day!\n")
        loop = False

and classes.py:

class Log:
    def __str__(self, title, release_year, genre, imdb_url):
        self.title = title
        self.release_year = release_year
        self.genre = genre
        self.imdb_url = imdb_url
    
    def __init__(self):
        return f"{self.title}, {self.release_year}, {self.genre}, {self.imdb_url}"

The error i get is:

/Exercitii/Data_Management_and_Storage_with_Python/Introduction/movie_task/movies.py

What do you want to do next?
Add new movie(1)
See movies list(2)
exit(3)
1

Add movie title:
The Godfather

Enter release year:
1973

Enter genre title:
Drama

Enter imdb url:
https://imdb.com/title/0068646/
Traceback (most recent call last):
  File "c:\Users\i7\Desktop\Python\Exercitii\Data_Management_and_Storage_with_Python\Introduction\movie_task\movies.py", line 20, in <module>
    movie = Log(title, release_year, genre, imdb_url)
TypeError: Log.__init__() takes 1 positional argument but 5 were given
PS C:\Users\i7\Desktop\Python>

The __init__ method does not take the parameters. It looks like you switched the __str__ and __init__ implementations.

1 Like

Can you please tell me why is not persistent?

Code:

import os
import pickle
from classes import Log


if os.path.exists("db.pkl"):
    with open("db.pkl", "rb") as file:
        movies = pickle.load(file)

movies = []

loop = True
while loop:
    command = input("\nWhat do you want to do next?\nAdd new movie(1)\nSee movies list(2)\nexit(3)\n")
    if command == "1":
        title = input("\nAdd movie title: \n")
        release_year = int(input("\nEnter release year: \n"))
        genre = input("\nEnter genre title: \n")
        imdb_url = input("\nEnter imdb url: \n")
        movie = Log(title, release_year, genre, imdb_url)
        movies.append(movie)
        with open("db.pkl", "wb") as file:
            pickle.dump(movies, file)
    elif command == "2":
        if (len(movies) <= 0):
            print("\nNo movie in the list.\n")
        else:
            print("\nAll movie list: ")
            for i in range(len(movies)):
                print(f"{i + 1}. {movies[i]}")
            print("\n")  
            print("\n")
    elif command == "3":
        print("\nHave a nice day!\n")
        loop = False

Output:

PS C:\Users\i7\Desktop\Python> & C:/Users/i7/AppData/Local/Programs/Python/Python313/python.exe c:/Users/i7/Desktop/Python/Exercitii/Data_Management_and_Storage_with_Python/Introduction/movie_task/movies.py

What do you want to do next?
Add new movie(1)
See movies list(2)
exit(3)
2

No movie in the list.


What do you want to do next?
Add new movie(1)
See movies list(2)
exit(3)
1

Add movie title:
The Godfather

Enter release year:
1973

Enter genre title:
Drama

Enter imdb url:
https://imdb.com/title/tt8383839

What do you want to do next?
Add new movie(1)
See movies list(2)
exit(3)
2

All movie list:
1. The Godfather, 1973, Drama, https://imdb.com/title/tt8383839





What do you want to do next?
Add new movie(1)
See movies list(2)
exit(3)
1

Add movie title:
Interstellar

Enter release year:
2014

Enter genre title:
Adventure

Enter imdb url:
https://imdb.com/title/tt0816692

What do you want to do next?
Add new movie(1)
See movies list(2)
exit(3)
1

Add movie title:
Inception

Enter release year:
2010

Enter genre title:
Adventure

Enter imdb url:
https://imdb.com/title/771375666

What do you want to do next?
Add new movie(1)
See movies list(2)
exit(3)
2

All movie list:
1. The Godfather, 1973, Drama, https://imdb.com/title/tt8383839
2. Interstellar, 2014, Adventure, https://imdb.com/title/tt0816692
3. Inception, 2010, Adventure, https://imdb.com/title/771375666





What do you want to do next?
Add new movie(1)
See movies list(2)
exit(3)
3

Have a nice day!

PS C:\Users\i7\Desktop\Python> & C:/Users/i7/AppData/Local/Programs/Python/Python313/python.exe c:/Users/i7/Desktop/Python/Exercitii/Data_Management_and_Storage_with_Python/Introduction/movie_task/movies.py

What do you want to do next?
Add new movie(1)
See movies list(2)
exit(3)
2

No movie in the list.


What do you want to do next?
Add new movie(1)
See movies list(2)
exit(3)

The problem is in classes.py you need to flip the __str__ and __init__ (just the names). Your __init__ is returning the string and the __str__ is performing the initialization.

It’s not persistent because you’re always assigning [] to movies after reading from the file.

i commented that line and its still not saving them at second run

It’s working for me.

Please post your code so that it can be double-checked.

classes.py:

class Log:
    def __init__(self, title, release_year, genre, imdb_url):
        self.title = title
        self.release_year = release_year
        self.genre = genre
        self.imdb_url = imdb_url
    
    def __str__(self):
        return f"{self.title}, {self.release_year}, {self.genre}, {self.imdb_url}"

movies.py:

import os
import pickle
from classes import Log


if os.path.exists("db.pkl"):
    with open("db.pkl", "rb") as file:
        movies = pickle.load(file)

movies = []

loop = True
while loop:
    command = input("\nWhat do you want to do next?\nAdd new movie(1)\nSee movies list(2)\nexit(3)\n")
    if command == "1":
        title = input("\nAdd movie title: \n")
        release_year = int(input("\nEnter release year: \n"))
        genre = input("\nEnter genre title: \n")
        imdb_url = input("\nEnter imdb url: \n")
        movie = Log(title, release_year, genre, imdb_url)
        movies.append(movie)
        with open("db.pkl", "wb") as file:
            pickle.dump(movies, file)
    elif command == "2":
        if (len(movies) <= 0):
            print("\nNo movie in the list.\n")
        else:
            print("\nAll movie list: ")
            for i in range(len(movies)):
                print(f"{i + 1}. {movies[i]}")
            print("\n")  
            print("\n")
    elif command == "3":
        print("\nHave a nice day!\n")
        loop = False

Output:

PS C:\Users\i7\Desktop\Python> & C:/Users/i7/AppData/Local/Programs/Python/Python313/python.exe c:/Users/i7/Desktop/Python/Exercitii/Data_Management_and_Storage_with_Python/Introduction/movie_task/movies.py

What do you want to do next?
Add new movie(1)
See movies list(2)
exit(3)
1

Add movie title: 
The movie

Enter release year:
1873

Enter genre title:
drama

Enter imdb url:
https://imdb.com/title/383847247

What do you want to do next?
Add new movie(1)
See movies list(2)
exit(3)
3

Have a nice day!

PS C:\Users\i7\Desktop\Python> & C:/Users/i7/AppData/Local/Programs/Python/Python313/python.exe c:/Users/i7/Desktop/Python/Exercitii/Data_Management_and_Storage_with_Python/Introduction/movie_task/movies.py

What do you want to do next?
Add new movie(1)
See movies list(2)
exit(3)
2

No movie in the list.


What do you want to do next?
Add new movie(1)
See movies list(2)
exit(3)

That movies = is what’s causing the issue. You are creating the list if the file exists and then replacing it with an empty list. There are 2 ways you can fix this:

movies = []
if os.path.exists("db.pkl"):
    with open("db.pkl", "rb") as file:
        movies = pickle.load(file)

OR

if os.path.exists("db.pkl"):
    with open("db.pkl", "rb") as file:
        movies = pickle.load(file)
else:
    movies = []

Either of these options will not replace the list loaded from the file with an empty list.

1 Like

movies.py:

import os
import pickle
from classes import Log


if os.path.exists("db.pkl"):
    with open("db.pkl", "rb") as file:
        movies = pickle.load(file)
else:
    movies = []



loop = True
while loop:
    command = input("\nWhat do you want to do next?\nAdd new movie(1)\nSee movies list(2)\nexit(3)\n")
    if command == "1":
        title = input("\nAdd movie title: \n")
        release_year = int(input("\nEnter release year: \n"))
        genre = input("\nEnter genre title: \n")
        imdb_url = input("\nEnter imdb url: \n")
        movie = Log(title, release_year, genre, imdb_url)
        movies.append(movie)
        with open("db.pkl", "wb") as file:
            pickle.dump(movies, file)
    elif command == "2":
        if (len(movies) <= 0):
            print("\nNo movie in the list.\n")
        else:
            print("\nAll movie list: ")
            for i in range(len(movies)):
                print(f"{i + 1}. {movies[i]}")
            print("\n")  
            print("\n")
    elif command == "3":
        print("\nHave a nice day!\n")
        loop = False

Output:

& C:/Users/i7/AppData/Local/Programs/Python/Python313/python.exe c:/Users/i7/Desktop/Python/Exercitii/Data_Management_and_Storage_with_Python/Introduction/movie_task/movies_v3.py

What do you want to do next?
Add new movie(1)
See movies list(2)
exit(3)
1

Add movie title:
The movie

Enter release year:
1983

Enter genre title:
drama

Enter imdb url:
https://imdb.com/title/7655645654

What do you want to do next?
Add new movie(1)
See movies list(2)
exit(3)
3

Have a nice day!

PS C:\Users\i7\Desktop\Python> & C:/Users/i7/AppData/Local/Programs/Python/Python313/python.exe c:/Users/i7/Desktop/Python/Exercitii/Data_Management_and_Storage_with_Python/Introduction/movie_task/movies.py

What do you want to do next?
Add new movie(1)
See movies list(2)
exit(3)
2

No movie in the list.


What do you want to do next?
Add new movie(1)
See movies list(2)
exit(3)

Please check code after posting solution. i’m running windows 11.

So now it leads me to believe that it’s not finding the file. Perhaps you could add a print to that else clause stating that the file is not found. This can happen, and often does, when not using the full path to the file.

On the first run you’re running “movies_v3.py”.

On the second run you’re running “movies.py”.

I’m guessing that “movies.py” is the first version and “movies_v3.py” is the fixed version.

2 Likes

db.pkl , movies.py, classes.py are in the same subfolder thats why i used if os.path.exists. at first add is listing correctly the list added but after close and reopen at option see movies list it says no movies in list. its not persistent db.pkl

You are using os.path.exists before attempting to read the file and that makes sense. The way the code is written if the file does not exist where the interpreter is looking for it it will silently give you an empty list.

When you run the program initially and add a movie and then print the list it is printing from the list in RAM and not from the file, so the fact that it prints it out just means that the list is correct.

I think the current culprit here, as @MRAB wrote, is that you’re not calling the same Python script for both iterations. So the first iteration is using (I assume) the current version of the script (movies_v3.py) while the second iteration is using movies.py with the issue of replacing the file contents in RAM with an empty list.

None of them is the fixed version using permanent storing. If it’s possible please check the pasted code on your compiler and paste me please the persistent version or give me the correct hint to fix it. Thank’s.

I was attempting to help you troubleshoot your issue. That was the second time you responded rudely to my attempts. I am not going to attempt to assist you any more.

Ok. I already submitted the task with movies.py and classes.py. Thanks anyway.

“movies_v3.py” is the version that works.

No it doesn’t. I submitted the movies.py version and my python teacher gave me the correct solution a little bit improved that actually works and is persistent.
Here is the code:

movie.py:

class Movie:
    def __init__(self, title, release_year, genre, imdb_url):
        self.title = title
        self.release_year = release_year
        self.genre = genre
        self.imdb_url = imdb_url
    
    def __str__(self):
        return f"{self.title}, {self.release_year}, {self.genre}, {self.imdb_url}"

main.py:

import os
import pickle
from datetime import datetime
from movie import Movie

current_year = datetime.now().year

FILE = "movies.pkl"

def deserialize_movies():
    if os.path.exists(FILE):
        with open(FILE, "rb") as f:
            return pickle.load(f)

    return []

while True:
    command = input("\nWhat do you want to do next?\nAdd new movie(1)\nSee movies list(2)\nexit(3)\n")

    if command == "1":
        title = input("\nAdd movie title: \n")

        if not title:
            print("Title is empty.")

        try:
            release_year = int(input("\nEnter release year: \n"))
            if release_year > current_year:
                print("the value of the production year exceeds that of the current year")
                continue
        except:
            print("The value entered for the year is not numeric!")
            continue

        genre = input("\nEnter the genre of movie: \n")

        if not genre:
            print("Genre is empty.")

        imdb_url = input("\nEnter imdb url: \n")

        if not imdb_url:
            print("IMDB URLs is empty.")

        movie = Movie(title, release_year, genre, imdb_url)
        movies_list = deserialize_movies()
        movies_list.append(movie)

        with open(FILE, "wb") as file:
            pickle.dump(movies_list, file)

    elif command == "2":
        movies_list = deserialize_movies()
        for i in range(len(movies_list)):
            print(f" movie {i + 1} is {movies_list[i]}")

        print("\n\n")

    elif command == "3":

        print("\nHave a nice day!\n")
        break

    else:
        print("Command index " + command + " not exists")

Output:

PS C:\Users\i7\Desktop\Python\Exercitii\Data_Management_and_Storage_with_Python\Introduction\movie_task\task> cd c:/Users/i7/Desktop/Python/Exercitii/Data_Management_and_Storage_with_Python/Introduction/movie_task/solution
PS C:\Users\i7\Desktop\Python\Exercitii\Data_Management_and_Storage_with_Python\Introduction\movie_task\solution> & C:/Users/i7/AppData/Local/Programs/Python/Python313/python.exe c:/Users/i7/Desktop/Python/Exercitii/Data_Management_and_Storage_with_Python/Introduction/movie_task/solution/main.py

What do you want to do next?
Add new movie(1)
See movies list(2)
exit(3)
1

Add movie title:
The Godfather

Enter release year:
1983

Enter the genre of movie:
drama

Enter imdb url:
https://imdb.com/title/3288246

What do you want to do next?
Add new movie(1)
See movies list(2)
exit(3)
1

Add movie title:
The Scientist

Enter release year:
1985

Enter the genre of movie:
drama

Enter imdb url:
https://imdb.com/title/38724646

What do you want to do next?
Add new movie(1)
See movies list(2)
exit(3)
3

Have a nice day!

PS C:\Users\i7\Desktop\Python\Exercitii\Data_Management_and_Storage_with_Python\Introduction\movie_task\solution> & C:/Users/i7/AppData/Local/Programs/Python/Python313/python.exe c:/Users/i7/Desktop/Python/Exercitii/Data_Management_and_Storage_with_Python/Introduction/movie_task/solution/main.py

What do you want to do next?
Add new movie(1)
See movies list(2)
exit(3)
2
 movie 1 is The Godfather, 1983, drama, https://imdb.com/title/3288246
 movie 2 is The Scientist, 1985, drama, https://imdb.com/title/38724646




What do you want to do next?
Add new movie(1)
See movies list(2)
exit(3)