前五篇露水

計算將港鐵車程拆開以減低車費的車程組合
2016 年 8 月 22 日 (星期一) 13:54

注意:
本人並不確保本文的準確性,對任何損失或傷害概不負責,亦非鼓吹這樣做,只為作出簡單的計算供參考。本文提及的車費於本文刊登日有效。

眾所周知,如果在某些港鐵站前往羅湖或落馬洲,在上水出閘再原站入閘,總車費有可能會減少。我嘗試利用以下的小程式,計算出成人車票,包括八達通及單程車票,在港鐵系統內有可能因中途出閘再入閘而便宜了的組合。

先到政府資料一線通網站下載最新的港鐵車費表 mtr_lines_fares.csv(不包括輕鐵)。

再執行以下程式:
#!/usr/bin/env python

import csv
from math import ceil

octopusFareList = {}
ticketFareList = {}
stationList = {}
"""
	field available
	"SRC_STATION_NAME",
	"SRC_STATION_ID",
	"DEST_STATION_NAME",
	"DEST_STATION_ID",
	"OCT_ADT_FARE",
	"OCT_STD_FARE",
	"SINGLE_ADT_FARE",
	"OCT_CON_CHILD_FARE",
	"OCT_CON_ELDERLY_FARE",
	"OCT_CON_PWD_FARE",
	"SINGLE_CON_CHILD_FARE",
	"SINGLE_CON_ELDERLY_FARE"
"""
with open('mtr_lines_fares.csv', 'rb') as csvfile:
    reader = csv.DictReader(csvfile, delimiter=',')
    for row in reader:
		if (row['SRC_STATION_ID'] == row['DEST_STATION_ID']):
			continue
		srcId = int(row['SRC_STATION_ID'])
		destId = int(row['DEST_STATION_ID'])

		octopusFareList[srcId,destId] = float(row['OCT_ADT_FARE'])
		ticketFareList[srcId,destId] = float(row['SINGLE_ADT_FARE'])
		stationList[srcId] = row["SRC_STATION_NAME"]

# print octopusFareList[100,22]

# 1 = Central, 39 = Hong Kong , 3 = TST ,80 = ETST ,exclude these cases
centralStdId = 1
hongKongStdId = 39
tstStdId = 3
etstStdId = 80

