Total Pageviews

2019/12/05

[閱讀筆記] Thinking in Systems: A Primer (9/9)

  1. 打破各種清規戒律 (Defy the Disciplines)
    1. 不管你主修什麼、教科書說什麼、或是你覺得你是專家,要了解系統,你必須從各個來源學習,例如經濟學家、化學家、心理學家與神學家等。讓跨領域的人聚在一起、互相討論、共同解決一個真實問題,彼此間必須坦承先前忽略了什麼,並樂意被教導。
  2. 擴大關切的範圍 (Expand the Boundary of Caring)
    1. 在複雜系統的世界成功存活,代表著你擴展的不只是時間的水平線,還包含思想的水平線,更重要的是,擴大關心的水平線 (i.e. 範圍)。當然,這出自於道德的原因。如果道德的爭論不夠的話,系統思考提供實際的理由來支持道德的原因。在真實系統,元素間是互相相連的,例如:當人體的肺部失能時,心臟無法持續跳動;當你個員工表現低落,企業是無法成功的;當全球環境崩壞,全球經濟是無法達到預期目標的。
  3. 不要降低「善」的標準 (Don’t Erode the Goal of Goodness)
    1. 降低標準 (drift to low performance) 是系統最具破壞性的典型的例子,這也是在現代工業化的文化中最常見的 -- 不斷降低善的標準。現今的國家領導人,毫無道德觀念、甚至不將道德列入考量,理想主義者反招奚落。在公共場合談論仇恨,比談論愛與和平來得容易。
    2. 不要過度重視壞消息,將標準設為不可改變的絕對值
  4. 與系統共舞的方法 Summary
