Calling variables from inside functions in Python - python

I know I have already asked a question like this before but I have made my code much cleaner and I am still coming up with a problem.
My code goes like this:
class Email_Stuff:
def Get_From_Email():
#code to open up window and get email address
emailaddr = #the input
return emailaddr
def Get_To_Email():
#code to open up window and get to email address
recipaddr = #the input
return recipaddr
def Get_Email_Address():
#code to open up window and get email username
EmailUser = #the input
return EmailUser
def Get_Email_Password():
#code to open up window and get email password
EmailPass = #the input
return EmailPass
def Send_Email():
import smtplib
server = smtplib.SMTP('smtp.gmail.com', 587)
server.login((EmailUser),(EmailPass))
message = "Python Test Email"
server.sendmail(emailaddr,recipaddr,message)
I need to get the variables: emailaddr, recipaddr, EmailUser, and EmailPass into the function Send_Email. I'm not sure how I could do that though because when I run this code, it tells me that "the global name isn't defined".
Any ideas?

Make emailaddr, recipaddr, EmailUser, and EmailPass become instance variables by adding prefix "self.".
class Email_Stuff():
def Get_From_Email(self):
#code to open up window and get email address
self.emailaddr = #the input
def Get_To_Email(self):
#code to open up window and get to email address
self.recipaddr = #the input
def Get_Email_Address(self):
#code to open up window and get email username
self.EmailUser = #the input
def Get_Email_Password(self):
#code to open up window and get email password
self.EmailPass = #the input
def Send_Email(self):
import smtplib
server = smtplib.SMTP('smtp.gmail.com', 587)
server.login((self.EmailUser),(self.EmailPass))
message = "Python Test Email"
server.sendmail(self.emailaddr,self.recipaddr,self.message)
instance = Email_Stuff()
instance.Get_From_Email()
instance.Get_To_Email()
instance.Get_Email_Address()
instance.Get_Email_Password()
instance.Send_Email()
BTW, name of methods should be lowercase.

First, if you want these functions to methods associated with an instance of this class, then each method will need a reference to the instance itself as the first argument, usually designated as self, though you can name it anything you like.
For example:
def Get_Email_Password(self):
#code to open up window and get email password
EmailPass = #the input
return EmailPass
Next, you have two options to get the values ready for sendmail. You can either call each method from within the Send_Email method and store the returned values for each one. That would look like this:
def Send_Email(self):
emailaddr = self.Get_For_Email()
recipaddr = self.Get_Email_Address()
...
Or you can store the values, instead of returning them, as instance variables. So, you would have something like this:
def Get_Email_Password(self):
#code to open up window and get email password
EmailPass = #the input
self.emailaddr = EmailPass
And then, in your Send_Email method, you would reference the instance variables you have saved:
def Send_Email(self):
...
server.sendmail(self.emailaddr, self.recipaddr, self.message)
How you choose to do it is up to you, but I prefer the first way. I also suggest you read up on PEP8

Related

How to pass a variable from one function to another function

I am making python based Email broadcasting in which i have created entries like email, pass, there is csv browse as well which will brose a Email_list_container file and a submit button which will call a send mail function to send bulk email along with attachment, problem is when browse is used to grab emails from csv it stores to a variable and then return to function but when I call this variable in send mail function is does not allow me to use it there. same with attachment function is is not coming in send mail function either.
i have tried Global
newvar = browse()
and calling new var but this calls whole function to pop-up again new window to open another file which does not make any sense.
help me guys.
from tkinter import *
import tkinter.messagebox as msg
import smtplib as smtp
import csv
from itertools import chain
#browse function which stores value from csv file
def browse():
from itertools import chain
file_path=filedialog.askopenfilename(title="Open CSV file")
with open(file_path) as csvfile:
read = csv.reader(csvfile)
for row in read:
ini_list.append(row)
flatten_list = list(chain.from_iterable(ini_list))
rcvr_emails =list(flatten_list)
# print(rcvr_emails)
file_label = Label(window,text=file_path, border=0, bg='#BAE1E3',font="inter 10", fg="grey").place(x=330,y=230)
recemail = rcvr_emails
#what i want is submit function to grab a variable from browse function as email list
def submit():
try:
email = login_email.get()
pass_word = login_pass.get()
subject = email_subject.get()
body = email_body.get()
server = smtp.SMTP("smtp.gmail.com",587)
server.starttls()
server.ehlo()
server.login(email,pass_word)
massage = "subject:{}\n\n{}".format(subject,body)
server.sendmail(email,recemail,massage)
server.quit()
msg.showinfo("Status","Mails have been sent to the Targatted Email's List.\nThank You for using our services.")
except:
msg.showwarning("ERROR","SMTP API could not login the credentials,\nPlease check Email & Password then try again.")
Just return recemail from browse function then pass it as argument to submit function:
def browse():
from itertools import chain
file_path=filedialog.askopenfilename(title="Open CSV file")
with open(file_path) as csvfile:
read = csv.reader(csvfile)
for row in read:
ini_list.append(row)
flatten_list = list(chain.from_iterable(ini_list))
rcvr_emails =list(flatten_list)
# print(rcvr_emails)
file_label = Label(window,text=file_path, border=0, bg='#BAE1E3',font="inter 10", fg="grey").place(x=330,y=230)
recemail = rcvr_emails
return recemail
def submit(email_list):
// your code
Then in your main program:
received_email = browse()
submit(received_email)
Or in one line:
submit(browse())

How to replace email domain misspellings

