2018年6月30日 星期六

iOS 在 screens 之間傳資料


所謂 screens  之間就是 ViewControllers 之間,這裡討論的是 A screen 叫出了 B screen,但 B screen 想要送資料回 A screen 時該怎麼做。

通常如果是 A controller contains B controller (A screen 叫出了 B screen),那麼不應該讓 B screen 知道關於 A controller 的細節,否則就是 circular dependency,意思就是不該這樣做:


```swift
class BViewController: UITableViewController, . . . {

  // This variable refers to the other view controller
  var aController: AViewController

  @IBAction func done() {
    // Create the new checklist item object
    let item = ChecklistItem()
    item.text = textField.text!

    // Directly call a method from AViewController
    aController.add(item)
  }
}
```

有時候有些 screen 是要被很多 ViewController 呼叫的,所以如果這樣做也同時失去了可以被很多 controller 呼叫的彈性

比較好的作法應該是用 delegate



如此一來 B 就不知道 A 是誰,B 只知道有哪些 delegate 可以用。
那怎麼 delegate 呢?在 Swift 裡面就是寫一個 protocol,Protocol 的功用就是給有 implement 這個 protocol 的 class 一些規範,說白了就是定義有哪些 functions, 哪些是 required 哪些是 optional

example:

```swift
protocol AddItemViewControllerDelegate: class {
  func addItemViewControllerDidCancel(
                          _ controller: AddItemViewController)
  func addItemViewController(
                 _ controller: AddItemViewController,
         didFinishAdding item: ChecklistItem)
}
```

從此之後 B controller 只需要

```swift
weak var delegate: AddItemViewControllerDelegate?
```

就可以操作 delegate 的 controller 了

通常 delegate 會是 weak variable 以及 optional


optional 的原因是 delegate 本來就 optional,要不要 implement 都沒關係。另外一個主要原因是當 StoryBoard load 這個 controller 時,並不知道 delegate 是誰,所以應該要是 optional。


通常會在 prepare 的 function 指派 delegate,此例就是在 A segue 到 B 時指派 A 成為 B 的 AddItemViewControllerDelegate 的 delegate,在 A controller 裡面加上:

```swift
override func prepare(for segue: UIStoryboardSegue,
                         sender: Any?) {
  // 1
  if segue.identifier == "B" {
    // 2
    let controller = segue.destination
                     as! BController
    // 3
    controller.delegate = self
  }
}
```


Delegates in five easy steps:


These are the steps for setting up the delegate pattern between two objects, where object A is the delegate for object B, and object B will send messages back to A. The steps are:
1 - Define a delegate protocol for object B.
2 - Give object B a delegate optional variable. This variable should be weak.
3 - Update object B to send messages to its delegate when something interesting happens, such as the user pressing the Cancel or Done buttons, or when it needs a piece of information. You write delegate?.methodName(self, . . .)
4 - Make object A conform to the delegate protocol. It should put the name of the protocol in its class line and implement the methods from the protocol.
5 - Tell object B that object A is now its delegate.

NSRange vs. Range and NSString vs. String



NSRange 是 Objective-C 的 Range, Range 則是 Swift 的 Range,是不同的結構。

但是 iOS API 內因為歷史因素都是給 NSRange ,所以通常要 cast 一下,例如:

```swift
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    let oldText = textField.text!
    let stringRange = Range(range, in: oldText)!
    let newText = oldText.replacingCharacters(in: stringRange, with: string)

    if newText.isEmpty {
      doneBarButton.isEnabled = false
    } else {
      doneBarButton.isEnabled = true
    }
   
    return true
  }
```

至於String 則是會 bridge 到 NSString,所以都有一樣的 API


Swift 回收 memory 的機制 - ARC

Automatic Reference Counting

字面意思就是看 object 被 reference 多少次,沒被 reference 就回收

https://tommy60703.gitbooks.io/swift-language-traditional-chinese/content/chapter2/16_Automatic_Reference_Counting.html#how_arc_works

