Python 3 Changes and How to Make 2.7 Code Works

  • make print “” into print(“”), like as a function
    # in code editor, using Regular Expression to replace
    find: (print)\s(.+)
    replace: $1\($2\) or \1(\2) depending on your code editor
  • other stuff
    # python 2 reload
    reload(myModule)
    # python 3 reload
    from imp import reload
    reload(myModule)
     
    # python 2 execfile
    execfile("testScript.py")
    # python 3
    exec(open("testScript.py").read(), globals())

Python basics

My Wiki Page related

to read:

  • single line comment
    # single comment
  • multiple line comment
    '''
    line 1
    line 2
    '''
  • block, section, partition
    ########################################
    # a major block of asset (40x#)
    ########################################
     
    #------------------------------
    # a function collection (30x-)
    #------------------------------
     
    # ---- section comment ----
     
    # function section tip
    def ________Loading_Functions________():
        # 8x_
        pass
  • launch in windows command batch file next to it
    @echo off
    call python %~dp0\\MyPythonScript.py
  • launch in Mac AppleScript file (wip)
    set myScriptPath to path to me
    set myScriptFolderPath to POSIX path of (container of myScriptPath as string) -- in "/" form
    set myScriptName to name of myScriptPath
     
    tell application "Terminal"
        do script with command "python /path_to_script/myScript.py"
    end tell
  • get user folder
    os.path.expanduser('~')
  • make python code able to print unicode directly without .encode('utf-8') for text
    import sys
    import codecs
    sys.stdout = codecs.getwriter('utf8')(sys.stdout)
  • get python program path
    import sys
    print(sys.executable) # the python cmd or app containing the python call path
  • get python module path
    import ModuleName
    os.path.dirname(ModuleName.__file__)
  • get script path
    os.path.dirname(__file__)
  • get class path but not its super class
    self.location = os.path.realpath(sys.modules[self.__class__.__module__].__file__)
    self.location = os.path.abspath(inspect.getfile(self.__class__))
  • get class name
    self.__class__.__name__
  • get basename of folder and file
    os.path.basename(os.path.normpath('/folderA/folderB/folderC/folderD/')) # 'folderD'
  • get expanded and un-symbolic path
    os.path.abspath(__file__)
    os.path.realpath(__file__)
  • path comparison
    os.path.relpath(childPath, parentPath) # get the sub path only based on parent Path
    os.path.commonprefix(list_of_paths) # get the common parent path of all input pathes
  • python code to detect platform, python version, bit
    from sys import platform
     
    def get_platform():
        if platform.startswith('win'):
            return 'windows'
        elif platform.startswith('darwin'):
            return 'mac'
        return 'linux'
     
    import sys
    pyMode = '.'.join([ str(n) for n in sys.version_info[:3] ])
    print("Python: {0}".format(pyMode))
     
    is_64bits = sys.maxsize > 2**32
    print(is_64bits)
  • check file and path exists
    os.path.exists(myPath):
  • scan file and folder content with pattern filtering
    result_list = [x for x in os.listdir(scanPath) if os.path.isdir(os.path.join(scanPath,x))] 
    # isdir for folder, isfile for file
    cur_pattern = re.compile('\d{3}_\d{4}') # match 000_0000 name pattern
    result_list = [x for x in result_list if cur_pattern.match(x)]
     
    # jpg name example
    jpg_list = [x.rsplit('.',1)[0] for x in os.listdir(scanPath) if os.path.isfile(os.path.join(scanPath,x)) and x.lower().endswith('.jpg')]
  • rename file or folder
    os.rename(os.path.join(parentPath,old_name), os.path.join(parentPath,new_name))
  • system cmds for each os
    os.system('move "%s\%s" "%s\zBk.%s"' % (rootDir,oldPreset,rootDir,oldPreset))
    os.system('mklink /D "%s\%s" "%s\%s"' % (rootDir,oldPreset,resDir,newPreset))
  • cross-platform delivery from source
    • win: frozen
    • mac: frozen
    • lin: packaged
    • def getSetup():
          if hasattr(sys, 'frozen'):
              return 'frozen'
          elif is_packaged():
              return 'packaged'
          return 'source'
  • change file permission
    # ref: http://stackoverflow.com/questions/16249440/changing-file-permission-in-python
    import os
    import stat
    os.chmod("R:\\folder\\permit.txt", stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH) # user, group, other readonly
  • windows register operation
    PS_key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,"SOFTWARE\\Adobe\\Photoshop\\12.0") # may need check version no.
    PS_APP = _winreg.QueryValueEx(PS_key, 'ApplicationPath')[0] + 'Photoshop.exe'
     
    def ps_loc_win():
        import _winreg
        regKey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\Photoshop.exe")
        regPath = _winreg.QueryValueEx(regKey, 'Path')[0] + 'Photoshop.exe'
        return regPath
  • windows set default playback device
    subprocess.call('nircmd.exe setdefaultsounddevice "Speakers"') # need download nircmd
  • run python script itself as admin
    import ctypes, sys
    def is_admin():
        try:
            return ctypes.windll.shell32.IsUserAnAdmin()
        except:
            return False
     
    if is_admin():
        # Code of your program here
    else:
        # Re-run the program with admin rights
        ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, "", None, 1)
  • run cmd with admin (3rd party module)
    # pywin32 : sourceforge.net/projects/pywin32/files/pywin32/
    import win32com.shell.shell as shell
    commands = 'echo hi'
    shell.ShellExecuteEx(lpVerb='runas', lpFile='cmd.exe', lpParameters='/c '+commands)
  • control, start, stop, restart service (3rd party module method)
    import win32serviceutil
    serviceName = "serviceName"
    win32serviceutil.RestartService(serviceName)

