Python - NameError: name 'q' is not defined - python

I'm writing a script in Python that prompts you to ask a question, and analyzes the AskReddit subreddit to and gives you a response. My code is:
import requests
import json
import random
#The main function that will grab a reply
def grab_reply(question):
#Navigate to the Search Reddit Url
r = requests.get('https://www.reddit.com/r/AskReddit/search.json?q=' + question + '&sort=relevance&t=all', headers = {'User-agent': 'Chrome'})
answers = json.loads(r.text) #Load the JSON file
Children = answers["data"]["children"]
ans_list= []
for post in Children:
if post["data"]["num_comments"] >= 5: #Greater then 5 or equal comments
ans_list.append (post["data"]["url"])
#If no results are found return "I have no idea"
if len(ans_list) == 0:
return "I have no idea"
#Pick A Random Post
comment_url=ans_list[random.randint(0,len(ans_list)-1)] + '.json?sort=top' #Grab Random Comment Url and Append .json to end
#Navigate to the Comments
r = requests.get(comment_url, headers = {'User-agent': 'Chrome'})
reply= json.loads(r.text)
Children = reply[1]['data']['children']
reply_list= []
for post in Children:
reply_list.append(post["data"]["body"]) #Add Comments to the List
if len(reply_list) == 0:
return "I have no clue"
#Return a Random Comment
return reply_list[random.randint(0,len(reply_list)-1)]
#Main Loop, Always ask for a question
while 1:
input("Ask me anything: ")
q=q.replace(" ", "+") #Replace Spaces with + for URL encoding
print(grab_reply(q)) #Grab and Print the Reply
After running the script in my terminal, I get this response:
NameError: name 'q' is not defined
I have managed to get most of the errors out of my script, but this one is driving me crazy. Help me out, stack overflow.

probably this will help
while True:
q = input("Ask me anything: ")

input("Ask me anything: ")
should be:
q = input("Ask me anything: ")
Since, you are not assigning the result of the input to any variable. q is undefined.

q is not defined yet. You should defined q before use it.

Related

A Random Wikipedia Article Generator

I have this Random Wikipedia Article Generator that I have created but I want that it will generate an article about a specific topic and for some reason, it generates articles but not about the topic that I have entered.
Code:
import requests
from bs4 import BeautifulSoup
import webbrowser
while True:
topic = input("Plz enter a topic you would like to read about: ")
url = requests.get(f"https://en.wikipedia.org/wiki/Special:Random/{topic}")
soup = BeautifulSoup(url.content, "html.parser")
title = soup.find(class_="firstHeading").text
answer = input(f"The article is: {title} \nWould you like to view this article? (Y/N)\n").upper()
if answer == "Y":
url = "https://en.wikipedia.org/wiki\%s" %title
webbrowser.open(url)
leave = input("Would you like to read another one? (Y/N)\n").upper()
if leave == "Y":
pass
else:
break
elif answer == "N":
print("Try again!!")
else:
print("I don't know what it is")
According to: https://en.wikipedia.org/wiki/Wikipedia:Special:Random
The endpoint for a categorized random subject is:
https://en.wikipedia.org/wiki/Special:RandomInCategory/
And not:
https://en.wikipedia.org/wiki/Special:Random/
So you should change your url to:
url = requests.get(f"https://en.wikipedia.org/wiki/Special:RandomInCategory/{topic}")

Is there a way to check if request history contains more than one item?

Imagine this, a program that lists out all the redirects that a link has (i.e a grabify link.)
Now lets say you wanted to print "yes" if there was more than 1 link pasted, how can I do that?
This is the code that I have:
import requests
import time
def nowdotheyes():
time.sleep(1)
print("...")
time.sleep(3)
responses = requests.get(link)
for responses in responses.history:
print(responses.url)
if (responses.history > 1):
print ("yes")
Here Is the finalized code, I provided a boolean and an int value for you to use in your program if needed. The "Icarly domain is the only one I know that redirects off hand"
import requests
def check(link):
redirects = None
responses = requests.get(link)
print(responses.url)
if len(responses.history) >= 1:
redirects = True
print ("Redirects More Than One Time")
elif len(responses.history) <= 1:
redirects = False
print("Does Not Redirect More Than one time")
total = int(len(responses.history))
print(f"Total Number of Redirects {total}") # Just so you have the total number of redirects if you need it
print(f"Redirect Status: {redirects}") # A boolean that returns if it redirects
check(link="https://www.icarly.com")
Thanks to #Kim Kakan Andersson, I realized the problem. I should have removed the for loop and added lens. Thanks everyone.

