วันศุกร์ที่ 23 ตุลาคม พ.ศ. 2552

Python send mail email e-mail

วันนี้ได้ไปเล่นกับ blog ของ นายบอส มามีในส่วนการส่งเมล์ เผอิญที่เป็นเป็น รูปแบบธรรมดา
ยาว ๆ เลยขอมาจับแยกให้ดูดีขึ้น แต่ยังไม่ได้ test เลย คือเอามาแปลงอย่างเดียว
เดี๋ยวถ้าว่าง ๆ จะมาประกอบและ test ใหม่

ตอนนี้ง่วงมาก ๆ เลย Z z z z . . .

อ้างอิงจาก : http://bluegear.wordpress.com/2009/10/20/email-attach-file-with-python/#comment-32

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
import xml.etree.ElementTree as ET

class EMail(Object):
    def init(self, url_mail_server):
        self.url_mail_server = 'mailserver.company.com'
        self.smtp = smtplib.SMTP(self.url_mail_server)
        
    def gen_template(self, **kw):
        root = ET.Element("html")
        head = ET.SubElement(root, "head")
        body = ET.SubElement(root, "body")
        p = ET.SubElement(body, "p")
        a = ET.Element('a', href='http://www.companyhomepage.com')
        img = ET.Element('img', src='cid:image1')
        a.append(img)
        p.append(a)
        return ET.tostring(root, 'UTF-8')
        
    def msg(self, **kw):
        msg = MIMEMultipart('alternative')
        msg['Subject'] = kw.get('subject')
        msg['From'] = kw.get('sender')
        msg['To'] = ''.join(['%s, '%b for b in kw.get('receiver')]).rstrip(', ')
        msg.attach(MIMEText(gen_template(**kw), 'html'))
        
        fp = open(kw.get('image'), 'rb')
        img = MIMEImage(fp.read())
        fp.close()
        img.add_header('Content-ID', '')
        msg.attach(img)
        return msg
        
    def send(self, **kw):
        self.smtp.sendmail(kw.get('sender'), kw.get('receiver'), msg(**kw))
        
    def finish(self):
        self.smtp.quit()
        

if '_main_' == _name_:
    d = {}
    d['sender'] = 'sender@company.com'
    d['receiver'] = ['vip1@something.com', 'vip2@something.com']
    d['subject'] = 'Test Embed Image With Url'
    d['image'] = 'image1.gif'
    
    email = EMail('mailserver.company.com')
    email.send(**d)
    
    d['image'] = 'image2.gif'
    email.send(**d)
    
    d['image'] = 'image3.gif'
    email.send(**d)
    email.finish()

วันพุธที่ 21 ตุลาคม พ.ศ. 2552

Python lambda

lambda ในภาษา python นับเป็นเครื่องอำนวยความสะอาดอย่างหนึ่ง
คือ ทำให้เราสามารถ ย่น code ที่ไม่มีอะไรซับซ้อน ได้ ทำให้
การอ่าน code เป็นไปอย่างสบายตา แต่ไม่ใช่ว่าต้องใช้ทุกครั้งไปนะครับ
ดูที่ความเหมาะสม

จริง ๆ แล้วก็เป็นเหมือนการเขียน function ที่ไม่ซับซ้อนให้อยู่
ในบรรทัดเดียว

ตัวอย่าง ถ้าเราเขียน function ขึ้นมาอย่างหนึ่ง
ใช้หาเลขคู่ ก็จะได้ประมาณนี้
a = [1, 2, 3, 4]
ab = []
for b in a:
    if (b % 2) == 0:
        ab.append(b)
ยาวไป เอาใหม่
a = [1, 2, 3, 4]
ab = [b for b in a if (b % 2) == 0]

จริง ๆ แค่นี้ก็ดูดีมีชาติตระกูลแล้ว
แต่ลองเขียนใหม่ดู

a = [1, 2, 3, 4]
ab = filter(lambda b: (b % 2) == 0, a)

lambda ในที่นี้จะรับเอาค่า ทีละค่าจาก array a มา check
คือนำเอามาแทน b ใน lambda แล้วเช็คว่า หาร 2 แล้ว
ลงตัวใหม ถ้าไม่ลงก็จะ return False ถ้าพอดี ก็ return True

ในที่นี้ใช้ filter มาช่วย จัดการกับค่า array a
ถ้าเป็น True จะ return ค่าออกมา ถ้าเป็น False ก็ไม่เอาค่านั้น

------------------------------

ลองมาดูง่ายกว่านั้น
เอาเป็นว่า มีข้อมูล อยู่
a = [1, 2, 3, -3, 4, 'a']

ต้องการดึงค่าออกมาเฉพาะ เลขจำนวนเต็ม มากกว่าศูนย์ และเป็นเลขคู่ แล้วเอาไป *2

อันนี้แบบย่อสุด ๆ

a = [1, 2, 3, -3, 4, 'a']
ab = [b*2 for b in a if int == type(b) and b > 0 and (b % 2) == 0]

เริ่มอ่านยากแระ ลองแยกในส่วน check ออกเป็น function ดู

a = [1, 2, 3, -3, 4, 'a']
def find_x(x):
    return int == type(x) and x > 0 and (x % 2) == 0

ab = [b*2 for b in a if find_x(b)]

ลองเขียนแยกเพื่อให้ง่ายต่อการแก้ไข
และเขียนเป็น แต่ละ function

a = [1, 2, 3, -3, 4, 'a']
def is_type_int(x):
    return int == type(x)

def is_over_zero(x):
    return x > 0

def is_mod_two(x):
    return (x % 2) == 0

def cal_double(x):
    return x*2

def chk_x(find_x, cal_x, x):
    ab = []
    for i in x:
        ff = True
        for f in find_x:
            if not f(i):
                ff = False
                break
        if ff
            ab.append(cal_x(i))
    return ab

ab = chk_x([is_type_int, is_over_zero, is_mod_two], cal_double, a)

มองว่า function ย่อย ไม่ได้สำคัญอะไร ก็ยุบไปซะ

a = [1, 2, 3, -3, 4, 'a']
def chk_x(find_x, cal_x, x):
    ab = []
    for i in x:
        ff = True
        for f in find_x:
            if not f(i):
                ff = False
                break
        if ff:
            ab.append(cal_x(i))
    return ab

ab = chk_x([lambda i: int == type(i), lambda i: i > 0, lambda i: (i % 2) == 0], lambda i: i*2, a)

คือคิดเผื่อว่า เอาเป็น หาร 3 ลงตัว แล้ว เอาไป *3 ก็จะแก้แค่นี้อะครับ

ab = chk_x([lambda i: int == type(i), lambda i: i > 0, lambda i: (i % 3) == 0], lambda i: i*3, a)

ยิ่งเขียนยิ่งไปกันใหญ่ เป็นตัวอย่างเฉย ๆ ครับ สำหรับการประยุกต์ใช้