2014/8/18

【Python】print不換行作法

網路上網路上Google:python print no new line,可以得到很多的討論串,多數會將Case分成python3與先前版本兩種來解決這問題,先看看這兩種作法(最後探討各版本間相容的作法):
  1. python3的作法
    1
    2
    print('Hello World', end='')
    print(', Same Line')
    
  2. 早期版本的作法
    1
    2
    print('Hello World'),
    print(', Same Line')
    
上面二分法的解決方法在能確保選定python版本後就不會作修改的情況下,一切都能運作正常不會發生"意外"。但實際上,在程式開發中很多臭蟲都是在這一念之間埋下惡果的!

在知道有版本相容性問題時,最好方法還是得找個兩全其美的方案會好些,參考下面思緒決定第三種解決方案:
  • 查閱手冊發現2.1版以後增加了Lib/__future__.py模組:在遇到換行的問題上可透過引入此模組的print_function讓2.1到2.X版都能使用python3的解法。
  • 但如上述所說必須2.1以後版本才支援此模組,稍微查了一下python2.1大約是2001年finally release的,掐指一算離現在大概也13年了,再查看手邊系統環境python版本是2.7。
  • 考量上述兩點,遇到2.1以前的版本機率應該遠小於之後更新python版本到3.X甚至更之後版本,因此採用第三種解決方法應該會是比較好的選擇。
1
2
3
4
from __future__ import print_function

print('Hello World', end='')
print(', Same Line')

2014/8/6

巴里島‧人

  前陣子聽了關於旅遊與攝影的演講,體認到旅行中文化體驗很重要的一環就是與當地人有互動,這次到巴里島便試著開口與當地人有些互動,確實讓旅行增添了很多樂趣與回憶!

  下面這張照片是在象洞(Goa Gajah)遇到的小兄妹,他們正一起享用午餐?鼓起勇氣說了Hello,回了我靦腆的笑容,接著用按快門手勢比著手機說Can I?小弟弟點點頭舉起了YA擺了個Pose給我拍。

  把手機的照片拿給他們欣賞,小妹妹接著拿起湯匙放在嘴巴,眼睛變看著鏡頭,顯然很有做Model的天分!

  下面這張照片是在Jatiluwih梯田(Jatiluwih Rice Terrace)拍的,這裡的人滿有趣的,看到你有拿拍照機器只要彼此有Eye Contact後,他們就會擺一個帥氣的姿勢定格,等待你按下快門,彼此Hello打個招呼發現他們也不太能說英文後就用笑容結束了這短暫的交流囉。

跟這YES小女孩互動的過程很有趣。
我:Hello, Can I have a picture for you?
小女孩:Yes!
說完擺了個YA讓我拍完照片。
我:You are so beautiful. What's your name?
小女孩:Yes!
我(揮手狀):Thank you, bye bye!
......好吧,原來我們剛剛成功完成拍照交流,是透過肢體語言成功的,我想因為這梯田已經成為重要觀光景點,大人可能教他們回應外來遊客都說Yes吧!

  在準備離開梯田前,不小心和這位阿伯Eye Contact到了,立馬拿起鐮刀擺起這帥氣姿勢,這下不拍可就尷尬了,所以有了下面這張照片。

  在塔曼阿雲寺(Pura Taman Ayun)裡有個亭子,有兩位畫家正在進行創作,原本看他們很專注不好意思上前打擾,但他們的畫像其實很漂亮,外面繞了又繞決定上前問問能不能拍照,得到的回應是:Of course。這次應該是真的用語言完成交流了吧!

  在水神廟遇到放風箏(很厲害,他們自己做的)的小男生們,一樣用手比著手機作勢拍照樣:Can I?得到了一個鬼臉定格。

