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.