Copy File - the Correct Way

  • use python shutil module copy, copyfile and copy2 function
    import shutil
    # copy: return target path, target can be file or folder
    shutil.copy('d:/z_tmp/aa.jpg','d:/z_tmp/bb.jpg')
    shutil.copyfile('d:/z_tmp/aa.jpg','d:/z_tmp/dd.jpg')
     
    ''' # result modified date change
    02/06/2017  02:13 PM           193,399 aa.jpg
    12/09/2017  12:06 PM           193,399 bb.jpg
    12/09/2017  12:06 PM           193,399 dd.jpg
    '''
     
    shutil.copy2('d:/z_tmp/aa.jpg','d:/z_tmp/bb.jpg')
    ''' # result keeps modified date
    02/06/2017  02:13 PM           193,399 aa.jpg
    02/06/2017  02:13 PM           193,399 cc.jpg
    '''
  • copy folder and its content
    import shutil, errno
     
    def copyFolder(src, dst):
        try:
            shutil.copytree(src, dst) # folder structure only
        except OSError as exc: # python >2.5
            if exc.errno == errno.ENOTDIR:
                shutil.copy2(src, dst) # file only with same date, or copy for current date
            else: raise
     
    # or use this
    distutils.dir_util.copy_tree(src_folder, tgt_folder)
  • python more complete version for copy folder and its content
    # ref: http://blog.csdn.net/liyuan_669/article/details/25346645
    # folder content to target folder content. created folders seams not same date, but file same date
    import os
    import shutil
    def copy_tree(src, dst, symlinks=False):
        names = os.listdir(src)
        if not os.path.isdir(dst):
            os.makedirs(dst)
        errors = []
        for name in names:
            srcname = os.path.join(src, name)
            dstname = os.path.join(dst, name)
            try:
                if symlinks and os.path.islink(srcname):
                    linkto = os.readlink(srcname)
                    os.symlink(linkto, dstname)
                elif os.path.isdir(srcname):
                    copy_tree(srcname, dstname, symlinks)
                else:
                    # perform overrides
                    if os.path.isdir(dstname):
                        os.rmdir(dstname)
                    elif os.path.isfile(dstname):
                        os.remove(dstname)
                    shutil.copy2(srcname, dstname)
                # other case like: devices, sockets etc.
            except (IOError, os.error) as why:
                errors.append((srcname, dstname, str(why)))
            # catch the Error from the recursive copy_tree so that we can
            # continue with other files
            except OSError as err:
                errors.extend(err.args[0])
        try:
            shutil.copystat(src, dst)
        except WindowsError:
            # can't copy file access times on Windows
            pass
        except OSError as why:
            errors.extend((src, dst, str(why)))
        if errors:
            raise Error(errors)
     
    copy_tree('E:/book', 'E:/newbook')
  • use system command to copy
    src = 'd:/z_tmp/aa.jpg'
    tgt = 'd:/z_tmp/sys_copy.jpg'
    os.system('copy {0} {1}'.format(os.path.normpath(src),os.path.normpath(tgt)) )
    # normpath will change the slash for win from unix path
     
    os.system ("xcopy /s {0} {1}".format(src_dir, tgt_dir))
  • use system file manager to copy with system progress window (windows)
    #ref: https://stackoverflow.com/questions/16867615/copy-using-the-windows-copy-dialog
    import pythoncom
    from win32com.shell import shell,shellcon
     
    def win_copy_process(src_files,tgt_folder):
        # win32com module
        pfo = pythoncom.CoCreateInstance(shell.CLSID_FileOperation,None,pythoncom.CLSCTX_ALL,shell.IID_IFileOperation)
        # Respond with Yes to All for any dialog
        # ref: http://msdn.microsoft.com/en-us/library/bb775799(v=vs.85).aspx
        pfo.SetOperationFlags(shellcon.FOF_NOCONFIRMATION)
        # Set the destionation folder
        dst = shell.SHCreateItemFromParsingName(tgt_folder,None,shell.IID_IShellItem)
        for f in src_files:
            src = shell.SHCreateItemFromParsingName(f,None,shell.IID_IShellItem)
            pfo.CopyItem(src,dst) # Schedule an operation to be performed
        # ref: http://msdn.microsoft.com/en-us/library/bb775780(v=vs.85).aspx
        success = pfo.PerformOperations()
        # ref: sdn.microsoft.com/en-us/library/bb775769(v=vs.85).aspx
        aborted = pfo.GetAnyOperationsAborted()
        return success and not aborted
     
    file_list = [r'D:\z_tmp\aa.jpg',r'D:\z_tmp\bb.jpg']
    tgt_folder = r'D:\zTmp'
    win_copy_process(file_list,tgt_folder)
  • use system API (windows)
    #ref: http://timgolden.me.uk/python/win32_how_do_i/copy-a-file.html
    # win32
    from win32com.shell import shell, shellcon
    win32file.CopyFile (filename1, filename2, 1)
     
    # win32com : with windows copy dialog
    shell.SHFileOperation (  (0, shellcon.FO_COPY, filename1, filename2, 0, None, None) )
    # for the "0" parameter: 
    # shellcon.FOF_RENAMEONCOLLISION: rename on collision
    # shellcon.FOF_NOCONFIRMATION: no confirmation dialog and always override
    # shellcon.FOF_NOERRORUI: no error pop dialog
    # shellcon.FOF_SILENT: no copying progress dialog
    # shellcon.FOF_NOCONFIRMMKDIR: no ask for non exist folder, create folder by default
  • encode and decode Qt QString
    str(myQStringObj) # ascii output
    unicode(myQStringObj) # unicode output
    unicode(myQStringObj.toUtf8(), encoding="UTF-8") # decode based on utf8, then encode in utf-8 python string as unicode output
  • ref:
    • UTF-8 is an encoding used to translate numbers into binary data.
    • Unicode is a character set used to translate characters into numbers.
  • text block to clean row list
    data_list = [row.strip() for row in source_txt.split('\n')]
  • define function
    def my_fun(para1):
        print para1
  • logic and condition and loop operation
    for tmpitem in tmplist:
        print tmpitem
     
    if tmp > 0:
        print 'ok'
    elif x == 0:
        print 'zero'
    else:
        print 'no'
     
    # logic operation
    x or y
    x and y
    not x
  • data type check
    isinstance(Vehicle(), Vehicle)  # returns True
    type(Vehicle()) == Vehicle      # returns True
    isinstance(Truck(), Vehicle)    # returns True, takes inheritance
    type(Truck()) == Vehicle        # returns False, take exact class type
     
    # check string, both python 2,3
    isinstance(my_data, (str, unicode) )
    # check list
    isinstance(my_data, (list, tuple) )
     
    # check not None, note, None is its own type and has only one instance
    my_vec != None # sometime, it may cause error when = try to read certain way
    my_vec is not None # this way is preferred to be error free
    isinstance(my_vec, om.MVector) # this way even better, not only check it is defined and also check its type match
     
    # compare type
    if type(A) is type(B):
        print('Same Class')
     
    # note : is for same object and like pointer comparision, while == is same value comparision
  • data type convertion
    int('42')
    str(42)
  • get datetime date
    date_text = datetime.date.today().strftime("%Y.%m.%d")
  • get processing time
    import time
     
    start = time.time()
    print("hello")
    end = time.time()
    print(end - start)
  • wild char process
    import glob
    os.chdir(path)
    for file in glob.glob("*.jpg"):
        print file
     
    tmplist=glob.glob('*.[jJ][pP][gG]')
     
    # other method: fnmatch and re
  • string operation
    name="01_Blue_Sun_DSC08897.jpg"
    print name[3:-13].replace('_',' ') #Blue Sun#
     
    len(str) # string length
     
    "hello world".title()
    'Hello World'
     
    # remove Whitespace on the both sides:
    s = "  \t a string example\t  "
    s = s.strip()
     
    # remove Whitespace on the right side:
    s = s.rstrip()
    # remove Whitespace on the left side:
    s = s.lstrip()

