<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Richard隨手筆記 - 後端程式</title><link href="https://blog.richardnote.com/" rel="alternate"></link><link href="https://blog.richardnote.com/feeds/hou-duan-cheng-shi.atom.xml" rel="self"></link><id>https://blog.richardnote.com/</id><updated>2022-09-05T19:46:00+08:00</updated><subtitle>紙上得來終覺淺，絕知此事要躬行</subtitle><entry><title>依賴注入的心得筆記</title><link href="https://blog.richardnote.com/2022/09/ioc-di/" rel="alternate"></link><published>2022-09-05T19:46:00+08:00</published><updated>2022-09-05T19:46:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2022-09-05:/2022/09/ioc-di/</id><summary type="html">&lt;p&gt;依賴注入的心得筆記&lt;/p&gt;</summary><content type="html">
&lt;h2 id="_1"&gt;依賴注入的入門階段&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;自從被打槍不會ASP.&lt;span class="caps"&gt;NET&lt;/span&gt; Core 後，就不斷的學習新的NetCore技術，先後買了幾本書，&lt;/p&gt;
&lt;p&gt;第一本：&lt;a href="https://www.tenlong.com.tw/products/9789865501402?list_name=srh"&gt;完全精通微軟Web架構: &lt;span class="caps"&gt;ASP&lt;/span&gt;.Net Core 3最新強實戰&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;說實在的，這本書似乎不太適合我看，首先對於兩岸的文字描述，對我來講實在有點障礙，在專有名詞上，我還是偏好非中國那邊的用語，另外這本的講解，讓我覺得文字說明不夠簡單扼要，常常看了一個段落，然後實在看不明白到底要表達什麼，看過另外一本的依賴注入後才發覺這本書文字的累贅，不過其實還是不錯的書，至少把NetCore的最根本原理與NetCore如何實現跨平台與各個Middleware說明的很徹底，還是值得的一本，只不過我要看很久。&lt;/p&gt;
&lt;p&gt;第二本：&lt;a href="https://www.tenlong.com.tw/products/9789864344987?list_name=srh"&gt;依賴注入：原理、實作與設計模式 (Dependency Injection: Principles, Practices, Patterns, 2/e)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;這本在看了上面第一本ASP.&lt;span class="caps"&gt;NET&lt;/span&gt; Core 3 後，發現依賴注入是ASP.&lt;span class="caps"&gt;NET&lt;/span&gt; Core 核心概念，並且第一本的依賴注入講解的內容我覺得實在不懂，後來又買了這本。 著實的認為這本真的是非常好的書，&lt;/p&gt;
&lt;h2 id="_2"&gt;依賴注入的概念假想&lt;a class="headerlink" href="#_2" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;說道依賴注入，書上用插座的範例來說明設計模式的譬喻，來讓讀者能夠深刻體會設計模式是如何實現的。不免俗的我自己也有自己一套譬喻假想，常常人家說到依賴注入就會說到 IoC (控制反轉)，然後就是依賴注入的 組合根，建構子注入，屬性注入，方法注入，DI容器，光是這麼多名詞，硬記也不知道在記什麼，但是讀到後面卻產生一個很相似的譬喻：{『武林的世界』&lt;/p&gt;
&lt;p&gt;首先，要成為一個武林高手，必須內外兼修，內就是修煉內功心法，外就是修煉武學招式，
對於依賴注入，IoC控制反轉就感覺是修煉內功心法，為何如此說法呢？先看看名詞定義，以下引用&lt;a href="https://www.tenlong.com.tw/products/9789865501402?list_name=srh"&gt;完全精通微軟Web架構: &lt;span class="caps"&gt;ASP&lt;/span&gt;.Net Core 3最新強實戰&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="inverse-of-control"&gt;控制反轉（Inverse of Control）&lt;a class="headerlink" href="#inverse-of-control" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;對於任何一項工作，不論大小，基本上都可以分解成對應的步驟，所以任何一項工作的實施都有固定的流程，而IoC的控制就是視作『&lt;strong&gt;&lt;em&gt;針對流程的控制&lt;/em&gt;&lt;/strong&gt;』。一般來講，設計模式是為了解決一個實際問題的方案，但是IoC沒有一個針對性的問題領域，本身也沒有提供一種可操作的解決方案，所以認為視為IoC是一種『&lt;strong&gt;&lt;em&gt;設計原則&lt;/em&gt;&lt;/strong&gt;』&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;由以上的定義可以瞭解，控制反轉是一個概念，一個設計原則，當我們在定義介面的時候，對於功能的切割是由哪些類別來注入，實際的控制權是由外部注入的，所以『&lt;strong&gt;&lt;em&gt;針對流程的控制&lt;/em&gt;&lt;/strong&gt;』要如何定義的靈活與彈性就要靠日後的練習，完全就是一個心法的概念。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="_3"&gt;什麼是『組合根』&lt;a class="headerlink" href="#_3" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;可以組合應用程式中使用的類別。 將需要實體物件的建立作業，全部集中化到一個地方，而這個負責處理作業的區塊就是『組合根』，通常是應用程式的啟動點，在NetCore就是Main方法中。&lt;/p&gt;
&lt;h3 id="_4"&gt;建構子注入&lt;a class="headerlink" href="#_4" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;必須在Public 修飾子的建構子中以建構子參數的形式，定義這份依賴需求，要求外部提供物件。 重要：建構子參數要增加必須在同一個建構子增加額外的參數，避免使用多載方式導致混淆。&lt;/p&gt;
&lt;h3 id="_5"&gt;屬性注入&lt;a class="headerlink" href="#_5" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;接著讓我們來看看屬性注入，顧名思義就是&lt;strong&gt;從公開的屬性丟進去&lt;/strong&gt;，因此有時候也會被叫做設值注入。
通常我們會在 &lt;strong&gt;「外部使用者要能夠隨時切換依賴對象」或是「類別已經有預設值了，但希望提供使用者可以覆寫掉預設值的彈性」時用到屬性注入&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="_6"&gt;方法注入&lt;a class="headerlink" href="#_6" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;當依賴對象可能會隨著每次呼叫的方法不同，又或者是依賴對象不變但每次的使用方都有可能變化時，就需要透過方法參數的形式來設定依賴關係。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;上述這些定義就是依賴注入的方法，組合根就是在定義如何引用各個類別，組合起所有的類別，這些方式就是類似拳腳基本功，有了基本的拳腳功夫，接下來就是討論到DI容器，DI容器可以說是各個門派的獨有的技能。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr/&gt;
&lt;h3 id="di"&gt;DI容器技術&lt;a class="headerlink" href="#di" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;所謂的DI容器技術指的就是一套軟體函式庫，協助我們將許多包括『物件關聯組合』，『管理物件生命週期』等作業自動化。&lt;/p&gt;
&lt;p&gt;由上述的定義可瞭解到，使用依賴注入，會有許多相關的知識需要理解，在此不多講解，可參考
&lt;a href="https://www.tenlong.com.tw/products/9789864344987?list_name=srh"&gt;依賴注入：原理、實作與設計模式 (Dependency Injection: Principles, Practices, Patterns, 2/e)&lt;/a&gt;&lt;br/&gt; 第七章到第九章的內容&lt;/p&gt;
&lt;p&gt;然而DI容器其實是協助我們管理跟自動化，而提供許多的函式方法來協助我們，下面就會記錄與說明函式的方法。讓我們加入華山派的劍宗吧。&lt;/p&gt;
&lt;h2 id="autofac"&gt;依賴注入的容器：Autofac的記錄&lt;a class="headerlink" href="#autofac" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://autofac.org/apidoc/html/62C594FF.htm"&gt;Autofac .&lt;span class="caps"&gt;NET&lt;/span&gt; Inversion of Control Container&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ConfigureContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ContainerBuilder&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Assembly&lt;/span&gt; &lt;span class="n"&gt;domainAssembly&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ITimeProvider&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Assembly&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterType&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;DefaultTimeProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="n"&gt;As&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ITimeProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="n"&gt;SingleInstance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterInstance&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IUserContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;AspNetUserContextAdapter&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;CommerceContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConnectionString&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InstancePerLifetimeScope&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterAssemblyTypes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;domainAssembly&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;AsClosedTypesOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ICommandService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&amp;gt;));&lt;/span&gt;

    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterGenericDecorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AuditingCommandServiceDecorator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&amp;gt;),&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ICommandService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&amp;gt;));&lt;/span&gt;

    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterGenericDecorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SaveChangesCommandServiceDecorator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&amp;gt;),&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ICommandService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&amp;gt;));&lt;/span&gt;
    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterGenericDecorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SecureCommandServiceDecorator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&amp;gt;),&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ICommandService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&amp;gt;));&lt;/span&gt;

    &lt;span class="c1"&gt;// ---- Start code section 13.4.4 ----&lt;/span&gt;
    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterAssemblyTypes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;domainAssembly&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;As&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
            &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;interfaceType&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetInterfaces&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;interfaceType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsClosedTypeOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IEventHandler&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&amp;gt;))&lt;/span&gt;
            &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;KeyedService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"handler"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;interfaceType&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterGeneric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CompositeEventHandler&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&amp;gt;))&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;As&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IEventHandler&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&amp;gt;))&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithParameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResolveNamed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"handler"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ParameterType&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="c1"&gt;// ---- End code section 13.4.4 ----&lt;/span&gt;

    &lt;span class="c1"&gt;// Register adapters to external systems&lt;/span&gt;
    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterAssemblyTypes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WcfBillingSystem&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Assembly&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AsImplementedInterfaces&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Register repositories&lt;/span&gt;
    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterAssemblyTypes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SqlProductRepository&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Assembly&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EndsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Repository"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AsImplementedInterfaces&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class="caps"&gt;TODO&lt;/span&gt;：等待學習中….