No.
與系統共舞的方法
說明
1
跟上系統的節拍
如果可以的話,找出系統的實際資料,並繪製出 time graph。去了解系統的行為,別相信人們的記憶,因為那是不可靠的
2
把你的心智模式攤開在陽光下
你知道的任何事情,與每個人知道的每件事情,都只是個 model。將你的 model 攤開來,邀請別人來挑戰你的假設,與挑戰別人的假設。正所謂真理越辯越明,謹慎分析假設,透過證據來驗證,若未通過驗證就將其揚棄
3
相信、尊重並分享資訊
大部分出錯的系統,都是因為錯誤 (biased)、延遲 (delay) 與缺乏 (missing) 的資訊。若你想改善系統的運作,試著讓資訊更即時 (timely)、更精確 (accurate)、更完整 (complete),你將會收到令你驚訝的成效
4
謹慎地使用語言,並用系統的概念去豐富語言
尊重資訊代表避免語言汙染 (language pollution, 即用最清楚的語言避免誤解),這樣才能討論複雜系統的問題。
5
關注重要的,而不只是容易衡量的
若因為某些事物難以量化,就假裝它不存在,會導致 faulty models。若以此態度來設定目標,就導致僅考量容易量化的事物,而非重要的的事物此系統陷阱 (seeking the wrong goals)
6
為反饋系統制定帶有反饋功能的政策
建立新的 feedback loops 來解決系統問題,例如若美國能協助墨西哥改善經濟,而非花錢建築圍牆、增派軍警巡邏,非法移民的問題就能解決
7
追求整體利益
組織的層級架構 (hierarchies) 的存在是用來服務 bottom layers 而非 top layers。不要過度放大某個部分或子系統的利益,卻忽略了整體系統的利益
8
聆聽系統的智慧
先傾聽系統現況 (即 hierarchy 底部有哪些力量與結構維持現有系統),再思考改善方法
9
界定系統的職責
內在責任是指系統設計用來針對決策結果產生的回饋,對於決策者是最直接的。例如開 A380 的機師,坐在駕駛艙內,將最直接經歷其所做的決策所產生的後果。
10
保持謙遜,做一名學習者
當你遇到不懂的事物時,不需要虛張聲勢、不需要呆住,去學習就是了,透過實驗與試誤法 (trial and error) 不斷地學習,並且堅持到底 (stay the course)
11
慶祝複雜性
這個世界就是一團亂、非線性、突然地改變與動態的。其產生了多樣性與一致性,讓我們所處的世界既有趣、又美麗
12
擴展時間的範圍
當你走在難以應付、蜿蜒、未知、未預期與荊棘遍佈的道路,傻子都只是頭低低的往前走,你應該看清楚前方的道路後再往前邁進。你需要關注整體的系統狀態,包含短期與長期
13
打破各種清規戒律
讓跨領域的人聚在一起、互相討論、共同解決一個真實問題,彼此間必須坦承先前忽略了什麼、樂意被教導。
14
擴大關切的範圍
在真實系統,元素間是互相相連的,例如:當人體的肺部失能時,心臟無法持續跳動;當你個員工表現低落,企業是無法成功的;當全球環境崩壞,全球經濟是無法達到預期目標的
15
不要降低「善」的標準
降低標準 (drift to low performance) 是系統最具破壞性的典型的例子,這也是在現代工業化的文化中最常見的 -- 不斷降低善的標準。不要過度重視壞消息,將標準設為不可改變的絕對值。

  1. Summary for systems
    1. 一個系統不僅僅是其各個部分的總和;
    2. 系統是透過多個 information flow 的相互關聯來運作;
    3. 系統中最不明顯的部分,常常是決定系統行為最具決定性影響的地方 (i.e. function or purpose);
    4. 系統結構是系統行為的來源。系統行為透漏隨著時間更迭所產生的一系列的事件。
  2. Summary for stocks, flows and dynamic equilibrium
    1. Stock 是系統內 flow 改變的歷史記憶;
    2. 若 inflow 的總和 > outflow 的總和,stock level 會上升;
    3. 若 outflow 的總和 > inflow 的總和,stock level 會下降;
    4. 若 inflow 總和 = outflow 總和,stock level 為維持動態平衡 (dynamic equilibrium);
    5. 無論是降低 outflow rate 或是提升 inflow rate,都可以提升 stock level;
    6. Stock 在系統中扮演 delays, buffer 或 shock absorber 的角色;
    7. Stock 允許將 inflows 與 outflows 獨立分開來看。
  3. Summary for feedback loops
    1. Feedback loop 是一連串與 stock 相關的因果關聯,透過一套決策、規定、法律或決策,使其達到調整 stock level 的目的
    2. Balancing feedback loops 用來使系統保持動態平衡,是一個 goal-seeking 的結構,這是系統穩定的來源、也是抗拒改變的來源
    3. Reinforcing feedback loops 具備自我強化的功能,可以導致指數化的成長或是導致一段時間後,系統崩壞。
    4. 根據Feedback loop 所傳遞的資訊所做的回應,只能影響系統未來的行為,你無法矯正當下系統的行為
    5. Stock-maintaining balancing feedback loop 一定要有自己的目標,用來適當地補償影響 stock 的 inflow 或 outflow 流程。否則,feedback process 會低於或超過 stock 的目標
    6. 系統間都會擁有類似的 feedback structure,因此也會產生類似的動態行為
  4. Summary for shifting dominance, delays, and oscillations
    1. 系統複雜行為常常起因於 feedback loop 強度的改變,有些時候是 balancing loop 占上風,有時則是 reinforcing loop 占上風
    2. Balancing feedback loop 中的 delay,是系統產生上下震盪的原因
    3. 改變 delay 的長度,可以讓系統行為大不同
  5. Summary for scenarios and testing models
    1. 系統動態模型 (system dynamics models) 用來探索可能的未來 (不是預測未來),並且會詢問如果...會怎麼樣的問題 (what-if questions)
    2. Model utility 的重點並不在於驅動情境 (driving scenario) 是否真實 (因為沒人能確定),重點在於遇到真實的行為做何反應 (response)
  6. Summary for constraints on systems
    1. 在一個指數型成長的系統,一定至少有一個驅動成長的 reinforcing loop,但也至少會有一個 balancing loop 來限制成長,在一個資源有限的環境,沒有一個系統可以永遠成長
    2. Nonrenewable resources 代表 stock-limited;renewable resource 代表 flow-limited。
  7. Summary for resilience, self-organization and hierarchy
    1. 彈性 (resilience) 永遠都有限制
    2. 系統不僅僅需要管理生產力 (productivity) 或穩定性 (stability),還要管理彈性 (resilience)
    3. 自我組織 (self-organization) 是指系統能自我學習、產生新的結構、產生多樣化與複雜化
    4. 層級化系統 (hierarchical systems) 是由下而上緩慢發展而來。高層的目的是用來服務較低層級的目的
  8. Summary for source of system surprises
    1. 系統中許多關係都是非線性的
    2. 系統無法獨立存在,這個世界是逐漸演變的連續體 (continuum)。我們繪製系統邊界的目的是為了方便討論
    3. 在任何時候,系統中最重要的 input,通常也是系統的限制所在
    4. 任何一個實際的個體,一定擁有多個 inputs 與 outputs,並被多層限制所圍繞
    5. 系統永遠都有成長限制
    6. 當系統以指數型成長的方式朝向限制前進時,將會以極短且驚人的速度碰頂
    7. 當 feedback loops 擁有 long delays 時,遠見 (foresight) 就是一個很重要的能力
    8. 每個人的有限理性 (bounded rationality) 是導致無法達成共識的原因,應予以導正朝向系統整體福祉的方向思考
  9. Summary for mindsets and models
    1. 我們所認為我們知道的世界都是一個 model
    2. 我們認知的 model 必須與世界有高度一致性,但是可惜的是,我們所知與世界的全貌永遠都有落差