友人問Can I?但沒做出拍照手勢,得到了這個No的鬼臉,猜想應該是以為要借風箏玩吧!

  這小鬼很皮,在拍照過程一直用風箏線要把我頭上帽子勾下來。

  這張是在飯店Check in時拍的,問他能不能拍,用滿標準英文回應:Sure。但臉上似乎有一點點的無奈感,當時是晚上八點左右。隔天早上七點多到大廳吃早餐發現他已經在那邊咚咚咚,終於明白他那臉上的疲累感是怎麼來的......

  在巴里島還能看到很多東南亞國家人民必備技能:頭頂工夫。這技能實在是一絕,而且不論男女老少都具備,連我們司機都很得意的說我也會喔!


  最後我決定把這兩隻猴子也歸為人,看看這猴子在懸崖邊惆悵的望著印度洋,眼神深的像是裝進了全世界的憂愁般,都想把張老師熱線抄給牠了。
  地點:烏魯瓦圖懸崖廟(Pura Luhur Uluwatu)。

  這隻坐在垃圾桶旁的也是,像是吞進多少的委屈悶在心頭似的。

【C#】設定/查詢螢幕背光

  為了要能用C#控制螢幕背光,跟CreateFile與DeviceIoControl函數奮戰大半天,一直搞不定DeviceIoControl函數使用,後來幸運的在網路上找到有人寫好class可以直接調用,之後有需要用到DeviceIoControl函數功能也能參考這class的做法。

調用方法很簡單:
1
2
3
LCDBrightness lcd = new LCDBrightness();
lcd.SetBrightness(100);                                 // Set backlight full on
LCDBrightness.Brightness value = lcd.GetBrightness();   // Query backlight value

原始class內容為:
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
/// <summary>
/// Permet de contrA’ler la luminositAc de l'Accran LCD (sous Windows XP SP2 et ultAcrieur)
/// </summary>
/// <remarks>Sous rAcserve que le driver de la carte graphique et/ou de l'Accran supporte cette interface</remarks>
namespace LCDBrightness
{
  public class LCDBrightness
  {
    //Ouvre un fichier ou un pAcriphAcrique
    [DllImport("kernel32")]
    private static extern IntPtr CreateFile (
        string lpFileName,
        uint dwDesiredAccess,
        int dwShareMode,
        IntPtr lpSecurityAttributes,
        int dwCreationDisposition,
        int dwFlagsAndAttributes,
        IntPtr hTemplateFile);

    //accA‥s en lecture, partagAc et ouverture uniquement d'un pAcriphAcrique existant
    private const uint GENERIC_READ = 0x80000000U;
    private const int SHARE_ALL = 0x7;
    private const int OPEN_EXISTING = 0x3;

    //indique l'Acclairage en mode d'alimentation AC ou DC ou les deux
    private const int DISPLAYPOLICY_AC = 1;
    private const int DISPLAYPOLICY_DC = 2;
    private const int DISPLAYPOLICY_BOTH = DISPLAYPOLICY_AC | DISPLAYPOLICY_DC;

    /// <summary>
    /// Indique les niveaux d'Acclairage en fonction du mode d'alimentation
    /// </summary>
    /// <remarks></remarks>
    public class Brightness
    {
      /// <summary>
      /// Eclairage en mode Alimentation
      /// </summary>
      /// <remarks></remarks>
      public byte AC;
      /// <summary>
      /// Eclairage en mode Batterie
      /// </summary>
      /// <remarks></remarks>
      public byte DC;
    }

    /// <summary>
    /// Contient les donnAces brutes des niveaux d'Acclairage
    /// </summary>
    /// <remarks></remarks>
    private struct DISPLAY_BRIGHTNESS
    {
      public byte ucDisplayPolicy;
      public byte ucACBrightness;
      public byte ucDCBrightness;
    }