Data Type

  • Lists []: a list of values. Each one of them is numbered, starting from zero - the first one is numbered zero, the second 1, the third 2, etc. You can remove values from the list, and add new values to the end. Example: Your many cats' names.
  • Tuples (): are just like lists, but you can't change their values. The values that you give it first up, are the values that you are stuck with for the rest of the program. Again, each value is numbered starting from zero, for easy reference. Example: the names of the months of the year.
  • Dictionaries {:,}are similar to what their name suggests - a dictionary. In a dictionary, you have an 'index' of words, and for each of them a definition. In python, the word is called a 'key', and the definition a 'value'
  • list operation (so-called array) (ref)
    [1,2,3]
    len(arrayName) # size of list
     
    # add value to all elements of list
    my_list=[1,3,5,7,8]
    new_list = [x+1 for x in my_list] # [2,4,6,8,9]
     
    list.append(obj)
    list.extend(list)
    list.index(obj)
    list.count(obj) # count appearance of obj
     
    # array to string and string to array
    sentence = ["there", "is", "no", "spoon"]
    ' '.join(sentence) #'there is no spoon'
     
    list=[3.1,121.2,34.1]
    ', '.join(map(str,list)) #'3.1, 121.2, 34.1'
     
    '3.1, 121.2, 34.1'.split(', ') #['3.1','121.2','34.1']
    # 2nd number make how many split point
    '3.1, 121.2, 34.1'.split(', ',1) #['3.1','121.2, 34.1'] 
     
    # list sort (modify itself)
    versionList.sort(reverse=1) # higher to lower
    versionList.sort() 
     
    str([-4, -2, 0, 2, 4]) # '[-4,-2,0,2,4]'
    bb_str ='_'.join(map(str, bb)) # -4_-2_0_2_4
     
    # list compare
    [-4, -2, 0, 2, 4] == [-4, -2, 0, 2, 3] # false
     
    # multiple list operation
     
    wMap_zero_Jnt=[x for x in wMap_All_Jnt if x not in wMap_Jnt_tgt] # remove list from list
     
    a = [1, 2, 3, 4, 5]
    b = [9, 8, 7, 6, 5]
    common = set(a) & set(b) #[5], no order applied
     
    [i for i, j in zip(a, b) if i == j] # [5] for equal-sized lists, which order matters 
     
    version_list_prefix=["previous","current"]
    version_list_postfix=["A","B"]
    version_list_color=["rgb(255, 128, 128)","rgb(85, 170, 255)"]
    for each,post,color in zip(version_list_prefix,version_list_postfix,version_list_color):
        print(each+" "+post+" is "+color)
     
    # list slice operation
    # n = len(L)
    # item = L[index]
    # seq = L[start:stop]
    # seq = L[start:stop:step]
    seq = L[::2] # get every other item, starting with the first
    seq = L[1::2] # get every other item, starting with the second
     
    seq=L[::-1] # reverse reading list
    list(reversed(seq)) # generate a list reversed
    L.reverse() # reverse list, it changed original list
    seq=L[::-2] # reverse reading list, and get every other item
     
    list=[1,2,3,4,5,6]
    seq=list[::-2] # [6,4,2]
     
    # list flatten, and remove duplicates
    nestList = [[2,3],[1,2,4],[5,6]]
    flatList = set(sum(nestList,[])) # for small list of 2 level nest
     
    # delete a element from list
    a = [1,2,3,4]
    del(a[2]) # [1,2,4]
     
    # for large list
    import itertools
    flatList = set( list(itertools.chain.from_iterable(nestList)) ) # for same type element list, no mix of list and element like [[5],6], as it will error
     
    import operator
    flatList = set( reduce(operator.add, map(list, nestList)) ) # like itertool, but it will not error for mix of list and element situation
     
    # for any mix list
    def flatFn(mainList):
        newList = []
        for each in mainList:
            if isinstance(each, (list, tuple)):
                newList.extend( flatFn(each) )
            else:
                newList.append(each)
        return newList
     
    flatList = set( flatFn(nestList) )
  • dictionary operation
    # ref: http://www.dotnetperls.com/dictionary-python
    dict.clear()
    dict.get(key, default=None) #  returns value or default if key not in dictionary
    dict.has_key(key)
    dict.items() # a list dict's (key, value) tuple pairs
    dict.keys() # a list of keys
    dict.values() # a list of values
    len(dict) # size of dict
     
    #example, obj property
    dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'};
     
    #example, obj list
    dict = {'Alice': '2341', 'Beth': '9102', 'Cecil': '3258'}
     
    # delete key
    my_dict.pop(key_name, None)
  • set operation
    set( ("hello", "world", "of", "words", "of", "world") )
    # set(['world', 'hello', 'words', 'of'])
     
    fib=set( [1,1,2,3,5,8,13] )
    prime=set( [2,3,5,7,11,13] )
    combine=fib | prime # set([1, 2, 3, 5, 7, 8, 11, 13])
    common=fib & prime #set([2, 3, 5, 13])
    diff = fib - prime # set([8, 1])
    fib ^ prime # combine - common #set([1, 7, 8, 11])
     
    # <, <=, >, >=, ==, !=, in, not in works in set
    len(fib)=6
    max(fib)=13
    min(fib)=1
    sum(fib)=32
    any(set([false,true])) # For sets, Return True if there exists any item which is True.
    all(set([false,true])) # For sets, Return True if there all items which is True.
    set.add(new)
    set.remove(old)
  • list attribute of a object
    object.__dict__
  • a file can be a module like
    import FileName
    FileName.functionName() # call function side that file
  • you can turn a list of python file under same folder into a module by create a empty file under the directory:
    __init__.py
    • it will automatically turn the folder into a module so that you can call each file after import folder like
      import FolderName
      from FolderName import FileName
    • whenever you call import FolderName, the initpy will be run-ed first, so you can put some code inside to do some pre-run task, or append the folder into python path
      __init__.py
      import os, sys
      my_path = os.path.dirname(__file__)
      my_path in sys.path or sys.path.append(my_path)
  • How to install extra module automatically with pip
    • download pip and use bellow method to manually install it, or run this line of command to get or update pip stuffs.
      python -m pip install --upgrade pip wheel setuptools
    • once done, you can install rest modules with cmd
      python -m pip install package_name
  • How to install wheel package
    REM pip app is at PythonAppDir/Scripts
    REM make sure that wheel is in 32/64bit matching your python 32/64bit version
    pip install C:/some-dir/some-file.whl
  • How to install extra modules manually
    1. download the module source,
      • if it has setup.py in its directory, run
        python setup.py install

        to ask python to automatically install it into your python site-package directory

      • if it has no setup.py in its directory, or just a single folder or a python .py file, then just include its path in your python path under your system variable or run this command in python cmd line before you call
        import sys;myPath='/YourPath/ToTheFolderOrFile/';myPath in sys.path or sys.path.append(myPath)
      • Ideally, if you put the Module Folder (not its parent distribution folder) under the Lib/site-package folder, it should work out of box when you type “import Module” in cmd, of course, if you want to use specific version of the module or having the module in some other location, use the path way is more controllable to use exactly what you need.
      • However, if you want your Python module to be at a specific location, then add it to python path environment variable. For windows advanced system setting > environment variable
        set PYTHONPATH=%PYTHONPATH%;D:\Dev\PyQT
    2. distribute your python file with module,
      • you can ask user to manually install those modules that used in your python program file
      • or just put those dependent file or folder next to your python program file
  • check with module info
    # check whether a module has that attribute
    if hasattr(QtGui, 'QTabWidget'):
        print("yes")
     
    # try get a function from a module and with fallback option
    resultFunc = getattr(MyClass, "function_A_name", default_function_if_not_found_A)
     
    # check imported module name dictionary
    if 'MyModule' in sys.modules:
        print('yes')
  • work with module using variable names
    # import PySide
    __import__('PySide')
     
    # same as from PySide import QtNetwork as Net
    qtModeList = ("PySide", "PyQt4", "PySide2", "PyQt5")
    qtMode = 0
    Net = getattr( __import__(qtModeList[qtMode], fromlist=['QtNetwork']), 'QtNetwork')
  • import module from its parent directory
    import os,sys
    os.path.join(sys.path[0], '..') in sys.path or sys.path.insert(1, os.path.join(sys.path[0], '..'))
    import my_module_at_current_file_parent_dir

