Showing posts with label python. Show all posts
Showing posts with label python. Show all posts

对Python List 进行 quick sort 竟如此简单明了...

挺让我意外的Python list comprehensions... 简单,自然的List QuickSort实现:
from random import randrange       
def qsortlist(list):
    """
    Quicksort using list comprehensions and randomized pivot
    """
    def qsort(list):
        if list == []: 
            return []
        else:
            pivot = list.pop(randrange(len(list)))
            lesser = qsort([l for l in list if l < pivot])
            greater = qsort([l for l in list if l >= pivot])
            return lesser + [pivot] + greater
    return qsort(list[:])
如此清晰,简便的快速排序...虽然性能肯定远不如一般的C,C++之类的实现,但是鉴于这是针对list的排序,应用广阔而方便,python的数字计算能力也不差, 又有不错的随机数生成器。 C的话要提供比较方法,C++的话要用模板类来推广,而我自认为C/C++水平远不及Python解释器. C的那些存储,赋值,等小数据处理操作一不小心性能就被拉下去了... 所以懒惰的我觉得这也算是挺实用的,比如英文姓名排序...

Send mail(smtp) in Python

# -*- coding: utf-8 -*-
import sys
import os
from time import strftime, localtime
import getopt
import smtplib
from email.MIMEText import MIMEText
from optparse import OptionParser

__version__ = u'0.0.1'
__author__ = u'MeaCulpa '
__all__ = [u'sendmail']

CHARSET = 'utf8'

def main(argv=None):

    default_input = os.path.join(os.getcwd(), u'test', u'testmail.txt')
    RECIPIENT = ''
    
    # parse commandline options
    optparse = OptionParser(version=__version__)
                        
    optparse.add_option('-i', '--inputfile',
                        dest = "inputfile",
                        metavar = "FILE",
                        default = default_input,
                        help = "file to post content to e-mail")
                        
    optparse.add_option('-r', '--recipient',
                        dest = "recipient",
                        default = RECIPIENT,
                        help = "e-mail recipient")   

    optparse.add_option("-q", "--quiet",
                        action = "store_false", 
                        dest = "verbose", 
                        default = True,
                        help = "don't print status messages to stdout")

    opts, args = optparse.parse_args()

    if args:
        optparse.error(u'invalid arguments')

    # if no option print help()
    if len(sys.argv) == 1:
        optparse.print_help()
    else:
        doRealThings(args)    
        sendmailfromfile(opts.inputfile, opts.recipient)

def doRealThings(args):
    print "---" + strftime(u' %Y-%m-%d %H:%M:%S ', localtime()) + "---"
    
def sendmailfromfile(filename, recipient):

    smtpserver = ''
    AUTHREQUIRED = 1 # if need to use SMTP AUTH set to 1
    SENDER = ''    
    # for SMTP AUTH, set SMTP username here
    smtpuser = ''
    # for SMTP AUTH, set SMTP password here
    smtppass = ''
                                           
    # Set up a MIMEText object (it's a dictionary)
    mmsg = open(filename, 'r').read()
    msg = MIMEText(mmsg, 'plain', CHARSET)

    # Can use add_header or set headers directly ...
    msg['Subject'] = 'Automated mail: ' + strftime(u'%Y-%m-%d', localtime()) + ' GMT+8'
    # Following headers are useful to show the email correctly
    # in your recipient's email box, and to avoid being marked
    # as spam. They are NOT essential to the snemail call later
    msg['From'] = SENDER
    msg['Reply-to'] = SENDER
    msg['To'] = recipient  

    # Establish an SMTP object and connect to your mail server
    s = smtplib.SMTP(smtpserver)