    //envoie une requAate A  un pAcriphAcrique
    [DllImport("kernel32")]
    private static extern bool DeviceIoControl (
        IntPtr hDevice,
        int dwIoControlCode,
        ref DISPLAY_BRIGHTNESS lpInBuffer,
        int nInBufferSize,
        IntPtr lpOutBuffer,
        int nOutBufferSize,
        ref int lpBytesReturned,
        IntPtr lpOverlapped);
    [DllImport("kernel32")]
    private static extern bool DeviceIoControl (
        IntPtr hDevice,
        int dwIoControlCode,
        IntPtr lpInBuffer,
        int nInBufferSize,
        ref DISPLAY_BRIGHTNESS lpOutBuffer,
        int nOutBufferSize,
        ref int lpBytesReturned,
        IntPtr lpOverlapped);
    [DllImport("kernel32")]
    private static extern bool DeviceIoControl (
        IntPtr hDevice,
        int dwIoControlCode,
        IntPtr lpInBuffer,
        int nInBufferSize,
        [MarshalAs(UnmanagedType.LPArray)] byte[] lpOutBuffer,
        int nOutBufferSize,
        ref int lpBytesReturned,
        IntPtr lpOverlapped);

    //ferme un fichier ou un pAcriphAcrique
    [DllImport("kernel32")]
    private static extern int CloseHandle(IntPtr hObject);

#region IOCTL
    private const int FILE_DEVICE_VIDEO = 0x23;

    private const int FILE_ANY_ACCESS = 0;
    private const int FILE_SPECIAL_ACCESS = FILE_ANY_ACCESS;

    private const int METHOD_BUFFERED = 0;
    private const int METHOD_NEITHER = 3;

    private const int ERROR_INSUFFICIENT_BUFFER = 122;

    /// <summary>
    /// GA‥re la dAcfinition d'un code de requAate d'un pAcriphAcrique en fonction de ses catAcgories
    /// </summary>
    /// <param name="dwDeviceType">Type de pAcriphAcrique</param>
    /// <param name="dwFunction">RequAate</param>
    /// <param name="dwMethod">MActhode de la requAate</param>
    /// <param name="dwAccess">Mode d'accA‥s</param>
    /// <returns></returns>
    /// <remarks></remarks>
    private static int CTL_CODE(int dwDeviceType, int dwFunction, int dwMethod, int dwAccess)
    {
      return ((dwDeviceType) << 16) | ((dwAccess) << 14) | ((dwFunction) << 2) | (dwMethod);
    }

    //requAate de lecture des niveaux d'Aclcairage supportAcs
    private static int IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS = CTL_CODE(FILE_DEVICE_VIDEO, 293, METHOD_BUFFERED, FILE_ANY_ACCESS);
    //requAate de lecture des niveaux d'Acclairage en cours
    private static int IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS = CTL_CODE(FILE_DEVICE_VIDEO, 294, METHOD_BUFFERED, FILE_ANY_ACCESS);
    //requAate de dAcfinition des niveaux d'Acclairage en cours
    private static int IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS = CTL_CODE(FILE_DEVICE_VIDEO, 295, METHOD_BUFFERED, FILE_ANY_ACCESS);
#endregion