print '"TYPE","START","OUT_AND_IN","END","OLD","NEW","SAVE"'
for i in range(1,121):
	for j in range(1,121):
		if i == j or (i == centralStdId and j == hongKongStdId) or (i == hongKongStdId and j == centralStdId) or (i == etstStdId and j == tstStdId)or (i == tstStdId and j == etstStdId):
			continue
		if (i,j) not in octopusFareList.keys():
			continue
		for x in range(1,121):
			if x == i or x == j or (i == centralStdId and x == hongKongStdId) or (i == hongKongStdId and x == centralStdId) or (i == etstStdId and x == tstStdId)or (i == tstStdId and x == etstStdId) or (j == centralStdId and x == hongKongStdId) or (j == hongKongStdId and x == centralStdId) or (j == etstStdId and x == tstStdId)or (j == tstStdId and x == etstStdId):
				continue
			if (i,x) not in octopusFareList.keys():
				continue
			if (x,j) not in octopusFareList.keys():
				continue
			# normal octopus case
			newOctupusFare = octopusFareList[i,x] + octopusFareList[x,j]
			if newOctupusFare <= octopusFareList[i,j] - 0.01:
				print '"OCTOPUS","' + stationList[i] + '","' + stationList[x] + '","' + stationList[j] + '",' + str(octopusFareList[i,j]) + "," + str(newOctupusFare) + "," + str(octopusFareList[i,j] - newOctupusFare)
			# 2nd trip discount
			newOctupusFare = octopusFareList[i,x] + ceil(octopusFareList[x,j] * 0.9*10.0)/10.0
			if newOctupusFare <= octopusFareList[i,j] - 0.01:
				print '"OCTOPUS(2nd trip)","' + stationList[i] + '","' + stationList[x] + '","' + stationList[j] + '",' + str(octopusFareList[i,j]) + "," + str(newOctupusFare) + "," + str(octopusFareList[i,j] - newOctupusFare)
			# single trip ticket
			newTicketFare = ticketFareList[i,x] + ticketFareList[x,j]
			if newTicketFare <= ticketFareList[i,j] - 0.01:
				print '"TICKET","' + stationList[i] + '","' + stationList[x] + '","' + stationList[j] + '",'+ str(ticketFareList[i,j]) + "," + str(newTicketFare) + ","  + str(ticketFareList[i,j] - newTicketFare)
		# Handle TST and ETST
		if (i != tstStdId) and (j != etstStdId) and (i != etstStdId) and (j != tstStdId):
			# normal octopus case
			newOctupusFare = octopusFareList[i,tstStdId] + octopusFareList[etstStdId,j]
			if newOctupusFare <= octopusFareList[i,j] - 0.01:
				print '"OCTOPUS","' + stationList[i] + '","' + stationList[tstStdId] + "->" + stationList[etstStdId] + '","' + stationList[j] + '",' + str(octopusFareList[i,j]) + "," + str(newOctupusFare) + "," + str(octopusFareList[i,j] - newOctupusFare)
			# 2nd trip discount
			newOctupusFare = octopusFareList[i,tstStdId] + ceil(octopusFareList[etstStdId,j] * 0.9*10.0)/10.0
			if newOctupusFare <= octopusFareList[i,j] - 0.01:
				print '"OCTOPUS(2nd trip)","' + stationList[i] + '","' + stationList[tstStdId] + "->" + stationList[etstStdId] + '","' + stationList[j] + '",' + str(octopusFareList[i,j]) + "," + str(newOctupusFare) + "," + str(octopusFareList[i,j] - newOctupusFare)
			# single trip ticket
			newTicketFare = ticketFareList[i,tstStdId] + ticketFareList[etstStdId,j]
			if newTicketFare <= ticketFareList[i,j] - 0.01:
				print '"TICKET","' + stationList[i] + '","' + stationList[tstStdId] + "->" + stationList[etstStdId] + '","' + stationList[j] + '",'+ str(ticketFareList[i,j]) + "," + str(newTicketFare) + ","  + str(ticketFareList[i,j] - newTicketFare)
		

			# normal octopus case
			newOctupusFare = octopusFareList[i,etstStdId] + octopusFareList[tstStdId,j]
			if newOctupusFare <= octopusFareList[i,j] - 0.01:
				print '"OCTOPUS","' + stationList[i] + '","' + stationList[etstStdId] + "->" + stationList[tstStdId] + '","' + stationList[j] + '",' + str(octopusFareList[i,j]) + "," + str(newOctupusFare) + "," + str(octopusFareList[i,j] - newOctupusFare)
			# 2nd trip discount
			newOctupusFare = octopusFareList[i,etstStdId] + ceil(octopusFareList[tstStdId,j] * 0.9*10.0)/10.0
			if newOctupusFare <= octopusFareList[i,j] - 0.01:
				print '"OCTOPUS(2nd trip)","' + stationList[i] + '","' + stationList[etstStdId] + "->" + stationList[tstStdId] + '","' + stationList[j] + '",' + str(octopusFareList[i,j]) + "," + str(newOctupusFare) + "," + str(octopusFareList[i,j] - newOctupusFare)
			# single trip ticket
			newTicketFare = ticketFareList[i,etstStdId] + ticketFareList[tstStdId,j]
			if newTicketFare <= ticketFareList[i,j] - 0.01:
				print '"TICKET","' + stationList[i] + '","' + stationList[etstStdId] + "->" + stationList[tstStdId] + '","' + stationList[j] + '",'+ str(ticketFareList[i,j]) + "," + str(newTicketFare) + ","  + str(ticketFareList[i,j] - newTicketFare)

執行後,可得出一萬多項結果。我將結果輸出到一個 csv file,可到下載。

以下為部分結果:
mtr-1

第一列為車票種類,有八達通、第二程八達通可享九折的車程(詳情)和單程車票。
第二列為起點車站,本例選取了大埔墟作為起點。
第三列為中途出閘再入閘(單程車票需重新購票)的車站。
第四列為終點車站。
第五及第六列分別為原來車費及新車費。
第七列為可節省的車費。

回應 (0)
RTL-SDR 筆記(16):將環狀天線訊號接入 FUNcube Dongle Pro+
2016 年 8 月 19 日 (星期五) 09:51

好一段日子之前買了這個主動式環狀天線,意圖接收波長比較長的短波和中波(一般數碼電視「手指」的短天線無法接收短波和中波),但因為它的輸出為 3.5mm 耳機頭,一直都未能接入自己的 RTL-SDR 或 FUNcube Dongle Pro+:
IMG_5816
IMG_5817

最近終於買了一系列轉接頭成功將訊號接入 FUNcube Dongle Pro+ 的 SMA 接頭,雖然明知有 impedance mismatch 和訊號損耗等問題,但總算叫做 proof-of-concept(想不到可以將音源線接入 SMA 頭):
IMG_6700

總算檢測到一些短波訊號(例如這個由泰國發射的電台),也聽得出有些人聲,但實在比較微弱,未算非常清晰,也未收到業餘電台:
IMG_6701
IMG_6698

內部連結:
【目錄】RTL-SDR 筆記

回應 (0)
我在用的 ebook 網站
2016 年 8 月 18 日 (星期四) 12:02

Google Play
Safari Books Online
Amazon Kindle Cloud
多看
香港公共圖書館電子書

回應 (0)
暫時去過的日本地方(更新版)
2016 年 5 月 28 日 (星期六) 12:03

Capture-japan2
來源

回應 (0)
暫時去過的日本地方
2016 年 4 月 30 日 (星期六) 12:46

japan-area-cmc
來源

回應 (0)

前五篇露水
© 2002-2016 Harold Chan. 版權及聲明
counter