Wednesday, September 3, 2014

Decorator for easier callback handling

Sometimes you may want a function to be called and process the return of a previous function, this is how to do it easily with a decorator.

def register(proceeding_func):
    import functools
    def actualDecorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            return proceeding_func(func(*args, **kwargs))
        return wrapper
    return actualDecorator

And here is how to use it:

if __name__ == '__main__':
    from time import sleep
    def func2(string):
        print("after {string}, I did something".format(string = string))

    @register(func2)
    def func1(a):
        sleep(5)
        return "dealing with {a}".format(a = a)

    func1(3)

Written with StackEdit.

Tuesday, August 19, 2014

AutoHotKey current script

My current script for AHK. Basically it’s a HJKL as directional and YUIO as page operators.


; IMPORTANT INFO ABOUT GETTING STARTED: Lines that start with a
; semicolon, such as this one, are comments.  They are not executed.

; This script has a special filename and path because it is automatically
; launched when you run the program directly.  Also, any text file whose
; name ends in .ahk is associated with the program, which means that it
; can be launched simply by double-clicking it.  You can have as many .ahk
; files as you want, located in any folder.  You can also run more than
; one .ahk file simultaneously and each will get its own tray icon.

; SAMPLE HOTKEYS: Below are two sample hotkeys.  The first is Win+Z and it
; launches a web site in the default browser.  The second is Control+Alt+N
; and it launches a new Notepad window (or activates an existing one).  To
; try out these hotkeys, run AutoHotkey again, which will load this file.


Capslock::
   Gui, 93:+Owner ; prevent display of taskbar button
   Gui, 93:Show, y-99999 NA, Enable nav-hotkeys: hjkl
   Send {LCtrl Down}
   KeyWait, Capslock ; wait until the Capslock button is released
   Gui, 93:Cancel
   Send, {LCtrl Up}
Return





#IfWinExist, Enable nav-hotkeys: hjkl

   *h::Send {Blind}{LCtrl Up}{Left}{LCtrl Down}
   *j::Send {Blind}{LCtrl Up}{Down}{LCtrl Down}
   *k::Send {Blind}{LCtrl Up}{Up}{LCtrl Down}
   *l::Send {Blind}{LCtrl Up}{Right}{LCtrl Down}
   *y::Send {Blind}{LCtrl Up}{Home}{LCtrl Down}
   *o::Send {Blind}{LCtrl Up}{End}{LCtrl Down}
   *u::Send {Blind}{LCtrl Up}{PgDn}{LCtrl Down}
   *i::Send {Blind}{LCtrl Up}{PgUp}{LCtrl Down}





#IfWinExist, ; end context-sensitive block





#IfWinActive ahk_class CabinetWClass ; File Explorer
    ^Backspace::




#IfWinActive ahk_class Notepad
    ^Backspace::
    Send ^+{Left}{Backspace}




#IfWinActive

~Shift & Space::Send {Space}


; Note: From now on whenever you run AutoHotkey directly, this script
; will be loaded.  So feel free to customize it to suit your needs.

; Please read the QUICK-START TUTORIAL near the top of the help file.
; It explains how to perform common automation tasks such as sending
; keystrokes and mouse clicks.  It also explains more about hotkeys.

Written with StackEdit.

Saturday, May 17, 2014

C# 学习笔记 2

我的第二个C#程序

看来每个post是有长度限制的。上次有一段没发出来。

可选变量

直接加入一个默认值就行了,这个默认值一定得是Value type,不可以和ref, out共用。

public int add_one(int x = 23)
{
    return x + 1;
}

打完这个分割线就更爱markdown了。


Var 变量类型

Var在C#里面是直接让编译器去推断变量的类型。如果编译器能推断的话,那么这个var事实上还是会变成一个静态的类型。

例如:

var y = new System.Text.StringBuilder();
Console.WriteLine(y.GetType()); // System.Text.StringBuilder


var x = 5;
x = "Hello"; // Compile time error, x is int

运算符的优先级?

这个还是免了吧,直接用括号多爽。

循环的语法糖

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloCSharp
{

    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 0, prev_Fib = 1, cur_Fib = 1 ; i < 10; i++)
            // The initialization clause can do more.
            {
                Console.WriteLine(prev_Fib);
                int newFib = prev_Fib + cur_Fib;
                prev_Fib = cur_Fib; cur_Fib = newFib;
            }
            // And this one won't work, because we exited the scope of for loop.
            Console.WriteLine(prev_Fib); //!!!!
            Console.ReadLine();
        }
    }
}

