Skip to content

zh

我的手寫出我的心

我寫這篇文章是希望找到內心的平靜和自我反思。寫作是有治療效果的。此刻,它幫助我專注,整理我混亂的思想和想法,並在我心中尋找生活問題的答案。它提供了一種解決困擾我、影響我的睡眠並奪走我內心平靜的問題的方法。

今天,我失去了內心的平靜,因為這是我回到香港的最後一天,這是我近兩年來沒有造訪的地方。由於 COVID-19 的情況和各種政府政策,我無法自由地旅行。我待在新加坡,距離我的家人和女朋友只有四小時的飛行時間,我已經很長時間沒有見到他們了。儘管我應該對返回香港感到興奮,但我卻無法理解地感到失落,難過,和迷茫。

我應該對我的家人仍在這裡,我的女朋友安全並和我保持溝通感到感激。然而,香港已經變了,而且不是變好。我不想深入討論政治,但是這種外在變化部分解釋了我的悲傷。然而,我情緒困擾的根本原因在於我自己。我對自己未能達到一些期望感到失望。如果我只是為自己活著,生活將會很簡單;在酒店隔離一周,遠離工作和其他人,讓我感到平靜。

然而,現實是無法避免的。我不能永遠逃避需要我付出關注的關係。不管是家人,我的女朋友,同事,還是朋友,我一直在用大流行病作為藉口來避免面對這些責任。現在我回到了家,我不能再保持我的情緒距離,這打亂了我的內心平靜。

首先,我的家人很棒,能回家真好。然而,我的父母正老去並且即將退休。我必須找到勇氣面對這些事實。健康和金融挑戰是無可避免的,我必須準備好照顧他們。雖然他們在香港,我在新加坡,距離只有四個小時的飛行時間,這是可以管理的 —— 儘管旅行限制造成了不便。

其次,我的女朋友想結婚,但不願離開香港,因為她年邁的母親在那裡。我們的觀點不同,這對我來說很沮喪。我認為考慮移民是非常重要的,尤其是從政治的角度來看。然而,她仍然不信服,如果她愿不愿改變自己的想法,我無法改變她的想法。

第三,我對我自己的生活不滿意。我對漸老和脫髮,以及未能達到傳統的成功標誌感到不開心。我明白我不應該和別人比較,但社會壓力難以抗拒,尤其是當舊朋友和同學似乎按照亞洲的社會規範做得更好。

總的來說,我覺得我還沒有發揮出我全部的潛力,這深深地困擾著我。我正在努力尋找內心的平静,也許现在是停下來冥想,更好地了解自己的时候。

定位為科技諮詢

定位涉及應用系統性、重複性的過程,以識別我的服務的獨特屬性,將其與競爭對手區別開來,並將此定位表述為一個有效的銷售話語。在這篇文章中,我目標是根據我的服務的獨特功能和能力創建一個差異化的價值主張。

當一些客戶將我視為技術顧問,而其他人將我視為軟體開發人員時,就會出現定位挑戰。在與完全由軟體供應商組成的兩個類別競爭中,我發現自己沒有清晰的定位策略。即使在科技顧問市場飽和的情況下,即使是最好的人也難以獲得項目。客戶經常想知道為什麼他們應該選擇我的諮詢服務而不是其他選擇。有效的產品定位可以幫助我在擁擠的市場中脫穎而出,並捕捉到我的服務的獨特價值。

我的理想客戶是那些已經直觀地理解我的服務價值的人。特別是具有強大技術背景的成長階段金融科技初創公司的CEO和創始人。這些人優先考慮擴張團隊和產品擴展,並尋求解決他們的技術挑戰的解決方案。

從我目標客戶的角度來看,在選擇我的服務之前,他們可能會考慮幾種替代方案:

替代方案1:外包給諮詢公司

  • Accenture
  • Deloitte
  • Capgemini

替代方案2:在線搜索技術答案

  • Stack Overflow
  • Quora
  • Reddit

替代方案3:聘請內部角色

  • 軟體開發人員
  • 業務分析師
  • 架構師

替代方案4:透過影片自學

  • YouTube教學
  • Udemy 課程
  • 在線編碼培訓班

我的服務提供獨特的屬性,使其至少可以與其中一個替代方案區別開來:

  • 部落格內容
  • 技術專長
  • 知識共享
  • 產品管理技能
  • 個人故事
  • 視頻內容
  • 最佳實踐
  • 商業智識

為了識別我的服務最引人注目的方面,我反覆問 "那又怎樣?" 的問題,直到我得到一個明確差異化並直接對客戶有益的價值主張。通過這個練習,我找到了以下差異化的價值:

差異化價值1:CEO 是熱衷的讀者,經常依靠推薦的部落格。我的部落格提供:

  • 1.1 部落格內容:匯總成 Amazon Kindle 書本,方便閱讀。
  • 1.2 產品管理技能:在產品開發中具有豐富經驗。
  • 1.3 技術專長:具有實際的軟體開發能力。
  • 1.4 商業智識:有利害關係人管理、領導和溝通能力。