RegisterType
RegisterInstance
RegisterAssemblyTypes RegisterGenericDecorator&lt;/p&gt;
&lt;p&gt;&lt;a href="https://ithelp.ithome.com.tw/users/20144614/ironman/5120"&gt;[Dot Net Core](圖解系列與常用套件)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://autofac.readthedocs.io/en/latest/index.html"&gt;官方文檔&lt;/a&gt;&lt;/p&gt;</content><category term="後端程式"></category><category term="Dependency Injection"></category></entry><entry><title>GIT錯誤：the remote end hung up unexpectedly</title><link href="https://blog.richardnote.com/2022/07/git-remote-hung-up-unexpectedly/" rel="alternate"></link><published>2022-07-28T17:20:00+08:00</published><updated>2022-07-28T17:20:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2022-07-28:/2022/07/git-remote-hung-up-unexpectedly/</id><summary type="html">&lt;p&gt;&lt;span class="caps"&gt;GIT&lt;/span&gt; error：the remote end hung up&amp;nbsp;unexpectedly&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;最近修改專案，新增了許多packages，然後加入Git 清單內，但是當要PUSH時，就發生如下錯誤訊息，&amp;nbsp;git小烏龜報錯如標題&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;Enumerating objects: 490, done.&lt;/span&gt;
&lt;span class="err"&gt;Counting objects: 100% (381/381), done.&lt;/span&gt;
&lt;span class="err"&gt;Delta compression using up to 12 threads&lt;/span&gt;
&lt;span class="err"&gt;Compressing objects: 100% (288/288), done.&lt;/span&gt;
&lt;span class="c"&gt;error: RPC failed; HTTP 400 curl 22 The requested URL returned error: 400&lt;/span&gt;
&lt;span class="c"&gt;fatal: the remote end hung up unexpectedly&lt;/span&gt;
&lt;span class="err"&gt;Writing objects: 100% (299/299), 7.85 MiB | 8.89 MiB/s, done.&lt;/span&gt;
&lt;span class="err"&gt;Total 299 (delta 133), reused 16 (delta 1), pack-reused 0&lt;/span&gt;
&lt;span class="c"&gt;fatal: the remote end hung up unexpectedly&lt;/span&gt;
&lt;span class="err"&gt;Everything up-to-date&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;查詢google後，約略可能為如下原因所引發的，git上傳實際會將先檔案放入緩衝區，緩衝區如果設置的值比要上傳的內容小，那麼就會出現這個錯誤&lt;/p&gt;
&lt;p&gt;修改提交緩存區大小為5GB，或者更大的數字，該方式全域生效，一勞永逸&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git config --global http.postBuffer 5242880000&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;參考資料：&lt;a href="https://www.cnblogs.com/rgqjson/p/13297526.html"&gt;git 推送出现 &amp;#8220;fatal: The remote end hung up unexpectedly&amp;#8221;&amp;nbsp;解决方案&lt;/a&gt;&lt;/p&gt;</content><category term="後端程式"></category><category term="git"></category></entry><entry><title>ASP.NET MVC的參數驗證方式</title><link href="https://blog.richardnote.com/2021/12/asp-net-mvc-actionfilter/" rel="alternate"></link><published>2021-12-30T10:36:00+08:00</published><updated>2021-12-30T10:36:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-12-30:/2021/12/asp-net-mvc-actionfilter/</id><summary type="html">&lt;p&gt;用ASP.&lt;span class="caps"&gt;NET&lt;/span&gt; &lt;span class="caps"&gt;MVC&lt;/span&gt; 的&amp;nbsp;ActionFilterAttribute來過濾API參數&lt;/p&gt;</summary><content type="html">
&lt;h2 id="_1"&gt;前言&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;有時提供廠商的API，明明沒有定義的參數卻帶入，或是已經是舊版不用的參數還是會帶入，使用這個方式來過濾並且阻擋，使用ASP.&lt;span class="caps"&gt;NET&lt;/span&gt; &lt;span class="caps"&gt;MVC&lt;/span&gt; 的 ActionFilterAttribute 方式&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ParaFilterAttribute&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ActionFilterAttribute&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// 交易類型 &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt; &lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;ParaType&lt;/span&gt; &lt;span class="n"&gt;paraType&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// 比對Model名稱(MVC ModelBinding) &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt; &lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;ParameterName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;OnActionExecuting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ActionExecutingContext&lt;/span&gt; &lt;span class="n"&gt;filterContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//取得傳入Model ApiModel &lt;/span&gt;
        &lt;span class="n"&gt;ApiModel&lt;/span&gt; &lt;span class="n"&gt;viewModel&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;filterContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ActionParameters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ParameterName&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;ApiModel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;viewModel&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;//抓出交易類別的Property &lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ApiModel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetProperties&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;IsNotParameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;errorList&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GetErrorProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;errorList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;filterContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ContentResult&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="c1"&gt;//返回錯誤&lt;/span&gt;
                &lt;span class="p"&gt;};&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// 取得比對不符的參數 &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;param name="viewModel"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;param name="props"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt; &lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PropertyInfo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;GetErrorProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ApiModel&lt;/span&gt; &lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PropertyInfo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PropertyInfo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PropertyInfo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DiffValueType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DiffRefType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// 參考類型比較 &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;param name="viewModel"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;param name="props"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt; &lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PropertyInfo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;DiffRefType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ApiModel&lt;/span&gt; &lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PropertyInfo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PropertyType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsValueType&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// 值類型比較 &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;param name="viewModel"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;param name="props"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt; &lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PropertyInfo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;DiffValueType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ApiModel&lt;/span&gt; &lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PropertyInfo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PropertyType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsValueType&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PropertyType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetDefault&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// 抓出要比較交易類別 &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;param name="p"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt; &lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;IsNotParameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PropertyInfo&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ParaType&lt;/span&gt; &lt;span class="n"&gt;paraVal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;ParamterAttribute&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ParaType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;paraVal&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;ParaType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="_2"&gt;欄位屬性這樣用&lt;a class="headerlink" href="#_2" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="na"&gt;[Paramter(ParaType = 列舉物件)]&lt;/span&gt; 
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;SomeModelPara&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="filter"&gt;Filter這樣用&lt;a class="headerlink" href="#filter" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="na"&gt;[ParaFilter(ParaType = 列舉物件, ParameterName = "物件名稱")]&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="後端程式"></category><category term="ASPNETMVC"></category><category term="CSharp"></category></entry><entry><title>驗證的範例</title><link href="https://blog.richardnote.com/2021/12/some-verify-function/" rel="alternate"></link><published>2021-12-30T10:24:00+08:00</published><updated>2021-12-30T10:24:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-12-30:/2021/12/some-verify-function/</id><summary type="html">&lt;p&gt;記錄一些驗證規格的函數&lt;/p&gt;</summary><content type="html">
&lt;h2 id="_1"&gt;身份驗證&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;hr/&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;CheckIDNO&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;seed&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;       &lt;span class="c1"&gt;//除了檢查碼外每個數字的存放空間 &lt;/span&gt;

    &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;charMapping&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"B"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"D"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"E"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"F"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"G"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"H"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"J"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"K"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"L"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"M"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"N"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"P"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Q"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"R"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"S"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"T"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"U"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"V"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"X"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"W"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"I"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"O"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="c1"&gt;//A=10 B=11 C=12 D=13 E=14 F=15 G=16 H=17 J=18 K=19 L=20 M=21 N=22 &lt;/span&gt;

    &lt;span class="c1"&gt;//P=23 Q=24 R=25 S=26 T=27 U=28 V=29 X=30 Y=31 W=32  Z=33 I=34 O=35 &lt;/span&gt;

    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;charMapping&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;charMapping&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="c1"&gt;//10進制的高位元放入存放空間 &lt;/span&gt;
            &lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//10進制的低位元*9後放入存放空間 &lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;   &lt;span class="c1"&gt;//將剩餘數字乘上權數後放入存放空間 &lt;/span&gt;
        &lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Convert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToInt32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;//檢查是否符合檢查規則，10減存放空間所有數字和除以10的餘數的個位數字是否等於檢查碼 &lt;/span&gt;
    &lt;span class="c1"&gt;//(10 - ((seed[0] + .... + seed[9]) % 10)) % 10 == 身分證字號的最後一碼 &lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sum&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;Convert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToInt32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="_2"&gt;統編驗證&lt;a class="headerlink" href="#_2" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;hr/&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;CheckCompanyN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;CompanyId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;Logic&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;addition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;Logic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;no&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Convert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToInt32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CompanyId&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;no&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;Logic&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="n"&gt;addition&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;addition&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CompanyId&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"7"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="email"&gt;Email驗證&lt;a class="headerlink" href="#email" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;RegExString&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"^((([A-Za-z]|\d|[!#\$%&amp;amp;'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([A-Za-z]|\d|[!#\$%&amp;amp;'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([A-Za-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([A-Za-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([A-Za-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([A-Za-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([A-Za-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([A-Za-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([A-Za-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([A-Za-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="_3"&gt;手機驗證&lt;a class="headerlink" href="#_3" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;RegExString&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"[0-9\#\+\-\(\)]"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="後端程式"></category><category term="fction"></category><category term="CSharp"></category></entry><entry><title>ASP.NET CORE 在IIS錯誤問題</title><link href="https://blog.richardnote.com/2021/12/aspnetcore-iis-error/" rel="alternate"></link><published>2021-12-10T09:44:00+08:00</published><updated>2021-12-10T09:44:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-12-10:/2021/12/aspnetcore-iis-error/</id><summary type="html">&lt;p&gt;預覽標題&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;![[IIS錯誤問題.png]]&lt;/p&gt;