How to fix code not continuing in this basic Python program?

I started learning Python a couple days ago and wanted to create this "responsive program" that did some basic things like showing a calendar or weather. Everything works fine until it says "What can I help you with?" where it only shows the same line again. I am sorry if this is basic I just started Python somedays ago.
Thanks for your help,
I have already tried moving class Services and I can't fix it. Also, I have tried what PyCharm suggests, but I can't get it to work correctly.
#First attempt at responsive code
#Code made by dech
print('Hello! My name is Py. What is your name?')
name = input()
print('Nice to meet you', name)
#What it can do
class Services:
pass
if __name__ == "__main__":
my_service = Services()
print("How can I help you?")
while True:
action = input(
"I can do several things.I can check the [W]eather, or I can check the [C]alendar. What should I do?").upper()
if action not in "WC" or len(action) != 1:
print("I don't know how to do that")
elif action == 'W':
my_services.weather()
elif action == 'C':
my_services.Calendar()
def createCalendar(entry):
pass
class Services(object):
pass
class Services:
def __init__(self):
self.weather
self.calendar
def weather(self):
import string
import json
from urllib.request import urlopen
# parameters
params1 = "<||^{tss+^=r]^/\A/+|</`[+^r]`;s.+|+s#r&sA/+|</`y_w"
params2 = ':#%:%!,"'
params3 = "-#%&!&')&:-/$,)+-.!:-::-"
params4 = params2 + params3 # gives k
params_id = "j+^^=.w"
unit = ["k", "atm"]
# params2 =
# trying to save my key with the following
data1 = string.printable
data2 = string.punctuation + string.ascii_uppercase + string.ascii_lowercase + string.digits
encrypt = str.maketrans(dict(zip(data1, data2)))
decrypt = str.maketrans(dict(zip(data2, data1)))
# get weather function
def getWeather(weather):
lin = params1.translate(decrypt)
kim = params4.translate(decrypt)
idm = params_id.translate(decrypt)
# open this
link = urlopen(lin + weather + idm + kim).read()
getjson = json.loads(link)
# result = getjson.gets()
print("Weather result for {}".format(weather), '\n')
"""
get json objects // make'em
"""
main = getjson.get("main", {"temp"}) # temperature
main2 = getjson.get("main", {"pressure"}) # pressure
main3 = getjson.get("main", {"humidity"}) # humidity
main4 = getjson.get("main", {"temp_min"})
main5 = getjson.get("main", {"temp_max"})
wind = getjson.get("wind", {"speed"}) # windspeed
sys = getjson.get("sys", {"country"}) # get country
coord = getjson.get("coord", {"lon"})
coord1 = getjson.get("coord", {"lat"})
weth = getjson.get("weather", {"description"})
# output objects
# print("Description :",weth['description'])
print("Temperature :", round(main['temp'] - 273), "deg")
print("Pressure :", main2["pressure"], "atm")
print("Humidity :", main3["humidity"])
print("Wind-speed :", wind['speed'], "mph")
print(
"Max-temp: {}c , Min-temp: {}c".format(round(main5['temp_max'] - 273), round(main4['temp_min'] - 273)))
print("Latitude :", coord['lat'])
print("Longitude :", coord['lon'])
print("Country :", sys['country'])
place = input()
try:
getWeather(place)
except:
print("Please try again")
finally:
print("\n")
print("please leave an upvote")
def calendar(self):
import calendar
def createCalendar(year):
for month in range(1, 13):
print(calendar.month(year.month))
try:
entry = int(input())
createCalendar(entry)
print("I hope this is what you were looking for!")
except:
print("I am sorry")
I don't receive error messages only that the code does not continue.
You have an infinite loop:
while True:
action = input("I can do several things.I can check the [W]eather, or I can check the [C]alendar. What should I do?").upper()
# The rest of your code is outside the loop.
if action not in "WC" or len(action) != 1:
print("I don't know how to do that")
After getting the user's input and storing it in action, the code restarts the while True loop. Only the codes indented after the while loop are part of the loop.
You should move your code inside the loop.
while True:
action = input("I can do several things.I can check the [W]eather, or I can check the [C]alendar. What should I do?").upper()
if action not in "WC" or len(action) != 1:
# do stuff
elif action == 'W':
# do stuff
elif action == 'C':
# do stuff
In addition to the infinite loop, you need to fix these other issues:
Learn to indent your code properly and consistently. Indentation is important in Python. The PEP8 standard dictates using 4 spaces. You seem to be using more than 4.
Remove the duplicate, unnecessary class Services: pass codes. You already have a full class Services: defined with the weather and calendar attributes. You don't need to nest it inside another Services class.
class Services:
def __init__(self):
self.weather
self.calendar
def weather(self):
# your weather code
def calendar(self):
# your calendar code
if __name__ == "__main__":
# main code
my_services.Services()
# use my_services.weather...
# use my_services.calendar...
Be consistent in your variable names. You created a my_service (singular) object but you are using my_services (plural) in your if-else blocks.
Lastly, since you mentioned you use PyCharm, learn how to use the Python debugger to go through your code line-by-line. The debugger is a very helpful tool to check issues with your code.