    /// <summary>
    /// Ouvre un handle vers le pAcriphAcrique LCD
    /// </summary>
    /// <returns></returns>
    /// <remarks></remarks>
    private IntPtr OpenLCD()
    {
      //ouverture en lecture partagAce
      return CreateFile("\\\\.\\LCD", GENERIC_READ, SHARE_ALL, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
    }

    private byte[] mBrightness = null;
    /// <summary>
    /// Renvoie la liste des niveaux d'Acclairage supportAcs
    /// </summary>
    /// <value></value>
    /// <returns></returns>
    /// <remarks></remarks>
    public byte[] SupportedBrightness {
      get {
        if (mBrightness == null) {
          int lpRet=0;
          byte[] ret;
          //essaie d'ouvrir le LCD
          IntPtr pDisplay = OpenLCD();
          //si erreur, probablement pas un portable
          if (pDisplay != new IntPtr(-1)) {
              ret = new byte[256];

            //envoie la requAate des niveaux supportAcs
            if (DeviceIoControl(pDisplay, IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS, IntPtr.Zero, 0, ret, 256, ref lpRet, IntPtr.Zero)) {
              //rAccupA‥re un tableau d'octet contenant les niveaux
                mBrightness = new byte[lpRet];

              for (int i = 0; i < lpRet; i++) {
                mBrightness[i] = ret[i];
              }
            }

            CloseHandle(pDisplay);
          }
        }
        return mBrightness;
      }
    }

    /// <summary>
    /// Renvoie l'Acclairage en cours
    /// </summary>
    /// <returns>Eclairage en cours par modes d'alimentation</returns>
    /// <remarks></remarks>
    public Brightness GetBrightness()
    {
      int lpRet=0;
      Brightness ret = null;
      //essaie d'ouvrir le LCD
      IntPtr pDisplay = OpenLCD();
      //si erreur, probablement pas un portable
      if (pDisplay == new IntPtr(-1))
        return null;

      //envoie la requAate de lecture de l'Acclairage en cours
      DISPLAY_BRIGHTNESS pBrightness = new DISPLAY_BRIGHTNESS();
      if (DeviceIoControl(pDisplay, IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS, IntPtr.Zero, 0, ref pBrightness, Marshal.SizeOf(typeof(DISPLAY_BRIGHTNESS)), ref lpRet, IntPtr.Zero)) {
        //si OK, rAccupA‥re la valeur pour AC/Alimentation et DC/Batterie
        ret = new Brightness();
        ret.AC = pBrightness.ucACBrightness;
        ret.DC = pBrightness.ucDCBrightness;
      }

      CloseHandle(pDisplay);

      return ret;
    }

    /// <summary>
    /// DAcfinit l'Acclairage A  la mAame valeur pour les deux modes d'alimentation
    /// </summary>
    /// <param name="brightness">Niveau d'Acclairage</param>
    /// <returns>true si rAcussi, false sinon</returns>
    /// <remarks></remarks>
    public bool SetBrightness(int brightness)
    {
      return SetBrightness(brightness, brightness);
    }

    /// <summary>
    /// DAcfinit l'Acclairage par mode d'alimentation
    /// </summary>
    /// <param name="acBrightness">Niveau AC/Alimentation</param>
    /// <param name="dcBrightness">Niveau DC/Batterie</param>
    /// <returns>true si rAcussi, false sinon</returns>
    /// <remarks></remarks>
    public bool SetBrightness(int acBrightness, int dcBrightness)
    {
      bool ret;
      int lpRet=0;
      //essaie d'ouvrir le LCD
      IntPtr pDisplay = OpenLCD();
      //si erreur, probablement pas un portable
      if (pDisplay == new IntPtr(-1))
        return false;

      //remplit la structure et informe que l'on dAcfinit les deux valeurs
      DISPLAY_BRIGHTNESS pBrightness = new DISPLAY_BRIGHTNESS();
      pBrightness.ucACBrightness = (byte)(acBrightness & 0xFF);
      pBrightness.ucDCBrightness = (byte)(dcBrightness & 0xFF);
      pBrightness.ucDisplayPolicy = DISPLAYPOLICY_BOTH;

      //envoie la requAate de dAcfinition de l'Acclairage au pAcriphAcrique LCD
      ret = DeviceIoControl(pDisplay, IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS, ref pBrightness, Marshal.SizeOf(pBrightness), IntPtr.Zero, 0, ref lpRet, IntPtr.Zero);

      CloseHandle(pDisplay);

      return ret;
    }
  }
}

參考原始出處:http://codes-sources.commentcamarche.net/source/view/53617/1259513#browser

Keyword:C#, Windows, Backlight

2014/7/12

【Ubuntu】讓VLC可以播放中文字幕

要讓VLC可以正確顯示中文字幕需要確保兩件事:
  1. 系統有安裝中文字體
  2. VLC選擇正確的字幕編碼格式
  關於第一點,中文字體多數人推薦使用文泉驛正黑體,在Ubuntu系統可以使用以下指令完成安裝:

1
sudo apt-get install ttf-wqy-zenhei