2018年6月29日 星期五

可以傳 AR object 的自制 form object


```ruby
class BaseForm
  include ActiveModel::Model

  attr_reader :record
  def initialize(record)
    @record = record
    record.attributes.each do |key, value|
      class_eval do
        delegate "#{key}=", to: :record
        delegate "#{key}", to: :record
      end
    end
  end

  def save
    valid? && record.save
  end

  def save!
    valid? && record.save!
  end
end

```


讀書筆記 - 鉤癮效應 Hooked - Nir Eyal


習慣指的是想都不用想就能進行的行為,且習慣是可以刻意製造的,方式是
習慣不是創造出來的,而是累積出來的

觸發(內在與外在)-> 行動 -> 變動獎賞 -> 投入


## 觸發

一開始都是外在觸發,例如文章、廣告、通知等等
然後藉由刻意製造的習慣讓使用者開始有內在觸發,例如開啟臉書與社交需求結合,就變成了內在觸發

### 外在觸發:告訴使用者下一步該怎麼做,有幾種類型:
1. 付費買來的
2. 贏得的(例如其他媒體報導)
3. 透過關係的(口耳相傳)
4. 公司自有的(APP 通知、電子郵件訂閱等)

前三者是帶來新客源的好方法,第四種是促進使用者養成習慣

### 內在觸發

負面情緒是強大的內在觸發,例如無聊、寂寞、挫折、猶豫、疑惑等

這些觸發最後幾乎都跟社會認同有關



## 行動

預期會有獎賞的行為,例如點擊一個連結就看到有趣的照片

任何行為的開始都需要三大要素:
1. 必須有充分動機  (Motivation)
2. 必須有完成目標的能力 (Ability)
3. 必須有觸發 (Trigger) 來啟動

所以 行動 = MAT

若說內在觸發是使用者一天之中時常感到的心癢難耐,那行動就是搔癢

很重要的一點是要盡量讓所有人都有能力,這樣他們才會行動,就是要降低產品使用的難度,所謂難度有幾個面向:

1. 時間:完成需要多久
2. 金錢
3. 勞力付出
4. 腦力運轉:需要的心思與專注力
5. 社會偏差(social deviance):其他人對這個行為的接受度
6. 不符慣例:行動配合或是打亂目前例行活動的程度


所以提高動機或是能力呢?先從哪一個下手?

答案是絕對要先從提高能力



除了理性的原因外,人還有很多非理性的行為,例如

1. 認為物以稀為貴
2. 框架效應:根據周遭環境作出判斷(ex: 厲害的小提琴家在地鐵站拉小提琴沒人聽)
3. 定錨效應:在看到某個資訊時就會拿來做為參考標準。(打折跟沒打折一樣價,還是想買打折的)
4. 人為推進:人們在相信自己接近目標時動機就會加強,例如集點卡跟進度條


## 變動獎賞

使用者作出行動後得到的獎賞,若能增添獎賞的變化會更有效果

例如 App 無限下滑加載,因為期待之後無法預期的新 content,所以就會一直滑

這是由於受大腦中的伏隔核區域影響,且有趣的是期待獎賞時伏隔核區域的活躍程度比真正拿到獎賞時還高,代表期待拿到獎賞比真的拿到獎賞更令人興奮

三大變動獎賞:

1. 部落型獎賞:想被認同
2. 狩獵型獎賞:想持續追尋一個東西(人類狩獵就是在追尋),而現在就是追尋更多的資訊
3. 自我型獎賞:渴求勝利感、成就感


設計獎賞系統時的重點:
1. 獎賞必須與使用者使用的動機以及內在觸發一致
2. 讓使用者保持自主感,提醒他們有選擇的自由他們越容易被說服(開啟通知吧,之後隨時可以關唷)
3. 讓使用者覺得有主控權,讓他們自己想要使用而不是覺得自己必須使用



## 投入

讓使用者增進下一次循環的行動,例如追蹤人、分享好友、加到最愛選單等