差異化價值2:我的部落格充當我的顧問業的有效潛在客戶引導工具,特別提供:

  • 2.1 最佳實踐:在銀行業的專業知識。
  • 2.2 知識分享:對在金融市場部署新技術產品的見解。

差異化價值3: 客戶可以在聘請我的服務之前衡量我的商業和技術方法,這是通過以下方式實現的:

  • 3.1 個人故事: 揭示我在銀行業技術顧問的經驗。
  • 3.2 視頻內容:通過幽默講故事。

考慮到這些差異化價值,我的部落格與包括以下內容的框架相符:

  • A. 競爭替代方案:自己動手做。
  • B. 獨特屬性:簡潔、有價值的部落格文章。
  • C. 差異化價值:專門知識和思想領導。
  • D. 最佳適合的客戶:金融科技創業公司的A輪和B輪CEO。
  • E. 市場類別:為金融公司提供技術諮詢。

至於下一步,我計劃:

2022年4月

  • 更新我的網站上的登陸頁面信息。
  • 增加更多的案例研究。
  • 與前五名客戶進行訪談以微調訊息。

2022年5月

  • 創建專注於技術諮詢的銷售話語。
  • 回應提案請求(RFPs)。
  • 在我的部落格上增加更多的科技和商業內容以提高品牌知名度。

總的來說,我正在重新定位為金融公司的專門技術顧問。借助經過驗證的敏捷方法,我目標是幫助這些公司設計和開發提高業務績效的軟體解決方案。我的服務範疇從為初創公司開發軟體,到為較大的科技公司提供咨詢,以及定制產品管理。欲了解更多信息,請訪問 https://victorleungtw.com/

歡迎隨時聯繫,討論我如何在商業和科技方面幫助您的團隊。

將Apache Kafka連接到Azure事件中樞

最近,我在與Azure事件中心的整合中進行了一些工作。我的一位同事在嘗試將消息從現有的Kafka主題中導出並導入到事件中心時遇到了困難。為了提供協助,我在下文中記錄了所謂的步驟,你可能會發現這很有用。

第一步:下載並提取Apache Kafka

Apache Kafka是一個開源的、分佈式的事件流平台。它促進了分佈式系統的構建並確保了高吞吐量。你可以從以下的鏈接下載Apache Kafka:Apache Kafka下載

tar -xzf kafka_2.13-3.1.0.tgz
cd kafka_2.13-3.1.0

第二步:啟動Kafka環境

確保Java 8或更高版本已經安裝在你的本地環境中。如果沒有,請從Oracle的網站下載並安裝。

執行以下命令以開始所有服務:

開始ZooKeeper服務:

bin/zookeeper-server-start.sh config/zookeeper.properties

開始Kafka經紀人:

bin/kafka-server-start.sh config/server.properties

第三步:創建並設置配置文件

創建一個名為connector.properties的新文件,並下列的值:

... (內容主要正確且技術含義實在, 無需改動)

用您的Azure端點的值替換佔位符值。如果您還沒有,請從Azure門戶網站創建一個新的命名空間並部署事件中樞資源。請注意,您可能需要選擇Standard或更高的定價層級,以成功在下一步中創建Kafka主題。

所需的密碼可以在事件中樞命名空間的Shared access policies設置中找到,位於稱為RootManageSharedAccessKey的SAS策略下。

第四步:創建三個Kafka主題

要手動創建主題,請使用kafka-topics命令:

創建configs主題:

... (命令主要正確且技術含義實在, 無需改動)

創建offsets主題:

... (命令主要正確且技術含義實在, 無需改動)

創建status主題:

... (命令主要正確且技術含義實在, 無需改動)

第五步:運行Kafka Connect

Kafka Connect是一種可靠且具有擴展性的数据流工具,用於Apache Kafka和Azure Event Hubs之間。要持續地導入和導出你的數據,請在本地以分佈式模式開始工作人員。

bin/connect-distributed.sh path/to/connect-distributed.properties

設置好所有的內容後,你可以繼續測試導入和導出功能。

第六步:創建輸入和輸出文件

創建一個目錄和兩個文件:一個用於FileStreamSource連接器讀取的種子數據,另一個用於FileStreamSink連接器寫入的文件。

mkdir ~/connect-demo
seq 1000 > ~/connect-demo/input.txt
touch ~/connect-demo/output.txt

第七步:創建FileStreamSource連接器

接下來,讓我引導你啟動FileStreamSource連接器:

... (命令主要正確且技術含義實在, 無需改動)

第八步:創建FileStreamSink連接器

同樣地,讓我們繼續啟動FileStreamSink連接器:

... (命令主要正確且技術含義實在, 無需改動)

最後,確認數據已經在文件之間復制並且是相同的。

cat ~/connect-demo/output.txt

你應該會看到output.txt文件包含從1到1000的數字,就像input.txt文件一樣。就是這樣!如果你更新input.txtoutput.txt將相應地同步。