useful module list

  • useful audio module
    • pyaudio
      import pyaudio
      p = pyaudio.PyAudio()
      for i in range(p.get_device_count()):
          print p.get_device_info_by_index(i).get('name')
  • useful Game building modules
  • database and file modules
  • encryption modules
    • hashlib (built-in)
      m = hashlib.md5()
      m.update(user_input_text)
      # a sample hash code example
      if m.hexdigest() != '88888888888888888888888888888888':
          return
  • system info modules
    • getpass (built-in, user name)
      getpass.getuser()
    • glob (built-in, wild char file list)
      glob.glob(os.path.join(cur_path,prefix)+'_v???.[Mm][abAB]')
      # get all file named prefix variable _v001 like ma/mb file
    • stat (built-in, file permission)
      # lock down file for user, group, other readonly
      os.chmod(filePath, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
    • time (built-in, time related)
      time.strftime('%Y/%m/%d %H:%M') # 1980/12/31 23:55 format
  • system command modules
    • subprocess (built-in)
      • subprocess.Popen don't block your main program
        subprocess.Popen([r'notepad.exe', r'D:\zTmp\coder.py']);print('ok')
      • subprocess.call will block the main program till call finish, equals
        subprocess.call('nircmd.exe win close class "CabinetWClass"')
        subprocess.call(r'notepad.exe D:\zTmp\coder.py');print('ok')
        subprocess.Popen([r'notepad.exe', r'D:\zTmp\coder.py']).wait();print('ok')
        os.system(r'notepad.exe D:\zTmp\coder.py');print('ok')
      • subprocess.check_call will raise an exception
      • both return result
      • Ask System to Open Folder
        if os.path.isdir(folderPath):
            if sys.platform == 'darwin':
                try:
                    subprocess.check_call(['open', '--', folderPath])
                except subprocess.CalledProcessError:
                    pass # handle errors in the called executable
                except OSError:
                    pass # executable not found
            elif sys.platform == 'linux2':
                try:
                    subprocess.check_call(['xdg-open', '--', folderPath])
                except subprocess.CalledProcessError:
                    pass # handle errors in the called executable
                except OSError:
                    pass # executable not found
            elif sys.platform in ['win32','win64']:
                try:
                    subprocess.check_call(['explorer', folderPath.replace("/","\\")])
                except subprocess.CalledProcessError:
                    pass # handle errors in the called executable
                except OSError:
                    pass # executable not found
      • check if a process is running
        appName = 'googledrivesync.exe'
        info=subprocess.Popen('tasklist.exe /FO CSV /FI "IMAGENAME eq {0}"'.format(appName),stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
        out, err = info.communicate()
        result = [ x for x in out.replace('"','').split('\r\n') if x !='' ]
        if len(result)>1 and result[1].startswith(appName):
            print('process found: '+appName)
        else:
            subprocess.Popen([r'D:\path_to_app\googledrivesync.exe'])
      • ask System to open file
        if sys.platform in ['win32','win64']:
            os.startfile(filePath)
        elif sys.platform == 'darwin':
            os.open(filePath)
        elif sys.platform == 'linux2':
            os.xdg-open(filePath)
      • launch a subprocess to run a Bat file or python file in desktop
        subprocess.Popen([r'D:\App\Python27\python.exe',r'D:\Dev\Pipeline\PyDesktop\CompFolder\CompFolder.py'])
        subprocess.Popen([r'D:\Dev\Pipeline\PyDesktop\CompFolder\CompFolder.bat'])
         
        # if above method failed because PATH or PYTHONPATH issue, especially when call like above in a mixed python environment like Maya,
        # you need to use a clean copy of environment, like this Example
        env2={}
        env2['PATH']='''C:\Windows\system32
        D:\App\Python27
        D:\App\Python27\Lib\site-packages\PyQt4
        D:\App\Python27\lib\site-packages\pywin32_system32
        '''.replace('\n',';')
        env2['PYTHONPATH']='''D:\App\Python27\python27.zip
        D:\App\Python27\DLLs
        D:\App\Python27\lib
        D:\App\Python27\lib\plat-win
        D:\App\Python27\lib\lib-tk
        D:\App\Python27
        D:\App\Python27\lib\site-packages
        D:\App\Python27\lib\site-packages\win32
        D:\App\Python27\lib\site-packages\win32\lib
        D:\App\Python27\lib\site-packages\Pythonwin
        '''.replace('\n',';')
         
        subprocess.Popen([r'D:\App\Python27\python.exe',r'D:\Dev\Pipeline\PyDesktop\CompFolder\CompFolder.py'], env=env2)
        subprocess.Popen([r'D:\Dev\Pipeline\PyDesktop\CompFolder\CompFolder.bat'], env=env2)
  • string related
    • re (built-in, regular expression)
      # capture group and non-capture group:
      # http://stackoverflow.com/questions/3512471/what-is-a-non-capturing-group-what-does-a-question-mark-followed-by-a-colon
      re.findall('([a-zA-Z0-9_]+)_atn(?:Msg)?', 'test_atn') # return ['test']
      re.findall('([a-zA-Z0-9_]+)_atn(?:Msg)?', 'test_atnMsg') # return ['test']
      # since we only need the prefix, the Msg group is to test exisits
  • compile and de-compile module
    • cx_Freeze: compile to exe, app, bin
      • After compile, the only files need to do partial update each time is (exe + library.zip)
    • uncompyle2: convert pyc to py (python 2.7 code support only) https://github.com/wibiti/uncompyle2
      • code example
        # in the init file
        main('/pyc_file_dir/', '/pyc_file_dir_decompile_dir/', ['that_pyc_file.pyc'], [])
  • check module installed
    help(moduleName)
    dir(moduleName)
    #import moduleName
    #then type moduleName to show location
  • check module in shell command
    pydoc moduleName
  • change current working path
    os.chdir('/my_path/')
  • import python function from another python file
    import sys
    sys.path.append("/home/my/python_file_folder")  # you need to have python path knows your file location
    # method 1
    import sample  
    sample.abcd()
    # method 2
    from sample import abcd  
    abcd()
    #method 3
    from sample import *
    abcd()
  • run another python script
    execfile("testScript.py")
    # python 3, that one not work, use this one
    exec(open("testScript.py").read(), globals())
  • pass parameter to a python script (ref: http://www.tutorialspoint.com/python/python_command_line_arguments.htm)
    # method 1: python myscript.py arg1 arg2
    import sys
     
    print 'Number of arguments:', len(sys.argv), 'arguments.'
    print 'Argument List:', str(sys.argv)
     
    # method 2
    import getopt, sys
  • example code for a mel file to html file process, in both module and app way
    • run code
      python viewMel.py myMelFunc.mel
    • run in python
      import viewMel
      viewMel.viewMel_html('myMelFunc.mel','mydoc.html')
    • code
      #view mel lib
      #a python tool to view mel lib file functionts
      import sys
       
      def viewMel(file):
          with open(file) as f:
              for line in f:
                  lineClean=line.strip()
                  if lineClean.startswith('//==') or lineClean.startswith('global proc') or lineClean.startswith('/**'):
                      print lineClean.replace('{','').replace('*/','').replace('/**',' - ')
       
      def viewMel_html(melFile,htmlFile):
          h = open(htmlFile,'w')
          with open(melFile) as f:
              h.write('<html><head><link rel="stylesheet" type="text/css" href="s1.css"></head>\n<body>'+'\n')
              for line in f:
                  lineClean=line.strip()
                  if lineClean.startswith('//=='):
                      h.write('<h1>'+lineClean.replace('//==','').replace('=','')+'</h1>'+'\n')
                  elif lineClean.startswith('global proc'):
                       h.write('<h5>'+lineClean.replace('{','').replace('global proc ','')+'</h5>'+'\n')
                  elif lineClean.startswith('/**'):
                       h.write('<p>'+lineClean.replace('*/','').replace('/**',' - ')+'</p>'+'\n')
              h.write('</body></html>'+'\n')
          h.close()
       
      if __name__=="__main__":
          viewMel_html(sys.argv[1],sys.argv[1].replace('.mel','.html'))
  • open url in brower
    import webbrowser
    webbrowser._browsers # list registered browsers
     
    new = 2 # open in a new tab, if possible
    # open a public URL, in this case, the webbrowser docs
    url = "http://docs.python.org/library/webbrowser.html"
    webbrowser.open(url,new=new)
    # for using firefox, note, firefox needs to be default or in the system environment path
    webbrowser.get('firefox').open(url,new=2)
    # open an HTML file on my own (Windows) computer
    url = "file://X:/MiscDev/language_links.html"
    webbrowser.open(url,new=new)
  • check file exists
    os.path.isfile(path)
  • access file and folder
    # delete a file
    os.remove(tmpitem)
     
    # check exist of a file
    if not os.path.exists(tmpJPG):
        print tmpitem
     
    # get file with a certain name pattern in a directory and all its sub-directories
    scanDir = r'D:\scanDir_start_dir'
    my_list = []
    for (dirpath, dirnames, filenames) in os.walk(scanDir):
        my_list.extend( [ os.path.join(dirpath, x) for x in filenames if re.match('[a-zA-Z]+_lang_.+\.json', x) ] )
     
    # get file with a certain name pattern in a directory
    [x for x in os.listdir(scanDir) if os.path.isfile(os.path.join(scanDir, x)) and re.match('MyApp_lang_.+\.json', x) ]
    [x for x in glob.glob(os.path.join(scanDir,'MyApp_lang_*.json')) if os.path.isfile(x) ]
  • lines to array
    with open(fname) as f:
        content = f.readlines()
     
    with open(fname) as f:
        for line in f:
            #do something with line    
  • remove any non-ascii words in file names
    import os
    import urllib
    curdir = os.getcwd()
    os.chdir(parentDir)
    file_list_en = os.listdir('.') # this is ok ascii list
    file_list_cn = os.listdir(u'.') # this u fix extreme non-ascii names
    for i in xrange(len(file_list_en)):
        itemName = file_list_en[i]
        print(itemName)
        if itemName.startswith('%'):
            # convert %AA cn name to unicode
            new_fixName1 = urllib.unquote(itemName).decode('utf8').replace('+',' ')
            # then remove cn chars
            new_itemName2 = ''.join([c for c in new_fixName1 if ord(c) < 128 ]).replace('?','').replace('+',' ').strip()
            if itemName != new_itemName2:
                print([itemName,new_itemName2])
                os.rename(itemName,new_itemName2)
        else:
            itemName = file_list_cn[i] # for non ascii names
            # just remove cn chars
            new_itemName = ''.join([c for c in itemName if ord(c) < 128 ]).replace('?','').replace('+',' ').strip()
            if itemName != new_itemName:
                print([itemName,new_itemName])
                os.rename(itemName,new_itemName)
     
    os.chdir(curdir)
  • read line from a huge file by multiple process at the same time, without accident write operation
    import linecache
    linecache.getline('/path_to_file.txt', 2) # get 2nd line of text, the first line is no. 1, unlike 0 in arrary
  • process line by line rewrite
    import sys
    import fileinput
     
    for i, line in enumerate(fileinput.input('color_test.htm', inplace=1)):
      #sys.stdout.write(line.replace('colour','color'))
      if line.find('color') > -1:
        color=line.split(';',1)[0]
        color=color.split('color',1)[1]
        sys.stdout.write(line.replace('</span',(color+'</span')))
      else:
        sys.stdout.write(line)
  • make sure directory is created before create file in defined path
    my_filePath = '/your_path/intermedia_folders/file.ext'
    # method 1: these 2 lines only create last leaf folder, won't deal all the inbetween folders
    if not os.path.isdir(os.path.dirname(my_filePath)):
        os.mkdir(os.path.dirname(my_filePath))
     
    # method 2: these 2 lines create all the needed folders forming the path
    try: 
        os.makedirs(os.path.dirname(my_filePath))
    except OSError:
        pass
  • write python data
    # write raw data and read raw data
    os.getcwd()
     
    import json
    def writeDataFile(data, file):
        with open(file, 'w') as f:
            json.dump(data, f)
     
    def readDataFile(file):
        with open(file) as f:
            data = json.load(f)
        return data
     
    # write dictionary data and read dictionary data
    import csv
    def writeDictFile(dict, file):
        w = csv.writer(open("output.csv", "w"))
        for key, val in dict.items():
            w.writerow([key, val])
     
    def readDictFile(file):    
        dict = {}
        for key, val in csv.reader(open(file)):
            dict[key] = val
        return dict
  • UTF-8 unicode file write
    ############### UTF-8 content write #############
    import codecs
    txt=u"<table border=1>\n"
    i=0
    for each in a:
        i=i+1;
        txt=txt+u"<tr><td><a href='{link}'>{title}</a></td><td>{code}</td><td>{idx}</td><tr>\n".format(link=each['link'], title=each['title'],code=each['code'], idx=i)
     
    txt=txt+u'</table>'
     
    with codecs.open('page.htm',mode='w',encoding='utf-8') as f:
        f.write(txt)
  • copy directory structure only
    for dirpath, dirnames, filenames in os.walk(srcPath):
        to_mkdir = os.path.join(tgtPath, dirpath[1+len(srcPath):])
        if not os.path.isdir(to_mkdir):
            os.mkdir(to_mkdir)
    os.startfile(tgtPath) # show result folder

Python Important Modules

  • pip is a quick python module get and installer module for python, it can download module for your python library.
  • update it before install other module, make sure you already in python' pip folder path
    sudo pip install --upgrade pip
  • regular expression pattern
all data file
(?!(.*[.]db)|(^Keyboard$)|(^[.].*))
all maya file
[^.].+(.ma|.mb|.abc|.xml|.fbx)
  • 3rd party module, html get post request response operation library
  • Single Get web link content
    import requests
    result = requests.get('http://my_site/my_page', timeout=5)
    print(result.text)
  • Single post web link content with login info
    result = requests.post('http://my_site/my_page', data={'site_username_field_name': 'your_name', 'site_password_field_name': 'your_pass'})
    print(result.text)
  • one-time login with continue consistent header info for session operation
    with requests.Session() as session:
        # first time login,
        reply = session.post('http://site/login_page', data={'site_username_field_name': 'your_name', 'site_password_field_name': 'your_pass'})
        print(reply.text)
        # read rest login-required pages
        reply = session.get('http://site/other_info_page')
        print(reply.text)
  • check send header and received header info
    print(session_object.headers) # user sending header info
    print(reply_object.headers) # server replying header info
  • more function explain
    result.content # is html in bytes
    result.text # is html in unicode text
  • a html info extractor, best works with another parser module “lxml” to get partial info
  • example code
    from bs4 import BeautifulSoup
    soup = BeautifulSoup(html, 'lxml') # html byte from requests.get
    # find all title link text
    link_list = soup.find_all("a", {'class':['title', 'threadtitle_unread']} ) # or 'title' only if no multiple
    name_list = [x.string for x in link_list ] # text element extract
    link_list[0].attrs['href'] # link url element extract
  • you need install 2 things to get it working:
    1. Python module:
    2. system platform dependent webdriver binary: http://www.seleniumhq.org/download/
      1. for chrome browser automate: go above link and find 3rd binding “Google Chrome Driver”
    3. then you can load that drive binary into python selenium module object to start
      from selenium import webdriver
      driver = webdriver.Chrome('/your_path_to_that_binary_driver/chromedriver.exe')
      driver.get('http://google.com')
      driver.implicitly_wait(20)
      driver.get_screenshot_as_file(r'D:\testshot.png')
      driver.quit()
  • get element
    # get css selector by right click browser's inspector view, right click on html element to copy css selector
    driver.find_element_by_css_selector('.jsb > center:nth-child(1) > input:nth-child(1)') 
    # path method
    driver.find_element_by_xpath('//input[@name="btnk"]')
  • element operation
    • element.get_attribute('href')
    • element.get_attribute('outerHTML')
    • element.text
    • element.click()
    • element_input.send_keys() and webdriver.common.keys
    • element_form.submit()
    • driven_browser.back(), forward(), refresh()
  • mouse control
    • click(), doubleClick(), rightClick()
    • click([x,y])
    • moveTo(x,y [,duration=sec])
    • moveRel(x_offset, y_offset [,duration=sec])
    • dragTo(x,y [,duration=sec])
    • position(), size(),
    • displayMousePosition()
      # note, that displayMousePosition require 3rd party library
      # * PIL (Py2.x only, adapted by Pillow) > PIL.ImageGrab > pyscreenze (edit line 309 with "from PIL import ImageGrab") > pyautogui
      http://www.pythonware.com/products/pil/
      https://pypi.python.org/pypi/PyScreeze
  • keyboard control
    • typewrite('Text goes here', [,interval=secs]) # pyautogui.KEYBOARD_KEYS
    • press('pageup')
    • hotkey('ctrl', 'o')
    • note: best work with time.sleep(5) to give 5 sec for pc to respond
  • image recognition
    • pixel(x,y) # return RGB
    • screenshot([filename]) # return PIL,Pillow Image object [and save file]
    • locateOnScreen(imageFilename) # returns (x,y, w, h) or None
    • linux: scrot
    • example code
      import pyautogui as pui
      pos = pui.locateOnScreen('d:\\zTmp\\test_build.png')
      pui.click( (pos[0]+pos[2]*0.5 , pos[1]+pos[3]*0.5) )
  • a mostly windows only GUI automation module, with mouse, keyboard support on linux
    • API level interaction

  * tip and ref:

  • install and restart computer to get dll reg refreshed
    https://sourceforge.net/projects/pywin32/files/pywin32/
    (or) python -m pip install pypiwin32
  • get windows explorer in taskbar order, return [(title, hwnd int, addressbar url, [top,left,w,h], vis)]
    import win32com
    from win32com import client
    def get_explorer_list():
        # win32com: get folder windows in taskbar order; return [(title, hwnd int, addressbar url, [top,left,w,h], vis)]
        shell = client.Dispatch("Shell.Application")
        win_list = shell.Windows()
        result_list = []
        for win in win_list:
            info = []
            info.append(win.LocationName) # title name
            info.append(win.hwnd) # handle value as int
            info.append(win.LocationURL) # address bar url, eg. file:///C:/Users/Test/Downloads
            info.append([win.Top, win.Left, win.width, win.height]) # win pixel position
            info.append(win.visible) # visible
            info.append(win) # com object
            result_list.append(info)
        return result_list
    ''' full list of property
    ['ReadyState', 'Busy', 'Container', 'Silent', 'Top', 
    'RegisterAsDropTarget', 'LocationName', 'Application', 'Offline', 'Document', 
    'Type', 'ToolBar', 'MenuBar', 'FullScreen', 'Parent', 'TheaterMode', 
    'Path', 'Name', 'RegisterAsBrowser', 'StatusText', 'Left', 'TopLevelContainer', 
    'Resizable', 'Width', 'StatusBar', 'HWND', 'Height', 'Visible', 'FullName', 
    'LocationURL', 'AddressBar']
    '''
  • get selected item in window explorer
    # ref: 
    # https://win32com.goermezer.de/microsoft/windows/find-selected-files-in-windows-explorer.html
    # https://msdn.microsoft.com/en-us/library/windows/desktop/bb787810(v=vs.85).aspx
     
    def get_selection_list(win):
        # win32com: get selection item detail from win COM object
        item_list = []
        folderItems = win.Document.SelectedItems()
        for i in range(folderItems.Count):
            tmp_info = []
            tmp_info.append(folderItems.Item(i).path) # C:\Users\Test\Downloads\example.zip
            tmp_info.append(folderItems.Item(i).name)
            tmp_info.append(folderItems.Item(i).isFolder)
            tmp_info.append(folderItems.Item(i).size)
            tmp_info.append(folderItems.Item(i).type)
            item_list.append(tmp_info)
        return item_list
  • explorer window COM object control
    # control the window COM object to go to a location
    win.Navigate('file:///C:/Users/Test/Desktop')
    win.Busy # a check for still in processing
     
    # check visibile and make full screen
    win.FullScreen =1 # make first windows explorer full screen
  • system operation
    # get system dir and 
    oShell = win32com.client.Dispatch("Wscript.Shell")
    print(oShell.SpecialFolders("Desktop"))
     
    # change drive letter
    # ref: http://timgolden.me.uk/python/win32_how_do_i/change-a-drive-letter.html
     
    # create windows shortcut and read it
    shortcut = shell.CreateShortCut("t:\\test.lnk")
    shortcut.Targetpath = "D:\\tmp"
    shortcut.save()
     
    shortcut = shell.CreateShortCut("t:\\test.lnk")
    print(shortcut.Targetpath)
     
    # get single screen resolution and total screen
    # ref: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724385(v=vs.85).aspx
    import win32api
    w=win32api.GetSystemMetrics(0) # primary screen width
    h=win32api.GetSystemMetrics(1) # primary screen height
    vw = win32api.GetSystemMetrics(78) # total screen area width
    vh = win32api.GetSystemMetrics(79) # total screen area height
    print('screen resolution: {0}x{1}'.format(w,h))
    print('virtual area resolution: {0}x{1}'.format(vw,vh))
  • ctypes is an advanced ffi (Foreign Function Interface) package, ctypes allows to call functions in dlls/shared libraries and wrap libraries in pure Python. ctypes works cross-platform with libffi support.
  • (method 1) get all windows explorer windows in Z order, return [(title, class, [x,y,w,h], hwnd int)]
    def get_win_order_all():
        # ctype: grab folder windows in z order, return [(title, class, [x,y,w,h], hwnd int)]
        order_list = []
        result_list = []
        top = ctypes.windll.user32.GetTopWindow(None)
        if not top:
            return order_list
        length = ctypes.windll.user32.GetWindowTextLengthW(top)
        buff = ctypes.create_unicode_buffer(length + 1)
        ctypes.windll.user32.GetWindowTextW(top, buff, length + 1)
        class_name = ctypes.create_string_buffer(200)
        ctypes.windll.user32.GetClassNameA(top, ctypes.byref(class_name), 200)
        r=ctypes.wintypes.RECT()
        ctypes.windll.user32.GetWindowRect(top,ctypes.byref(r))
        result_list.append( [buff.value, class_name.value, [r.left,r.top,r.right-r.left,r.bottom-r.top], top ])
        order_list.append(top)
        while True:
            next = ctypes.windll.user32.GetWindow(order_list[-1], 2) # win32con.GW_HWNDNEXT
            if not next:
                break
            length = ctypes.windll.user32.GetWindowTextLengthW(next)
            buff = ctypes.create_unicode_buffer(length + 1)
            ctypes.windll.user32.GetWindowTextW(next, buff, length + 1)
            class_name = ctypes.create_string_buffer(200)
            ctypes.windll.user32.GetClassNameA(next, ctypes.byref(class_name), 200)
            r=ctypes.wintypes.RECT()
            ctypes.windll.user32.GetWindowRect(next,ctypes.byref(r))
            result_list.append( [buff.value, class_name.value, [r.left,r.top,r.right-r.left,r.bottom-r.top], next] )
            order_list.append(next)
        return result_list
     
    full_list = get_win_order_all()
    visible_list = [x for x in full_list if ctypes.windll.user32.IsWindowVisible(x[-1])]
    # visible list is actually more useful, 10+ instead 100+ items
     
    explorer_list = [x for x in visible if x[1]=='CabinetWClass']
    firefox_list = [x for x in visible if x[1]=='MozillaWindowClass']
  • (method 2) get all (visible) (windows explorer) windows in Z order, return [(title, class, hwnd as pointer)]
    def get_win_order_v2():
        # ctypes
        # ref: https://sjohannes.wordpress.com/2012/03/23/win32-python-getting-all-window-titles/
        # info (title, class_name, hwnd)
        window_list = []
        # propare windows list passing
        def window_info_process(hwnd, lParam):
            if ctypes.windll.user32.IsWindowVisible(hwnd):
                length = ctypes.windll.user32.GetWindowTextLengthW(hwnd)
                buff = ctypes.create_unicode_buffer(length + 1)
                ctypes.windll.user32.GetWindowTextW(hwnd, buff, length + 1)
                class_name = ctypes.create_string_buffer(200)
                ctypes.windll.user32.GetClassNameA(hwnd, ctypes.byref(class_name), 200)
                if class_name.value == 'CabinetWClass':
                    window_list.append( [ buff.value, class_name.value, hwnd ])
            return True
        procObj = ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int))
        # execute it
        ctypes.windll.user32.EnumWindows(procObj(window_info_process), 0)
        return window_list
  • (method 3) Break down ctypes hwnd, pid, process_handle into functions modules
    '''
    ref: http://timgolden.me.uk/python/win32_how_do_i/find-the-window-for-my-subprocess.html
        Window handle → process ID: GetWindowThreadProcessId
        Process ID → process handle: OpenProcess
        Process handle → executable path: QueryFullProcessImageName (compare this with your target)
        Close the process handle: CloseHandle
    ref: http://www.mengwuji.net/forum.php?mod=viewthread&tid=1432
        Windows 2000 = GetModuleFileName()
        Windows XP x32 = GetProcessImageFileName()
        Windows XP x64 = GetProcessImageFileName()
        Windows Vista = QueryFullProcessImageName()
        Windows 7 = QueryFullProcessImageName()
    ref:
        uisoup - utils : https://pypi.python.org/pypi/UISoup
        https://programtalk.com/python-examples/ctypes.windll.user32.GetWindowThreadProcessId/
        https://pypkg.com/pypi/pywinauto/f/pywinauto/win32functions.py
    '''
     
    def get_win_pid(hwnd):
        cur_pid = ctypes.c_long()
        ctypes.windll.user32.GetWindowThreadProcessId(hwnd, ctypes.byref(cur_pid))
        return cur_pid
    def get_process_path(pid):
        PROCESS_QUERY_INFORMATION = 0x0400
        max_unicode_path = 32767 * 2 + 200
        file_path_buffer = ctypes.create_unicode_buffer(max_unicode_path)
        length_path = ctypes.c_ulong(max_unicode_path)
        pHandle = ctypes.windll.kernel32.OpenProcess(PROCESS_QUERY_INFORMATION, False, pid) # won't get admin process if not as admin
        retval = ctypes.windll.kernel32.QueryFullProcessImageNameW(pHandle, 0, file_path_buffer, ctypes.byref(length_path))
        if retval == 0:
            raise Exception('QueryFullProcessImageNameW failed')
        #ctypes.windll.kernel32.CloseHandle(pHandle)
        return file_path_buffer.value
    def get_win_path(hwnd):
        return get_process_path(get_win_pid(hwnd))
     
    def get_win_rect(hwnd):
        from ctypes import wintypes
        r=ctypes.wintypes.RECT()
        ctypes.windll.user32.GetWindowRect(hwnd,ctypes.byref(r))
        return [r.left,r.top,r.right-r.left,r.bottom-r.top]
    def get_win_title(hwnd):
        length = ctypes.windll.user32.GetWindowTextLengthW(hwnd)
        title_buffer = ctypes.create_unicode_buffer(length + 1)
        ctypes.windll.user32.GetWindowTextW(hwnd, title_buffer, length + 1)
        return title_buffer.value
    # AE CS6: AE_CApplication_11.0
    def get_win_class(hwnd):
        class_name = ctypes.create_string_buffer(200)
        ctypes.windll.user32.GetClassNameA(hwnd, ctypes.byref(class_name), 200)
        return class_name.value
    def is_win_top(hwnd):
        top_hwnd = ctypes.windll.user32.GetTopWindow(None)
        return hwnd == top_hwnd
     
    def get_win_list(visible=1, orderMethod=0):
        # both method get result
        # orderMethod uses : ctypes.windll.user32.GetTopWindow
        # callBackMethod uses: ctypes.windll.user32.EnumWindows
        win_list = []
        if orderMethod:
            order_list = []
            top = ctypes.windll.user32.GetTopWindow(None)
            if not top:
                return win_list
            visible_info = ctypes.windll.user32.IsWindowVisible(top)
            win_list.append( [ top, visible_info ])
            order_list.append(top)
            while True:
                next = ctypes.windll.user32.GetWindow(order_list[-1], 2) # win32con.GW_HWNDNEXT
                if not next:
                    break
                visible_info = ctypes.windll.user32.IsWindowVisible(next)
                win_list.append( [next, visible_info] ) # hwnd: as int
                order_list.append(next)
        else:
            # propare windows list passing
            def window_info_process(hwnd, lParam):
                visible_info = ctypes.windll.user32.IsWindowVisible(hwnd)
                win_list.append( [ hwnd, visible_info ]) #hwnd: as LP_c_long
                return True
            # ref: http://makble.com/the-story-of-lpclong
            # function 1: this will get as LP_c_long as hwnd
            #procObj = ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int))
            # function 2: this will get int as hwnd like other win32api function
            procObj = ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.c_int, ctypes.POINTER(ctypes.c_int))
            # execute it
            ctypes.windll.user32.EnumWindows(procObj(window_info_process), 0)
        if visible:
            return [x for x in win_list if x[1]]
        return win_list
  • ctypes window operation by hwnd
    # my_hwnd can be a int or a ctypes int pointer
    # full function ref: http://www.jasinskionline.com/windowsapi/ref/funca.html
     
    # bring window to bring
    ctypes.windll.user32.SetForegroundWindow(my_hwnd)
     
    # close window
    WM_CLOSE = 0x0010
    ctypes.windll.user32.PostMessageA(my_hwnd, WM_CLOSE, 0, 0)
     
    # get window x,y,w,h
    from ctypes import wintypes
    r=ctypes.wintypes.RECT()
    ctypes.windll.user32.GetWindowRect(my_hwnd,ctypes.byref(r))
    print( [r.left,r.top,r.right-r.left,r.bottom-r.top] )
     
    # move window by x,y,w,h and refresh
    ctypes.windll.user32.MoveWindow(my_hwnd, 0, 0, 760, 500, True)
  • mouse, keyboard operation
    # get mouse position
    class POINT(ctypes.Structure):
        _fields_ = [("x", ctypes.c_ulong), ("y", ctypes.c_ulong)]
    pt = POINT()
    ctypes.windll.user32.GetCursorPos(ctypes.byref(pt))
    print('{0} {1}'.format(pt.x,pt.y))
     
    ctypes.windll.user32.SetCursorPos(1200, 850)  # move cursor to 1200,850 (x,y)
    ctypes.windll.user32.mouse_event(2, 0, 0, 0,0) # left mouse button down
    ctypes.windll.user32.mouse_event(4, 0, 0, 0,0) # left mouse button up
  • get and set wallpaper in windows
    def getWallpaper():
        SPI_GETDESKWALLPAPER = 0x0000073
        #    try:
        #        win32con.SPI_GETDESKWALLPAPER 
        #    except AttributeError, attributeError:
        #        raise WinDesktopError, "getWallpaper() not supported on this OS"
        wallpaper = ctypes.c_buffer("\000" * 256)
        ctypes.windll.user32.SystemParametersInfoA(SPI_GETDESKWALLPAPER, len(wallpaper), ctypes.byref(wallpaper), 0)
        return wallpaper.value
     
    def setWallpaper(wallpaperPath, conversionPath=None):    
        # Convert to bitmap if necessary
        wallpaperImage = Image.open(wallpaperPath)
        if wallpaperImage.format != 'BMP':
            conversionPath = conversionPath or os.getenv('SystemRoot')
            wallpaperPath = os.path.join(conversionPath, os.path.splitext(os.path.split(wallpaperPath)[-1])[0] + '.bmp')
            wallpaperImage.save(wallpaperPath)
        # Set wallpaper
        wallpaperPath = ctypes.c_buffer(wallpaperPath)
        ctypes.windll.user32.SystemParametersInfoA(win32con.SPI_SETDESKWALLPAPER, 0, wallpaperPath, 0)
  • wallpaper set (win7) the simple version
    import ctypes
    SPI_SETDESKWALLPAPER=20
    ctypes.windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, r"D:\Rec\bg2.jpg",0)
  • set id
    ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID('com.app.1.0')
  • get if user is admin
    print(ctypes.windll.shell32.IsUserAnAdmin())
  • system operation
    # get screen count
    screen_cnt = ctypes.windll.user32.GetSystemMetrics(80)
    # get screen resolution
    screen_x, screen_y = ( ctypes.windll.user32.GetSystemMetrics(78), ctypes.windll.user32.GetSystemMetrics(79) )