2019/12/04

[Java] How to magnify and shrink image?

Scenario


How-To
Here has sample code:
  package test.util;
  
  import java.awt.Graphics;
  import java.awt.image.BufferedImage;
  import java.io.File;
  import java.io.IOException;
  
  import javax.imageio.ImageIO;
  
  import org.apache.commons.io.FilenameUtils;
  import org.springframework.stereotype.Component;
  
  import lombok.extern.slf4j.Slf4j;
  
  @Slf4j
  @Component
  public class ImageUtils {
  
      /**
       * Magnify image
       * 
       * @param oFile
       *            original file
       * @param times
       *            magnification times
       * @param mFile
       *            magnified image
       * @throws IOException
       */
      public void magnifyImage(File oFile, Integer times, File mFile) throws IOException {
          try {
              BufferedImage originalImage = ImageIO.read(oFile);
  
              int width = originalImage.getWidth() * times;
              int height = originalImage.getHeight() * times;
  
              BufferedImage newImage = new BufferedImage(width, height, originalImage.getType());
              Graphics g = newImage.getGraphics();
              g.drawImage(originalImage, 0, 0, width, height, null);
              g.dispose();
  
              ImageIO.write(newImage, FilenameUtils.getExtension(mFile.getName()), mFile);
              log.debug("magnified image successfully to {}", mFile.getAbsolutePath());
          } catch (IOException e) {
              throw new IOException("fail to magnify image", e);
          }
      }
  
      /**
       * Shrink image
       * 
       * @param oFile
       *            original file
       * @param times
       *            shrink times
       * @param sFile
       *            shrinked image
       * @throws IOException
       */
      public void shrinkImage(File oFile, Integer times, File sFile) throws IOException {
          try {
              BufferedImage originalImage = ImageIO.read(oFile);
              int width = originalImage.getWidth() / times;
              int height = originalImage.getHeight() / times;
  
              BufferedImage newImage = new BufferedImage(width, height, originalImage.getType());
              Graphics g = newImage.getGraphics();
              g.drawImage(originalImage, 0, 0, width, height, null);
              g.dispose();
  
              ImageIO.write(newImage, FilenameUtils.getExtension(sFile.getName()), sFile);
              log.debug("shinked image successfully to {}", sFile.getAbsolutePath());
          } catch (IOException e) {
              throw new IOException("fail to shrink image", e);
          }
      }
      
  }
  


Test class:
  package test.util;
  
  import static org.assertj.core.api.Assertions.assertThat;
  
  import java.io.File;
  import java.io.IOException;
  
  import org.junit.Test;
  import org.junit.runner.RunWith;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.boot.test.context.SpringBootTest;
  import org.springframework.test.context.junit4.SpringRunner;
  
  @RunWith(SpringRunner.class)
  @SpringBootTest
  public class ImageUtilsTest {
      
      private File originalFile = new File("C:\\Users\\user\\Downloads\\originalFile.jpg");
      private File shrinkFile = new File("C:\\Users\\user\\Downloads\\shrinkFile.jpg");
      private File magnificationFile = new File("C:\\Users\\user\\Downloads\\manificationFile.jpg");
      
      @Autowired
      private ImageUtils imageUtils;
      
      @Test
      public void testShrinkImage() throws IOException {
          imageUtils.shrinkImage(originalFile, 10, shrinkFile);
          assertThat(shrinkFile.exists()).isTrue();
      }
  
      @Test
      public void testMagnifyImage() throws IOException {
          imageUtils.magnifyImage(shrinkFile, 2, magnificationFile);
          assertThat(magnificationFile.exists()).isTrue();
      }
      
  }