語言治療(7)

語言治療,這次實際上是第九次,上完還有三次。
這次上課有點匆忙,父親載我跟大公子去慈濟醫院的途中,去市場買了葡萄,耽擱了一點時間。
進慈濟醫院,打算走樓梯上去,可是門卻被鎖了起來,打不開,只好等電梯,一等之下,就等了快十分鐘,真是很讓人挫折。幸好,還是及時掛完號、上完廁所,並且準時上了課。
一上課,我就跟老師說,我要拿東西上去一下再回來。上去是要拿葡萄給嬸婆,這一上去,就又花了十分鐘左右。等到回來,前面都沒有聽到。
這次上課的內容是講小蛇散步的故事,就有一個晴天,小蛇覺得天氣很好就出去散步,散步的途中遇到了一個水坑,突然他聽到一個聲音說,可不可以搭橋讓我過去啊?他回頭一看,原來是螞蟻,於是他很好心的就搭了一座橋,讓螞蟻過去。沒想到,螞蟻過去了,老鼠過去了,獅子也過去了。更令人驚訝的在後頭,大象,他也過去了。小蛇這下可是累到暈倒了,等到它醒過來,它就一口氣把水坑的水給喝光了,繼續上路。
基本上還是跟上次一樣,主要在於矯正發音,並且引導大公子說出故事。我發現大公子在上課到沒興趣的地方時,會開始東摸摸西摸摸,失去專注力,這邊之後要注意。
老師說要去作聽知覺檢查,還沒去做。但有問了常去的診所,醫生表示診所沒有,需要去比較專門的耳鼻喉科做才行。
下次換媽媽帶去,別忘了。

語言治療(6)

語言治療,這次算第7次了。
上次是太座帶大公子去的,是講貓咪的故事,就有一棟大樓,大樓的每一層都有貓咪隱藏在不同的場景裡,這次就是延續上次的故事。
大公子這幾次下來已經可以表達的不錯了,要說有問題,一個就是發音,另一個就是比較沒自信。發音的話,實際上他有記住正確發音的,但就是講的時候常會忘記,然後他又不喜歡被更正的感覺。像是’蛋’念成’幹’、’對’念成’貴’、’花’念成’瓜’…,目前有注意到的是ㄌㄏㄉ這幾個音。沒自信可以從老師問他事情,講話小聲,或是盲從而看出來。
老師在講故事的過程裡,常矯正大公子的發音,此外,也藉由小遊戲來讓他認識正確的發音,老師先念’蛋’跟’幹’,問他說這好不好聽,然後會顛倒’蛋’跟’幹’的順序,讓他來判斷,答對五次就有小饅頭。看的出來,大公子不是很樂意玩這遊戲,因為他分辨不太出來。除了小遊戲,也讓大公子看老師怎麼去發’蛋’的音,並且告訴他舌頭要伸出來。
發音之外,也加強對句子意義的了解,像是”只要x,不要y或是相反”、”先找x再找y”、如果有x就y”等等的。再來就是空間與位置的表達,大公子太常用”這邊”、”那邊”,容易讓人不知道東西在哪裡,加強這部份,對於以後講東西在哪兒會很有用。
老師最後說,他上完這期,也就是再五次,應該就不用再來上課。另外建議我們帶他去檢查聽知覺,看是否有問題。老師相當肯定他仿畫、組織空間的能力,我跟老師說,可能是上學期有上繪畫課,然後有教他看圖去組合積木有關係。
好吧,等上完語言治療的課,接下來就是靠我們自己平常要多注意並且跟學校老師配合了。

速率即斜率

今天早上騎車的時候想到昨天在看的斜率,然後又想到速率,速率=距離/時間,這公式不就跟斜率是一樣的嗎?
斜率 = (y2-y1)/(x2-x1),假定 y 軸是距離,x軸是時間,以幾何圖形來表示,就很清楚。在愈短的時間裡,經過的距離愈長,表示速度愈快,在圖形上的表示,就是斜率愈陡峭,代表速度愈快。
是說自己把觀念連通的時間也太晚了點,現在才發現。

台哥大Catch上網費率試算

就試算一下,然後作圖。

方案 Catch98 Catch198 Catch398
收費 98 198 398
傳輸量 15 50 150
超過以後費率(元/KB) 0.025 0.015 0.0048
費率 6.533333 3.96 2.653333
Cost if over/MB 25.6 15.36 4.9152


從 Catch 98 升到 Catch 198 時,看起來最划算,因為圖形上的斜率較陡峭,很明顯可以感覺到下降很多,從 6.53 下降到 3.96。

currying

前兩天看Wikipedia上的Currying時,突然頓悟了(可見之前都沒認真)。這個不看英文Wikipedia的說明,還真的是不容易看懂。簡單的說,假設有個 function 是 f( x, y, z ),currying 就是令 f1=f(1),當呼叫 f1( 2, 3 ) 時,就等於是呼叫 f( 1, 2, 3 )。