file and folder operation

  • show drive letter in use
    drive_list_data = ctypes.cdll.msvcrt._getdrives() # binary mask in decimal format
    mask_list = list( '{0:b}'.format(drive_list) )[::-1]
    A_code = 65 # ascii code of letter A
    drive_letter_in_use = [ chr(A_code+i) for i in range(len(mask_list)) if mask_list[i]=='1' ]
  • show file and select file in explorer (return 42)
    my_filePath = u'C:\\Users\\Public\\Pictures\\Sample Pictures\\Koala.jpg'
    ctypes.windll.shell32.ShellExecuteW(None, u'open', u'explorer.exe', u'/n,/select,'+my_filePath, None, 1)
  • open file property window
    import time
    import ctypes
    import ctypes.wintypes
     
    SEE_MASK_NOCLOSEPROCESS = 0x00000040
    SEE_MASK_INVOKEIDLIST = 0x0000000C
     
    class SHELLEXECUTEINFO(ctypes.Structure):
        _fields_ = (
            ("cbSize",ctypes.wintypes.DWORD),
            ("fMask",ctypes.c_ulong),
            ("hwnd",ctypes.wintypes.HANDLE),
            ("lpVerb",ctypes.c_char_p),
            ("lpFile",ctypes.c_char_p),
            ("lpParameters",ctypes.c_char_p),
            ("lpDirectory",ctypes.c_char_p),
            ("nShow",ctypes.c_int),
            ("hInstApp",ctypes.wintypes.HINSTANCE),
            ("lpIDList",ctypes.c_void_p),
            ("lpClass",ctypes.c_char_p),
            ("hKeyClass",ctypes.wintypes.HKEY),
            ("dwHotKey",ctypes.wintypes.DWORD),
            ("hIconOrMonitor",ctypes.wintypes.HANDLE),
            ("hProcess",ctypes.wintypes.HANDLE),
        )
     
    ShellExecuteEx = ctypes.windll.shell32.ShellExecuteEx
    ShellExecuteEx.restype = ctypes.wintypes.BOOL
     
    sei = SHELLEXECUTEINFO()
    sei.cbSize = ctypes.sizeof(sei)
    sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_INVOKEIDLIST
    sei.lpVerb = "properties"
    sei.lpFile = 'C:\\Users\\Public\\Pictures\\Sample Pictures\\Koala.jpg'
    sei.nShow = 1
    ShellExecuteEx(ctypes.byref(sei))
    time.sleep(5)

