安裝py2exe 問題& 解決

我的環境是 winpython 2.7 spyder

由於安裝pip install py2exe 結果他的版本只能用在python 3.3 以上

google了很久有人提供此方式

pip install http://sourceforge.net/projects/py2exe/files/latest/download?source=files

但只能抓到32位元版本py2exe



最後直接在系統上安裝一個 python

直接安裝py2exe 即可

然後使用c:\python27\python.exe 去編譯我的setup.py 檔案

至於如何使用setup.py 參考這篇blog:

http://koko.ntex.tw/wordpress/build-python-exe-using-py2exe/


meteor 卡在starting app

今天開始裝了meteor ,從官網上下載

安裝1.4 版之後

要重開機,path 才會啟用

但照官網教學

cd simple-todos meteor npm install meteor

輸入完指令後卡住了







經由此網頁

https://forums.meteor.com/t/meteor-stuck-at-starting-your-app/25592/6

得到解決方案

輸入set MONGO_URL=' ' 

就可正常執行


C# 中的訪問權限


修飾關鍵字訪問權限
public可以被任意程式碼存取
private只能在同一個類別中被存取
protected只能在同一個類別中及其繼承的類別中存取
internal只能在同一個namespace 中存取
protected internal只能在同一個namespace 中可存取之外,還可被繼承的類別中存取

public :


沒有存取限制,被public修飾後可被任意存取

internal:


只能在同一個namespace 中存取,也就是就算加了入參考也無法使用

C#中預設為internal 

protected:


只能被目前類別加上繼承的類別存取,在不同namespace 中,只要父類別中有被protected 的,即可被繼承

protected internal:


顧名思義,就是protected + internal。什麼意思呢? 就是保有internal 的特性( 在同一個namespace 中可以存取) 又有procted 的特性(在不同namspace 中,可被繼承的類別存取)

本來internal 是不可以在不同的namespace 中使用的,但是加上protected internal 之後即可在不同的namespace 中被繼承的類別存取。

private :


宣告為private 的只能在自己的類別中存取,此外,private 不可修飾類別類別只能被internal 、public 修飾



考慮到一個問題,如果父類別宣告為internal,而繼承的子類別為public ,這樣發生一個問題

子類別訪問權限> 父類別

父類別限定只能在同一個namspace 中繼承,但子類別卻宣告為public 讓人任意存取

這樣就違反了父類別限定的本意,就像我只能給我班上的人講議,但班上的同學卻在網路上說只要想拿即可來班上任意拿取。

所以這樣是會出現錯誤的,在撰寫時必須注意。





ArrayList 與 List<T>的差別:拆箱與裝箱

先來看ArrayList 與 List<T> 的效率差別

使用ArrayList:
        static void Main(string[] args)
        {
            ArrayList arrList = new ArrayList();
            
            Stopwatch sw = new Stopwatch();
            sw.Start();
            for (int i = 0; i < 100000; i++)
            {
                arrList.Add(i);

            }
            sw.Stop();

            Console.WriteLine(sw.Elapsed);
            Console.ReadKey();
        }


執行時間為:



將以上程式碼替換成List<int>
static void Main(string[] args)
        {
            //ArrayList arrList = new ArrayList();
            List arrList = new List();
            
            Stopwatch sw = new Stopwatch();
            sw.Start();
            for (int i = 0; i < 100000; i++)
            {
                arrList.Add(i);

            }
            sw.Stop();

            Console.WriteLine(sw.Elapsed);
            Console.ReadKey();
        }

執行時間為:


可以看到使用List<T> 的速度以這個case來說快了3倍左右

為什麼呢?

這是因為ArrayList 在add 方法時要傳入的值的型態為object



在此就發生了裝箱

何謂裝箱與拆箱?

Boxing(裝箱) 與 UnBoxing(拆箱) 的意義為


  • 裝箱:將數值型態轉換為參考型態
  • 拆箱:將參考型態轉換為數值型態


而 List<T> 沒有發生裝箱與拆箱,故無必要應避免不必要的裝拆箱 。






C#連接資料庫並回傳

C#程式常需要連接到資料庫,在此記錄了幾種方式的回傳方法。

*前置動作

0.1首先設定App.config

此為winform的設定,若是撰寫Asp.net 則要設定web.config

app.config


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <add name ="mssqlserver" connectionString="Data Source=.\SQLEXPRESS;
         Initial Catalog=test;Integrated Security=True"/>
  </connectionStrings>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
