How to print the variable inside the function - python

My code is below. trying to print the htmlStr inside the function. Is there any way
import urllib.request
import re
url = 'http://dummy.restapiexample.com/api/v1/employees'
def testhtml(self):
response = urllib.request.urlopen(url)
htmlStr = response.read().decode('ISO-8859-1')
with open("html.csv","a+") as file:
file.write(htmlStr)
pdata = re.findall(r'"employee_name":"(\'?\w+)"', htmlStr)
return pdata
print (htmlStr) I did outside the function thrown error
when I did print (htmlStr) got the error NameError: name 'htmlStr' is not defined

You're getting an error because you're trying to access a local variable outside of its domain.
Here's what this looks like in your code:
# 1. Begin creating your function
def testhtml(self):
# 2. This is a local environment.
# Any variables created here will not be accessible outside of the function
response = urllib.request.urlopen(url)
# 3. The local variable `htmlStr` is created.
htmlStr = response.read().decode('ISO-8859-1')
with open("html.csv","a+") as file:
# 4. Your local variable `htmlStr` is accessed.
file.write(htmlStr)
pdata = re.findall(r'"employee_name":"(\'?\w+)"', htmlStr)
return pdata
# 5. Your function is now complete. The local variable `htmlStr` is no longer accessible.
Does that make sense?
If you want to print your function (while debugging) you can place a print statement in the function. (Just make sure to eventually remove it to prevent disorganized console readouts.) If you need to access the variable outside of the function, consider including in the output.

Related

TestComplete with Python - Python runtime error. NameError: name 'page' is not defined

I am new to python and test complete just trying to automate a sample webpage but stuck with below error.
I have searched and know that I am surely making mistakes in defining the variables.
have recorded the below script and it runs fine if I keep it one function but when I keep it in separate functions(to login into page have kept the code in Login() function and calling it in Test1() ) it fails though it login into the page .
global browser,page
def Login():
Browsers.Item[btChrome].Navigate("http://secure.smartbearsoftware.com/samples/testcomplete11/WebOrders/login.aspx")
browser=Aliases.browser
page = browser.pageWebOrdersLogin
form = page.formAspnetform
form.textboxUsername.Keys("[Enter]")
page.Wait()
textbox = form.textboxUsername2
textbox.SetText("Tester")
textbox.Keys("[Tab]")
passwordBox = form.passwordboxPassword
passwordBox.SetText(Project.Variables.Password1)
passwordBox.Keys("[Enter]")
page = browser.pageDefault
page.Wait()
def Test1():
global page
Login()
page.formAspnetform.link.Click()
page = browser.pageProcess
page.Wait()
form = page.formAspnetform
form.selectProduct.ClickItem("FamilyAlbum")
textbox = form.textboxQuantity
textbox.SetText("40")
form.submitbuttonCalculate.ClickButton()
textbox = form.textboxCustomerName
textbox.SetText("nitin")
textbox.Keys("[Tab]")
textbox = form.textboxStreet
textbox.SetText("marvel")
textbox.Keys("[Tab]")
textbox = form.textboxCity
textbox.SetText("pune")
textbox.Keys("[Tab]")
textbox = form.textboxState
textbox.SetText("maharashta")
textbox.Keys("[Tab]")
form.textboxZip.SetText("411014")
cell = form.cell
cell.radiobuttonVisa.ClickButton()
textbox = form.textboxCardNr
textbox.SetText("411882781991")
textbox = form.textboxExpireDateMmYy
textbox.SetText("01/23")
form.linkInsertbutton.Click()
page.Wait()
textNode = page.textnode
aqObject.CheckProperty(textNode, "contentText", cmpEqual, "New order has been successfully added.")
page.link.Click()
browser.pageDefault2.Wait()
Error:
Python runtime error.
NameError: name 'page' is not defined
Error location:
Unit: "WebTesting\WebTesting\Script\WebTest"
Line: 22 Column: 1.
The global declaration for page needs to be repeated inside the def Login; but a much better design is to pass non-global variables between these functions. Either
def login():
browser = ...
page = ...
...
return browser, page
def test1():
browser, page = login()
...
or perhaps conversely have the caller define and pass these in;
def login(browser, page):
...
def test1()
browser = ...
page = ...
login(browser, page)
...
Your current design calls for the former, but both patterns are common, and the second is perhaps more logical. Generally, try to define variables in the context where they are going to be used, and then pass them down into other functions as necessary. As a rule of thumb, try to make your variables as narrowly scoped and short-lived as possible.
Notice also how we usually do not capitalize function names in Python.

How to set explicit variables in an URL - python