#        s = smtplib.SMTP_SSL(smtpserver)
    # Send the email - real from, real to, extra headers and content ...
    if AUTHREQUIRED:
        s.login(smtpuser, smtppass)
    print "Posting: " + filename
    print "     to: " + recipient
    smtpresult = s.sendmail(SENDER,recipient, msg.as_string())
    s.close()
    if smtpresult:
      errstr = ""
      for recip in smtpresult.keys():
          errstr = """Could not delivery mail to: %s"""
      print u' Result: failed! ' + errstr
    else:
        print u' Result: success!'

if __name__ == "__main__":
    sys.exit(main())

Fetch pop3 email using Python

# -*- coding: utf-8 -*-
import poplib
import email
import email.Parser
import email.header
import os
import sys
import base64
from optparse import OptionParser

__version__ = u'0.0.1'
__author__ = u'MeaCulpa '
__all__ = [u'fetchmail']

class email_attachment:
    def __init__(self, messagenum, attachmentnum, filename, contents):
        '''
        arguments:
            messagenum - message number of this message in the Inbox
            attachmentnum - attachment number for this attachment
            filename - filename for this attachment
            contents - attachment's contents
        '''
        self.messagenum=messagenum
        self.attachmentnum=attachmentnum
        self.filename=filename
        self.contents=contents
        return

    def save(self, savepath, savefilename=None):
        '''
        Method to save the contents of an attachment to a file
        arguments:
            savepath - path where file is to be saved
            safefilename - optional name (if None will use filename of attachment
        '''

        savefilename=savefilename or self.filename
        f=open(os.path.join(savepath, savefilename),"wb")
        f.write(self.contents)
        f.close()
        return

class email_msg:
    def __init__(self, messagenum, contents):
        self.messagenum=messagenum
        self.contents=contents
        self.attachments_index=0  # Index of attachments for next method
        self.ATTACHMENTS=[]       # List of attachment objects

        self.msglines='\n'.join(contents[1])
        #
        # See if I can parse the message lines with email.Parser
        #
        self.msg=email.Parser.Parser().parsestr(self.msglines)
        if self.msg.is_multipart():
            attachmentnum=0
            for part in self.msg.walk():
                # multipart/* are just containers
                mptype=part.get_content_maintype()
                filename = part.get_filename()
                if mptype == "multipart": continue
                if filename: # Attached object with filename
                    attachmentnum+=1
                    self.ATTACHMENTS.append(email_attachment(messagenum, attachmentnum, filename, part.get_payload(decode=1)))
                    print "Attachment filename=%s" % filename

                else: # Must be body portion of multipart
                    self.body=base64.b64decode(part.get_payload())

        else: # Not multipart, only body portion exists
            self.body=base64.b64decode(self.msg.get_payload())

        return


    def get(self, key):
        try: return self.msg.get(key)
        except:
            emsg="email_msg-Unable to get email key=%s information" % key
            print emsg
            sys.exit(emsg)

    def has_attachments(self):
        return (len(self.ATTACHMENTS) > 0)

    def __iter__(self):
        return self

    def next(self):
        #
        # Try to get the next attachment
        #
        try: ATTACHMENT=self.ATTACHMENTS[self.attachments_index]
        except:
            self.attachments_index=0
            raise StopIteration
        #
        # Increment the index pointer for the next call
        #
        self.attachments_index+=1
        return ATTACHMENT