請注意,Azure事件中樞對Kafka Connect API的支持仍處於公共預覽階段。已部署的FileStreamSource和FileStreamSink連接器不適合生產用途,只應用於演示目的。

Product Engagement Strategy

I recently took a class on the Psychology of Engagement, where I learned the methodologies and vocabulary needed to create highly engaging products. I am applying these concepts to a product of my choosing.

One product that has me "hooked" is an app I use daily to manage my savings and investments. The intended behavior of this product is to encourage users to deposit and save money. I find it rewarding to check my account balance every night and see my progress. The internal trigger driving my engagement with this product is my goal of achieving financial freedom.

I currently work at Thought Machine, a product company that has developed a core banking product aimed at transforming the banking industry. This product empowers banks to offer innovative financial services to their customers. We recently raised $200 million in our Series C funding round, backed by industry-leading venture capitalists and major global banks like Nyca Partners, Molten Ventures, JPMorgan, and Standard Chartered. This has brought our total funding to $350 million, valuing the company at over £1 billion.

According to customer feedback, banks are enamored with our Vault product. It's a ledger system that operates on cloud-native platforms like Amazon Web Services, Google Cloud Platform, and Microsoft Azure, without relying on legacy technology. Vault can be configured through Smart Contracts to run any type of retail banking product, such as checking accounts, savings accounts, loans, credit cards, and mortgages. However, bank customers often find it easy to spend money but difficult to save.

To identify behaviors with strong habit-forming potential, I've utilized "habit zones." Here are three behaviors my company could focus on:

  • Behavior 1: Spending money (e.g., paying monthly rent through a checking account)
  • Behavior 2: Saving money (e.g., accruing daily interest in a savings account)
  • Behavior 3: Borrowing money (e.g., using a credit card that offers reward points or taking out a personal loan)

Based on my personal experience, the behavior with the greatest habit-forming potential is saving money while monitoring daily interest accruals.

To better understand this behavior, I asked myself "why?" five times:

  1. Why? Because I want to check my bank account for daily interest accrual.
  2. Why? To monitor my progress and see how much interest has accumulated.
  3. Why? To gauge whether I am saving enough to meet my financial goals.
  4. Why? Because I fear not having enough money for significant life events like a wedding.
  5. Why? Due to uncertainties about the future, I feel more secure with a financial cushion for emergencies.

I then applied the 5 Panels framework to design an external trigger that cues customers to perform the intended behavior.

Persona:

  • Characteristics: Alex is a 34-year-old working professional in Singapore.
  • Values: Enjoys life, loves coffee, cars, and cooking.
  • Needs: To pay for a wedding, purchase a car, repay loans, buy a coffee machine.
  • Constraints: Faces high inflation, has no savings, and spends his entire monthly salary.

Internal Trigger: Alex wants to start saving money while controlling his expenses. He feels anxious about not being able to afford his upcoming wedding.

Context: Alex is discussing wedding plans and finances with Melanie at a coffee shop. During the conversation, he mentions a car he wishes to purchase.

External Trigger: Alex feels social pressure as his peers are getting married and starting families.

Association: Fear of not saving enough for the wedding = Checking bank account for daily interest accrual.

Action Phase: Steps and hurdles a customer faces:

  1. Receive salary: Financial commitment towards monthly rent and loan repayment.
  2. Allocate 10% for savings: Monetary discipline required, can't spend that money now.
  3. Log into the bank account: Physical effort needed to open the app and click.
  4. Transfer money to the savings account: Another click required.
  5. Wait for the next day: Time needed to see any significant interest accrual.
  6. Verify daily interest accrual: Cognitive load to check if the amount is correct.
  7. Resist temptation: Numerous reasons may tempt the user to withdraw the saved money.

From the customer's perspective, the most challenging hurdle is to allocate 10% of income for savings.

User Story: As a working professional, I find it difficult to save money because of my many expenses and loan repayments. To save, I need to cut back on unnecessary spending and determine a savings target.

Solution Description: Through daily interest accrual, our app can reward users for saving. It can project future savings and interest accruals, enabling customers to set aside money more effectively. The app can also tailor its services based on the user's risk profile and savings goals.

Engagement Strategy:

  • Trigger: Notification reminders to allocate money for savings, along with projections for future account balances.
  • Action: Schedule automatic transfers to a savings account and view daily interest accruals.
  • Variable Rewards: Offer a sense of achievement as users get closer to their financial goals. Provide tips on saving money and reducing daily expenses, along with cash back offers and discount notifications.
  • Investment: Incentivize users to refer friends, which earns them a higher interest rate on their savings account.

Strategic Priorities: The next step for Thought Machine is to enhance user engagement by offering more rewarding incentives for saving money.

KPIs:

  • Number of reminder notifications sent
  • Number of new savings accounts opened through referrals
  • Total amount of interest paid to customer savings accounts