  第二點設定,開啟VLC後點選功能表單的工具→編號設定,接著選擇字幕/OSD頁面,將預設編碼設定為正體中文(Big5)並在偏好的字幕語言欄位填入字體路徑:


1
/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc

  做完上述設定重新開啟VLC後應該就可以正確顯示繁體中文字幕了!

2014/7/8

【Ubuntu】設定開機背光值

  在Linux上背光值每次重開機都會被設成最亮,這個問題一直很困擾人,查了一下可以透過修改/sys/class/backlight/acpi_video*/brightness內容來調整背光設定。
底下寫了一個簡單的Script來修改這設定值:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#!/bin/sh

if [ $# -ne 1 ]; then
 echo "Usage: $0 <back light percent>"
 echo "Example: $0 100: Set back light to maximum"
 exit 1
fi

percent=$1

for acpi in /sys/class/backlight/acpi_video*
do
 max=`cat ${acpi}/max_brightness`
 val=$((max*percent/100))
 sudo sed -i "/exit 0$/i echo $val > ${acpi}/brightness" /etc/rc.local
done

使用方式如下:

  • ./set_backlight.sh 100:背光調成最亮
  • ./set_backlight.sh 0:關掉背光

  根據觀察在Notebook上會有兩組設定值,分別是acpi_video0與acpi_video1,acpi_video0是插上電源線會參考的數值,而acpi_video1是沒接電源線參考的數值,不過沒找到相關說明文件不是很確認這兩者的區別。

【Ubuntu】開關筆電的觸控板功能

  用Notebook打字最討厭被鍵盤下方的觸控面板干擾,如果筆電觸控板的快捷鍵開關是用Driver控制,這在Linux下就沒法直接用Fn+FunctionKey來作開關了,這時得用到xinput這隻工具來進行控制。
  後來在AskUbuntu討論區有看到別人用script來完成開關切換:執行一次功能就會由關閉變成開啟或是開啟變成關閉,直接看內容:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/bin/bash

declare -i ID
ID=`xinput list | grep -iEo 'TouchPad\s*id\=[0-9]{1,2}' | grep -Eo '[0-9]{1,2}'`
declare -i STATE
STATE=`xinput list-props $ID|grep 'Device Enabled'|awk '{print $4}'`
if [ $STATE -eq 1 ]
then
    xinput disable $ID
    echo "Touchpad disabled."
else
    xinput enable $ID
    echo "Touchpad enabled."
fi

關鍵字:Touchpad、Toggle、Enable、Disable
參考:How to disable the touchpad?

2014/6/11

【樹莓派】(Hidden SSID)無線網路連線

若無線網路環境並沒有取消SSID廣播功能(隱藏SSID),可以參考先前文章設定→http://inpega.blogspot.tw/2013/09/blog-post_15.html

無線網路的SSID是隱藏沒有廣播的話,則可以參考下面設定流程完成連線:
  1. 在命令視窗輸入:wpa_passphrase "SSID" "PASSWORD"

    SSID與PASSWORD需換成實際連線資訊,接著把psk後面推算出來的加密密碼(上圖紅色框起來的資料)記起來。
  2. 接著修改設定文件,sudo nano /etc/network/interfaces
    iface wlan0 inet dhcp
      wpa-scan-ssid 1
      wpa-ap-scan 1
      wpa-key-mgmt WPA-PSK
      wpa-proto RSN WPA
      wpa-pairwise CCMP TKIP
      wpa-group CCMP TKIP
      wpa-ssid
    "SSID"
      wpa-psk d67cff074e68196339ea79313451616edfa4d8c3a3bfd0a64a5ebc06c02fd51d

  3. 紅色框框記得更換成步驟一產生的加密密碼
  4. 接著先關閉wlan功能:sudo ifdown wlan0
  5. 再重新開啟wlan功能:sudo ifup wlan0
  6. 這時可以用指令確認連線狀況:ifconfig wlan0