class pop3_inbox:
    def __init__(self, server, userid, password):
        self._trace=0
        if self._trace: print "pop3_inbox.__init__-Entering"
        self.result=0             # Result of server communication
        self.MESSAGES=[]          # List for storing message objects
        self.messages_index=0     # Index of message for next method
        #
        # See if I can connect using information provided
        #
        try:
            if self._trace: print "pop3_inbox.__init__-Calling poplib.POP3(server)"
            self.connection=poplib.POP3(server)
            if self._trace: print "pop3_inbox.__init__-Calling connection.user(userid)"
            self.connection.user(userid)
            if self._trace: print "pop3_inbox.__init__-Calling connection.pass_(password)"
            self.connection.pass_(password)

        except:
            if self._trace: print "pop3_inbox.__init__-Login failure, closing connection"
            self.result=1
            self.connection.quit()

        #
        # Get count of messages and size of mailbox
        #
        if self._trace: print "pop3_inbox.__init__-Calling connection.stat()"
        self.msgcount, self.size=self.connection.stat()
        #
        # Loop over all the messages processing each one in turn
        #
        for msgnum in range(1, self.msgcount+1):
            self.MESSAGES.append(email_msg(msgnum, self.connection.retr(msgnum)))

        if self._trace: print "pop3_inbox.__init__-Leaving"
        return

    def close(self):
        self.connection.quit()
        return

    def remove(self, msgnumorlist):
        if isinstance(msgnumorlist, int): self.connection.dele(msgnumorlist)
        elif isinstance(msgnumorlist, (list, tuple)):
            map(self.connection.dele, msgnumorlist)
        else:
            emsg="pop3_inbox.remove-msgnumorlist must be type int, list, or tuple, not %s" % type(msgnumorlist)
            print emsg
            sys.exit(emsg)

        return

    def __iter__(self):
        return self

    def next(self):
        #
        # Try to get the next attachment
        #
        try: MESSAGE=self.MESSAGES[self.messages_index]
        except:
            self.messages_index=0
            raise StopIteration
        #
        # Increment the index pointer for the next call
        #
        self.messages_index+=1
        return MESSAGE

if __name__=="__main__":
    
    # parse commandline options
    optparse = OptionParser(version=__version__)
                        
    optparse.add_option('-s', '--server',
                        dest = 'server',
                        default = '',
                        help = 'smtp server')
                        
    optparse.add_option('-u', '--userid',
                        dest = 'userid',
                        default = '',
                        help = 'smtp userid')   

    optparse.add_option('-p', '--password',
                        dest = 'password', 
                        default = '',
                        help = 'smtp password')

    opts, args = optparse.parse_args()

    if args:
        optparse.error(u'invalid arguments')
        sys.exit()

    #if in-sufficient option print help
    if len(sys.argv) < 3:
        optparse.print_help()
        sys.exit()

    inbox=pop3_inbox(opts.server, opts.userid, opts.password)
    if inbox.result:
        emsg="Failure connecting to pop3_inbox"
        print emsg
        sys.exit(emsg)

    print "Message count=%i, Inbox size=%i" % (inbox.msgcount, inbox.size)

    counter=0
    for m in inbox:
        counter+=1
        print "Subject: %s" % email.header.decode_header(m.get('subject'))[0][0]
        print "-------------Message (%i) body lines---------------" % counter
        print m.body
        print "-------------End message (%i) body lines-----------" % counter
        if m.has_attachments():
            acounter=0
            for a in m:
                acounter+=1
                print "-------------Message (%i) attachments-------------" % counter
                print "%i: %s" % (acounter, a.filename)
                print "-------------End message (%i) attachments---------" % counter
                a.save(os.path.join(os.getcwd(), u'tmp'))

        else: print "-------------Message has no attachments----------"

    inbox.close()

Simple indent Normalizer

# -*- coding: utf-8 -*-
#!/usr/bin/env python

"""Try to standalize indentation"""

import sys
import re
from collections import defaultdict

INDENT = 4  # what we should set it to

_whitespace_re = re.compile(r'\s*')
_blank_re = re.compile(r'^\s+$')

class RedentError(Exception):
    pass

def main():
    data = sys.stdin.read()
    if u'\t' in data:
        raise RedentError(u'omg tabs detected, fix that before running this')
    lines = data.splitlines()
    changes = defaultdict(int)
    last_indent = None
    parsed = []
    for line in lines:
        line = _blank_re.sub(u'', line)
        indent = len(_whitespace_re.match(line).group(0))
        tail = line[indent:]
        parsed.append((indent, tail))
        if last_indent is not None:
            change = last_indent - indent
            if change < 0:
                change *= -1
            if change:
                changes[change] += 1
        last_indent = indent
    changes = sorted(changes.iteritems(), key=lambda item: item[1],
                     reverse=True)
    detected_indent = changes[0][0]
    if detected_indent == INDENT:
        raise RedentError(u'no work needs to be done, indent level is same')
    for i, line in enumerate(parsed):
        indent, tail = line
        if indent % detected_indent:
            raise RedentError(u'uneven indentation detected')
        level = indent / detected_indent
        print (u' ' * INDENT * level) + tail
    return 0

