0

Im trying to write a chat logic, so here what I want to do

def chatlogic():
    talk=True
    while talk:
        if __name__ == '__main__':
            Thread(target = fluse).start()
        message = raw_input('enter a message: ')
        if not message: #Ending Conversation if empty message was sent
            talk=False          
        conv_file.write('[%s]%s: %s\n' %(msgtime,user,message))
        #conv_file.flush()
        return 'Conversation Ended'

def fluse():
    while True:
        time.sleep(1)
        conv_file.fluse()

the file must update every second, nomatter what you are doing. What am i doing wrong? note: I have never used multitasking before

Pythonizer
  • 1,080
  • 4
  • 15
  • 25
  • First, what is `conv_file`, and what is its `fluse` method supposed to do? – abarnert Sep 18 '13 at 18:35
  • Second, why do you have an `if __name__ == '__main__'` check in the middle of a function? Do you ever call this function? – abarnert Sep 18 '13 at 18:36
  • conv_file is the conversation file where messages should be stored, and I have used fluse to let use see what have other user messaged to him – Pythonizer Sep 18 '13 at 18:36
  • @abarnert I just searched in the inernet how to use the multitasking and found this example – Pythonizer Sep 18 '13 at 18:38
  • I don't see how more than one person could be conversing here. There's just one thread running the `raw_input` and the file `write`s. Even if there were multiple threads, they'd all be calling `raw_input` and therefore listening to the same local user. And if you intended to have multiple people chat by all writing to some SMB- or NFS-shared file, you don't have any code that ever reads that file. – abarnert Sep 18 '13 at 18:39
  • Are you sure you don't want `flush()` instead of `fluse()`? `fluse` looks like a typo. – Tim Peters Sep 18 '13 at 18:39
  • If this is an example you found somewhere, post the link to where you found it. Presumably whoever wrote it understands what it's doing, and can explain it better than you can. (It's also possible that it's just a bad example written by someone who knows even less than you do, in which case we could tell you to find a better example.) – abarnert Sep 18 '13 at 18:39
  • @abarnert http://stackoverflow.com/questions/2957116/make-2-functions-run-at-the-same-time – Pythonizer Sep 18 '13 at 18:42
  • @Streak: You can't learn by just copying random lines of code that you don't understand. Read a tutorial, or at least a blog post, explaining the basics of using threads in Python. – abarnert Sep 18 '13 at 18:48

1 Answers1

2

There are many problems in this code, but the one you seem to be asking about is here:

while talk:
    if __name__ == '__main__':
        Thread(target = fluse).start()

This means that each time through the loop—that is, once per message—you're going to fire off a new fluse thread. And that thread loops forever, calling conv_file.fluse() every second until the end of time.

So, if you type messages at 0.3, 2.7, and 5.1 seconds after app startup, you're going to get a fluse at 5.3 seconds, another at 5.7, another at 6.1, and so on.

If you want this to only happen once/second, just start a single thread, instead of starting a new one each time through the loop. For example:

if __name__ == '__main__':
    Thread(target = fluse).start()
while talk:
    # etc.

If, instead, you want it to happen a second after each write, but not every second again after that, just take the loop out of the function:

def fluse():
    time.sleep(1)
    conv_file.fluse()

Although in this case, threading.Timer is an easier way to do the same thing.


Anyway, even with this fix, as I said, there are a number of other problems:

  • You're calling a file method that doesn't exist—presumably you meant flush instead of fluse?
  • The file doesn't exist either. Maybe you meant it to be a global, created outside the functions? Or an argument to them?
  • You're trying to loop forever until an empty message, but you call return each time through the loop, which means you're only going to loop once.
  • There's no way to exit your program, because you fire off a non-daemon background thread that runs forever.
  • You never call the chatlogic function anyway, so the program just exits immediately without doing any work.

If I fix all of the other errors in your program, and add something that shows me whether the fluse thread is doing its job, it does something… and maybe you can tell us whether it's the thing you wanted.

from threading import Thread
import time

def chatlogic(conv_file):
    user = 'Nobody'
    t = Thread(target=flusher, args=[conv_file])
    t.daemon=True
    t.start()
    while True:
        message = raw_input('enter a message: ')
        if not message: #Ending Conversation if empty message was sent
            break
        msgtime = time.asctime()
        conv_file.write('[%s]%s: %s\n' %(msgtime,user,message))
    return 'Conversation Ended'

def flusher(conv_file):
    while True:
        time.sleep(1)
        print 'Flushing the file now'
        conv_file.flush()

if __name__ == '__main__':
    conv_file = open('convfile.txt', 'w')
    chatlogic(conv_file)

This is still a strange design. The file is being flushed once/second even if you didn't write anything, and that there's no guarantee it actually gets flushed at the end, and so on. But this is what it sounds like you were attempting to do.

abarnert
  • 354,177
  • 51
  • 601
  • 671
  • the script ends immediately after entering to the function 'chatlogic' – Pythonizer Sep 18 '13 at 18:51
  • @Streak: By "the script ends", do you mean that it prints out an exception traceback telling you that the file has no attribute `fluse`? As I explained at the top, there are all kinds of other problems with your code besides the one you asked about. I've written a version that actually runs, so you can tell us whether it's what you wanted. – abarnert Sep 18 '13 at 19:01