In the following code snippet at the bottom, how do I explicitly set {0} and {1} to variables like:
0=host-123
1=128.24.22.21
such that I can keep the URL with the variables and call those variables elsewhere without actually explicitly setting them as host-123 and 128.24.22.21 elsewhere ?
def getipam(host, neighboraddr, token):
"""Fetch IPAM data for host and neighbor ip"""
url = 'https://ipam.app.secretcdn.net/v1/hosts/{0}/bgp/neighbors/neighbor/{1}'.format(host, neighboraddr)
response = requests.get(url, headers={'x-api-rw': token})
results = response.json()
return results
0/1/integers are immutable in python. You cannot change the value. You might want to call it by some other name like x or y something and then you can assign it

"SyntaxWarning: name 'our_mongo' is used prior to global declaration"

My code keeps giving me the above syntax warning. My code includes, but is not limited to:
class SocketHandler(WebSocketHandler):
def on_message(self, message):
ball = json.loads(message)
user = User(ball['identifier'])
if ball['command'] == 'search':
global our_mongo
search_results = our_mongo.find({'$text':{'$search':ball['search_term']}},{'score':{'$meta':"textScore"}})
self.write_message({
'command': 'search-results',
'results': list(search_results.sort([('score', {'$meta': 'textScore'})]).limit(10)),
})
elif ball['command'] == 'save-node': # hopefully this can handle both new nodes and changes to nodes
node_dict = ball['node_dict']
if 'importance' in node_dict.keys():
node_dict['importance'] = int(node_dict['importance'])
try:
node_obj = node.create_appropriate_node(node_dict)
print('node made. looks like: '+str(node_obj)+'. Now time to put it into the DB...')
global our_mongo
# take a look at the dependencies now
previous_dependency_ids = [node.reduce_string(dependency) for dependency in list(our_mongo.find({"_id": node_obj.id}))[0]["_dependencies"]] # if this works, try using set() instead of list and elimination the set()s below
print('prev deps are: '+str(previous_dependency_ids))
our_mongo.upsert({ "_id": node_obj.id }, node_obj.__dict__)
# take a look at the current dependencies
current_dependency_ids = [node.reduce_string(dependency) for dependency in list(our_mongo.find({"_id": node_obj.id}))[0]["_dependencies"]] # if this works, try using set() instead of list and elimination the set()s below
print('curr deps are: '+str(current_dependency_ids))
update_our_DAG()
# send an update of the graph to the user if there is a new dependency:
for new_dependency in set(current_dependency_ids) - set(previous_dependency_ids):
self.request_node(new_dependency, ball, user)
# OR IF THE SAVED NODE IS A BRAND NEW NODE, we have to include all the deps
except Exception as error:
# stuff didn't work, send error back to user
print('ERROR: '+str(error))
self.write_message({
'command': 'display-error',
'message': str(error),
})
def update_our_DAG():
# 1. grab nodes and edges from database
all_node_dicts = list(Mongo("math", "nodes").find())
# 2. create a networkx graph with the info...
global our_DAG
our_DAG = nx.DAG()
for node_dict in all_node_dicts:
node = create_appropriate_node(strip_underscores(node_dict))
our_DAG.add_n(node)
def make_app():
return Application(
[
url('/', RedirectHandler, {"url": "index.html"}, name="rooth"),
url('/websocket', SocketHandler),
url('/json', JSONHandler, name="jsonh"),
url(r'/index(?:\.html)?', IndexHandler, name="indexh"),
# captures anything at all, and serves it as a static file. simple!
url(r'/(.*)', StaticHandler, {"path": "../www/"}),
],
# settings:
debug=True,
)
def make_app_and_start_listening():
# enable_pretty_logging()
application = make_app()
# by listening on the http port (default for all browsers that i know of),
# user will not have to type "http://" or ":80" in the URL
application.listen(80)
# other stuff
IOLoop.current().start()
if __name__ == "__main__":
# 0. create a global mongo object for later use (for upserts in the future)
our_mongo = Mongo("math", "nodes")
# 1 and 2
update_our_DAG()
axioms = [our_DAG.n(node_id) for node_id in ['set', 'multiset', 'vertex']]
# 3. launch!
make_app_and_start_listening()
I've tried everything and it's still an issue. WHY is this a syntax error? What is the best way to fix this?
It is not a SyntaxError but a SyntaxWarning. Python warns that you're using our_mongo variable before a global our_mongo within the function.
Syntactically it does not actually matter on which line of the function the global statement is; but the idiomatic way would be to use global before the first access.
Another issue altogether is that you have multiple global our_mongo statements, where single would do, and also that you do not even need the global at all - it is only for the case when you want to assign a new value to the global variable; i.e.
def foo():
global bar # this line is required for the next line
# to change the global variable instead of
# the local variable
bar = 42
Thus, just remove all global statements altogether from your on_message, they're unnecessary.
The only reason a name is declared global in a function is so that it will be bound in global scope instead of local scope; when accessing a name the global scope is always searched regardless. Since your code never binds our_mongo within any function there is no reason to declare it global in the first place.