if __name__ == u'__main__':
    sys.exit(main())

Simple HTML cleaner

# -*- coding: utf-8 -*-
#!/usr/bin/env python
'''
Cleansing HTMLs
'''

import sys
from optparse import OptionParser
import re
import os

newline = re.compile(r'[\r\n]+')
tag = re.compile(r'^\s*<(/?)(\w+).*?(/?)>$', re.DOTALL)
sw = 2
noindent = ('br',)

def clean(filename):
    fo = open(filename, 'rb')
    try:
        data = fo.read()
    finally:
        fo.close()
    data = newline.sub('\n', data)
    data = data.replace('>', '>\n')
    data = data.replace('<', '\n<')
    data = data.splitlines()
    new = []
    for line in data:
        line = line.strip()
        if len(line):
            new.append(line)
    data = new
    new = []
    ilevel = 0
    for line in data:
        padding = ' ' * (sw * ilevel)
        line = padding + line
        try:
            close1, tagname, close2 = tag.search(line).groups()
            if close2 or tagname.lower() in noindent:
                pass
            elif close1:
                if ilevel:
                    ilevel -=1
                    padding = ' ' * (sw * ilevel)
                    line = padding + line.strip()
            else:
                ilevel += 1
        except:
            pass
        new.append(line)
    data = '\n'.join(new) + '\n'
    sys.stdout.write(data)


def main():
    op = OptionParser()
    opts, args = op.parse_args()
    for filename in args:
        clean(filename)

    return 0

if __name__ == '__main__':
    sys.exit(main())

Simple python code format cleaner

This simple script helps me fix indentions:
# -*- coding: utf-8 -*-
#!/usr/bin/env python

import sys

def main():
    assert len(sys.argv) == 2, u'need a filename'
    f = open(sys.argv[1], u'rb')
    try:
        data = f.read()
    finally:
        f.close()

    lines = data.splitlines()
    lines = map(lambda x: x.rstrip(), lines)
    lines = filter(lambda x: len(x), lines)
    lines.reverse()

    fixed = []
    for line in lines:
        fixed.append(line)
        if line.strip().startswith(u'def '):
            fixed.append(u'')
        elif line.strip().startswith(u'class '):
            fixed += [u'', u'']
    fixed.reverse()

    print u'\n'.join(fixed)

    return 0

if __name__ == u'__main__':
    sys.exit(main())

A sample python main function

# -*- coding: utf-8 -*-
"""
A sample of main function
to demostrate usage of getopt.
"""

import sys
import getopt

class Usage(Exception):
  def __init__(self, msg):
    self.msg = msg

def main(argv=None):
  if argv is None:
    argv = sys.argv
  try:
    try:
      opts, args = getopt.getopt(argv[1:], "h", ["help"])
    except getopt.error, msg:
       raise Usage(msg)
  # display help msg
  except Usage, err:
    print >>sys.stderr, err.msg
    print >>sys.stderr, "for help use --help"
    return 2

  # parse options
  for o, a in opts:
    if o in ("-h", "--help"):
      print __doc__
      sys.exit(0)
  # parse arguments
  for arg in args:
    parse(arg) # parse() is defined elsewhere

  doRealThings(args)
    
def parse(arg):
  print 'Parsing option: ' + arg

def doRealThings(args):
  print 'Now do the real things.'

if __name__ == "__main__":
  sys.exit(main())
| More

Twitter Updates