如果說頻率是習慣的第一要素,那第二要素就是「使用者對行為的態度有所改變」,人們會隨著付出越多而越喜愛某件事物

1. 我們在評價自己的付出時是不理性的
2. 且我們希望自己的前後行為是一致的(所以可以漸進式的"引導"使用者,這樣就會想要行為一致而接受)
3. 我們都不想認知失調,所以別人說好的東西我就會慢慢也覺得好


確切來說,價值儲存是最好的投入方式之一,所謂價值儲存包含:
1. 內容(ex: 歌單)
2. 數據(ex: 輸入資訊)
3. 粉絲關注
4. 聲譽




要做到:

* 當用戶將產品融入例行公事,就會產生依賴,且會對價格更不敏感
* 新進入市場者若想要成功,不能只是比別人好,要比現有產品好好上 9 倍


知覺效用就是相對於其他方案的有用程度,要讓使用者養成習慣,要嘛就是發生頻率要高、不然就是要很有用





rails model conditional validation 的神奇用法 extend

lol, 沒想過可以這樣

```ruby
user = User.find(id)
user.extend(User::RegistrationContext)
```

```ruby
# app/models/user/registration_context.rb
module User::RegistrationContext
  def self.extended(model)
    class << model
      validates :terms_of_service_accepted, acceptance: true
    end
  end

  attr_accessor :terms_of_service_accepted
end
```

```ruby
user = User.new
user.extend(User::RegistrationContext)
user.terms_of_service_accepted = "0"
user.valid?
=> false
user.errors.messages[:terms_of_service_accepted]
=> ["must be accepted"]
```

哈,雖然應該不會去用這種做法,但還是學習了XD

https://karolgalanciak.com/blog/2018/06/24/rails-and-conditional-validations-in-models/

2018年6月28日 星期四

iOS learning

Table View 兩種:
* plain - 一般的
* grouped - 灰底,像設定檔

TableView 有 cell 和 row 的概念

可以想像 cell 就是顯示出來的 row,是會被 reuse 的 object
而 row 就是 table view 有的全部資料

所以 cell 要有 identifier,這樣才可以被 reuse,代表是哪一種 cell

TableView 要有 data 就要 implement data source protocol, 所謂 protocol 就是規定好的 functions 要你 implement

此時 ViewController 就是 table view data source 的 delegate,因為 data 是什麼都跑來問 view controller 了




story board 為元件加上 tag,就可以用 cell.viewWithTag(tag) 來拿到

cell 裡的 label 要用這樣的拿法因為如果用 @IBOutlet 就只能 reference 一個,是不合理的


UITableViewDataSource => 顯示的資料
UITableViewDelegate => 處理行為

```swift
if let cell = tableView.cellForRow(at: indexPath) {
    if cell.accessoryType == .none {
      cell.accessoryType = .checkmark
    } else {
      cell.accessoryType = .none
    }
  }
```

用 if let 的方法可以處理 let 後面的 expression 是 nil 的情況,是常用的技巧


```swift
override func tableView(_ tableView: UITableView,
      numberOfRowsInSection section: Int) -> Int {}
```

這裡的 numberOfRowsInSection 是外部參數,section 是區域參數,function 裡面用 section,外面的 function 是看到 numberOfRowsInSection,至於 _ 底線就是不想要有外部名稱時用的


```swift
// This declares that items will hold an array of ChecklistItem
// objects but it does not actually create that array.
// At this point, items does not have a value yet.
var items: [ChecklistItem]

required init?(coder aDecoder: NSCoder) {
// This instantiates the array. Now items contains a valid array
// object, but the array has no objects inside it yet.
items = [ChecklistItem]()
}
```


2018年6月26日 星期二

Sam Altman co-found 的公司 Open AI 在強化學習 (Reinforcement Learning)上有了進展

http://blog.samaltman.com/reinforcement-learning-progress

