-1

So I'm trying to make a reddit bot that will exec code from a submission. I have my own sub for controlling these clients.

while __name__ == '__main__':
    string = open('config.txt').read()
    for submission in subreddit.get_new(limit = 1):
        if submission.url not in string:
            f.write(submission.url + "\n")
            f.close()
            f = open('config.txt', "a")
            string = open('config.txt').read()

So what this is suppose to do is read from the config file, then only do work if the submission url isn't in config.txt. However, it always sees the most recent post and does it's work. This is how F is opened.

if not os.path.exists('file'):
    open('config.txt', 'w').close()
f = open('config.txt', "a")
Ben Smith
  • 13
  • 2
  • 1
    Where does the variable `f` come from? You start writing to it without initializing it, at least that's how it looks in the code. Then you close it, just to open it for no obvious reason. – Xetnus Aug 28 '16 at 22:10
  • F is initialized just outside of this snippet. And I close f because it doesn't save to be read if I don't close. – Ben Smith Aug 28 '16 at 22:14
  • 1
    I think you used existing code from somewhere else to read a file. Use the `with` keyword to open the file and assign it to a variable `f`. For example: `with open('output.txt', 'w') as f: f.write('Hi there!')` – DeA Aug 28 '16 at 22:15
  • Are you sure of the value of `submission.url`? As an aside, what is this `while __name__ == '__main__'`? Very strange condition for a loop since it's going to be always true or always false depending on how your script was invoked. – Two-Bit Alchemist Aug 28 '16 at 22:23
  • Yes, submission.url at the moment can only be one value. And I just used that to always have it true. – Ben Smith Aug 28 '16 at 22:28
  • 1
    _"F is initialized just outside of this snippet."_ For future reference, before asking a question, please read: [How to create a Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) – John1024 Aug 28 '16 at 22:36
  • Your code "works". There doesn't seem to be a logic error. So one of your assumptions _has_ to be wrong. Start printing out values or using `pdb.set_trace()` and inspecting variables to see what is not as you think it is. – Two-Bit Alchemist Aug 28 '16 at 22:43
  • Where is the part where it 'does work'? Or does 'do work' just mean writing the url into config.txt? – Matthias Fripp Aug 29 '16 at 01:38

1 Answers1

0

First a critique of your existing code (in comments):

# the next two lines are not needed; open('config.txt', "a") 
# will create the file if it doesn't exist.
if not os.path.exists('file'):
    open('config.txt', 'w').close()
f = open('config.txt', "a")

# this is an unusual condition which will confuse readers
while __name__ == '__main__':
    # the next line will open a file handle and never explicitly close it
    # (it will probably get closed automatically when it goes out of scope,
    # but it's not good form)
    string = open('config.txt').read()
    for submission in subreddit.get_new(limit = 1):
        # the next line should check for a full-line match; as written, it 
        # will match "http://www.test.com" if "http://www.test.com/level2"
        # is in config.txt
        if submission.url not in string:
            f.write(submission.url + "\n")
            # the next two lines could be replaced with f.flush()
            f.close()
            f = open('config.txt', "a")
            # this is a cumbersome way to keep your string synced with the file,
            # and it never explicitly releases the new file handle
            string = open('config.txt').read()
    # If subreddit.get_new() doesn't return any results, this will act as
    # a busy loop, repeatedly requesting new results as fast as possible.
    # If that is undesirable, you might want to sleep here.
# file handle f should get closed after the loop

None of the problems pointed out above should keep your code from working (except maybe the imprecise matching). But simpler code may be easier to debug. Here's some code that does the same thing. Note: I assume there is no chance any other process is writing to config.txt at the same time. You could try this code (or your code) with pdb, line-by-line, to see whether it works as expected.

import time
import praw
r = praw.Reddit(...)
subreddit = r.get_subreddit(...)

if __name__ == '__main__':
    # open config.txt for reading and writing without truncating. 
    # moves pointer to end of file; closes file at end of block
    with open('config.txt', "a+") as f:
        # move pointer to start of file
        f.seek(0) 
        # make a list of existing lines; also move pointer to end of file
        lines = set(f.read().splitlines())

        while True:
            got_one = False
            for submission in subreddit.get_new(limit=1):
                got_one = True
                if submission.url not in lines:
                    lines.add(submission.url)
                    f.write(submission.url + "\n")
                    # write data to disk immediately
                    f.flush()
                    ...
            if not got_one:
                # wait a little while before trying again
                time.sleep(10)
Matthias Fripp
  • 17,670
  • 5
  • 28
  • 45
  • So it wasn't working because of a stupid error, but thank you for the help. And I'm doing extra processing if the file isn't there. – Ben Smith Aug 30 '16 at 00:05