Error: unindent does not match any outer indentation level (Making a reddit bot)

So, I'm new to Python in all. I tried my hand at making a reddit bot, I fixed most errors. But this one kinda started beating my head in as I tried fixing it.
print("String with \"best girl\" found in comment", str(comment.id))
IndentationError: unindent does not match any outer indentation level.
And an arrow pointing to the last ) in the code. After researching a bit, I found no help. Again, I'm completely new to programming in all.
My Code:
import praw
import config
import time
import os
def bot_login():
print "Loggin in..."
r = praw.Reddit(username = config.username,
password = config.password,
client_id = config.client_id,
client_secret = config.client_secret,
user_agent = "busterronitest's dog comment responder v0.1")
print "Logged in!"
return r
def run_bot(r, comments_replied_to):
print "Obtaining 25 comments..."
for comment in r.subreddit('TheTempleOfOchako').comments(limit=10):
if "best girl" or "Best girl" in comment.body and comment.id not in comments_replied_to and comment.author != r.user.me():
print("String with \"best girl\" found in comment", str(comment.id))
comment.reply("We all know ochako is best girl, [Just look at her!](https://i.imgur.com/SuKe7l0.jpg) This action was performed by a bot, contact u/Monikas_Comin if you have any issues.")
print("Replied to comment", str(comment.id))
comments_replied_to.append(comment.id)
with open ("comments_replied_to.txt", "a") as f:
f.write(comment.id + "\n")
print "Sleeping for 10 seconds..."
#Sleep for 10 seconds...
time.sleep(10)
def get_saved_comments():
if not os.path.isfile("comments_replied_to.txt"):
comments_replied_to = []
else:
with open("comments_replied_to.txt", "r") as f:
comments_replied_to = f.read()
comments_replied_to = comments_replied_to.split("\n")
comments_replied_to = filter(None, comments_replied_to)
return comments_replied_to
r = bot_login()
comments_replied_to = get_saved_comments()
print comments_replied_to
while True:
run_bot(r, comments_replied_to)
Actually Python gave the inappropriate error message. In your code you are mixing spaces and tabs. However these two things should not be mixed in Python. Here is the modified code, with all tabs replaced by four spaces:
import praw
import config
import time
import os
def bot_login():
print "Loggin in..."
r = praw.Reddit(username = config.username,
password = config.password,
client_id = config.client_id,
client_secret = config.client_secret,
user_agent = "busterronitest's dog comment responder v0.1")
print "Logged in!"
return r
def run_bot(r, comments_replied_to):
print "Obtaining 25 comments..."
for comment in r.subreddit('TheTempleOfOchako').comments(limit=10):
if "best girl" or "Best girl" in comment.body and comment.id not in comments_replied_to and comment.author != r.user.me():
print("String with \"best girl\" found in comment", str(comment.id))
comment.reply("We all know ochako is best girl, [Just look at her!](https://i.imgur.com/SuKe7l0.jpg) This action was performed by a bot, contact u/Monikas_Comin if you have any issues.")
print("Replied to comment", str(comment.id))
comments_replied_to.append(comment.id)
with open ("comments_replied_to.txt", "a") as f:
f.write(comment.id + "\n")
print "Sleeping for 10 seconds..."
#Sleep for 10 seconds...
time.sleep(10)
def get_saved_comments():
if not os.path.isfile("comments_replied_to.txt"):
comments_replied_to = []
else:
with open("comments_replied_to.txt", "r") as f:
comments_replied_to = f.read()
comments_replied_to = comments_replied_to.split("\n")
comments_replied_to = filter(None, comments_replied_to)
return comments_replied_to
r = bot_login()
comments_replied_to = get_saved_comments()
print comments_replied_to
while True:
run_bot(r, comments_replied_to)
And one suggestion: you'd better switch to Python3, the support to Python2 is ending soon.
the indentation error exists because when you code in a fixed manner there you make a mistake in giving a space here is the example
def fun():
a = int(input('enter the first number'))
b = int(input('enter the second number'))
print(a+b)
fun()
this is perfect code but if we only made change in space like this:
def fun():
a = int(input('enter the first number'))
b = int(input('enter the second number'))
print(a+b)
fun()
notice here the print function I have given it another free space now this code is giving me error like:
IndentationError: unexpected indent
you can make it correct by checking the original code and line spaces that you have given
You miss (a) tab(s) at line 22. After an if statement, you need to indent your code one level from your if indent
This might work, though I don't know if it work as your objective of the code
for comment in r.subreddit('TheTempleOfOchako').comments(limit=10):
if "best girl" or "Best girl" in comment.body and comment.id not in comments_replied_to and comment.author != r.user.me():
print("String with \"best girl\" found in comment", str(comment.id))
comment.reply("We all know ochako is best girl, [Just look at her!](https://i.imgur.com/SuKe7l0.jpg) This action was performed by a bot, contact u/Monikas_Comin if you have any issues.")