Conclusion: The Hooked Model is a powerful framework that synthesizes decades of research into a simple four-phase process. By understanding and applying these principles, we can encourage more people to save money effectively and ethically through our product design.

尋找充實的工作

上週,我從公司收到了一筆獎金。事情進行得很順利,這筆獎金作為一種良好的經濟獎勵,回報我過去一年的辛勤工作。在新加坡,獲得第13個月的薪資是相當標準的做法,而我收到的變動薪酬也符合行業慣例。我的薪資在外籍人士社區中大約屬於平均水平,讓我能維持單身的生活水平。儘管有這種經濟穩定性,我一直在思考我的職業發展並尋找我真正熱愛的工作。我也專注於產生更大的影響,而不僅僅是工作更努力來證明我的薪資價值。

與此同時,我在目前的角色中面臨一些挑戰。就在昨天,我在一個活動中遇到了一個新的客戶。雖然他友善且愉快,但當我試圖建立強而有力的商業關係時,我卻語無倫次。隨著我的公司成長,對我的軟性技能,包括演講,網絡和溝通能力的需求正在增加。我需要克服與陌生人交往的恐懼,並發展我的領導才能以成功於全球工作市場。

如果我唯一的目標是最大化收入和地位,我可能會成為一名全職銷售人員。他們擁有我崇敬的軟性技能:影響客戶的能力,謀求利潤和產生新的商業機會。傭金中的潛在收入也非常吸引人。然而,我避開了這條職業道路,因為我是個內向的人,面對陌生人並在社交場合保持高能量的想法讓我感到害怕。

在我還是個孩子的時候,我喜歡閱讀歷史書籍。我尤其被普通人通過他們卓越的溝通技能贏得信任,團結民族,打敗共同敵人,從而拯救他們的社區,最終崛起成為國王顧問的故事所吸引。這深深地吸引了我,儘管我的自身經驗僅限於策略性的電腦遊戲和寫作。激發我興趣的是策略元素——使用知識和策略來實現目標的樂趣。

作為一個成年人,我仍然重視策略。我不斷學習,閱讀書籍,並參加在線課程來吸收新資訊。我的願望是成為一個值得信賴的顧問,幫助他人成功並實現比我自己更大的事情。我被同理心和使他人快樂的樂趣所驅動。

我常常羨慕像埃隆·馬斯克,萊昂納多·狄卡皮歐等非常成功的人。然而,我意識到每條這樣的道路都伴隨著自身的挑戰和犧牲。相反,我專注於他們生活中我真正欽佩的方面,例如他們對世界的影響力或他們的財務能力。

我工作中的樂趣來自於賺錢,學習新技術,帶領團隊和幫助人們。我相信,通過協作解決複雜的現實世界問題可能導致私營部門創新和可擴展的解決方案。

如果我知道我不會失敗,我下一步將是創建我自己的企業,並構建一款可擺脫全球市場的可擴展產品。然而,我最大的恐懼是這個新企業可能不會盈利,並且我可以冒著過大的風險,導致財務破產。

我的家庭傾向於尊重傳統的職業角色,如工程,會計,廚藝等方面。他們對數位時代的職位,如 Scrum Master 或 Data Scientist不太熟悉。他們的主要憂慮是我要有一個穩定的,財富回報豐厚的職業。政治角色,特別是那些反對中國共產黨的角色,將是他們的擔憂。

然而,我渴望超越家庭的成就,成為具有國際視野和獨立經濟來源的人。我希望透過旅遊和科技普及幫助他們擴闊視野。

我的社交圈也有自己的挑戰。雖然我的大學同學和前商業合作夥伴支持我的野心,但我的女朋友則有不同的興趣和冒險胃口。這在追求我的熱情和投入關係的時間上造成了緊張。

最後,我需要聆聽的聲音是「內在的愛」。如果有人不喜歡我,重要的是記住我不能取悅所有人。

許多人夢想在像 Google 這樣的公司工作,著迷於他們的文化,前沿技術和高薪資。但同樣的好處也常常可以在科技新創企業,甚至在創業時找到。

儘管我有恐懼--創業,和陌生人說話,或公開演講--我不必成為世界上最富有的人才能感到滿足。創業、新機會和有意義的關係可以提供不只是能忍受的工作,還有充滿目標,友誼和創意的充實職業。

要實現這一點,我們需要集中研究找到真正充實工作的複雜性。如果您有同樣的目標,我很想聽聽您的看法。我們可以一起探索不只是付錢的工作,而是我們深深,非常欣賞的工作。

商業策略建議

我最近上了一門名為「Section4 策略 Sprint」的線上課程。學習了關於定義全球最有價值公司的策略後,我正在應用這個框架來評估真實世界的公司並識別戰略機會。我選擇分析的公司是 Thought Machine,這是我工作的地方,我對它相當瞭解。

Thought Machine 概覽

Thought Machine 是一家產品為本的公司,已開發了核心銀行解決方案,改變了銀行業並賦權銀行向客戶提供創新服務。

Thought Machine 的成長