&lt;p&gt;在IIS上執行ASP.&lt;span class="caps"&gt;NET&lt;/span&gt; core&amp;nbsp;需要安裝：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;span class="caps"&gt;NET&lt;/span&gt; Core的程式&amp;nbsp;aspnetcore-runtime-3.1.11-win-x64&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span class="caps"&gt;NET&lt;/span&gt; Core 裝載套件組合&amp;nbsp;dotnet-hosting-3.1.11-win&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;a href="https://docs.microsoft.com/zh-tw/aspnet/core/tutorials/publish-to-iis?view=aspnetcore-5.0&amp;amp;tabs=netcore-cli"&gt;這是微軟的官方說明教學&lt;/a&gt;&lt;/p&gt;</content><category term="後端程式"></category><category term="ASPNETCore"></category><category term="IIS"></category><category term="微軟筆記"></category></entry><entry><title>內容管理系統CMS</title><link href="https://blog.richardnote.com/2021/12/python-cms/" rel="alternate"></link><published>2021-12-01T09:58:00+08:00</published><updated>2021-12-01T09:58:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-12-01:/2021/12/python-cms/</id><summary type="html">&lt;p&gt;使用CMS系統建構網站&lt;/p&gt;</summary><content type="html">
&lt;h2 id="_1"&gt;需求&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;需要建置一個快速的內容形象網站，最好的就是找CMS系統，以目前學的C#，還有新手Python程度，找到有幾個CMS來選擇&lt;/p&gt;
&lt;h3 id="djangocms-wagtailcms-orchardcodecms"&gt;DjangoCMS WagtailCMS  OrchardCodeCMS&lt;a class="headerlink" href="#djangocms-wagtailcms-orchardcodecms" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;OrchardCodeCMS&lt;/li&gt;
&lt;li&gt;WagtailCMS&lt;/li&gt;
&lt;li&gt;DjangoCMS&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最後選擇使用WagtailCMS來處理我的需求以及找到一個套件能快速建構內容網站。&lt;/p&gt;
&lt;h2 id="orchardcodecms"&gt;OrchardCodeCMS&lt;a class="headerlink" href="#orchardcodecms" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;使用ASP.&lt;span class="caps"&gt;NET&lt;/span&gt; Core 來建置CMS系統，.&lt;span class="caps"&gt;NET&lt;/span&gt; Core 目前還沒學到，而且我比較偏向使用Python來學習順便練習，但是這個OrchardCoreCMS內容功能蠻強大的，而且也蠻靈活的，由於NET Core 已經可以跨平臺，所以在我的Mac也可以建置。使用Visual Studio 2019 開啟，直接建置完成，啟動後，就直接一個設定頁面可以選擇，資料庫提供SQLite，&lt;span class="caps"&gt;SQL&lt;/span&gt; Server，還有一些基本的樣板，提供基本的Agency，Blog，ComingSoom 等的樣板。&lt;/p&gt;
&lt;p&gt;![[OrchardCodeCMS開始設定頁面.jpg]]&lt;/p&gt;
&lt;p&gt;![[可以設定版型.jpg]]&lt;/p&gt;
&lt;p&gt;![[Pastedimage20211201104159.png]]&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;節錄一下官方文件的重點：&lt;/p&gt;
&lt;p&gt;不同的網站建設策略¶
Orchard Core CMS支持所有主要的網站建設策略：&lt;/p&gt;
&lt;p&gt;完整的CMS。在這種模式下，網站使用主題和模板來呈現您的內容，目的是實現很少甚至沒有自定義開發。&lt;/p&gt;
&lt;p&gt;解耦CMS。除了內容管理後端之外，該網站一開始是空白。您可以使用Razor Pages或MVC操作創建所需的所有模板，並通過內容服務訪問內容。
參考：&lt;a href="https://www.youtube.com/watch?v=yWpz8p-oaKg"&gt;https://www.youtube.com/watch?v=yWpz8p-oaKg&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;無頭CMS。該站點僅管理內容，並且您創建了一個單獨的應用程序，該應用程序將使用GraphQL或REST API來獲取託管內容。
參考：&lt;a href="https://www.youtube.com/watch?v=4o9zG17cfa0"&gt;https://www.youtube.com/watch?v=4o9zG17cfa0&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;解耦CMS比較適合拿來做客製化的樣板網站，對於OrchardCodeCMS功能的理解，另外鏈結一篇文章: [[OrchardCore CMS系統]] ，內容之多對於我只是想要簡單的內容展示形象網站似乎有點大，先放著以後再來學好了。&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="djangocmswagtailcms"&gt;DjangoCMS與WagtailCMS&lt;a class="headerlink" href="#djangocmswagtailcms" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;DjangoCMS之前有稍微研究一下官方提供的測試後臺，玩了一下，對於我這個Python新手而言，還有操作上，覺得有點不直覺，後來就跑去看WagtailCMS，對於想要快速建構一個Blog或是小型形象網站，WagtailCMS似乎比較能夠達成我的需求，而且還不太會寫Python的我&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/playlist?list=PLMQHMcNi6ocsS8Bfnuy_IDgJ4bHRRrvub"&gt;https://www.youtube.com/playlist?list=PLMQHMcNi6ocsS8Bfnuy_IDgJ4bHRRrvub&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Youtube上的Wagtail學習系列影片，相關的教學還蠻多的，個人覺得WagtailCMS，也還是需要一點程式底子去處理細微的修改，但是後來發現一個好套件。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/coderedcorp/coderedcms"&gt;CodeRed &lt;span class="caps"&gt;CMS&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;這個CodeRed像是Wagtail的加強版，把很多想要的功能都做好了，&lt;/p&gt;
&lt;p&gt;![[RedcodeCMS的功能項目.jpg]]&lt;/p&gt;
&lt;p&gt;一開始還不太懂架構的堆疊，後來摸熟之後，就像是在玩疊積木一樣，能夠快速的建立一個小站臺，非要說缺點就是要精確的調整樣式的話，會比較麻煩，若是有設計的人員可能比較好，基本上CodeRed套件樣式是使用 &lt;a href="https://bootswatch.com/lux/"&gt;https://bootswatch.com/lux/&lt;/a&gt; 基本的版型。&lt;/p&gt;
&lt;p&gt;以上就是碰過的內容管理系統，各個架構都感覺不錯，各有長處，但是以本業是微軟方面的我，OrchardCodeCMS可以好好學學看，可以學到蠻多東西，而且 .&lt;span class="caps"&gt;NET&lt;/span&gt; Core 是微軟較新的技術，順便練習。&lt;/p&gt;</content><category term="後端程式"></category><category term="WagtailCMS"></category><category term="CodeRedCMS"></category><category term="Python"></category></entry><entry><title>Python爬蟲程式錯誤</title><link href="https://blog.richardnote.com/2021/11/python-crawler-error/" rel="alternate"></link><published>2021-11-25T23:04:00+08:00</published><updated>2021-11-25T23:04:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-11-25:/2021/11/python-crawler-error/</id><summary type="html">&lt;p&gt;ConnectionResetError(54,&amp;#8217;Connection reset by&amp;nbsp;peer&amp;#8217;))&lt;/p&gt;</summary><content type="html">
&lt;h2 id="traceback"&gt;錯誤發生的Traceback&lt;a class="headerlink" href="#traceback" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;Traceback&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/urllib3/response.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;438&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;_error_catcher&lt;/span&gt;

 &lt;span class="k"&gt;yield&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/urllib3/response.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;767&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;read_chunked&lt;/span&gt;

 &lt;span class="n"&gt;chunk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_handle_chunk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/urllib3/response.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;711&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;_handle_chunk&lt;/span&gt;

 &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_fp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_safe_read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/http/client.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;625&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;_safe_read&lt;/span&gt;

 &lt;span class="n"&gt;chunk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MAXAMOUNT&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/socket.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;704&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;readinto&lt;/span&gt;

 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_sock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;recv_into&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/ssl.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;1241&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;recv_into&lt;/span&gt;

 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nbytes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/ssl.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;1099&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt;

 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_sslobj&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="ne"&gt;ConnectionResetError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Errno&lt;/span&gt; &lt;span class="mi"&gt;54&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;Connection&lt;/span&gt; &lt;span class="n"&gt;reset&lt;/span&gt; &lt;span class="n"&gt;by&lt;/span&gt; &lt;span class="n"&gt;peer&lt;/span&gt;



&lt;span class="n"&gt;During&lt;/span&gt; &lt;span class="n"&gt;handling&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;above&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;another&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt; &lt;span class="n"&gt;occurred&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;



&lt;span class="n"&gt;Traceback&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/requests/models.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;753&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt;

 &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;chunk&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunk_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;decode_content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/urllib3/response.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;572&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;

 &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_chunked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;decode_content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;decode_content&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/urllib3/response.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;793&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;read_chunked&lt;/span&gt;

 &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_original_response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/contextlib.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;137&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="fm"&gt;__exit__&lt;/span&gt;

 &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gen&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;throw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;typ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;traceback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/urllib3/response.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;455&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;_error_catcher&lt;/span&gt;

 &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;ProtocolError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Connection broken: &lt;/span&gt;&lt;span class="si"&gt;%r&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;urllib3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exceptions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProtocolError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Connection broken: ConnectionResetError(54, 'Connection reset by peer')"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ne"&gt;ConnectionResetError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;54&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Connection reset by peer'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;



&lt;span class="n"&gt;During&lt;/span&gt; &lt;span class="n"&gt;handling&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;above&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;another&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt; &lt;span class="n"&gt;occurred&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;



&lt;span class="n"&gt;Traceback&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/FileSource/batch_stock.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

 &lt;span class="n"&gt;auto_update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'otc_cap_reduction'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;crawl_otc_cap_reduction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/FileSource/batch_stock.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;auto_update&lt;/span&gt;

 &lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;crawl_function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/finlab/crawlers/api.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;454&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;crawl_otc_cap_reduction&lt;/span&gt;

 &lt;span class="n"&gt;res4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests_get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;urs_crawl_otc_cap_reduction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/finlab/crawlers/helper.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;363&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;requests_get&lt;/span&gt;

 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;args2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/requests/sessions.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;555&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt;

 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/requests/sessions.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;542&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;

 &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prep&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;send_kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/requests/sessions.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;697&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;send&lt;/span&gt;

 &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/requests/models.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;831&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;

 &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iter_content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CONTENT_CHUNK_SIZE&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;

 &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;"/Users/jarvis.zheng/miniforge3/envs/finlab/lib/python3.9/site-packages/requests/models.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;756&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt;

 &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;ChunkedEncodingError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exceptions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ChunkedEncodingError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Connection broken: ConnectionResetError(54, 'Connection reset by peer')"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ne"&gt;ConnectionResetError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;54&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Connection reset by peer'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr/&gt;
&lt;h2 id="_1"&gt;問題原因&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;參考：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/59851207/connectionreseterror-with-requests-module-raises-exception-inside-of-exception"&gt;帶有請求模塊的 ConnectionResetError 在異常內部引發異常，使程序崩潰&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;由參考的資訊來看，我的發生也是依序發生&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ConnectionResetError: [Errno 54] Connection reset by peer&lt;/li&gt;
&lt;li&gt;urllib3.exceptions.ProtocolError: (“Connection broken: ConnectionResetError(54, ‘Connection reset by peer’)”, ConnectionResetError(54, ‘Connection reset by peer’))&lt;/li&gt;
&lt;li&gt;requests.exceptions.ChunkedEncodingError: (“Connection broken: ConnectionResetError(54, ‘Connection reset by peer’)”, ConnectionResetError(54, ‘Connection reset by peer’))&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;由第三點的說明來看，是連線已經中斷了，而導致程式Crash，原本的程式在request的寫法&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;args2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ne"&gt;ConnectionError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ReadTimeout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;ses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;看來只有ConnectionError或Timeout才會被忽略，再新增&lt;code&gt;ConnectionResetError&lt;/code&gt; 再來觀察看看連線中斷的問題，避免程式因為斷線而Crash，在except內再重新request&lt;/p&gt;</content><category term="後端程式"></category><category term="ConnectionResetError"></category><category term="Python"></category></entry><entry><title>ASCII認識</title><link href="https://blog.richardnote.com/2021/11/ascii/" rel="alternate"></link><published>2021-11-22T18:27:00+08:00</published><updated>2021-11-22T18:27:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-11-22:/2021/11/ascii/</id><summary type="html">&lt;p&gt;程式在使用XML的序列化時發生十六進位值(0x08)是無效的字&lt;/p&gt;</summary><content type="html">
&lt;h2 id="_1"&gt;錯誤&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;發生錯誤訊息如下，程式在使用XML的序列化時發生這樣的錯誤&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;ErrorMsg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InvalidOperationException&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;產生&lt;/span&gt; &lt;span class="n"&gt;XML&lt;/span&gt; &lt;span class="err"&gt;文件時發生錯誤。&lt;/span&gt; &lt;span class="p"&gt;---&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ArgumentException&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;''&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;十六進位值&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="n"&gt;x08&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;是無效的字元。&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;查詢問題後發現文字內有特殊的符號 &lt;span class="caps"&gt;EX&lt;/span&gt; ： &lt;/p&gt;
&lt;p&gt;![[Pasted image 20211123110703.png]]&lt;/p&gt;
&lt;p&gt;測試程式有特殊符號，會Exception在&lt;code&gt;xmlSerializer.Serialize&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;public&lt;/span&gt; &lt;span class="n"&gt;ActionResult&lt;/span&gt; &lt;span class="nf"&gt;test1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;xmlData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Data&lt;/span&gt; &lt;span class="n"&gt;oData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;try&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;oData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inputText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"測試_測試測試測試測試測試"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// 序列化為XML。&lt;/span&gt;
        &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Serialization&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;XmlSerializer&lt;/span&gt; &lt;span class="n"&gt;xmlSerializer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Serialization&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;XmlSerializer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;oData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetType&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="n"&gt;XmlWriterSettings&lt;/span&gt; &lt;span class="n"&gt;xmlSettings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;XmlWriterSettings&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;xmlSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encoding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Encoding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetEncoding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Big5"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;xmlSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Indent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;xmlSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OmitXmlDeclaration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StringWriter&lt;/span&gt; &lt;span class="n"&gt;szWriter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;StringWriter&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;XmlWriter&lt;/span&gt; &lt;span class="n"&gt;xmlWriter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;XmlWriter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;szWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;xmlSettings&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;xmlSerializer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Serialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xmlWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;oData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="n"&gt;xmlData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;szWriter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xmlData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;其中的特殊符號在ASCII表轉換成 16進制的 08，是算ASCII的控制字元，無法轉換。&lt;/p&gt;
&lt;h2 id="ascii"&gt;ASCII碼表&lt;a class="headerlink" href="#ascii" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;整理一下代碼的意義：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第0～32號及第127號(共34個)是控制字元或通訊專用字元&lt;/li&gt;
&lt;li&gt;第33～126號(共94個)是字元&lt;/li&gt;
&lt;li&gt;第48～57號為0～9十個阿拉伯數字&lt;/li&gt;
&lt;li&gt;第65～90號為26個大寫英文字母&lt;/li&gt;
&lt;li&gt;第97～122號為26個小寫英文字母，其餘為一些標點符號、運算符號&lt;/li&gt;
&lt;/ul&gt;
&lt;hr/&gt;
&lt;p&gt;![[&lt;span class="caps"&gt;ASCII&lt;/span&gt;.gif]]&lt;/p&gt;
&lt;p&gt;參考資料：&lt;/p&gt;
&lt;p&gt;&lt;a href="http://kevin.hwai.edu.tw/~kevin/material/JAVA/Sample2016/ASCII.htm"&gt;ASCII碼介紹&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://idv.sinica.edu.tw/bear/charcodes/Section02.htm"&gt;認識中文字元碼&lt;/a&gt;&lt;/p&gt;</content><category term="後端程式"></category><category term="ascii"></category><category term="微軟筆記"></category></entry><entry><title>使用Bokeh產生技術圖表</title><link href="https://blog.richardnote.com/2021/11/shi-yong-bokehchan-sheng-ji-shu-tu-biao/" rel="alternate"></link><published>2021-11-03T11:05:00+08:00</published><updated>2021-11-03T11:05:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-11-03:/2021/11/shi-yong-bokehchan-sheng-ji-shu-tu-biao/</id><summary type="html">&lt;p&gt;在Django上套用Bokeh產生技術圖表&lt;/p&gt;</summary><content type="html">&lt;blockquote&gt;
&lt;p&gt;參考資料：
&lt;a href="https://www.finlab.tw/bokeh-stock-chart-with-technical-analysis/"&gt;Bokeh 探索頻道(2)~客製化技術圖表升級&lt;/a&gt;
&lt;a href="https://www.jianshu.com/p/8b4f17950777"&gt;在 Django 上使用数据可视化利器&amp;nbsp;Bokeh&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;![[bokeh指標views圖.png]]&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;參考老師的Blog文章，內附的程式碼就可以無痛升級美麗圖表，但是我架設在Django上，需要調整一下來顯示在Django頁面。&lt;/p&gt;
&lt;p&gt;在Django的View.py&amp;nbsp;上收先引用：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;bokeh.embed&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;bokeh.resources&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CDN&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;在程式加入Blog內的function來產生資料跟已經畫好的圖表，使用components，產生javascript與 html區塊，最後在render頁面帶入參數
![[bokeh指標views圖1.png]]&amp;nbsp;![[bokeh指標views圖2.png]]&lt;/p&gt;
&lt;p&gt;在Django的templates頁面上，下圖是圖表的Html的Div區塊&amp;nbsp;![[bokeh指標templates圖1.png]]&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;下圖是在&lt;code&gt;script&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt; 區塊中，先引用bokeh的js，我直接下載到我的本機，避免版本到時候又變了壞掉，最後使用bokeh產生的的javascript語法。&amp;nbsp;![[bokeh指標templates圖2.png]]&lt;/p&gt;
&lt;p&gt;就可以產生美美的圖了&amp;nbsp;![[bokeh指標總圖.png]]&lt;/p&gt;</content><category term="後端程式"></category><category term="Python"></category><category term="Bokeh"></category></entry><entry><title>MacM1執行Tensorflow錯誤問題</title><link href="https://blog.richardnote.com/2021/10/mac-tensorflow/" rel="alternate"></link><published>2021-10-28T07:50:00+08:00</published><updated>2021-10-28T07:50:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-10-28:/2021/10/mac-tensorflow/</id><summary type="html">&lt;p&gt;MacM1執行Tensorflow2.6出現錯誤&lt;/p&gt;</summary><content type="html">&lt;p&gt;每當執行如下的語法時：
&lt;code&gt;model.fit(x_train, y_train, epochs=5)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;就會出現以下錯誤：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mi"&gt;2021&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;06.945996&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;I&lt;/span&gt; &lt;span class="n"&gt;tensorflow&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;compiler&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;mlir&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;mlir_graph_optimization_pass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;185&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="n"&gt;None&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;MLIR&lt;/span&gt; &lt;span class="n"&gt;Optimization&lt;/span&gt; &lt;span class="n"&gt;Passes&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="nf"&gt;enabled&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;registered&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="mi"&gt;2021&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;06.948454&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;W&lt;/span&gt; &lt;span class="n"&gt;tensorflow&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;platform&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;profile_utils&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cpu_utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="n"&gt;Failed&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;CPU&lt;/span&gt; &lt;span class="n"&gt;frequency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;Hz&lt;/span&gt;

&lt;span class="n"&gt;Epoch&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;

&lt;span class="mi"&gt;2021&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;07.052295&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;I&lt;/span&gt; &lt;span class="n"&gt;tensorflow&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;grappler&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;optimizers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;custom_graph_optimizer_registry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;112&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="n"&gt;Plugin&lt;/span&gt; &lt;span class="n"&gt;optimizer&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;device_type&lt;/span&gt; &lt;span class="n"&gt;GPU&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="mi"&gt;2021&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;07.079&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;8109&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;118092&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-[&lt;/span&gt;&lt;span class="n"&gt;MPSGraph&lt;/span&gt; &lt;span class="n"&gt;adamUpdateWithLearningRateTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;beta1Tensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;beta2Tensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;epsilonTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;beta1PowerTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;beta2PowerTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;valuesTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;momentumTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;velocityTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;maximumVelocityTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;gradientTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;unrecognized&lt;/span&gt; &lt;span class="n"&gt;selector&lt;/span&gt; &lt;span class="n"&gt;sent&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="mh"&gt;0x29ee0f660&lt;/span&gt;

&lt;span class="mi"&gt;2021&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;07.091&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;8109&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;118092&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;***&lt;/span&gt; &lt;span class="n"&gt;Terminating&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="n"&gt;due&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;uncaught&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt; &lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="n"&gt;NSInvalidArgumentException&lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;-[&lt;/span&gt;&lt;span class="n"&gt;MPSGraph&lt;/span&gt; &lt;span class="n"&gt;adamUpdateWithLearningRateTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;beta1Tensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;beta2Tensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;epsilonTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;beta1PowerTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;beta2PowerTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;valuesTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;momentumTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;velocityTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;maximumVelocityTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;gradientTensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;unrecognized&lt;/span&gt; &lt;span class="n"&gt;selector&lt;/span&gt; &lt;span class="n"&gt;sent&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="mh"&gt;0x29ee0f660&lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;hr /&gt;
&lt;p&gt;一開始以爲是只能執行在Python 3.8的環境，但是參考教學 https://www.youtube.com/watch?v=_CO-&lt;span class="caps"&gt;ND1FTOU&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;影片中也是能夠在Python3.9使用Tensorflow2.5，使用以下語法查看版本&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;tensorflow.keras&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pandas&lt;/span&gt; &lt;span class="kn"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;pd&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sklearn&lt;/span&gt; &lt;span class="kn"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;sk&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;tensorflow&lt;/span&gt; &lt;span class="kn"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;tf&lt;/span&gt;

&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Tensor Flow Version: {tf.__version__}&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Keras Version: {tensorflow.keras.__version__}&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Python {sys.version}&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Pandas {pd.__version__}&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Scikit-Learn {sk.__version__}&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;gpu&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list_physical_devices&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;GPU&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;GPU is&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;available&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;gpu&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;NOT AVAILABLE&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Tensor Flow Version: 2.6.0
Keras Version:&amp;nbsp;2.6.0&lt;/p&gt;
&lt;p&gt;Python 3.9.6 | packaged by conda-forge | (default, Jul 11 2021, 03:35:11) 
[Clang 11.1.0 ]
Pandas 1.3.0
Scikit-Learn 0.24.2
&lt;span class="caps"&gt;GPU&lt;/span&gt; is&amp;nbsp;available&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;用另外一個環境一樣Python3.9，TensorFlow2.5就可以正確執行，看來需要降版本，只好先移除了&lt;/p&gt;
&lt;p&gt;安裝參考：
&lt;a href="https://developer.apple.com/metal/tensorflow-plugin/"&gt;tensorflow-metal PluggableDevice&amp;nbsp;入門&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://makeoptim.com/deep-learning/tensorflow-metal"&gt;&lt;span class="caps"&gt;AI&lt;/span&gt; - Apple Silicon Mac M1 原生支持 TensorFlow 2.6 &lt;span class="caps"&gt;GPU&lt;/span&gt; 加速（tensorflow-metal&amp;nbsp;PluggableDevice）&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;參考第二個連接的處理，重新安裝 Xcode&amp;nbsp;，並且重新執行安裝語法就OK了&lt;/p&gt;
&lt;p&gt;先解除安裝
&lt;code&gt;python -m pip uninstall tensorflow-macos&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;python -m pip uninstall tensorflow-metal&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;執行重新安裝
&lt;code&gt;conda install -c apple tensorflow-deps --force-reinstall&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;python -m pip install tensorflow-macos&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;python -m pip install tensorflow-metal&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;測試語法：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;tensorflow.keras&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;layers&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;tensorflow.keras&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sequential&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Conv2D&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;activation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;relu&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input_shape&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MaxPooling2D&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Conv2D&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;activation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;relu&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MaxPooling2D&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Conv2D&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;activation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;relu&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Flatten&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;activation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;relu&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;activation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;softmax&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;tensorflow.keras.datasets&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;mnist&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;tensorflow.keras.utils&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;to_categorical&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;train_images&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;train_labels&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;test_images&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test_labels&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mnist&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load_data&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;train_images&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;train_images&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reshape&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;60000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;train_images&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;train_images&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;astype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;float32&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;
&lt;span class="n"&gt;test_images&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;test_images&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reshape&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;test_images&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;test_images&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;astype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;float32&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;
&lt;span class="n"&gt;train_labels&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;to_categorical&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;train_labels&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;test_labels&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;to_categorical&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;test_labels&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;optimizer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;rmsprop&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="n"&gt;loss&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;categorical_crossentropy&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;accuracy&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;train_images&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;train_labels&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;epochs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;test_loss&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test_acc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;test_images&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test_labels&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;test_acc&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;上面處理已經完成但是會引發一個問題：&lt;/p&gt;
&lt;p&gt;numpy&amp;nbsp;會被安裝成0.19的版本，而且會造成錯誤：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nl"&gt;ValueError:&lt;/span&gt;
&lt;span class="n"&gt;numpy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ndarray&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="n"&gt;changed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;may&lt;/span&gt; &lt;span class="n"&gt;indicate&lt;/span&gt; &lt;span class="n"&gt;binary&lt;/span&gt; &lt;span class="n"&gt;incompatibility&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Expected&lt;/span&gt; &lt;span class="mi"&gt;88&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;PyObject&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;需要再更新Numpy&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;upgrade&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="後端程式"></category><category term="TensorFlow"></category><category term="Mac"></category></entry><entry><title>LineLogin串接</title><link href="https://blog.richardnote.com/2021/10/lineloginchuan-jie/" rel="alternate"></link><published>2021-10-08T08:38:00+08:00</published><updated>2021-10-08T08:38:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-10-08:/2021/10/lineloginchuan-jie/</id><summary type="html">&lt;p&gt;Django串街LineLogin &lt;span class="caps"&gt;API&lt;/span&gt;&amp;nbsp;流程簡單教學&lt;/p&gt;</summary><content type="html">&lt;p&gt;參考資料：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://jerrynest.io/django-allauth/"&gt;使用 Django Allauth 套件&lt;/a&gt;
&lt;a href="https://wreadit.com/@wwwlearncodewithmikecom/post/50134"&gt;[Django教學13]Django&amp;nbsp;Allauth套件整合Google登入驗證實作教學&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;首先安裝django-allauth&lt;/p&gt;
&lt;p&gt;&lt;code&gt;pip install django-allauth&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;在Django站臺的Settings設定相關的參數設定&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在&lt;code&gt;INSTALLED_APPS&lt;/code&gt; 裏面新增 allauth allauth.account&amp;nbsp;&amp;#8230;以下的資料&lt;/li&gt;
&lt;li&gt;新增設定&lt;code&gt;AUTHENTICATION_BACKENDS&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;新增設定&lt;code&gt;SITE_ID&lt;/code&gt; ,數值要比對Django資料表內的  django_site&amp;nbsp;的ID值&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SOCIALACCOUNT_PROVIDERS&lt;/code&gt;這是要設定讀取使用者的資料&lt;/li&gt;
&lt;li&gt;在站臺的url.py設定路徑&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;![[settings設定參數1.png]]&amp;nbsp;![[settings設定參數二.png]]&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.contrib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.urls&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;include&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.conf.urls&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;

&lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;admin/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;

    &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;accounts/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;allauth.urls&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;hr /&gt;
&lt;p&gt;以上設定完成要執行Django語法來產生資料表：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;python manage.py makemigrations&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;python manage.py migrate&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;python manage.py runserver&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;以上就是Django的設定部分，另外LineLogin的設定需要注意的細節，因爲django-allauth已經將送LineLogin授權路徑參數自動拼裝好了，裏面有些規範需要注意&lt;/p&gt;
&lt;p&gt;在送授權的部分，django-allauth定義的callbackURL已經規範，如下圖
![[djangoallauth.png]]
&lt;a href="https://django-allauth.readthedocs.io/en/latest/providers.html#line"&gt;https://django-allauth.readthedocs.io/en/latest/providers.html#line&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;上面的 Callback &lt;span class="caps"&gt;URL&lt;/span&gt; 必須與LINE Login 內的設定相同&amp;nbsp;![[lineloginapi的設定.png]]&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;另外剩下的就是要設定KEY與ClientID:&lt;/p&gt;
&lt;p&gt;去內部後臺設定LINE SecrtKEY&amp;nbsp;![[linelogin內部後臺設定.png]]&lt;/p&gt;
&lt;p&gt;回到頁面去，雖然沒有寫什麼頁面，可是 django-allauth已經內建了許多頁面可以直接查看
![[linelogin預設路徑頁面.png]]&amp;nbsp;![[linelogin預設登入畫面.png]]&lt;/p&gt;
&lt;p&gt;以上就是完成初步的串街，內容套版需要再詳細實做與修改，另外在串街流程中發生的錯誤在導向到LineLogin畫面時出現 400 錯誤：&amp;nbsp;![[linelogin400錯誤情況.png]]&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;這個問題的發生原因先查看了LineLogin的文件說明&lt;/p&gt;
&lt;h2 id="_1"&gt;要求授權&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;hr /&gt;
&lt;p&gt;為進行使用者認證，並為 app 要求權限，請透過所需的 query parameter，如下面例子所示將使用者重新導向授權 &lt;span class="caps"&gt;URL&lt;/span&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nl"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//access.line.me/oauth2/v2.1/authorize?&lt;/span&gt;
&lt;span class="n"&gt;response_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;client_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1234567890&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;redirect_uri&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mf"&gt;2F&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mf"&gt;2F&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mf"&gt;2F&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;12345&lt;/span&gt;&lt;span class="n"&gt;abcde&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;openid&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nonce&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;09876&lt;/span&gt;&lt;span class="n"&gt;xyz&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;![[linelogin串街參數.png]]&lt;/p&gt;
&lt;p&gt;&lt;a href="https://developers.line.biz/zh-hant/docs/line-login/integrate-line-login/#making-an-authorization-request"&gt;&lt;span class="caps"&gt;URL&lt;/span&gt;&amp;nbsp;的查詢屬性&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我的參數：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="k"&gt;access&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;me&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;oauth2&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;authorize&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;

&lt;span class="n"&gt;client_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;U2c2bde960c5d7723082f2b9a491f51e1&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;redirect_uri&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;linebot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;richardrobot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xyz&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;accounts&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;response_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;BBwcp2EEdqnJ&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;錯誤問題1：client_id不對
client_id ：&lt;span class="caps"&gt;LINE&lt;/span&gt; Login Channel 的 Channel &lt;span class="caps"&gt;ID&lt;/span&gt;
錯誤問題2：scope沒有值&amp;nbsp;scope：向用戶請求授予權限，也就是要求取得使用者的資料&lt;/p&gt;
&lt;p&gt;修正：
1.在admin後臺修改設定
2.在settings.py新增如下參數：&amp;nbsp;![[linelogin新增參數.png]]&lt;/p&gt;</content><category term="後端程式"></category><category term="LineLoginAPI"></category><category term="LineBot"></category><category term="Django"></category></entry><entry><title>Blog發佈到netlify</title><link href="https://blog.richardnote.com/2021/10/git-netlify/" rel="alternate"></link><published>2021-10-05T16:36:00+08:00</published><updated>2021-10-05T16:36:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-10-05:/2021/10/git-netlify/</id><summary type="html">&lt;p&gt;使用Netlify來部署Pelican的程式&lt;/p&gt;</summary><content type="html">&lt;p&gt;![[Blog發佈到netlify.png]]&lt;/p&gt;
&lt;p&gt;Netlify&amp;nbsp;基本的說明：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://blog.alantsai.net/posts/2018/07/migrate-blog-to-ssg-demo-devops-8-netlify-free-static-site-hosting-service"&gt;netlify 超佛心的靜態網站hosting服務 -&amp;nbsp;不只做hosting還有更多&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;由 [[部落格建置]] 與 [[部落格建置-套件]] 兩個篇章的設定，已經把Pelican 可以在本機做測試查看了，接下來就要建置部署在網路上，首先就是要買個網域，看來看去還是 Namecheap&amp;nbsp;最便宜，詳細買過程可以參考：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://make9.tw/wordpress/website-server/namecheap-%E7%B6%B2%E5%9D%80%E8%A8%BB%E5%86%8A%E8%B3%BC%E8%B2%B7-dns-%E8%A8%AD%E5%AE%9A%E6%95%99%E5%AD%B8-%E7%B6%B2%E5%9F%9F%E7%B6%81%E5%AE%9A%E4%B8%BB%E6%A9%9F/"&gt;Namecheap 網址註冊購買 &lt;span class="caps"&gt;DNS&lt;/span&gt; 設定教學&amp;nbsp;網域綁定主機&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;https://richardrobot.xyz  一次買兩年才 &lt;span class="caps"&gt;NT&lt;/span&gt;$ 233 ，還蠻便宜，反正只是做Blog隨手記錄&amp;nbsp;買好了網址接下來就是要把GitHub與Netlify綁定在一起參考流程如下Blog：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://michaelabrahamsen.com/posts/pelican-static-site-on-Netlify/"&gt;Pelican static site on&amp;nbsp;Netlify&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;需要注意的是，Blog文章裏面的執行語法  &lt;/p&gt;
&lt;p&gt;Build&amp;nbsp;command&lt;/p&gt;
&lt;p&gt;&lt;code&gt;pelican content -s publishconf.py&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;這個設定了反而不能，會出現錯誤，我的設定&lt;/p&gt;
&lt;p&gt;![[Netlify設定發佈建置.png]]&lt;/p&gt;
&lt;p&gt;另外需要把Netlify提供的Name Server 設定到 Namecheap&amp;nbsp;的DNS設定&lt;/p&gt;
&lt;p&gt;Netlify的設定畫面：&amp;nbsp;![[Netlify設定Domain的畫面.png]]&lt;/p&gt;
&lt;p&gt;然後對應到：&lt;span class="caps"&gt;NAMESERVERS&lt;/span&gt;&amp;nbsp;選CustomDNS&lt;/p&gt;
&lt;p&gt;![[Namecheap設定的畫面.png]]&lt;/p&gt;</content><category term="後端程式"></category><category term="Namecheap"></category><category term="Netlify"></category><category term="Git"></category><category term="Pelican"></category></entry><entry><title>Pelican說明Metadata</title><link href="https://blog.richardnote.com/2021/09/pelican-metadata/" rel="alternate"></link><published>2021-09-30T14:21:00+08:00</published><updated>2021-09-30T14:21:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-09-30:/2021/09/pelican-metadata/</id><summary type="html">&lt;p&gt;整理一個表格來方便查看Pelican的Metadata&lt;/p&gt;</summary><content type="html">&lt;hr /&gt;
&lt;p&gt;![[2021-10-01_PM4.46.58.png]]&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;您還可以在模板中使用自己的元數據鍵（只要它們不與保留的元數據關鍵字衝突）。下表包含保留的元數據關鍵字列表：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align="center"&gt;Metadata&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align="center"&gt;title&lt;/td&gt;
&lt;td&gt;Title of the article or page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;date&lt;/td&gt;
&lt;td&gt;Publication date (e.g., &lt;span class="caps"&gt;YYYY&lt;/span&gt;-&lt;span class="caps"&gt;MM&lt;/span&gt;-&lt;span class="caps"&gt;DD&lt;/span&gt; &lt;span class="caps"&gt;HH&lt;/span&gt;:&lt;span class="caps"&gt;SS&lt;/span&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;modified&lt;/td&gt;
&lt;td&gt;Modification date (e.g., &lt;span class="caps"&gt;YYYY&lt;/span&gt;-&lt;span class="caps"&gt;MM&lt;/span&gt;-&lt;span class="caps"&gt;DD&lt;/span&gt; &lt;span class="caps"&gt;HH&lt;/span&gt;:&lt;span class="caps"&gt;SS&lt;/span&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;tags&lt;/td&gt;
&lt;td&gt;Content tags, separated by commas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;keywords&lt;/td&gt;
&lt;td&gt;Content keywords, separated by commas (&lt;span class="caps"&gt;HTML&lt;/span&gt; content only)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;category&lt;/td&gt;
&lt;td&gt;Content category (one only — not multiple)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;slug&lt;/td&gt;
&lt;td&gt;Identifier used in URLs and translations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;author&lt;/td&gt;
&lt;td&gt;Content author, when there is only one&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;authors&lt;/td&gt;
&lt;td&gt;Content authors, when there are multiple&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;summary&lt;/td&gt;
&lt;td&gt;Brief description of content for index pages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;lang&lt;/td&gt;
&lt;td&gt;Content language &lt;span class="caps"&gt;ID&lt;/span&gt; (en, fr, etc.)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;translation&lt;/td&gt;
&lt;td&gt;If content is a translation of another (true or false)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;status&lt;/td&gt;
&lt;td&gt;Content status: draft, hidden, or published&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;template&lt;/td&gt;
&lt;td&gt;Name of template to use to generate content (without extension)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;save_as&lt;/td&gt;
&lt;td&gt;Save content to this relative file path&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="center"&gt;url&lt;/td&gt;
&lt;td&gt;&lt;span class="caps"&gt;URL&lt;/span&gt; to use for this article/page&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</content><category term="後端程式"></category><category term="Pelican"></category><category term="Python"></category></entry><entry><title>部落格建置-套件</title><link href="https://blog.richardnote.com/2021/09/pelican-plugins/" rel="alternate"></link><published>2021-09-29T15:50:00+08:00</published><updated>2021-09-29T15:50:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-09-29:/2021/09/pelican-plugins/</id><summary type="html">&lt;p&gt;要使用Pelican的外掛套件，目前套件的來源有兩種&lt;/p&gt;</summary><content type="html">&lt;p&gt;要使用Pelican的外掛套件，目前套件的來源有兩種：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在命名空間之下的Git，&lt;a href="https://github.com/pelican-plugins"&gt;新版pelican-plugins&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;舊版的套件集合的Git，&lt;a href="https://github.com/getpelican/pelican-plugins"&gt;舊版pelican-plugins&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;導入套件的方式有兩種：&amp;nbsp;如果您的插件不在可導入路徑中，您可以通過PLUGIN_PATHS設置指定路徑列表。如以下示例所示，PLUGIN_PATHS列表中的路徑可以是相對於設置文件的絕對路徑或相對路徑：&lt;/p&gt;
&lt;p&gt;![[Pasted image&amp;nbsp;20210929155953.png]]&lt;/p&gt;
&lt;p&gt;若是沒有依照設定的套件名稱放置程式會出現錯誤訊息：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Pelican&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;jarvis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;zheng&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="nx"&gt;zhengruichangdeMac&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;mini&lt;/span&gt; &lt;span class="nx"&gt;Pelican&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;pelican&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;
&lt;span class="nx"&gt;WARNING&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="nx"&gt;usage&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;CATEGORY_FEED_ATOM&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;deprecated&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;use&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;instead&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nx"&gt;ERROR&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Cannot&lt;/span&gt; &lt;span class="nx"&gt;load&lt;/span&gt; &lt;span class="nx"&gt;plugin&lt;/span&gt; &lt;span class="sb"&gt;`related_posts`&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Cannot&lt;/span&gt; &lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;plugin&lt;/span&gt; &lt;span class="sb"&gt;`related_posts`&lt;/span&gt;
&lt;span class="nx"&gt;Done&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Processed&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="nx"&gt;articles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="nx"&gt;drafts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="nx"&gt;pages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="nx"&gt;hidden&lt;/span&gt; &lt;span class="nx"&gt;pages&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="nx"&gt;draft&lt;/span&gt; &lt;span class="nx"&gt;pages&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mf"&gt;0.20&lt;/span&gt; &lt;span class="nx"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h3 id="_1"&gt;總結&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;套件的使用，在命名空間下的，要執行安裝語法，會直接搜尋環境下的套件程式，若是用舊版的，要去舊版git&amp;nbsp;去clone下來，並且對照名稱放程式資料夾在/pelican-plugins&lt;/p&gt;
&lt;/blockquote&gt;</content><category term="後端程式"></category><category term="Pelican"></category><category term="Python"></category></entry><entry><title>部落格建置</title><link href="https://blog.richardnote.com/2021/09/pelican/" rel="alternate"></link><published>2021-09-28T17:44:00+08:00</published><updated>2021-09-28T17:44:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-09-28:/2021/09/pelican/</id><summary type="html">&lt;p&gt;用Pelican套件建置部落格在GitHub Pages&amp;nbsp;上，首先需要安裝Pelican的環境&lt;/p&gt;</summary><content type="html">&lt;h4 id="pelicangithub-pages-pelican"&gt;用Pelican套件建置部落格在GitHub Pages 上，首先需要安裝Pelican的環境&lt;a class="headerlink" href="#pelicangithub-pages-pelican" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;建立python的虛擬環境
&lt;code&gt;conda create -n Pelican&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;啓動虛擬環境
&lt;code&gt;conda activate Pelican&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="caps"&gt;CD&lt;/span&gt;&amp;nbsp;到新開的資料夾，&lt;/p&gt;
&lt;p&gt;當初已經在GitHub上建立好了Repository，所以就在本機建立資料夾然後Clone，在Pelican資料夾下，需要安裝pelican的相關套件，需要創建一個requirements.txt文件&lt;/p&gt;
&lt;p&gt;&lt;code&gt;touch requirements.txt&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;接下來安裝所有套件：
&lt;code&gt;pip install -r requirements.txt&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;若是還沒建立好預設開始環境需要執行以下語法，Pelican會建立基本的程式與資料夾，若是執行以下語法會需要回答一些預設環境的設定值
&lt;code&gt;pelican-quickstart&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;資料夾架構如下
![[Pasted image 20210929144934.png]]&amp;nbsp;每個文件的用途：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;content/ -&amp;nbsp;存儲所有網站內容的目錄&lt;/li&gt;
&lt;li&gt;task.py -&amp;nbsp;幫助我們自動化網站生成和發布的腳本&lt;/li&gt;
&lt;li&gt;output/ - 存儲生成的靜態網站的 &lt;span class="caps"&gt;HTML&lt;/span&gt;&amp;nbsp;文件的目錄&lt;/li&gt;
&lt;li&gt;pelicanconf.py -&amp;nbsp;包含網站所有配置的文件&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="_1"&gt;生成網站&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;此語法會在 output/ 目錄產生所有html 的頁面
&lt;code&gt;pelican content&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;此語法會產生一個臨時的站臺 127.0.0.1:8000 可以預覽頁面
&lt;code&gt;pelican --listen&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;查看外掛套件清單：
&lt;code&gt;pelican-plugins&lt;/code&gt;&lt;/p&gt;</content><category term="後端程式"></category><category term="Pelican"></category><category term="Python"></category></entry><entry><title>Obsidian 使用 Git 跨平台同步</title><link href="https://blog.richardnote.com/2021/09/git-obsidian/" rel="alternate"></link><published>2021-09-16T17:55:00+08:00</published><updated>2021-09-16T17:55:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2021-09-16:/2021/09/git-obsidian/</id><summary type="html">&lt;p&gt;使用Obsidian搭配Git達成可以跨越系統的同步&lt;/p&gt;</summary><content type="html">&lt;p&gt;第一步&amp;nbsp;先在Windows本機的建立一個資料夾，是拿來開啟Obsidian的Vault&lt;/p&gt;
&lt;p&gt;![[Pasted image 20210914152609.png]]
像上面的資料路徑我新開了一個 ObsidianNote資料夾，然後Obisdian設定這個資料夾就會有一些設定檔
![[Pasted image&amp;nbsp;20210914152831.png]]&lt;/p&gt;
&lt;p&gt;第二步&amp;nbsp;在GitHub建立一個repository，然後取名同樣的名稱ObsidianNote&lt;/p&gt;
&lt;p&gt;第三步
開啟CMD&amp;nbsp;然後CD至剛剛的資料夾，接下來就是執行GitHub上面的初始化語法&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git init&lt;/code&gt;
&lt;code&gt;git commit -m "first commit"&lt;/code&gt;
&lt;code&gt;git remote add origin https://github.com/TernenceZheng/ObsidianNote.git&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;![[Pasted image&amp;nbsp;20210914153508.png]]&lt;/p&gt;
&lt;p&gt;第四步
安裝第三方外掛套件 Obsidian Git
![[Pasted image&amp;nbsp;20210914161351.png]]&lt;/p&gt;
&lt;p&gt;安裝及啟用後，左方將出現 Obsidian Git&amp;nbsp;的設定，我有以下的建議：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;將 Vault 備份時間改為 5 分鐘 (Backup Interval:&amp;nbsp;5)&lt;/li&gt;
&lt;li&gt;每次打開軟件也從 Github Pull 所有的變更 (Pull updates on startup: &lt;span class="caps"&gt;ON&lt;/span&gt;)&lt;/li&gt;
&lt;li&gt;Commit Message 增加電腦名稱以便識別 (Commit message:&amp;nbsp;開首加電腦名稱）&lt;/li&gt;
&lt;li&gt;以及最重要的關掉 Disable Push（Disable Push: &lt;span class="caps"&gt;OFF&lt;/span&gt;)，才會自動把所有 Commit 推送到 Github&amp;nbsp;上，讓其他裝置可以同步。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;參考鏈接：&lt;a href="https://notes.desktopofsamuel.com/posts/Obsidian%E4%B8%8A%E6%89%8B%E5%8F%8A%E4%BD%BF%E7%94%A8Git%E8%B7%A8%E5%B9%B3%E5%8F%B0%E5%90%8C%E6%AD%A5/"&gt;Obsidian上手及使用Git跨平台同步&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;另外的手機版本同步參考：&lt;a href="https://forum.obsidian.md/t/mobile-setting-up-ios-git-based-syncing-with-mobile-app-using-working-copy/16499"&gt;[移動] 設置 iOS 與移動應用程序基於 git&amp;nbsp;的同步（使用工作副本）&lt;/a&gt;&lt;/p&gt;</content><category term="後端程式"></category><category term="Obsidian"></category><category term="Git"></category></entry><entry><title>使用VSCode遠端SSH開發</title><link href="https://blog.richardnote.com/2020/08/VisualStudioCode-GCP/" rel="alternate"></link><published>2020-08-25T18:22:00+08:00</published><updated>2020-08-25T18:22:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2020-08-25:/2020/08/VisualStudioCode-GCP/</id><summary type="html">&lt;p&gt;使用VSCode遠端開發，透過Remote-&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/p&gt;</summary><content type="html">
&lt;h2 id="ssh-key"&gt;產生SSH &lt;span class="caps"&gt;KEY&lt;/span&gt;&lt;a class="headerlink" href="#ssh-key" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;開啟 Terminal 執行以下語法，可以看到路徑預設在 &lt;code&gt;/Users/你的名稱/.ssh&lt;/code&gt; 下&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;ssh-keygen&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;如下圖，要求輸入名稱或是直接按Enter產生預設名稱id_rsa，我輸入jarvis.zheng-GithHub&lt;/p&gt;
&lt;p&gt;![[ssh-key產生.jpg]]&lt;/p&gt;
&lt;p&gt;在Mac 下使用快捷鍵來查看隱藏資料夾： &lt;code&gt;Command + Shift +  .&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;公鑰 (jarvis.zheng-GithHub.pub) 以及私鑰 (jarvis.zheng-GithHub)， 公鑰到時候要複製到GCP上，而私鑰則是自己用，雙方才能夠溝通。&lt;/p&gt;
&lt;p&gt;![[產生的公鑰與私鑰.jpg]]&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;如下圖，是GCP的Compute Engine 上面設定公鑰的地方&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;![[在GCP上面把公鑰複製上去.jpg]]&lt;/p&gt;
&lt;p&gt;如下圖在VSCode安裝外掛套件，Remote Development&lt;/p&gt;
&lt;p&gt;![[VSCode安裝RemoteDevelopment.jpg]]&lt;/p&gt;
&lt;p&gt;安裝完成後，在 VSCode介面的左下角可以看到圖標，按下去顯示清單，選擇Connect to Host，輸入要連線的伺服器，格式 username@server_host&lt;/p&gt;
&lt;p&gt;就是GCP上面的： 使用者名稱@外部IP&lt;/p&gt;
&lt;p&gt;![[在VScode安裝並且連線GCP的外部IP.jpg]]&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;番外篇：
&lt;span class="caps"&gt;SSH&lt;/span&gt; Key產生的時候權限問題 ，無法儲存檔案問題，&lt;/p&gt;
&lt;p&gt;完美解決： https://stackoverflow.com/questions/51614552/google-cloud-platform-ssh-to-google-cloud-instance-will-have-permission-denied&lt;/p&gt;
&lt;p&gt;參考資料：&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.wowfuncode.com/2020/07/14/vscode-using-remote-ssh/"&gt;&lt;span class="caps"&gt;VS&lt;/span&gt; Code 使用 Remote – &lt;span class="caps"&gt;SSH&lt;/span&gt; 開啟遠端 Linux 資料夾&lt;/a&gt;&lt;/p&gt;</content><category term="後端程式"></category><category term="VisualStudioCode"></category><category term="GoogleCloudPlatform"></category></entry><entry><title>VS 常用內建快速鍵</title><link href="https://blog.richardnote.com/2016/03/VisualStudio/" rel="alternate"></link><published>2016-03-08T12:43:00+08:00</published><updated>2021-11-18T16:32:00+08:00</updated><author><name>Richard</name></author><id>tag:blog.richardnote.com,2016-03-08:/2016/03/VisualStudio/</id><summary type="html">&lt;p&gt;&lt;span class="caps"&gt;VS&lt;/span&gt;&amp;nbsp;常用內建快速鍵&lt;/p&gt;</summary><content type="html">
&lt;hr/&gt;
&lt;p&gt;![[Pasted image 20210917172329.png]]&lt;/p&gt;
&lt;h2 id="_1"&gt;環境&lt;a class="headerlink" href="#_1" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="_2"&gt;環境設定的組合快捷鍵&lt;a class="headerlink" href="#_2" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;hr/&gt;
&lt;p&gt;程式碼編輯器分頁切換 ：Ctrl+&lt;span class="caps"&gt;TAB&lt;/span&gt; 
存檔：Ctrl + S 
執行(debug)：F5
==執行(non debug)==：&lt;code&gt;Ctrl + F5&lt;/code&gt;
全部儲存：Ctrl + Shift + S 
 單步執行：F11 (F10) 
切換斷點：F9 
==啟用/停用斷點==：&lt;code&gt;Ctrl + F9&lt;/code&gt;
==刪除所有斷點==：&lt;code&gt;Ctrl + Shift + F9&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="_3"&gt;編輯&lt;a class="headerlink" href="#_3" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="_4"&gt;編輯程式時的組合快捷鍵&lt;a class="headerlink" href="#_4" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;hr/&gt;
&lt;p&gt;==註解選取範圍==：&lt;code&gt;Ctrl+K,C&lt;/code&gt; 
==取消註解選取範圍==：&lt;code&gt;Ctrl+K,U&lt;/code&gt;
 ==自動縮排==：&lt;code&gt;選取範圍後，Alt + F8&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;選取文字改小寫：Ctrl + U 
選取文字改大寫：Ctrl + Shift + U 
==呼叫出類別成員==：&lt;code&gt;Ctrl + J&lt;/code&gt;
(編到一半時 tips 突然不見很好用) &lt;/p&gt;
&lt;p&gt;收攏原始碼：Ctrl + M, O 
展開原始碼：Ctrl + M, L 
==刪除目前這行==：&lt;code&gt;Ctrl + Shift + L&lt;/code&gt;
轉至定義： F12 
檔案最前面：Shift + Home 
檔案最後面：Shift + End 
==選到最前面==：Ctrl + Shift + Home 
==選到最後面==：Ctrl + Shift + End 
檢查括號匹配：Ctrl + ] 
跳至行號：Ctrl + G &lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="visualstudiocode"&gt;VisualStudioCode&lt;a class="headerlink" href="#visualstudiocode" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="vscode"&gt;VSCode環境的編輯快捷鍵&lt;a class="headerlink" href="#vscode" title="Permanent link"&gt;¶&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Code Formatting Shortcut:&lt;/p&gt;
&lt;p&gt;以下的設定在 &lt;span class="caps"&gt;VS2019&lt;/span&gt; 的設定是 ： &lt;code&gt;Ctrl + K  + D&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Visual Studio Code on Windows ： &lt;code&gt;Shift + Alt + F&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Visual Studio Code on MacOS : &lt;code&gt;Shift + Option + F&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Visual Studio Code on Ubuntu : &lt;code&gt;Ctrl + Shift + I&lt;/code&gt;&lt;/p&gt;</content><category term="後端程式"></category><category term="VisualStudio"></category><category term="微軟筆記"></category></entry></feed>