-2

I am trying to follow reddit u/busterroni's video on how to make a reddit bot, but while his program runs fine, mine keeps getting hung up on "filename" on the line below that says...

usernames = get_usernames(filename)

...under main(). Can anyone tell me what the issue is? BTW I am at 12:11 in the video in case that helps at all.

import praw
import sys


def main():
    reddit = authenticate()
    usernames = get_usernames(filename) #ERROR
    print(usernames)


def authenticate():
    print('Authenticating...')

    reddit = praw.Reddit(
        'notifier',
        user_agent="BlueWizard3's joketest v0.1")

    print('Authenticated as {}'.format(reddit.user.me()))

    return reddit


def get_usernames(filename):
    try:
        with open(filename, 'r') as f:
            usernames = f.read()
            usernames = usernames.split('\n')
            usernames = filter(None, usernames)
    except IOError:
        print('Error: file ', filename, " not found in the current directory.")
         quit()

    return usernames


main()


def send_message(r, username, subject, body):
    try:
        r.redditor(username).message(subject, body)
    except praw.exceptions.APIException as e:
        if 'USER_DOESNT_EXIST' in e.args[0]:
            print(e.args[0])

if len(sys.argv) != 4:
    print('usage: notifier.py file "subject" "body"')

filename = sys.argv[1] # ADDED
subject = sys.argv[2] # ADDED
body = sys.argv[3] # ADDED

for username in usernames:
    send_message(r, username, subject, body)

First time posting on Stack Overflow so please be patient.

bluewizard3
  • 19
  • 1
  • 1
  • 7
  • 6
    Yeah, well, `filenames` isn't in the global scope, nor is it in the local scope of `main` so it is undefined. – juanpa.arrivillaga Nov 29 '17 at 23:46
  • 1
    Post-edit, your problem is that you're invoking `main` before defining the other global variables. To ensure all your globals are set up correctly, you should always be invoking your `main()` function as the *last* step in your module, ideally under a `if __name__ == '__main__':` guard. – ShadowRanger Nov 30 '17 at 01:18

1 Answers1

1

Your code is missing the part where it assigns a value to the variable 'filename' in the code from the referenced video

this is done on line 47 in the end code, line 37 at around 11m in:

47:    filename = sys.argv[1]
48:    subject = sys.argv[2]
49:    body = sys.argv[3]
50:
51:    r = bot_login()
52:    usernames = get_usernames(filename)

EDIT: Now we've fixed that, we need to address the next problem, which is that you've got stuff in main that should just be straight after the values are passed in via sys.argv. That means the below code should not be in the 'main' method earlier in the program, but after line 50

reddit = authenticate()
usernames = get_usernames(filename) #ERROR
print(usernames)
Zooby
  • 325
  • 1
  • 7
  • have you actually passed in a value somehow so that the variable 'filename' contains a reference to the desired file? – Zooby Nov 30 '17 at 00:03
  • What do you mean by passed in a value? – bluewizard3 Nov 30 '17 at 00:04
  • If you run print(filename) do you have a value? The code is expecting the program to be called in the following format (lifted from the code): usage: notifier_bot.py file \"subject\" \"body\" this means you'd have something like: notifier_bot.py 'directory\with\file' 'I am a subject' 'and I am a body' or something to that effect, in which case: print(filename) will return something like 'directory\with\file' – Zooby Nov 30 '17 at 00:10
  • So in the video, he inputs the equivalent in my code to: 'python notifier.py notifier.txt (his usernames.txt) "subject" "body" pytho' in his command line. Is this perhaps what you mean? I am still confused, sorry. – bluewizard3 Nov 30 '17 at 00:16
  • Yeah, so your variable 'filename' if you were to correctly copy it, should contain the value 'notifier.txt' if you run print(filename), what does it show? – Zooby Nov 30 '17 at 00:24
  • It shows the same [error](https://gyazo.com/f301e084de15f315f743d8095c57888f)...shall we move this to a chat? – bluewizard3 Nov 30 '17 at 00:29
  • I think you need minimum reputation to start a chat. Your filename variable is never instantiated. Do you have a line in your code that starts with "filename = "? If so, make sure your code is reaching that point, and the right hand side of the equation is correct. Are you able to edit your code in the original post so it shows exactly what you're trying to run atm? – Zooby Nov 30 '17 at 00:32
  • If you look near the end of my code, you’ll see that I added the three lines you referenced earlier including filename=sys.argv[1]. Is that not helping? – bluewizard3 Nov 30 '17 at 00:41
  • Thanks, so when you call that code from the command line with python notifier.py notifier.txt "subject" "body", it is still producing an error? Because now it looks as though you have correctly instantiated filename. – Zooby Nov 30 '17 at 00:43
  • Yes indeed it is – bluewizard3 Nov 30 '17 at 00:44
  • I've edited my answer to include a more complete fix, your main method is inconsistent with the video and the code. Effectively you need to move the authenticate and get_usernames to AFTER you've done the sys.argv methods. – Zooby Nov 30 '17 at 00:51
  • Maybe I am mistaken but bboe, the author of PRAW recommended to use "def main()" to organize the things I have put in it. Is that not true or am I using it in the wrong place/way? – bluewizard3 Nov 30 '17 at 01:09
  • I would recommend following the tutorial word for word to understand what they're doing, and after that begin expanding on it. You are correct in structuring the work into __main__ is preferable as it [behaves differently with being called from command line vs imported](https://stackoverflow.com/questions/419163/what-does-if-name-main-do), but first follow and grok the tutorial. Once that's done, have a play around with refactoring into more solid code. – Zooby Nov 30 '17 at 01:16
  • Let me try that out – bluewizard3 Nov 30 '17 at 01:17
  • OK so that part works. Now there is a new error. Should I create a new question? – bluewizard3 Nov 30 '17 at 01:38
  • You should search stack overflow and the internet before posting a question, make sure you've copied the code in the tutorial letter for letter, and if still no luck after all that, post a new question, yeah – Zooby Nov 30 '17 at 01:57
  • Thanks for your help sir/ma’am – bluewizard3 Nov 30 '17 at 02:20