break, continue, goto

continue以前没怎么用过,作用就是在一个循环里面直接跳过后面的语句,直接到下一个变量,像是筛选不合格一样的。
Python可能会这么写:

print i for i in range(0, 10) if i %2 != 0

C#:

for (int i = 0; i < 10; i ++)
{
    if ((x % 2) == 0)
        continue;

    Console.WriteLine(i);
}

Written with StackEdit.

C# 学习笔记

我的第一个C#程序

下面就是一个最简单的C#程序,注意namespace。

加入一个类成员

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloCSharp
{
    public class UnitConverter
    {
        int ratio;
        public UnitConverter(int unitRatio) { ratio = unitRatio;}
        public int Convert (int unit) { return unit * ratio;}
    }



    class Program
    {
        static void Main(string[] args)
        {
            int x = 42; // The ultimate answer of life.

            UnitConverter feetToInchesConverter = new UnitConverter(12);
            UnitConverter milesToFeetConverter = new UnitConverter(5280);

            Console.WriteLine(feetToInchesConverter.Convert(30));
            string message = "This is my first C# language. Learning C# makes me a better man.";
            message += x.ToString();
            Console.WriteLine("Hello Console." + x);
        }
    }
}

所以其实还是和Java很像的。

C#里面类成员的static 属性

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloCSharp
{
    public class Panda
    {
        public string Name;
        public static int Population;


        public Panda ( string n = "HelloPanda")
        {
            Name = n;
            Population = Population + 1; // This will automatically COUNT THE POPULATION OF the pandas. Pretty Cool Uh.
        }

        public int get_population()
        {
            return Population;
        }
    }



    class Program
    {
        static void Main(string[] args)
        {
            int x = 42; // The ultimate answer of life.

            UnitConverter feetToInchesConverter = new UnitConverter(12);
            UnitConverter milesToFeetConverter = new UnitConverter(5280);


            Panda myPanda = new Panda("Jimmy");
            Panda yourPanda = new Panda();
            Panda anotherPanda = new Panda("Dongavel");


            Console.WriteLine(anotherPanda.get_population());
            Console.WriteLine(yourPanda.get_population()); // guess what? this is outputing 3 instead of 2. All pandas share the same population. That's why it's called population.
            Console.WriteLine(feetToInchesConverter.Convert(30));

            Console.WriteLine("Hello Console." + x);
            Console.WriteLine(x.GetType());

            Console.ReadLine();
        }
    }
}

值 vs 引用

Struct是值类型,每一个实例或者名称在内存里面都有自己的内存空间。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloCSharp
{

    public struct Point { public int x, y;}

    class Program
    {
        static void Main(string[] args)
        {
            int x = 42; // The ultimate answer of life.
            Console.WriteLine("Hello Console." + x);

            Point x1 = new Point(); // without giving parameters. But the memory is allocated for this instance.
            x1.x = 7;
            x1.y = 6;

            Point x2 = x1; // This will lead to a copy.

            x1.x = 9;

            Console.WriteLine(x1.x);
            Console.WriteLine(x2.x);
            Console.ReadLine();
        }
    }
}

如果将同样的东西定义成Class的话,就会变成引用。就算你定义了一个新的变量,然后用已有的Class来赋值,结果只会是很坑的添加了应用。最好的做法就是重载构建函数。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloCSharp
{
    public struct Point { public int x, y;}

    public class Point_reference {
        public int x, y;

        public Point_reference( Point_reference old_point)
        {
            x = old_point.x;
            y = old_point.y;
        }

        public Point_reference()
        {
            // This null function is there to act as a position holder, because you overloaded the original Constructor function, you have to provide this null one if you want this class to be constructed without filling in anything.
        }
    }


    class Program
    {
        static void Main(string[] args)
        {

            int x = 42; // The ultimate answer of life.
            Console.WriteLine("Hello Console." + x);

            Point x1 = new Point(); // without giving parameters. But the memory is allocated for this instance.
            x1.x = 7;
            Point x2 = x1; // This will lead to a copy.
            x1.x = 9;


            Point_reference new_x1 = new Point_reference();
            new_x1.x = 9;
            Point_reference new_x2 = new_x1; // This time it will be a reference. Just a name and be the attorney of new_x1.
            Point_reference diff_x3 = new Point_reference(new_x1);
            new_x2.x = 892;
            diff_x3.x = 129;

            Console.WriteLine(x1.x);
            Console.WriteLine(x2.x);


            Console.WriteLine(new_x1.x); // 892 because the new_x2 changed the value
            Console.WriteLine(diff_x3.x);// independent instance, not to worry
            Console.WriteLine(new_x2.x); // 892 
            Console.ReadLine();
        }
    }
}