I manage a booking system where people enter their emails to book appointments. Unfortunately, many of the email addresses have typos, especially in the top-level domain. I'd like to implement a function to identify when the domain should be .com, which should be all cases where it starts with ".c".
I wrote the function and tested the individual lines, which seem to work. But when I run the function on a set of emails, it only returns the email with no ".c", meaning it only returns 'my_name_is#orange.org'. The ideal output would be:
['me.you#perp.com',
'appleorange#msn.edu.com',
'laughable#gmail.com',
'notfunny#pointdexter.com',
'very.latin...word#word.nutherwork.com',
'very.latin..word#word.nutherwork.com',
'my_name_is#orange.org']
Any help would be appreciated!
emails = ['me.you#perp.comp',
'appleorange#msn.edu.cot',
'laughable#gmail.copl',
'notfunny#pointdexter.com',
'very.latin...word#word.nutherwork.com',
'very.latin..word#word.nutherwork.cnm',
'my_name_is#orange.org']
def domain(emails):
for email in emails:
parse_mail = email.split('.')
parse_mail = parse_mail[-1]
if parse_mail[0] == "c":
email = email.replace(parse_mail,"com")
pass
return email
print(domain(emails))
It returns the email without "c" because that's the last one in the array.
Your routine "domain" only returns the last email in the array. If you put the org address higher up, it'll return an email with a "c".
I expect what you're looking for is:
def domain(emails):
for i in range(len(emails)):
parse_mail = emails[i].split('.')
if parse_mail[-1][0] == "c":
parse_mail = emails[i].split('.')[:-1]
parse_mail.append("com")
correct = '.'.join(parse_mail)
emails[i] = correct
pass
return emails
print(domain(emails))
But as Sembei Norimaki, mentioned - this will also auto-correct (erroneously) other extensions beginning with a 'c'.

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.

npyscreen and threading : change form in an other thread

So here we go. I am working on a funny project that purpose a login interface (standard username/password input) :
class LoginDisplay(npyscreen.Form):
def create(self):
self.name = Config.welcome_message
self.wgUsername = self.add(npyscreen.TitleText, name="Username :")
self.wgPassword = self.add(TitlePassword, name="Password :")
def beforeEditing(self):
self.parentApp.unlog_user()
self.wgUsername.value = ""
self.wgPassword.value = ""
def afterEditing(self):
self.parentApp.log_user(self.wgUsername.value, self.wgPassword.value)
Sounds cool, work fine.
My issue is that I am working on an other way to login using an NFC reader. The code is kind of simple :
def badge(myApp):
""" Target function of a Thread """
device = serial.Serial('/dev/ttyUSB0',timeout=60)
device.setTimeout(1)
buff = ''
while myApp.isAlive:
s = device.read(1)
if s == '':
sleep(1)
elif s == '\r' :
# buff var containing the badge id
myApp.login_by_badge(buff)
else:
buff = buff + s
So the objective is, if the login is correct, to change the current form (the current form) like this :
class MyApplication(npyscreen.NPSAppManaged):
# .../...
def log_user(self, username, password):
if self._valid_login(username, password):
self.switchForm("ANOTHER_FORM")
def login_by_badge(self, badge_id):
if self._valid_badge(badge_id):
self.switchForm("ANOTHER_FORM")
Of course, switching forms in the sub-thread does. I look deep in the sources, and it looks like the library npyscreen is absolutely not designed for this kind of things.
Question: Should I implement my owns windgets, forms and parts of my application to manage this, or is there a common way to deal with threads interactions in npyscreen ?
I'm the author of npyscreen.
You should look in to using the event system that was added in the most recent versions. I added that in part to allow you to send messages between threads.

Passing variables to functions in Python

Im writing test scripts in Python for Selenium web testing.
How do I pass parameters through a Python function to call in a later function?
I first have a login test function.
Then I have a new user registration function. Im trying to pass the Username and Password I use in the registration function to the testLogin() function that I call inside the testRegister() function.
This is my python code:
userName = "admin"
password = "admin"
#pass username and password variables to this function
def testLogin(userName,password):
browser = webdriver.Firefox()
browser.get("http://url/login")
element = browser.find_element_by_name("userName")
element.send_keys(userName)
element = browser.find_element_by_name("userPassword")
element.send_keys(password)
element.send_keys(Keys.RETURN)
browser.close()
# test registration
def testRegister():
browser = webdriver.Firefox()
browser.get("http://url/register")
#new username variable
newUserName = "test"
element = browser.find_element_by_name("regUser")
element.send_keys(newUserName)
#new password variable
newUserPassword = "test"
element = browser.find_element_by_name("regPassword")
element.send_keys(newUserPassword)
#
#now test if user is registered, I want to call testLogin with the test user name and pw.
testLogin(newUserName,newUserPassword)
browser.close()
Any values you have around—whether you got them as function arguments, or received them by calling functions, or just defined them on the fly—you can pass as arguments to any other function.
So, if you want to pass some values through testRegister for it to use with testLogin, just do this:
# test registration
def testRegister(userName, password):
browser = webdriver.Firefox()
browser.get("http://url/register")
element = browser.find_element_by_name("regUser")
element.send_keys(userName)
element = browser.find_element_by_name("regPassword")
element.send_keys(password)
Is there something more you wanted?
You can create a new function to run all of your tests.
def run_tests(username, password):
testLogin(username,password)
testRegister(username, password)
You will need to modify testRegister so it accepts username and password parameters.
Then you can start your script with run_tests('admin', 'letmein')

Categories

Resources