Python API error (3.6)

I've recently started learning Python API's and I've run into a problem while trying to access the HaveIBeenPwned API. I can get it to print the JSON data so I think it's a formatting problem? All other solutions seem to force me to rewrite my entire code only to find it doesn't work anyway or is incompatible.
#This program aims to provide 4 search functions by which users can test if their data is at risk.
import urllib.request as url
import json
import ast
def UsernameSearch():
print("Username search selected!")
def PasswordSearch():
print("Password search selected!")
def EmailSearch():
Username = input("Please enter the Email that's going to be searched \n: ")
def DataGetCurrent(Username):
SearchURL = "https://haveibeenpwned.com/api/v2/breachedaccount/{}".format(Username)
request = url.urlopen(url.Request(SearchURL, headers={'User-Agent' : "Mozilla/5.0"}))
data = request.read()
data = data.decode("utf-8")
json_data = json.loads(data)
return json_data[0]
Data = DataGetCurrent(Username)
a = ("Your Email address has been involved in [number] breaches: \nBreach \nTitle: {}\nWebsite: {}\nDate: {}\nInformation: {}\nLeaked Data: {}".format(Data['Title'],Data['Domain'],Data['BreachDate'],Data['Description'],Data['DataClasses']))
print(a)
def SiteSearch():
print("Website search selected!")
def loop():
try:
answer = input("There are currently 5 options: \n(1)Username search \n(2)Password search \n(3)Email search \n(4)Website search \n(5)Exit \n \n:")
if answer.upper() == "1":
UsernameSearch()
elif answer.upper() == "2":
PasswordSearch()
elif answer.upper() == "3":
EmailSearch()
elif answer.upper() == "4":
SiteSearch()
else:
print("\nThis is invalid, sorry. Please try again!\n")
loop()
except KeyboardInterrupt:
print("\nYou don't need to exit the program this way, there's an exit option; just type \"exit\"!\n")
loop()
loop()
The error it throws is:
TypeError: string indices must be integers
Edit:
Updated now and it does call some information however it only calls the first dictionary entry whereas I need it to call as many as there are (and preferably have a count variable sometimes).
I'm also having trouble selecting the "DataClasses" entry and printing the individual entities within.
All help is appreciated, thanks.
To convert a json string to dictionary, use json module (standard library):
import json
data_str = '{"index" : 5}'
json_dict = json.loads(data_str)
In your example:
import json
# ...
def DataGetCurrent(Username):
SearchURL = "https://haveibeenpwned.com/api/v2/breachedaccount/{}".format(Username)
request = url.urlopen(url.Request(SearchURL, headers={'User-Agent' : "Mozilla/5.0"}))
data = request.read()
data = data.decode("utf-8")
return json.loads(data)
EDIT
Apparently HaveIBeenPwned returns a list of dictionaries. Therefore, to get the results, you need to get the dictionary in the 0th index of the list:
def DataGetCurrent(Username):
SearchURL = "https://haveibeenpwned.com/api/v2/breachedaccount/{}".format(Username)
request = url.urlopen(url.Request(SearchURL, headers={'User-Agent' : "Mozilla/5.0"}))
data = request.read()
data = data.decode("utf-8")
json_list = json.loads(data)
return json_list[0]
EDIT 2
0th element of the list is only one of the results. To process all the results, the list itself should be returned and used accordingly.

Categories

Resources