我們最近在我們的 C 輪資金籌集中籌集了 2 億美元,這涉及到了業界領先的風險投資者和全球主要銀行,如 Nyca Partners、Molten Ventures、摩根大通和渣打銀行。這使我們的總籌資額達到了 3.5 億美元,並使我們的公司估值超過了 10 億英鎊。

Thought Machine 的客戶

我們與各種客戶合作,範圍從第一層次銀行到挑戰者,包括 Atom Bank、Curve、Lloyds Banking Group、Monese、SEB、Standard Chartered、TransferGo、Arvest、ING和摩根大通。

Thought Machine的產品

我們的產品,Vault,運行在像亞馬遜網路服務、Google Cloud Platform 和 Microsoft Azure 這樣的雲原生平台上,消除了對傳統技術的需求。Vault可以通過 Smart Contracts 進行配置,運行任何類型的零售銀行產品,從當前的賬戶到貸款和抵押貸款。

T-Algorithm 策略評估

我在這次分析中使用了 T-Algorithm 框架,該框架識別了像蘋果、Google、Facebook 和 Amazon 這樣的公司取得億萬身價的策略。它能夠實現爆炸性的增長和大量的利潤,並且影響力強大的商業領袖使用它專注於客戶最關心的事情,同時推進關鍵的業務優先事項。

傳統的第一層次銀行必須迅速適應以滿足他們的客戶需求,這使得Thought Machine的客戶從傳統系統過渡到更有效,雲原生技術棧成為了高商業優先級的事項。

1. Rundle

Rundle 指的是能夠產生再生收入的商品和/或服務的捆綁。銀行渴望降低復雜性,並經常受到過時的、整塊的系統的阻礙。Thought Machine 提供了一種解決方案,銀行可以訂閱我們的帳本,根據使用量付費,這創造了一種常態收入模式。

2. 吸引人類本能

成功的企業通常會吸引一種基本的人類本能。在我們的案例中,我們通過提供實用且成本有效的解決方案來鎖定人類大腦的邏輯部分。Thought Machine 通過穩定性、安全性、韌性和成本效益上的產品優勢吸引新的銀行。

3. Benjamin Button Effect

利用網絡效應的產品隨著時間的推移變得更有價值。傳統銀行常常發現很難從他們的傳統系統中提取資料。Thought Machine的產品提供了與其他平台(如Salesforce和Tableau)集成的靈活性,以解決這個問題。

4. Visionary Storytelling

景觀敘事是能夠有效地闡述大膽願景的能力。傳統銀行通常缺乏深層的工程卓越文化,而 Thought Machine 由一位具有這種文化的前 Google 員工創立。這種故事在資金籌集中很有幫助。

5. 縱向整合

通過儘可能地讓一個公司擁有價值鏈,該公司可以控制端到端的客戶體驗。銀行優先考慮成本、方便性和速度,Thought Machine通過合作夥伴提供整合的解決方案來滿足這些需求。

6. Accelerant

一個"助燃劑"公司用作職業的跳板。傳統的第一層次銀行是保守的並且缺乏靈活性。在 Thought Machine,我們的文化鼓勵持續學習,高品質的工作,並有很多的樂趣。

T-Algorithm 策略:景觀敘事

根據我的分析,對 Thought Machine 最有潛力的策略是景觀敘事。我建議我們為改變銀行業的形象擁有一個簡單,吸引人,並有說服力的視野。

銀行業的未來

  1. 增加我們 CEO 的社交媒體存在(低費力,高影響力)

正如 Elon Musk 被描繪為創新者一樣,我們的 CEO,Paul Taylor,可以增加他的網路存在感。我們需要一位有魅力的領導者來挑戰銀行業的現狀。在 Instagram 和 TikTok 等平台上的短片可以提高品牌知名度。

  1. 與科技社群交流(中等費力,高影響力)

我們應該考慮開源一部分我們的技術以吸引更多的開發者。組織附帶免費啤酒和披薩等禮品的聚會可以讓科技社區的人們積極參與。每週的新聞通訊可以讓社區的人們保持更新。

  1. 與 Banks 建立更深的聯繫(高費力,高影響力)

在銀行業建立良好的聲譽可以幫助我們籌集更多的資金。與頂尖的諮詢公司如 Accenture,Deloitte,和 BCG 的合作也可能會有所幫助。

下一步

  1. 從 CEO 的 Twitter 帳號發布更多的推文,強調大膽的願景。
  2. 開源我們的一部分技術並創建一個科技聚會小組。
  3. 鼓勵我們的銀行客戶分享他們使用我們產品的成功經驗。

有任何問題?

我期待收到能夠鞏固我學習並改進這些建議的反饋。歡迎您通過 LinkedIn 與我聯繫:https://linkedin.com/in/victorleungtw

從Google試算表發起API呼叫