Python by Reference or by Value

  • my experience found: “pure = assignment will not change original holder's value, but other operation will change original holder's value”
  • here is my study experiment
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # Example 1
    dict = {}
    dict['seq']={}
    for each in 'aa bb cc dd'.split():
        dict['seq'][each]=[]
    list_aa = dict['seq']['aa'] # passing by reference!!!
    for i in [1,2,3,4,5]:
        list_aa.append(i)
    print dict # affect both list_aa and dict
     
    temp_list = dict['seq']['aa']
    temp_list.append(22) # you are not get a copy of dict entry, but affect orginal dict as well
    print temp_list
    print dict # changed ------- because it is a operation
     
    # ref: http://stackoverflow.com/questions/2612802/how-to-clone-or-copy-a-list-in-python
    temp_list2 = dict['seq']['aa'][:] # actually duplicate the value out, the fastest way
    temp_list2.append(55)
    print temp_list2
    print dict # stay same
     
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # Example 2
    locs = [ [1], [2] ]
    for loc in locs: # passing by values !!!
        loc = []
    print locs # stay same
     
    for loc in locs:
        loc[0] = loc[0] * 2
    print locs # changed ------- because it is a operation
     
    #~~~~~~~~~~~~~~~~~~~~~~~~
    # Example 3
    a=1
    b=a
    b=2
    print a # stay the same
     
    a=[1]
    b=a
    b=[2]
    print a # stay the same
     
    a=[1]
    b=a
    b.append(2)
    print a # changed ------- because it is a operation
     
    # thus: assignment will not change original one, but operation will change original one
     
    a=[1,2,3]
    b=a
    c=[4,5,6]
    b=c
    print a # stay the same
     
    a=[1,2, [3.1,3.2,3.3] ]
    b=a[2]
    c=[4,5,6]
    b=c
    print a # stay the same
     
    a=[1,2, [3.1,3.2,3.3] ]
    b=a[2]
    b=[4,5,6]
    print a # stay the same
     
    a={'first':[3.1,3.2,3.3] }
    b=a['first']
    b=[4,5,6]
    print a # stay the same
     
    a={'first':[3.1,3.2,3.3] }
    b=a['first']
    b[0]=4
    print a # changed ------- because it is a operation
     
    a=[1,2, [3.1,3.2,3.3] ]
    b=a[2][:] # fast copy
    c=[4,5,6]
    b=c
    print a # stay the same
     
    #~~~~~~~~~~~~~~~~~~~~~~~
    # example 4: 
        # ref: http://stackoverflow.com/questions/1132941/least-astonishment-in-python-the-mutable-default-argument
    # explain: http://effbot.org/zone/default-values.htm
    def foo(a=[]):
        a.append(5)
        return a
    foo() # changed every time
     
    ########################################
    # reference 
    '''
    # ref: http://stackoverflow.com/questions/9696495/python-when-is-a-variable-passed-by-reference-and-when-by-value
    Everything in Python is passed and assigned by value (like Java)
    Every value in Python is a reference (pointer) to an object. 
    Objects cannot be values. 
    Assignment always copies the value (which is a pointer); 
    two such pointers can thus point to the same object. 
    Objects are never copied unless you're doing something explicit to copy them.
    # ref: http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#other-languages-have-variables
    ????Everything is passed by object. Rebinding and mutating are different operations
    '''