Sam Altman co-found 的公司 Open AI 在強化學習上有了進展,證明專精於特定領域的強化學習演算法可以有效的解決問題,在這篇文章中 Dota 機器人的勝率已經高達 95%


強化學習被稱作「近似動態規劃」(approximate dynamic programming,ADP)

https://zh.wikipedia.org/zh-tw/%E5%BC%BA%E5%8C%96%E5%AD%A6%E4%B9%A0


2018年6月24日 星期日

growth engineering at Netflix


用 API 控制前端 signup 時要顯示的 fields,算是 API 控制 UI 的一種方法,有趣


https://medium.com/netflix-techblog/growth-engineering-at-netflix-accelerating-innovation-90eb8e70ce59

2018年6月23日 星期六

Vue + Webpacker + Rails



https://mkdev.me/en/posts/rails-5-vue-js-how-to-stop-worrying-and-love-the-frontend

Suspender 用 1.46.0 可以使用 rails 5.1.6

ThoughtBot 的 rails bootstraper,現在最新版 default 使用了 rails 5.2 很煩,因為我不喜歡 5.2 的 credential

要使用 5.1.x 版本的話要用 v1.46.0 版本的 Suspender,但 1.46.0 是用 Ruby 版本 2.5.0

所以確切方法是


```
rvm install 2.5.0
rvm use 2.5.0
gem install suspenders -v 1.46.0
suspender your_project_name
```

然後再進去 project 裡面把 Gemfile 和 .ruby-version 裡的 ruby version 改成2.5.1

https://github.com/thoughtbot/suspenders/tree/v1.46.0

讀書筆記 - 看人的藝術 - Sam Gosling


屬於心理學研究的書籍


個性的表達方式分為三個層面

1. 身份標籤 (Identity Claims)
2. 情感調節器 (Feeling regulations)
3. 行為痕跡 (behavioral residue)

這些是作為我們判斷的線索,將線索分類成這三種層面

在對方感到真正安全的地方才能更容易發現這些象徵,例如臥室或書房,被丟棄的垃圾也是很有參考價值的物品

評估一個人則可以從五大個性來評估


1. 開放性 (Openness)
2. 責任感 (Conscientiousness)
3. 外向性 (Extraversion)
4. 宜人性 (Agreeableness)
5. 神經質 (Neuroticism)


麥克亞當斯體系:先看特徵,再關注個體。特徵即上述五大性格,個體則從角色、目標、技能、價值觀來判斷,當兩個層面都理解,就能觸碰到個性的根基:身份。

人是很容易用片段經驗定義自己,這稱為自我定義記憶


用物品來判斷一個人時,只根據片面的資訊是不實際的,例如看到辦公桌凌亂就覺得此人沒責任感是不實際的判斷,必須要從各個不同的環境裡蒐集正反證據來判斷,環境又分為不同維度,有私人安全以及公開的環境

直覺有時也是錯的,研究顯示常講甜言蜜語的戀人跟常互相開罵的戀人之間在一起的時間沒有太大差異。



握手和常使用的語言是有用的判斷依據,觀察先要確定要觀察哪個面向後再開始觀察會更有效

所有的偽裝都有破綻

自戀者在權利和責任感方便表現特好,且對讚美有無限的接受能力


不同個性的人看待世界也是不同的,有些人覺得自己很懶散,但其他人並不這麼認爲,因為心中的標準不一

人不一定只會希望別人用積極的方式對待自己,有時也會希望別人看待自己負面,這稱作自我驗證理論。例如:某人认为自己没有创造力,即便他认为这是不好的一种品质,他也会将这种缺乏创造力的方面展现出来

刻板印象有時還是很有效的判斷依據,居住地、人種、膚色、性別


伦斯维克的分析表明,交谈、手势以及衣着确实是表现社交能力的有效线索,但是只有正式的着装才能预测应聘者的工作动机

居住空间中两个最明显的线索是大五特征中的两个特征——开放性和责任感




障眼法