目前想到可以應用在 c/c# 沒辦法帶預設參數的情況上,像:[c]void func( int x, int y, int z ) { }
void new_func1( int y, int z ) { return func( 1, y, z ); }
void new_func2( int y, int z ) { return func( 2, y, z ); }
[/c]
你可以想像到,這是一項複製、貼上的體力活,用 currying 的話,可以很快創造出新函數:[c]/* 以下為虛擬碼 */
void func( int x, int y, int z ) { }
new_func1 = func(1); /* new_func1 仍是函數 */
new_func2 = func(2); /* new_func2 仍是函數 */
[/c]
在 python 裡,透過 *arg、**kwargs 可以很容易實現,文章可以參考 Currying and Python, a practical example,裏面有點複雜,其實只要看 curry 類別的部份,下面就是直接摘錄出來的實例:[python]class curry:
def __init__(self, fun, *args, **kwargs):
self.fun = fun
self.pending = args[:]
self.kwargs = kwargs.copy()
def __call__(self, *args, **kwargs):
if kwargs and self.kwargs:
kw = self.kwargs.copy()
kw.update(kwargs)
else:
kw = kwargs or self.kwargs
return self.fun(*(self.pending + args), **kw)
def func( a, b, c ):
print( a, b, c )
return (a+b+c)
func1 = curry( func, 1, 100 )
func2 = curry( func, 2 )
print( func1( 200 ), func2( 300, 400 ) )
[/python]
原理就是利用類別的特殊方法 __call__ ,呼叫 func2=curry( func, 2 ) 時,實際上是得到 curry 類別的實體。curry 類別的 __init__ 裡去做參數的判斷跟預存,等到把 func2 當函數執行時,就會執行到 __call__,這裡再去呼叫真正的函數。

Python 2 與 3 之字串與檔案

Python 3 裡,很多常用的 package 名稱都變更了,這個倒還好,在 python 2.x 的文件裡,都已經可以看到說 3 的時候,名稱會是什麼,以及要注意什麼,甚至也有 2to3 的工具來輔助轉換。
最近遇到比較麻煩的是字串與檔案的處理,Python 3 裡的字串都是以 unicode 處理,好處當然是不用轉來轉去了,比較麻煩就是讀取檔案跟寫檔案的時候。我的程式有同時用到 subprocess、urllib/urllib2與一般檔案操作,以下是整理:

  1. 進行 subprocess pipe 操作時,讀出時,都是 bytes
  2. 使用 urllib/urllib2 讀取時,都是 bytes
  3. 使用一般檔案操作,沒特別指定的話,檔案編碼會以你當前的環境編碼來讀取,預定是讀取文字檔。

所以在讀取時,為了後續能用一樣的邏輯來讀取,我統一以 binary 來讀取,避掉 encoding 問題(對於 python 3 在 binary mode時,也能正確分行、tokenize這件事上,真的是深感佩服)。是說剛好之後也不需要做精確的內容判斷,所以也不用硬轉成 string(unicode),在 python3 時,都以 bytes 存在。在 python 2,讀出來就都是一般的 string (無 unicode),不是 bytes。
寫入時,也儘量使用 bytes 去寫入,避免encoding轉來轉去的問題。

儲存空間即將不足(續)

  1. 想用 statfs 去看 /data 到底是剩多少可用,結果要自己弄 jni,一整個懶惰,就…
  2. SL4A的python應該可以用吧,查了 python 文件,得知要用 os.statvfs,但是 SL4A 的 os.statvfs 被閹割掉… 囧
  3. 查 threshold,這個應該是可以的,只是要把 Settings.Secure.SYS_STORAGE_THRESHOLD_PERCENTAGE 改成 “sys_storage_threshold_percentage”,這個沒真的下去寫程式驗證。
  4. 用 terminal+busybox df 去查 /data 的,total bytes 是 162529280,心一橫,就拿這數字設到 debug.freemem (sudo setprop debug.freemem 162529280),真的,那個討厭的”儲存空間即將不足”的通知就消失了。

以上。但是要裝比較大的app的時候,還是沒辦法裝,可惡!!

儲存空間即將不足