想象一下,你是一位商業用戶,你最喜歡的工具是Excel。你可能不足夠技術化來編碼,但你很擅長寫函數、在試算表中計算和繪圖。在這篇文章中,我將向你展示如何在Google試算表中編寫簡單的指令碼,這樣你就可以從中發出一個簡單的API呼叫,並做更多強大的計算。使用起來非常容易,無需安裝。

首先,開啓一個新的空白Google試算表。然後我們會利用兩個單元格作為輸入坐標。我們可以稍後從Google試算表獲取這個單元格的值。在這個例子中,我們將B1和B2作為日期時間和日期的變數。

其次,我們創建一個按鈕。从上方的导航工具中,简单地点击“插入”然后选择“画图”选项。然后我们会画一个带有“获取空气温度”文字的矩形按钮。点击保存并关闭以创建新按钮。

在新创建的按钮上点击右键并选择“分配脚本”。我们现在先输入“getAirTemperature”,稍后我们再来创建这个方法。

第三步,在导航栏中,选择“扩展”然后选择“应用脚本”。我们将编写一些Javascript代码,类似于微软Excel的视觉基本宏脚本,所有的魔力都会在这里发生。

在代码编辑器里,复制并粘贴下面的代码:

function getAirTemperature() {
    // 使用Google試算表獲取輸入值
    let ui = SpreadsheetApp.getUi();
    let sheet = SpreadsheetApp.getActiveSheet();

    // Google試算表單元格 - [行, 列]
    let inputCoordinates = {
        datetime: [1, 2],
        date:
  created: [2, 2],
    }

    let outputCoordinates = {
        stations: [2, 4],
        readings: [2, 6]
    }

    let datetime = sheet.getRange(
        inputCoordinates.datetime[0],
        inputCoordinates.datetime[1]
    ).getValue();

    let date = sheet.getRange(
        inputCoordinates.date[0],
        inputCoordinates.date[1]
    ).getValue();

    let result = ui.alert(
        '請確認以下參數:',
        'datetime' + ":" + datetime + "\n" +
        'date' + ":" + date + "\n",
        ui.ButtonSet.YES_NO);

    if (result == ui.Button.YES) {

        // 對天氣API發送HTTP呼叫
        let apiCaller = ApiCaller()
        let response = apiCaller.getAirTemperature(datetime, date);
        Logger.log(response.getContentText());

        ui.alert('成功獲取氣象數據');

        let data = JSON.parse(response.getContentText());
        let stations = data["metadata"]["stations"];
        let readings = data["items"][0]["readings"];

        for (let i = 0; i < stations.length; i++) {
            // 將輸出值設置到Google試算表
            sheet.getRange(
                outputCoordinates.stations[0] + i,
                outputCoordinates.stations[1]
            ).setValue([stations[i]["name"]]);

            sheet.getRange(
                outputCoordinates.readings[0] + i,
                outputCoordinates.readings[1]
            ).setValue([readings[i]["value"]]);
        }


    } else {
        ui.alert('權限被拒絕。');
    }

}

