-3
def make_bill(): # makes bill
    global t, c, B, cur, st, names, qty, sl , named, addd, name1, add,det, vc_id,m
    price=[0.0]*10
    q=0
    det=['','','','','','','','']
    det[2]=str(sl)
    for i in range(len(sl)):
        print (sl[i],' ',qty[i],' ',names[i])
    for k in range(len(sl)):
        cur.execute("select * from med where sl_no=?",(sl[k],))
        for i in cur:
            price[k]=int(qty[k])*float(i[4])
            print (qty[k],price[k])
            cur.execute("update med set qty_left=? where sl_no=?",(int(i[3])-int(qty[k]),sl[k]))
        c.commit()
    det[5]=str(random.randint(100,999))
    B='bill_'+str(det[5])+'.txt'
    total=0.00
    for i in range(10):
        if price[i] != '':
            total+=price[i] #totalling
    m='\n\n\n'
    m+="===============================================\n"
    m+="                                  No :%s\n\n" % det[5]
    m+="          MEDPLUS CHEMIST AND DRUGGIST\n"
    m+="  VIT University, Katpadi, Vellore, T.M.\n\n"
    m+="-----------------------------------------------\n"
    if t==1:
        m+="Name: %s\n" % named
        m+="Address: %s\n" % addd
        det[0]=named
        det[1]=addd
        cur.execute('select * from cus')
        for i in cur:
            if i[0]==named:
                det[7]=i[2]
    else:
        m+="Name: %s\n" % name1.get()
        m+="Address: %s\n" % add.get()
        det[0]=name1.get()
        det[1]=add.get()
    m+="-----------------------------------------------\n"
    m+="Product                      Qty.       Price\n"
    m+="-----------------------------------------------\n"#47, qty=27, price=8 after 2
    for i in range(len(sl)):
        if names[i] != 'nil':
            s1=' '
            s1=(names[i]) + (s1 * (27-len(names[i]))) + s1*(3-len(qty[i])) +qty[i]+ s1*(15-len(str(price[i])))+str(price[i]) + '\n'
            m+=s1
    m+="\n-----------------------------------------------\n"
    if t==1:
        ntotal=total*0.8
        m+='Total'+(' '*25)+(' '*(15-len(str(total)))) + str(total)+'\n'
        m+="Valued customer Discount"+ (' '*(20-len(str(total-ntotal))))+'-'+str(total-ntotal)+'\n'
        m+="-----------------------------------------------\n"
        m+='Total'+(' '*25)+(' '*(12-len(str(ntotal)))) +'Rs '+ str(ntotal)+'\n'
        det[3]=str(ntotal)
    else:
        m+='Total'+(' '*25)+(' '*(12-len(str(total)))) +'Rs '+ str(total)+'\n'
        det[3]=str(total)

    m+="-----------------------------------------------\n\n"
    m+="Dealer 's signature:___________________________\n"
    m+="===============================================\n"
    print (m)
    p=time.localtime()
    det[4]=str(p[2])+'/'+str(p[1])+'/'+str(p[0])
    det[6]=m
    bill=open(B,'w')
    bill.write(m)
    bill.close()
    cb=('cus_name','cus_add','items','Total_cost','bill_dt','bill_no','bill','val_id')
    cur.execute('insert into bills values(?,?,?,?,?,?,?,?)',(det[0],det[1],det[2],det[3],det[4],det[5],det[6],det[7]))
    c.commit()

I have this function above. I want to use the m variable from this function in send_mail function below.

def send_mail(): # Sends Email  
    mail_from ='Admin <mail@pharmacy.store>'
    mail_to ='Noor <khan.noorulameen@yahoo.com>'

    msg = MIMEMultipart()
    msg['From'] = mail_from
    msg['To'] = mail_to
    msg['Subject'] = 'Billing'
    mail_body = m
    msg.attach(MIMEText(mail_body))

    try:
        server = smtplib.SMTP_SSL('smtp.sendgrid.net', 465)
        server.ehlo()
        server.login('apikey', '[redacted]')
        server.sendmail(mail_from, mail_to, msg.as_string())
        server.close()
        print("mail sent")
    except:
        print("issue")

I made the m variable as global but still I am getting m as undefined

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Arif
  • 33
  • 6
  • 2
    you should probably not post your apikey here... remove it from the question and make sure to change the key on the server – Felix Dec 10 '18 at 21:54
  • I do not see any call of `send_mail()` in your `make_bill()` function... – jeannej Dec 10 '18 at 21:55

1 Answers1

0

The proper way to do this would be to have some module-level scope where m is defined, and then passed between the functions.

This means ending the function make_bill() with a line line return m, the send_mail() function made to take the m as an input, and then the module would look like

def make_bill():
    # ... and so on
    return m

def send_mail(m):
    # ... and so on

if __name__ == '__main__':
    m = make_bill()
    send_mail(m)
Andrew F
  • 2,690
  • 1
  • 14
  • 25
  • ```def make_bill(): #..... and so on return m``` def send_mail(m): mail_body=m Calling the func = ```Button(st,width=15,text='Buy', command=send_mail(m)).grid(row=5,column=6)``` – Arif Dec 10 '18 at 22:16
  • That looks like a tkinter `Button` object. If so, no. The `command` object expects a function, whereas `send_mail(m)` evaluates to some returned value, `None` in the above case. See [here](https://stackoverflow.com/questions/6920302/how-to-pass-arguments-to-a-button-command-in-tkinter) for passing the `m` argument to the `send_mail` command function. – Andrew F Dec 11 '18 at 09:52
  • But `m` is in `def_bill`. How to use `m` outside it's scope as a global variable ? – Arif Dec 11 '18 at 19:23
  • The `make_bill` function *returns* a value that is assigned to the variable `m`. This can be used as an input to the next function. You can find a lot more detail about functions in [the Python Tutorial](https://docs.python.org/3/tutorial/controlflow.html#defining-functions). – Andrew F Dec 11 '18 at 21:46