How to deal with globals in modules?

I try to make a non blocking api calls for OpenWeatherMap, but my problem is:
When i was doing tests on the file, and run it, the global api was taking effect, but when importing the function, global dont work anymore, and api dident change: api = ""?
Just after declaring the function i put global api, and then when I use print 'The API link is: ' + api I get the exact api, but global dident took effect!
Here is the code: https://github.com/abdelouahabb/tornadowm/blob/master/tornadowm.py#L62
What am I doing wrong?
When I import the file:
from tornadowm import *
forecast('daily', q='london', lang='fr')
The API link is: http://api.openweathermap.org/data/2.5/forecast/daily?lang=fr&q=london
api
Out[5]: ''
When executing the file instead of importing it:
runfile('C:/Python27/Lib/site-packages/tornadowm.py', wdir='C:/Python27/Lib/site-packages')
forecast('daily', q='london', lang='fr')
The API link is: http://api.openweathermap.org/data/2.5/forecast/daily?lang=fr&q=london
api
Out[8]: 'http://api.openweathermap.org/data/2.5/forecast/daily?lang=fr&q=london'
Edit: here is the code, if the Git got updated:
from tornado.httpclient import AsyncHTTPClient
import json
import xml.etree.ElementTree as ET
http_client = AsyncHTTPClient()
url = ''
response = ''
args = []
link = 'http://api.openweathermap.org/data/2.5/'
api = ''
result = {}
way = ''
def forecast(way, **kwargs):
global api
if way in ('weather', 'forecast', 'daily', 'find'):
if way == 'daily':
way = 'forecast/daily?'
else:
way += '?'
for i, j in kwargs.iteritems():
args.append('&{0}={1}'.format(i, j))
a = ''.join(set(args))
api = (link + way + a.replace(' ', '+')).replace('?&', '?')
print 'The API link is: ' + api
def handle_request(resp):
global response
if resp.error:
print "Error:", resp.error
else:
response = resp.body
http_client.fetch(api, handle_request)
else:
print "please put a way: 'weather', 'forecast', 'daily', 'find' "
def get_result():
global result
if response.startswith('{'):
print 'the result is JSON, stored in the variable result'
result = json.loads(response)
elif response.startswith('<'):
print 'the result is XML, parse the result variable to work on the nodes,'
print 'or, use response to see the raw result'
result = ET.fromstring(response)
else:
print '''Sorry, no valid response, or you used a parameter that is not compatible with the way!\n please check http://www.openweathermap.com/api for more informations''
It's the side effect of using global.
When you do from tornadowm import * your forecast() function is, we could say metaphorically, "on its own" and is not "hard-linked" to your global space anymore.
Why? Because any effect you make on your global api will "end" with your function, and the definition of api = "" in your global space will take precedence.
Also, as a side note, it's not considered a good practice to use from something import *. You should do from tornadowm import forecast or even better, import tornadown and then use tornadowm.forecast().
OR
Even better, I just noticed your forecast() function doesn't return anything. Which technically makes it not a function anymore, but a procedure (a procedure is like a function but it returns nothing, it just "does" stuff).
Instead of using a global, you should define api in this function and then return api from it. Like this:
def forecast(blablabla):
api = "something"
blablabla
return api
And then
import tornadowm
api = tornadown.forecast(something)
And you're done.
Globals are global only to the module they're defined in. So, normally, you would expect tornadowm.api to be changed when you call forecast, but not api in some other namespace.
The import * is contributing to your understanding of the problem. This imports api (among other names) into the importing namespace. This means that api and tornadowm.api initially point to the same object. But these two names are not linked in any way, and so calling forecast() changes only tornadowm.api and now the two names point to different objects.
To avoid this, don't use import *. It is bad practice anyway and this is just one of the reasons. Instead, import tornadowm and access the variable in the importing module as tornadowm.api.
I'm afraid this is because global is coupled within module, by the time you from tornadowm import * you have imported the api name, but the global api won't take any effects within another module.

accessing the "local" variable

def get(self):
if self.request.get('fmt')=='json':
KeyofQuestion = self.request.path[1:]
QuestionText = Question.get_by_key_name(KeyofQuestion).question
AnswersQuery = Question.get_by_key_name(KeyofQuestion).answers_collection
a=[]
Jsonobject = {'Question':QuestionText}
for each in AnswersQuery:
a = a.append(each.answer)
Hey, i am just confused that when I run the codes above, I got an error that says, Nonetype variable:a doesnt have method append, but I declared the a as a list before I called and they are inside the same function "get", so I assumed they are all treated as local variables. How come it cant map it? Thank you
You are assigning None to a. Change this:
a = a.append(each.answer)
to:
a.append(each.answer)

Categories

Resources