多维矩阵

这个之后再说,因为我感觉我不会直接去用它……太懒了还是想用mathNet。

参数的修饰

C#里面有三个参数的修饰方法:

Modifier Passed by Direction
(None) Value Going in
ref Reference Going in
out Reference Going out

下面是几个例子。Python可以直接return好几个不同类型的结果,C#提供了一个out修饰词,用起来感觉差不多。注意传递参数的时候还是要加入相应的修饰词。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloCSharp
{

    class Program
    {
        static void function_to_return_multiple_values(int x, ref int y, out int z, out int w)
        {
            z = x + y;
            y = y + 1;
            w = x - y;
        }

        static void Main(string[] args)
        {
            int x, y, z, w;
            x = 9;
            y = 6;
            function_to_return_multiple_values(x, ref y, out z, out w);
            Console.ReadLine();
        }
    }
}

Written with StackEdit.

Tuesday, May 6, 2014

Cool decorators for python

这里是一些日常看到用到的多快好省decorators,积累起来当做自己的笔记。这些decorators可能已经被广泛流传了很长时间了,所以很难找到第一个出处。所以在此谢谢各位前辈分享。

timer

用来profile一个函数用了多长时间运行:

def timer(func):
    '''
    To time a function.
    ''' 
    def wrapper(*arg):
        t = time.time()
        res = func(*arg)
        print func.func_name, str("%.4f" % (time.time() - t)) + " second"
        return res

    return wrapper

在运行的时候,将输入的参数全部输出出来,方便debug:

def print_arg(function):
    def wrapper(*args, *kwargs):
        print "Argument:", args, kwargs
        return function(*args, *kwargs)
    return wrapper

获取当前运行的函数的名字

sys._getframe().f_code.co_name

这个其实不是decorator,因为事实上没法做decorator。假设我为了方便将这个函数搞成了一lambda表达式:

get_name = lambda : sys._getframe().f_code.co_name

在一个我要debug的函数里面调用了这个表达式:

print get_name()    #<lambda>

但如果正常使用的话:

def my_debug_function(*args):
    print sys._getframe().f_code.co_name

# OUTPUT:
my_debug_function

所以为了偷懒我就写了这个一个snippet for sublimetext:

<snippet>
    <content><![CDATA[
    func_name = sys._getframe().f_code.co_name
        ${1:print func_name}
        ${2:logging.debug(func_name)}
    ]]></content>
    <tabTrigger>get_name</tabTrigger>
    <scope>source.python</scope>
</snippet>

Written with StackEdit.

Tuesday, March 11, 2014

Python 各种常用小功能

print后不换行

就是在命令后面加一个逗号。

print this,

当然这样写出来的代码到了3.3就不太管用了。所以还是老老实实用转义符吧,‘\r’

两列数字点乘

当然直接可以变成numpy.array然后乘起来,但如果不想为了这个小函数就加入一个依赖,那就这样:

from operator import mul

def dot(a_list, b_list):
    return map(mul, a_list, b_list)

将当前的时间输出成seconds from epochtime

import time, datetime
time.mktime(datetime.datetime.now().timetuple())

Written with StackEdit.

PDF merging without tears

I guess nobody needs a cumbersome Acrobat software to merge PDF files. And when things gets a little bit more complex, manually merging hundreds of PDFs can be a PIAS.

Use this:

from PyPDF2 import PdfFileMerger, PdfFileReader
import os


filenames = ["1.pdf", "2.pdf"]
merger = PdfFileMerger()
for filename in filenames:
    merger.append(PdfFileReader(file(os.path.join(os.getcwd(), filename), 'rb')))
merger.write(os.path.join(os.getcwd(), "output.pdf"))

It works like magic. Put this .py file to the folder where you would like to have some PDFs merged, change filenames, and modify this script. Life is instantly easier.

Written with StackEdit.