1. 第一印象 - 刻板印象影響思考與觀察,讓人忽略了其他明顯的相反特徵
2. 从其他线索中得到的部分线索


如果你担心观察对象正尝试欺骗你,将这些公开的事物和那些更加私密的事物进行比较






Rails where.not 的寫法會略過欄位是 Null 的值


`where.not` 的寫法會略過欄位是 Null 的值,所要對有可能是 Null 值的字串欄位使用 `where.not` 有兩個做法:
1. default 空字串
2. 使用 `or`

另外如果是 boolean 欄位但有可能是 null (雖然一開始就不應該這樣,至少 default true or false),解決方法就脆直接用 where 反正總共才三個值

ex:

User.where(subscribed: [nil, false])


https://robots.thoughtbot.com/activerecord-s-where-not-and-nil

2018年6月22日 星期五

Conway's Game of Life



今年 Ruby Kaigi 看到 Matz 參加 live pair 做 Conway's Game of Life,才發現我常常聽到這個詞但從來沒去研究這到底是啥、為何這麼多人都知道

所以去查了一下,原來是一個模擬細胞生存的遊戲,吸引人的點在於這個遊戲可以有很多變體,甚至初始化細胞的方式不同就可以讓 "生命" 發展有很大的不同,有點像是扮演上帝的角色,而且規則明確,是一個很容易用程式實作的遊戲,難怪那麼有名

想要體驗一下可以到 http://nealwang.net/JustForFun/GameOfLife.html ,先把下面的格子一部分勾選成紅色的,記得要有三個連在一起的紅色,這樣比較好玩


規則:


  1. 當前細胞為存活狀態時,當周圍低於2個(不包含2個)存活細胞時, 該細胞變成死亡狀態。(模擬生命數量稀少)
  2. 當前細胞為存活狀態時,當周圍有2個或3個存活細胞時, 該細胞保持原樣。
  3. 當前細胞為存活狀態時,當周圍有3個以上的存活細胞時,該細胞變成死亡狀態。(模擬生命數量過多)
  4. 當前細胞為死亡狀態時,當周圍有3個存活細胞時,該細胞變成存活狀態。 (模擬繁殖)

  1. live < 2, die
  2. live 2/3, live
  3. live with >3, die
  4. dead with == 3, spawn


覺得挺有趣的,用 Ruby 簡單實現了一下:

https://github.com/wayne5540/conways_game_of_life


https://zh.wikipedia.org/wiki/%E5%BA%B7%E5%A8%81%E7%94%9F%E5%91%BD%E6%B8%B8%E6%88%8F
https://www.youtube.com/watch?v=zEf6iUIkjf4

2018年6月20日 星期三

關於 API 設計的一些想法

大哉問:什麼樣的 API 是好的 API?


  • 有明確的錯誤訊息
  • 回傳有意義的 HTTP status code
  • 能回傳指定的格式 (Multiple Output Formats)(accept: json/application)
  • 好記的名字
  • Deep Filtering (order, joins, pagination)
  • Typed Values - response 有固定格式
  • 好懂的文件 (Interactive Documentation better)
  • 能夠有版本管理,有 deprecated warning
  • High Performance
  • High Availability
  • Developer Community
  • 規範有跡可循並且一致
  • Sandbox mode


答案:沒有所謂的好跟壞,只有適合哪個場景。

所以要做出一個好的 API,最重要的是了解你的 API User 要拿這個 API 來做什麼。


業界常用的 Best Practice

## RESTful

常見的 API 規範:

RESTful, gRPC, GraphQL

以最常見的 RESTful (Representational State Transfer)為例說明

什麼是 RESTful? 網路上一堆複雜的說法,對我來說就是:


  1. 對應正確的 HTTP Request, 新增用 Post, 刪除用 Delete, 更新用 Patch, 查詢用 Get
  2. 每個 EndPoint 就是一個 Resource,`GET /user` 就應該回傳 User

## Authorization

* HTTP Authentication: Basic and Digest Access Authentication  https://tools.ietf.org/html/rfc2617