</configuration>

其中 name 可以設定為自己想要的名稱,如果有不同的connectionString 也可以在此新增多種,在撰寫程式碼 的時候再選擇要用哪一種connectionString 即可。Initial Catalog 是指定要存儲的資料庫,在此的資料庫名稱為test。

0.2增加一類別,名為SqlHelper





1. 使用創建連接資料庫字串 ConnectionString




 private static readonly String connStr = ConfigurationManager.ConnectionStrings["mssqlserver"].ConnectionString;
此時需要新增一個System.Configuration的參考才能使用 ConfigurationManager 存取到App.config。
此時因為剛才在App.config 設定的 name="mssqlserver",故可看到此時就調用"mssqlserver" 來存取剛才設定的連線字串。




2. 撰寫幾種sql 查詢後回傳種類




2.1執行insert/update/delete,回傳影響的資料列數


public static int ExecueNonQuery(string sql, CommandType cmdType, params SqlParameter[] pms) 
        {
            using (SqlConnection con = new SqlConnection(connStr))
            {
                using (SqlCommand cmd = new SqlCommand(sql, con)) 
                {
                    //設置目前執行的是「存儲過程? 還是帶參數的sql 語句?」
                    cmd.CommandType = cmdType;
                    if (pms != null) 
                    {
                        cmd.Parameters.AddRange(pms);
                    }
                    con.Open();
                    return cmd.ExecuteNonQuery();                
                }                          
            }        
        }


2.2 回傳單一個值

 public static object ExecuteScalar(string sql, CommandType cmdType, params SqlParameter[] pms) 
        {
            using (SqlConnection con = new SqlConnection(connStr))               
            {
                using (SqlCommand cmd = new SqlCommand(sql, con))
                {
                    cmd.CommandType = cmdType;
                    if (pms != null) 
                    {
                        cmd.Parameters.AddRange(pms);

                    
                    }
                    con.Open();
                    //MessageBox.Show("Login sussess!");
                    return cmd.ExecuteScalar();
                
                }
            
            }
        
        }

2.3 回傳SqlDataReader


 public static SqlDataReader ExecuteReader(string sql, CommandType cmdType, params SqlParameter[] pms)
        {
            SqlConnection con = new SqlConnection(connStr);
            using (SqlCommand cmd = new SqlCommand(sql, con))
            {
                cmd.CommandType = cmdType;
                if(pms!=null)
                {
                    cmd.Parameters.AddRange(pms);
                }
                try
                {
                    con.Open();
                    
                    return cmd.ExecuteReader(CommandBehavior.CloseConnection);

                }
                catch
                {
                    con.Close();
                    con.Dispose();
                    throw;
                }
            }

           
        }

2.4 回傳DataTable

public static DataTable ExecuteDataTable(string sql, CommandType cmdType, params SqlParameter[] pms)
        {
            DataTable dt = new DataTable();
            //use SqlDataAdapter ,it will establish Sql connection.So ,it no need to create Connection by yourself.
            using (SqlDataAdapter adapter = new SqlDataAdapter(sql, connStr)) 
            {
                adapter.SelectCommand.CommandType = cmdType;
                if (pms != null)
                {
                    adapter.SelectCommand.Parameters.AddRange(pms);

                }
                adapter.Fill(dt);
                return dt;
            }


        }

3. 調用Sqlhelper 實現比對

假設帳號及密碼都用明文儲存,則可透過以下方式連接資料庫比對

namespace UsingSqlHelper
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btn_Login_Click(object sender, EventArgs e)
        {   //sql 查詢語句,
            string sql="select count(*) from users where loginId=@uid and loginPwd=@pwd";
            SqlParameter[] pms = new SqlParameter[]
            {               
                 //設定變數,帳號去除空白字元
                new SqlParameter("@uid",txtB_ID.Text.Trim()),
                new SqlParameter("@pwd",txtB_PWD.Text) //pwd allowed to use 'space' char
               
            };  
            //因為有聚合函數,回傳的是數值,故可用int轉換
            int n =(int)SqlHelper.ExecuteScalar(sql, CommandType.Text, pms);
            if(n>0)
            {
                MessageBox.Show("Login sussess!");
            }
            else
            {
                MessageBox.Show("Wrong username or password!");
            }
        }
    }
}