ApiCaller = function () {

    var weatherApi = {
        "airTemperature": {
            "method": "GET",
            "endpoint": "https://api.data.gov.sg/v1/environment/air-temperature"
        }
    }

    return {

        getAirTemperature: function (datetime, date) {

            datetime = datetime.replace(/"/g, "")
            date = date.replace(/"/g, "")

            var method = weatherApi.airTemperature.method
            var url = weatherApi.airTemperature.endpoint + "?date_time=" + datetime + "&date=" + date

            var options = {
                "method": method,
                "contentType": "application/json",
                "headers": {
                    "Content-Type": "application/json"
                }
            };

            return UrlFetchApp.fetch(url, options)
        }
    }

}

如果你不理解这段代码在做什么,别慌,我来解释:当点击按键时,getAirTemperature方法会被触发。这个方法会从Google试算表中获取输入值,弹出一个等待用户确认的提示框。一旦用户确认,它就会使用UrlFetchApp.fetch发出一个API呼叫,获取新加坡的温度,然后它会遍历所有结果并显示输出。

第一次在按钮上点击,你会看到下面这条消息。

继续进行,登陆并选继续进行不安全的选项进行开发。

然后一個彈出式視窗會詢問是否確認輸入值:

點擊“是”繼續。如果一切順利,你應該可以看到成功確認的信息。

最后,我們從API調用中獲取溫度值,並將結果輸出到Google試算表。

就是这么简单。

如果你是一位开发人员而不是商业用户,你可能希望在你最喜欢的代码编辑器进行脚本更改,如VScode,并获取更好的源版本控制。你可以使用命令行界面clasp在你本地进行开发,而不是在线使用Apps Script编辑器。一旦你已经安装了Node.js,你可以使用以下的npm命令进行安装:

npm install @google/clasp

然后根据这个文档的说明操作:

https://developers.google.com/apps-script/guides/clasp

例如:

clasp login
clasp clone <你的脚本ID>

在你的VS code编辑器里进行更改,然后上传新的应用脚本。

clasp push

注意:你可能需要在访问https://script.google.com/home/usersettings后,再重新启用 Apps Script API。

总的来说,Google试算表是一个强大的用于计算的工具,从中直接发起API调用對於更复杂的使用场景而言更有用。你可以将它用作进行计算的前端,而对于商务用户来说,它比使用定制的UI更加友好。如果你有任何关于從Google試算表發出API調用的問題,請让我知道。编码愉快!

出版自己書籍的過程

幾個月前,我透過亞馬遜的自我出版服務在網上出版了一本書。僅給予澄清,我不是一個專業的作家或藝術家;我在金融科技行業擔任軟件工程經理。寫這本書的動機是為了提高我的溝通技巧——我在去年COVID-19封鎖期間自我反思時確定的目標。

我受到加拿大臨床心理學家和教授喬丹·彼得森(Dr. Jordan Peterson)在YouTube視頻的啟發。他建議:“如果你能思考,說話,和寫作,你就絕對致命。”這句話極大地激勵了我,所以我報名參加了他的自我作者計劃,該計劃提供了自我反思的在線提示。同時,我加入了一個Toastmasters俱樂部以提高我公開演講的技巧,並遇到了一位鼓勵我寫作並出版書籍的導師。

開始並不是困難的部分;挑戰在於維持寫作的習慣,尤其是當我感到沒有動力時。像我手機上的通知和負面的自我對話(“我不是好作家;沒有人會閱讀我寫的”)讓我經常放棄。儘管知道我的書可能不會成為暢銷書,但我繼續寫作,忠於我的目標。

讓我失望的不是收到負面反饋,而是完全沒有收到反饋。在如今的互聯網時代,傳統書籍面臨來自YouTube和播客的激烈競爭。我仍然欣賞印刷文字,並至少每週閱讀一本書以保持思考並避免過度思考和抑鬱。

我寫日記的主要目標是自我提升,而不是公眾認知。但是,即使是我亲密的關係,比如我的女朋友,也沒有花時間閱讀我的作品,這讓我感到沮喪。當我在社交媒體上宣布書籍出版時,確實收到了一些積極的反饋,但實際上只有兩個人購買了它——這是我努力的清醒驗證。

直言不諱的事實是,如果你不是像迪士尼公司的CEO,傑夫·貝佐斯,或伊隆·馬斯克這樣的知名人物,你的貢獻可能會被忽視。這也是我從自我出版中學到的一課。也許,如果我更為知名,我可以賣出一百萬份。一本未被讀到的書感覺像是解鎖了新的孤獨層次。也許我需要學習市場營銷策略或在進行另一個自我出版計劃之前理解觀眾的期望。

如果你對我的旅程感興趣,並正在尋找靈感,我的書現在可以在亞馬遜上找到:

https://www.amazon.com/dp/B09FHXLD4G

失落的訊息

一個晚上,我的手機螢幕亮起了一條WhatsApp訊息,讓我驚醒。以為是緊急事態,我很意外發現只是一個女孩說嗨。"Victor, 你過得如何?"來自香港的前女友Joanne發來的訊息。"你收到我的訊息了嗎?"她問道,"為什麼你沒有回覆?"

"我在從香港搬到新加坡的時候換了手機號碼,"我解釋道。當我說著的時候,我心中湧現出對她的思念,想知道遺失的訊息是什麼。

我們就讀不同的大學,選擇不同的學位。我對科學有興趣,選擇化學作為主修。我的目標是揭開宇宙的神秘面紗。和我不同,Joanne 是實際的。她進入會計領域,希望取得好成績,建立穩固的職業生涯,並獲得豐厚的薪水——同時找到一個合適且富有的丈夫。

在我們的一次午餐約會中,我建議道,"讓我帶你去我最喜歡的小販中心吃5美元的蛋炒飯。"她不滿意,回答說,"不,我想去日本餐廳吃美味的壽司,即使只是幾顆米。"我嘗試改變話題,談論我們的度假計劃。"我們去新加坡的圣淘沙島旅遊如何?"我提議。"不,我想去歐洲,去看瑞士的雪山,"她堅持。

金錢是個絆腳石。"這不僅僅是關於金錢,"Joanne詳述道。"這關乎你的抱負,去努力工作,賺更多錢,提升你的社會地位。這就是一個負責任的成年人該做的。"即使我長時間工作,但量子力學、薛丁格方程式和黑洞理論的專業知識並沒有讓我得到高薪工作。"Victor,你能不能成熟點?"她問。

最終,我換了工作,並得到了加薪。隨著收入的增加,我覺得需要提升自己的生活水平。當我告訴Joanne我正在考慮買車的時候,她立刻驚喜地叫道,"好呀!"我買了一輛藍色的Mini Cooper,她對此比我更興奮。

我開始每天用我的新車接送Joanne。我就像她的私人司機,經常免費接送她的家人和朋友。雖然維護車輛的費用很高,但維護和Joanne的關係更是昂貴。

Joanne非常喜愛名牌手袋。即使我無法正確地說出她最愛的牌子的名字,我也必須送她奢侈的禮物。不管是Gucci還是Chanel,其中任何一個手袋都會花掉我好幾個月的薪水。為了償還我的信用卡欠款,我不得不削減我給父母的零花錢,這讓我感到內疚。

在一頓浪漫的日本餐廳晚餐中,Joanne問,"Victor,你是不是比愛你的車還愛我?"我試圖以幽默來緩解這個緊張的時刻,答道,"當然,我愛我的車,"但她並不覺得好笑。我們繼續為些小事吵架。"Victor,你能不能更成熟一點?"她又問了。

我們是一對性格迥異的情侶。我是一個宅男軟體開發者,我更喜歡與機器交談而不是人。另一方面,Joanne是一家銀行的外向型關係經理,以軟性但堅定的口吻銷售金融產品。那意味著什麼?這意味著她賺的錢比我多。

經過18個月的交往,Joanne決定是時候做一個重要的選擇:繼續與這個"不成熟的傢伙"交往還是尋找替代品。在我們的一次通常的外出中,我感覺到有些不對勁。她變得冷淡,拒絕握住我的手。最後,在一個難熬的沉默之後,她說道,"Victor,我們分手吧。"我的心像是被撕裂般疼痛,我努力地忍住不流淚。"Victor,能你不能更成熟一點?"她再次這麼說。

我們在分手後仍然是朋友。雖然我依然在她生日時送她禮物,但她從未回贈。時間總能愈合一切,有一天,她的一條出乎意料的訊息突然出現。內容是,"嘿 Victor,我要結婚了。你想來參加嗎?"我有些惱怒,開始打"恭喜",但我從未按下送出。反倒是刪除了這則訊息。"我為什麼要去呢?"我對自己這麼想。

我後來在Facebook上看到了她的婚禮照片。她看起來很漂亮,她的丈夫看起來很富有,受過良好的教育。"真是浪費錢,"我這麼想,但很快就把那個念頭拋到腦後。我已經走出來了。人際關係建立在試錯上,大多是錯誤。如果你不想重蹈覆轍,就繼續看下去。我有很多關於如何應對生活挑戰的建議。

財富

當我還是個孩子時,我的媽媽總是告訴我,“要努力讀書!否則,你可能會像那個垃圾工人一樣。”這訊息十分清楚:我並不想靠收集垃圾來謀生。由這種恐懼所驅動,我在學校努力學習,最終進入了大學。

大約十年前,我以化學學士學位畢業。然而,由於香港是國際金融中心,理科畢業生的就業機會非常有限。

我的第一份工作與我所學的專業無關。我在日本的服裝店Uniqlo做了一份初級銷售員的工作,每天工作時間很長。這份工作讓我感覺像是在受罪。就像希臘神話中的西西弗斯,不停地將石頭推上山坡,只是為了讓它滾下來,我會整齊地摺好衣服,然後客人進來就把它們弄亂。這種情況讓我質疑我受的教育的價值。

最終,我辭職去澳洲做了一年的打工度假。我做了各種工作來生活,其中一份工作,諷刺的是,在新年夜晚會做了一名垃圾工人。醉酒和嘔吐的惡臭令人難以忍受。這是一個警醒:如果我聽了我媽媽的話,也許我就不會找到自己在這樣的角色中。

在澳洲呆了一年後,我回到了香港。仍然無法在我專業領域找到工作,我轉變了職業,學習编程並成為一名軟件工程師。然而,在一家有聲譽的顧問公司工作,我卻困擾於冒牌者症候群。我找的解決辦法是繼續學習。我攻讀了一個兼職的計算機科學碩士學位,然後是工商管理碩士學位,希望能有更好的職業生涯,並避免變成我曾經做過的垃圾工人。

在我攻讀MBA期間,我遇到了Jonathan,他在一家軟件公司擔任高級銷售總監。他幫助我轉行,成為一名技術銷售顧問。這份工作需要我娛樂客戶,通常是通过過度飲酒——這是我發誓再也不會做的事情。

一個難以忘懷的夜晚,在與一個大客戶的業務晚宴上,我因為飲酒過度而感到極度不適。我藉口到洗手間去嘔吐,這一刻讓我反思我的選擇。我回憶起我在澳洲當垃圾工人的日子,那正是我努力避免的境地。

我的新工作還涉及到在中國各地出差,並在KTV中娛樂客戶,這經常帶給我道德上的困境。儘管我看似有了好運,但我卻無法不對那裡工作的女性過度同情。她們沒有優先考慮教育的奢侈,在我無法想象的困境中掙扎。

在反思我的經歷時,我體認到我媽媽是對的——教育是無價的。然而,我一方面在如KTV這樣的地方用酒精娛樂客戶,與那些KTV裡工作的女性一樣。我們的掙扎並無太大區別。所以,在對他人妄下評論之前,記得:每一份工作背後都有一個你可能不知道的故事。不論他們的職位如何,把每個人都當作應得的尊重對待。謝謝你。