```
Authorization: Basic xxxxxxx
```
* JWT token - https://jwt.io/
* OAuth(2)

我們? HTTP Auth + 自製 Token

## Response

* JSON format
* Error code, error message
* 正確的 status code

## Documentation

* API blueprint
* Swagger

我們:V0,V1: Test generated HTML document, can support Swagger or API blueprint. V2: Swagger


開發流程

1. 跟 Client 討論需要的數據
2. 用 Swagger 或是 API blueprint 先寫 document
3. Client 按照 document 先 mock 資料
4. Server 開發 API, 用自動化工具測試 API endpoint 是否符合 document (Bonus: easy to TDD)
5. Client & Server 一起完工,皆大歡喜


開發盲點

1. RESTful 代表我要把 Table 映射到 API response 嗎?
2. Client 要求跟 Server 的衝突,Client 想要一個request 拿到所有資訊,Server 想根據規定給 response, 例如 GET /user 還要順便拿 user.groups 的資訊



https://github.com/shieldfy/API-Security-Checklist


讀書筆記 - 成功與運氣 - Robert H Frank

規律一:運氣可以放大
規律二:運氣可以累加
規律三:競爭越激烈,運氣越重要


成功和失敗常常取決於人無法控制的重要事件
那些對自己優勢視若無睹的人,往往同樣無視別人的劣勢
謙虛讓世界變更好

框架效應:針對同一個問題用兩種邏輯上意義相似的說法描述,可以導致不同的判斷 => 認為成功是自己努力得來的,或是承認成功是一部分的運氣


框架效應製造了巨大的偏見,認為自己努力得來的人變得中私人消費而輕公共建設

然而所謂運氣卻也包含了你出生的國家、你從小受的教育,這些都跟公共建設有關

必須認清自己是一個幸運的人,你的成功是建築在你的運氣,所以你得到的不全然都應該是你的


後市偏差:個體面臨不確定性時,往往對先前獲得的訊息有過高評價,進而在決策上導致偏差。(人們在一件事情發生後,很常用一個故事來證明這在所難免)

後視偏差讓人簡單化成功的要素,卻遺忘了成功是各種前因後果累積的結果

馬太效應:反映經濟學中贏家通吃的情況
月暈效應:以偏概全的正反面版本,ex: 一首歌的成功很大程度取決於第一個評價是否是好的


無數的例子證明了微小的隨機因素的力量,例如:
職業曲棍球員有 40% 出生在 1~3 月,只有 10%  出生在 10~12 月,因為青少年曲棍球聯盟的截止出生日期是每年的 1/1,代表越前面月份出生的人越能夠在體能上有同年齡層的優勢,甚至 6~7 月出生的CEO人數比均值低 1/3, 姓氏字母排序也會造成不同



運氣很重要,但努力也重要,對於渴望成功的人來說,對於一個別人重視的事情上累積專業知識是最有用的,因為專業知識不來自於運氣而來自於努力


運氣可以放大,新技術和市場制度為最能幹的人提供了更多的工具,所以能幹(運氣好的人)變得更能幹

尤其是高度競爭的情況下運氣更重要,因為大家的條件都差不多,此時勝負往往取決於那些隨機因素

這是一個贏家通吃的市場,通常這種市場有兩個特點:
1. 回報取決於相對實力而非絕對實力(ex: 網球冠軍因為對手狀況不佳而得冠)
2. 回報往往高度集中在某幾個頂尖玩家手中(ex: Federral, Nadal)

甚至連長尾的得利者都是贏家,因為即使是新技術也很難解除一個重要的市場限制:的時間精力和稀缺性

理由是大多數人都不喜歡做選擇,於是就選擇最受歡迎的商品來逃避選擇


(Lake Wobegon effect)沃博艮湖效應:人往往高估自己

而這也被達爾文的觀點所應證,因為覺得自己會贏得比賽的人會去參加更多的比賽