Common Python syntax

comment #
print print
string var=“string”
long string varL='''\ whatever '''
raw string r“Any dangerous Character here”
os navigation file operation string operation lib rename
os.chdir('/path') cd tfile=open('t.txt','w') str.replace('o','n') replace os system prefix_remove_fixed
os.getcwd() tfile.write('hello') str[2:6] substring glob wildchar list prefix_add_fixed
os.ctermid() tfile.close() str1+str2 concatenate re regular expression end_remove_fixed
os.uname() tfile.read() str(100) string convert end_add_fixed
os.listdir('/path') tfile.writeline() prefix_remove_vary
os.mkdir('/path') tfile.readline() [a-c] [abc] class
os.removedirs('/path') [^ abc] not in class
os.rename(src,dst) a* may have
os.getenv('HOME') a+ must have one
a? may have one
a{1,3} May 1~3 one
r”str” raw string
regular expression

http://docs.python.org/howto/regex.html#regex-howto

Python based tool and application

Python GUI

wxPython

  • main build block
    • A Frame is a top-level window.
  • basic wxPython widget syntax and codes
    # get wxWidget frame work,
    import wx
     
    # create class, since you are doing a App or a script
     
    # inheriate a python window (so-called frame)
    class myApp(wx.Frame): 
      # constructor, (so-called the initialize function)
      def __init__(self,parent,id):
        wx.Frame.__init__(self,parent,id,'My Window', size=(300,200))
        panel=wx.Panel(self)
     
        #bitmap button
        pic=wx.Image('img.bmp', wx.BITMAP_TYPE_BMP).ConvertToBitmap()
        myBtn=wx.BitmapButton(panel, -1, pic, pos=(10,100))
        self.Bind(wx.EVT_BUTTON,self.btnAct,myBtn)
        myBtn.SetDefault()
     
        #slider
        slider=wx.Slider(panel,-1,50,1,100,pos=(10,30), size=(250,-1),style=wx.SL_AUTOTICKS | wx.SL_LABELS)
        slider.SetTickFreq(5,1) # interval
     
        # spinner
        spinner=wx.SpinCtrl(panel,-1,'',pos=(10,1), size=(90,-1))
        spinner.SetRange(1,100)
        spinner.SetValue(10)
     
        # checkbox
        wx.CheckBox(panel,-1,'Apples',pos=(100,1),size=(60,-1))
        wx.CheckBox(panel,-1,'Orange',pos=(160,1),size=(60,-1))
        wx.CheckBox(panel,-1,'Banana',pos=(220,1),size=(60,-1))
     
        # combo box
        mylist=['Apple','Orange','Banana']
        cbox=wx.ListBox(panel,-1,(300,1),(80,60),mylist,wx.LB_SINGLE)
        cbox.SetSelection(0)
     
    # event handlers
      def btnAct(self,event):
        self.Destroy()
     
    if __name__=='__main__':
        app=wx.PySimpleApp() # application obj
        frame=myClass(parent=None,id=-1) # frame obj
        frame.Show() # show frame
        app.MainLoop() # start app    
  • wxWidget binding for python tutorial: http://zetcode.com/wxpython/introduction/
  • prompts
    #import wx.lib.agw.multidirdialog as MDD
    import multidirdialog as MDD
    def showMsg(msg):
        wx.MessageBox(msg, 'Info', 
        wx.OK | wx.ICON_INFORMATION)
     
    import wx.lib.dialogs
    def showTxt(txt):
        ask = wx.lib.dialogs.ScrolledMessageDialog(None, txt, "Info")
        ask.ShowModal()
        ask.Destroy()
     
    def getInput():
        tmpT=""
        ask = wx.TextEntryDialog(
                None, 'Your input:',
                'Input', '1')
        if ask.ShowModal() == wx.ID_OK:
            print "Input: %s\n" % ask.GetValue()
            tmpT = ask.GetValue()
        ask.Destroy()
        return tmpT
     
    def getFolder():
        tmpPath=""
        dialog = wx.DirDialog ( None, message = 'Select a directory.' )
        if dialog.ShowModal() == wx.ID_OK:
            print 'Directory:', dialog.GetPath()
            tmpPath = dialog.GetPath()
        else:
            print 'No directory.'
        dialog.Destroy()
        return tmpPath
     
     
    def getFolders():
        tmpPaths=""
        ask = MDD.MultiDirDialog(None, title="Select folders:", defaultPath='', agwStyle=0)
        if ask.ShowModal() == wx.ID_OK:
            tmpPaths = ask.GetPaths()
            print "You chose the following file(s):"
            for path in tmpPaths:
                print path
        ask.Destroy()
        return tmpPaths
     
    def getFile():
        tmpPaths=""
        wildcard = "Python source (*.py)|*.py|" "All files (*.*)|*.*"
        ask = wx.FileDialog(None, message="Choose a file", defaultDir="", defaultFile="", wildcard=wildcard,style=wx.OPEN | wx.MULTIPLE | wx.CHANGE_DIR)
        if ask.ShowModal() == wx.ID_OK:
            tmpPaths = ask.GetPaths()
            print "Select file(s):"
            for path in tmpPaths:
                print path
        ask.Destroy()
        return tmpPaths
     
    def saveFile():
        tmpPaths=""
        wildcard = "Python source (*.py)|*.py|" "All files (*.*)|*.*"
        ask = wx.FileDialog(None, message="Save As", defaultDir="", defaultFile="", wildcard=wildcard,style=wx.SAVE)
        if ask.ShowModal() == wx.ID_OK:
            tmpPath = ask.GetPath()
            print "Save file:", tmpPath
        ask.Destroy()
        return tmpPath
     
    def getColor():
        ask = wx.ColourDialog(None)
        ask.GetColourData().SetChooseFull(True)
        if ask.ShowModal() == wx.ID_OK:
            data = ask.GetColourData()
            print 'You selected: %s\n' % str(data.GetColour().Get(includeAlpha=False))
        ask.Destroy()
        return data.GetColour().Get(includeAlpha=False)
     
    def getChoice():
        tmpC=""
        ask = wx.SingleChoiceDialog(
            None, "Select a choice", 'The direction',
            ["Up", "Down", "Left", "Right"], 
            wx.CHOICEDLG_STYLE
            )
        if ask.ShowModal() == wx.ID_OK:
            tmpC = ask.GetStringSelection()
            print 'Choice: %s\n' % ask.GetStringSelection()
        ask.Destroy()
        return tmpC
     
    def getChoices():
        tmpCs=[]
        list = ["Photo", "Movie", "Docs"]
        ask = wx.MultiChoiceDialog( None, 
                                   "Select the choices",
                                   "wx.MultiChoiceDialog", list)
     
        if (ask.ShowModal() == wx.ID_OK):
            selections = ask.GetSelections()
            strings = [list[x] for x in selections]
            print "You chose:" + str(strings)
            tmpCs = strings
        ask.Destroy()
        return tmpCs
     
    application = wx.PySimpleApp()
  • all dialog reference:

PyQt

Python Portable for Windows

  • since all mac and linux have python built-in

Workflow on portable python

  1. Prepare python 2.7/3.5, by download the official python exe, and install it to D drive
      • for Python3.5.2: Windows x86 executable installer
      • for Python2.7.12: Windows x86 MSI installer
  2. Prepare PyQt4 library for py2.7/3.5 by download the official, and install to the correct PythonX.X folder
  3. other library:
    • cx_Freeze

Python Cool Tricks

  • start HTML and FILE server in current directory
    python -m SimpleHTTPServer 8181