都上 SD Card,加裝 Link2SD 了,才裝幾個程式,Android 手機就開始唉唉叫,左上角老是出現”儲存空間即將不足”的訊息,真的是太令人生氣。本來不想挖程式出來看的,唉~
Android 程式的文字多半是存在 xml 檔案,也就是 resource 檔,關鍵是在於對應所使用的變數名稱。在 mydroid 目錄下先用 source build/envsetup.sh ,再用 resgrep ‘儲存空間即將不足’ 來找,出現這段文字的檔案有兩個,不過很明顯,變數名稱應該是 low_internal_storage_view_title。
再用 jgrep 去找:jgrep low_internal_storage_view_title ,排除掉 R.java 之後,可以看到一個不一樣的:frameworks/base/services/ajva/com/android/server/DeviceStorageMonitorService.java
看來關鍵就在這檔案裡了。從裏面可以看到在 sendNotification 裡,會把 low_internal_storage_view_title 當作訊息丟出去,於是上方的通知欄就有了’儲存空間即將不足的訊息’。那麼是在那邊去 sendNotification 的呢? 是同個檔案裡的 checkMemory()。
checkMemory() 裡的檢查邏輯很簡單,先 getMemThreshold(),再用 mFreeMem 去做判斷,如果比取到的 threshold 值要小,mLowMemFlag 還沒設為true,就先試著清理 cache,再不行,就 sendNotification。
getMemThreshold() 是怎麼取 threshold 的呢?是從 Content Resolver 裡找 “sys_storage_threshold_percentage” 來的,如果沒取到,則以 10 為預設值,然後乘上 mTotalMemory。
好,上面有幾個關鍵的變數:mTotalMemory、mFreeMem,這兩個變數又是怎麼來的?checkMemory() 裡在檢查 mFreeMem 之前,有先呼叫 restatDataDir(),這個函數會呼叫到底層的 C 函數 – statfs 來取得 /data 的資訊,statfs 回傳一個結構體,主要會使用到裏面的 f_bavail、f_bsize、f_blocks。mFreeMem = f_bavail * f_bsize; mTotalMemory = f_blocks * f_bsize。
從上面的資訊看來,如果要避免不足的問題,要不就是增加 /data 的可用空間,要不就是降低 threshold 的值。但原始碼裡透露了另外一個密技,restatDataDir() 裡,在使用 statfs 取得資訊以後,接著去取 System properties 裡的 debug.freemem,如果有取到,就拿這個當作 mFreeMem 的值來用。看來是可以利用的喔~搭配 setprop 可以設置 debug.freemem ,不過需要 root 嗎? 待驗證。

語言治療(5)

轉眼就第五次上課了,這次上課前發生了請假風波。因為趕著出門,大公子以為是要去學校,所以就情緒激動地叫不要,於是我打電話給醫院老師,跟她請假。結果下了樓,大公子才又說是要去醫院,這下尷尬了,我趕上樓,再打一次電話給老師,說今天還是會去。
今天是爸爸載大公子、媽、二公子跟我一起去的,爸跟媽要去耕莘醫院買醫療用品,二公子就順便一起去,而大公子跟我則到慈濟醫院。到了醫院,大公子喊說餓了,也是該餓的時候了,在家時叫他吃早餐,他死活都不要。就帶他到樓下全家買了蛋酥麵包跟養樂多給他吃,他很快就吃掉半個蛋酥麵包,然後喝完養樂多。
這次上課一開始,老師先問他為什麼心情不好,因為我是以他心情不好的理由跟老師請假的。他沒說,老師就先拿出3個拼圖給他拼,邊拼圖的時候,邊請他講拼圖內的圖案,然後藉機會也問他說,綠色的水果有哪些,橘色的水果有哪些。綠色的水果他只講了芭樂,老師提醒他還有哈密瓜,可惜我們家真的很少吃哈密瓜,西瓜還比較常吃,橘色的水果只講了橘子。
接著拿出三張左右對照的圖片,就左邊是不好的行為,右邊是好的行為,然後教他講跟請他講,有些部份,大公子已經講的不錯了。講到後面時,老師請他跟她講一樣的,大公子總是接著老師的話說,例如:老師說,”好寶寶要”,大公子就直接接話,而不是跟著念”好寶寶要”。老師花了一點時間,才讓他明白要跟著念。等講完這三張圖片,又再拼了3個拼圖。最後老師再請他說為什麼心情不好,大公子才說,”早上不來老師這裡啊”,所以才生氣,老師因此多給了他一張貼紙。
這次講完,老師有跟我說,大公子從評估到現在進步很多,也比一般需要語言治療的孩子要來的好,像是ㄉㄨㄟ,大公子隔週還會記得,一般的孩子則是會忘記。我是說,可能因為從年初到現在,大公子好像正處在爆發期,所以感覺上很快,也跟評估時的情況不一樣。然後有提到回家跟他複習時,他會說”不要說”。老師說,接著會調整課程內容,只是她下週請假一週。
附帶一提,晚上在看綠15路線圖時 (大公子很愛看地圖、路線圖),我發現他已經有在認字了,像”七張”,他就已經可以直接看著念出來,不需要問我。

WIFI優先於3G?

蠻怕浪費錢的,所以還去挖code驗證了一下。NetworkStateTracker 用 NetworkUtils.setDefaultRoute() 設置routing。
在ConnectiveService裡有定義優先權,但這邊的陣列值其實是在 framework/base/core/res/res/values/config.xml 中的 networkAttributes:

Type radio priority
wifi 1 1 1
mobile 0 0 0
mobile_mms 2 0 2
mobile_supl 3 0 2
mobile_hipri 5 0 3

所以再依照程式裡的邏輯,應該是WIFI為優先… (好吧,我承認我沒認真去看懂程式邏輯,所以說”應該”…)