面對直接威脅到生存的環境,強調當前的成本收益可能是有利的。但在相對穩定的環境,只關心眼前成本利益則是失敗的根源。


可利用性法则(Availability heuristic):我們會用容易記憶的事情來作為判斷的依據,這幾乎從根本上這幾乎從根本上決定了我們的描述是偏頗的(記得成功的理由是自己做的正確決定)


計劃未來是,相信一切在自己掌握中,哪怕那只是一個幻覺。回顧過去時,你應該知道你得到的遠超過你應得的



我們對事物的衡量很大程度取決於周圍的事物
生活中很多重要的回報取決於相對地位


不過分看重自己的人,總是能得到他人的尊重。不過份要求利益的人,總是能對自己得到的那份滿意

所以,承認你的成功一定程度上是源自於他人的努力。




2018年6月17日 星期日

Amazing dolphin


看到 Netflix 的海洋紀錄片,裡面提到海豚捕食沙丁魚群方法是潛入水裡釋放泡泡,利用泡泡把沙丁魚聚集起來補食,會不會太聰明?

難怪銀河列車指南裡面說地球上第二聰明的生物是海豚,第三才是人類,哈哈 XD

蛤?什麼?你問第一是誰?不會自己去看銀河列車指南嗎

2018年6月16日 星期六

讀書筆記 - 股市心裡操縱術 - G.C. Selden



只要有更好的投資標的,就不該管現在投資的損益,那些都是沈沒成本,而應該直接把現在的投資換到更好的投資標的上
大眾堅信不移的說法大多是錯的

自己過度貪心可以從幾點看出來:
1. 不斷提高自己的投資報酬率
2. 原先覺得風險高的投資,現在看起來能穩操勝卷
3. 不再分散投資風險
4. 堅信這次肯定不同


恐慌是一種比貪婪更強烈、更猛爆的情緒,這也是為什麼股市空頭跌勢通常極為猛烈,讓人措手不及,而相對的上漲過程中總是較趨勢溫和的原因

恐慌不是突然出現的,而是長期累積的結果

恐慌時期出現的價格底部往往不是由恐懼造成,因為恐懼的股民早已拋售股票,它是由於一些人資源耗盡、不得不賣出股票造成,如果能給他們時間他們會繼續持有的,所以「時間是交易的本質」不能忘記

持續下跌後,價格本身並不能吸引購買,問題的核心是資金的流動量有多少(曾經被證明過:紐約票據交換所儲蓄超過放貸,快速反彈很快就出現了)

一個人想要什麼,就會相信什麼(盲點)

理性的股民會在最大收益時最小化所承擔的風險,然而,過分自信的股民會錯誤地判斷他們所承擔的風險水平,從而持有較高風險的投資組合

過度自信的股民傾向買賣過去勝利過的組合

股民最好做到完全忘記自己的艙位、收益和損失,忘記當前價格與自己買進或賣出價格的關係,而只管心市場動態。不論是營利還是損失。


不該下單的情況:
1. 沒有未來的企業不下單
2. 未經研究不下單
3. 短期暴漲過的個股不下單
4. 情緒不好的時候不下單
5. 未設止損不下單


最糟糕的幾種心態:

1. 賭徒心態,追求短期刺激,盲目追逐高風險高獲利
2. 鴕鳥心態,虧太慘就當作沒看到放在那繼續爛
3. 敝叟自珍心態,因為是自己的所以認為很好
4. 急功近利心態,投資要看長線





2018年6月10日 星期日

Understanding your Circle of Competence


之前在 Twitter 看到一個段落是說成功的關鍵在於 focus

但什麼是 focus,這個 Circle of Competence 也許是一個更好的解釋



所謂 Circle of Competence 意思就是「你自己真的理解但多數人不是真的理解的知識」

以餐廳運作為例,大家也許都知道餐廳的定價策略等等,人人都可以侃侃而談,但如果餐廳換成藥店、換成生物科技呢?

from 灣區日報

