I have two files:
File 1: Takes a text file of a certain format and reformats in a way I prefer
# Dataframe_maker.py
from dataclasses import dataclass
from typing import List
import re
# Defined a class
class Message:
sender: str
date: str
time: str
content: str
isreply: bool
isreact: bool
# This function takes a block of text in a specific format and returns a Message object
def parse_message(Message_Block: str) -> Message:
lines = Message_Block.split('n')
sender = lines[2][20:]
date = lines[2][:10]
time = lines[2][11:19]
content = lines[4]
isreply = '➜ Replying to' in content
isreact = bool(re.search(r'Laughed at “|Loved “|Questioned “|Emphasised “|Liked “|Disliked “', content))
return Message(sender=sender, date=date, time=time, content=content, isreply = isreply, isreact = isreact)
# I have real addresses here of course
file_path_read = 'filepathRead'
file_path_write = 'filepathWrite'
with open(file_path_read, "r", encoding='utf-8') as file_read:
data = file_read.read()
# Each message was seperated by this string, and the first message was empty so that is removed
message_blocks = data.split('----------------------------------------------------')
message_blocks.pop(0)
messages: List[Message] = [parse_message(block) for block in message_blocks]
with open(file_path_write, 'w', encoding='utf-8') as file_write:
for Message in messages:
file_write.write(f"{Message.sender}, {Message.date}, {Message.time}, {Message.content}, {Message.isreply}, {Message.isreact}n")
# A function that is not used in this file, but is here so I can import it into other files. It takes each line of the output file of this code and converts it back into a Message object
def parse_line(line) -> Message:
parts = line.strip().split(', ')
sender, date, time, content, isreply, isreact = parts
return Message(sender=sender, date=date, time=time, content=content, isreply=isreply, isreact=isreact)
File 2: This is just a test to see if i can actually read the file I created and turn it back into a list of Message objects in a few short lines. The string finding code is just a simple test
from Dataframe_maker import parse_line, Message
file_path = 'filepathRead'
with open(file_path, 'r', encoding='utf-8') as file:
lines = file.readlines()
messages = [parse_line(line) for line in lines]
# Test begins here
given_string = 'First off, it is important to note that '
for Message in messages:
if not Message.isreact and not Message.isreply:
text = Message.content
if given_string in text:
index = messages.index(Message)
length = len(text)
print(f'The {index}th message is {length} characters long')
The problem I get when I run file 2 is:
- It calls a problem in line 7 of file 2 (defining the List of Message objects)
- Within that line it calls a problem within the parse_line function
- In the function (going back to file 1) it calls a problem in the final line of the function which is the return value of that function, where it returns the input as a Message object
- It says TypeError: ‘Message’ object is not callable
I am not a proficient coder by any means, and this is a hobby project where I am analysing a group chat I share with some friends. I understand what that TypeError means, but to my knowledge the dataclasses in python are callable so I am confused. Any help is appreciated
Edit:
Here is the exact error message (file address changed for privacy):
Traceback (most recent call last):
File "FileAddress_file2", line 7, in <module>
messages = [parse_line(line) for line in lines]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "fileAddress_file2", line 7, in <listcomp>
messages = [parse_line(line) for line in lines]
^^^^^^^^^^^^^^^^
File "fileAddress_file1", line 48, in parse_line
return Message(sender=sender, date=date, time=time, content=content, isreply=isreply, isreact=isreact)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: 'Message' object is not callable
6
Class names live in the same namespace as everything else; you’re rebinding the name Message
to something other than the class it originally referred to. Use a different name:
with open(file_path_write, 'w', encoding='utf-8') as file_write:
for message in messages:
file_write.write(f"{message.sender}, {message.date}, {message.time}, {message.content}, {message.isreply}, {message.isreact}n")
2