巴菲特与 Charlie Munger 的投资、处世哲学:找到你的 Circle of Competence,在里面努力你就更容易成功;学习、实践、经验积累可以慢慢拓展这个 circle,但要勇于承认自己不知道的事。

https://wanqu.co/a/6593/2018-06-09-understanding-your-circle-of-competence.html
https://www.fs.blog/2013/12/mental-model-circle-of-competence


產品定位決定你可以定價的高低,你想過換句話說嗎?


哈,有趣,產品定位換句話說就可以提高產品定價


以下 quote from 灣區日報

产品定位决定你可以定价的高低

假如你的用户每个月在 Google 上投放广告 $4万,你现在有一款“节省投广告成本”的产品,你每个月可以帮助用户省 $2万,那你定价肯定不能超过 $2万,要不然用户为什么需要你。但你其实可以定超过$2万的

你只需要重新定位你的产品:“帮助增长用户”。如果原来用户每个月投 $4万可以获取200个用户,他们会愿意投 $8万来获取400个用户,那么你就有 $4万的利润空间可以定价了。用户来投广告是为了增长不是为了省钱。

同理,那些“省时”、“提高效率”的产品定位都可以改进,只要抓住用户真正价值所在(比如增长),那你就可以大大提高你产品的定价。


https://wanqu.co/a/6597/2018-06-10-how-repositioning-a-product-allows-you-to-8x-its-price-asmartbear.html?s=email
https://blog.asmartbear.com/more-value-not-save-money.html?utm_source=wanqu.co&utm_campaign=Wanqu+Daily&utm_medium=email

用 Ruby proc 做 success and error handler, like JS Promise


```rb

# A base class for all classes implement calls to API.
class ApiCall
  attr_reader :params

  def self.call(params)
    new(params).call
  end

  def initialize(params)
    @params = params
  end

  def call
    @res = execute
    self
  end

  def on_success
    yield @res if @res.success
    self
  end

  def on_error
    yield @res unless @res.success
    self
  end

  private

  def execute
    fail NotImplementedError
  end
end

StripeCall.(number: 'valid')
  .on_success { |response| puts response.body }
  .on_error { |response| puts response.body }
# => ok response

StripeCall.(number: 'invalid')
  .on_success { |response| puts response.body }
  .on_error { |response| puts response.body }
# => bad response
```


感覺有點借鑑 JS promise 的做法,傳 on_success 和 on_failure 的 proc 進到 method 當作 handler,之前有想過這種做法,剛好在 Ruby weekly 看到有人示範了,的確是減少了 if else 判斷,也省略了 response 這種 hidden context,不過最後為了寫的方便一點用了 method(:handle_success) 就沒有特別喜歡,但還是學習了這個用法,又是 meta programing 流派...


原文: https://railsguides.net/conditional-execution-with-dsl/


另外在 comment 裡看到一個 gem https://github.com/apneadiving/waterfall

也是挺有趣的,真的很有 functional programing 的味道

是不是大家開始慢慢被影響導致越來越多人用 Funtional Ruby 了呢~?最近也常常聽到和看到有人要用 Ruby 實現以及使用 elixir pipe operator XD

2018 Ruby Kaigi 網路上看到的懶人整理




  • Matz considering alias yied_self with then
  • Rib, an alternative for irb
  • Stripe team building Ruby type checker



https://blog.bigbinary.com/2018/05/31/rubykaigi-2018-day-one.html






http.rb replace net::http


作者認為 Net::Http 雖然是 standard lib 之一,但 API 設計很不好,底層實作也有很多覺得不滿的地方,包含 Net::Http 的 Error 封裝方式,讓人不知道怎麼 rescue

有機會可以試用看看

https://github.com/httprb/http

https://twin.github.io/httprb-is-great/


2018年6月6日 星期三

skip document installation when gem install


https://stackoverflow.com/questions/1381725/how-to-make-no-ri-no-rdoc-the-default-for-gem-install

1. 加 ~/.gemrc

```
gem: --no-document
```

done