OmniAICreator/Qiita-1.07M huggingface dataset:
【MSTest】Assert.ThrowsExceptionを使用した例外のテスト

※ 個人blogに投稿した記事（投稿日：2020/3/29）をQiitaに移行しました

# 前置き

「[ドメイン駆動設計入門 ボトムアップでわかる! ドメイン駆動設計の基本](https://www.amazon.co.jp/dp/B082WXZVPC)」のサンプルコード内で、  以下のようなテストコードを見かけました。  

https://github.com/nrslib/itddd/blob/master/Layered/SnsApplication.Tests/Users/UserRegisterTest.cs#L52

```cs
[TestMethod]
public void TestInvalidUserNameLengthMin()
{
    var userFactory = new InMemoryUserFactory();
    var userRepository = new InMemoryUserRepository();
    var userService = new UserService(userRepository);
    var userApplicationService = new UserApplicationService(userFactory, userRepository, userService);
    bool exceptionOccured = false;
    try
    {
        var command = new UserRegisterCommand("12");
        userApplicationService.Register(command);
    }
    catch
    {
        exceptionOccured = true;
    }
    Assert.IsTrue(exceptionOccured);
}
```

`UserRegisterCommand`内でユーザー名が3文字以上で無い場合`ArgumentException`が発生することを検証するテストコードです。
上記のコードでは、例外が発生する箇所をtry〜catchで補足し検証する形式とされています。

# MSTestで例外をテストする（ExpectedExceptionAttribute）

前述のテストコードを見たときに、MSTestで例外をアサーションする場合、`ExpectedExceptionAttribute`を使用するパターンも考えられるのではと感じました。

```cs
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void TestInvalidUserNameLengthMin_old()
{
    var userFactory = new InMemoryUserFactory();
    var userRepository = new InMemoryUserRepository();
    var userService = new UserService(userRepository);
    var userApplicationService = new UserApplicationService(userFactory, userRepository, userService);
    var command = new UserRegisterCommand("12");
    userApplicationService.Register(command);
}
```

# MSTestで例外をテストする（Assert.ThrowsException）

最新のMSTestのバージョンでは`Assert.ThrowsException`を使うのが良いようです。

https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.testtools.unittesting.assert.throwsexception?view=mstest-net-1.2.0

```cs
[TestMethod]
public void TestInvalidUserNameLengthMin()
{
   var userFactory = new InMemoryUserFactory();
   var userRepository = new InMemoryUserRepository();
   var userService = new UserService(userRepository);
   var userApplicationService = new UserApplicationService(userFactory, userRepository, userService);
   var ex = Assert.ThrowsException<ArgumentException>(() => 
        {
            var command = new UserRegisterCommand("12");
            userApplicationService.Register(command);
        }
    );
    Assert.AreEqual("ユーザ名は3文字以上です。 (Parameter 'value')", ex.Message);
}
```

アノテーションよりも`Assert.ThrowsException`の方が、例外が発生する箇所も明確になるし、発生したexceptionを更に検証できるのも良いですね。
`Assert.ThrowsException`はVS2017の時代にリリースされた「MSTest v2」で追加された機能のようです。
そもそもMSTest v2の存在自体把握できていませんでした・・・

https://devblogs.microsoft.com/devops/upgrade-to-mstest-v2
クラスのメモリ管理

Swiftはクラスのメモリ管理にARCという方式を採用しています。

ARCでは、インスタンスが初めて生成された時に参照カウントが1になり、以降そのインスタンスへの参照が増えると参照カウントがインクリメントされ、減るとデクリメントされます。そして、参照カウントが0になると、インスタンスも自動的に破棄されます。

# デイニシャライザ

```
class クラス名 {
    deinit {
        クリーンアップなどの終了処理
    }
}
```

ARCによってインスタンスが破棄されるタイミングで、クラスのデイニシャライザが実行されます。
初期化は一番最初に呼ばれるイメージですが、デイニシャライザはメモリがすべて開放された後の一番最後に呼ばれるというイメージです。なので、デイニシャライザの中にはクリーンアップなどの終了処理を実装します。

# 値の比較と参照の比較

```
class SomeClass: Equatable {
    static func ==(lhs: SomeClass, rhs: SomeClass) -> Bool {
        return true
    }
}

let a = SomeClass()
let b = SomeClass()
let c = a

// 値は同じ
a == b // true

// 参照先は別
a === b　// false

// aとcの参照先は同じ
a === c // true
```

参照先の値の比較と、参照先の比較は別になります。
値比較は==, 参照先比較は===を使用します。
【Flutter/Dart】RangeError (index): Invalid value: Valid value range is empty: 0 のエラーの解決方法

Flutterでアプリを開発中、Widget周りでよく出てきたエラーだったので、解決方法をメモとして残させて頂きます。

###エラー内容

List.builderでWidgetを開発中に下記のエラーが出現....

```Flutter
RangeError (index): Invalid value: Valid value range is empty: 0
```

###解決方法

下記のように、```itemCount```の値を指定することで上記エラーは解消できます。
（エラーが出た時点はitemCountのプロパティの値を指定していませんでした。）

```Flutter
ListView.builder(
            itemCount: items.length,
            itemBuilder: (ctx, index) {
              return ExampleWidget();
            });

```

###参考

https://api.flutter.dev/flutter/widgets/ListView-class.html
【Azure Cognitive Services】Speech Serviceのニューラル音声を使って、日本語テキスト読み上げをしてみた

# ニューラル音声とは
ディープニューラルネットワークを使用して、話し言葉のアクセントとイントネーションに関する従来の音声合成の限界を克服します。韻律予測と音声合成が同時に行われるため、より滑らかで自然な音声出力が得られます。ニューラル音声を使用すると、チャットボットや音声アシスタントとの対話をより自然で魅力的なものにすることができます。

> [ 引用 ] https://docs.microsoft.com/ja-jp/azure/cognitive-services/speech-service/text-to-speech#core-features

# はじめに
この記事では、**日本語で女性のニューラル音声であるNanamiがテキストを読み上げてくれます。**
以下のMicrosoftドキュメントを参考に作成してみました。

- [テキスト読み上げの概要](https://docs.microsoft.com/ja-jp/azure/cognitive-services/speech-service/get-started-text-to-speech?tabs=script%2Cwindowsinstall&pivots=programming-language-csharp)

Cognitive Servicesのリソースを作成する際に、リージョン選択に注意してください。
かなり重要なことですが、**ニューラル音声を使用できるリージョンが限られています**。この記事を日本人が見る場合が多いと思うので、おそらく東日本もしくは西日本のリージョンを選択すると思いますが、なんとニューラル音声がサポートされていません！！！
ニューラル音声がサポートされているリージョンに関してはMSドキュメントで確認してください。
私は**米国東部**のリージョンを選択して、リソースを作成しています。

# 前提・環境
- Windows 10 home
- visual studio 2019
- Azure portal上でCognitive Servicesのリソース作成済み
    - キーを取得できる。
    - 場所を取得できる。
- NuGetパッケージ
    - Microsoft.CognitiveServices.Speech v1.16.0


# ソースコード

```cs
using Microsoft.CognitiveServices.Speech;
using System.Threading.Tasks;

namespace AzureCognitiveServicesAPI
{
    class Program
    {
        static string subscriptionKey = "YourSubscriptionKey";
        static string serviceRegion = "YourServiceRegion";

        static async Task Main(string[] args)
        {
            var config = SpeechConfig.FromSubscription(subscriptionKey, serviceRegion);
            var synthesizer = new SpeechSynthesizer(config);
            var text = "こんにちは";
            await synthesizer.SpeakSsmlAsync(CreateTextReadOut(text));
        }

        static string CreateTextReadOut(string text)
        {
            return $"<speak version='1.0' xmlns='https://www.w3.org/2001/10/synthesis' xml:lang='ja-JP'><voice name='ja-JP-NanamiNeural'>{text}</voice></speak>";
        }
    }
}

```
フィールド変数のsubscriptionKeyとserviceRegionに前提で取得しておいたキーと場所に書き換えてください。
実行すると、”こんにちは”とNanamiが話してくれるかと思います。

以上です。ありがとうございました。
Git For Windowsでメッセージ「Warning: 'C:\ProgramData/Git/config' has a dubious owner: 'XXXXX'.」が表示された

※ 個人blogに投稿した記事（投稿日：2019/10/10）をQiitaに移行しました

# 背景

現場で新しいPC（離任された方が使用していたPCを引き継ぎ）に変更になったので、Git For Windows をインストールした。 
Git For Windowsのバージョンは「2.23.0」。

# 現象
 
Gitコマンドを実行したところ、以下のようなエラーメッセージが表示された。  
  
```
Warning: 'C:\ProgramData/Git/config' has a dubious owner: '(XXXXX)'.
For security reasons, it is therefore ignored.
To fix this, please transfer ownership to an admininstrator.
```
  
自分の場合、「XXXXX」がこのPCを前に使用していた方のユーザーアカウントだった。
現場のポリシーとして、PCの使用者を変更する場合は、クリーンインストールせず引き継ぎ。
よって、今回 Git For Windows は前任者の方がインストールしていた状態だったところに上書きインストールしたような形になった。  

# 解決策

メッセージの指示通り、「C:\ProgramData/Git/config」のプロパティから所有者を変更しようとしたが上手く行かず、
configファイルを自作して「C:\ProgramData/Git/config」に配置した。  

# 参考

[stackloverflow - Latest Update brings Github error on pull, push, or sync](https://stackoverflow.com/questions/57592530/latest-update-brings-github-error-on-pull-push-or-sync)
【C# / ASP.NET WebForm】HttpRequestBase を継承しMock クラスを作成し、HttpRequest をテストする

※ 個人blogに投稿した記事（投稿日：2019/10/21）をQiitaに移行しました

# 前置き

現場の案件で、外部APIやDB接続が絡んだ少々複雑な判定でCookie を作成するという処理を実装することになり、
対象の処理でユニットテストを作成しておきたくなりました。

Cookie の作成や、作成した値を検証するには当然ですが`HttpRequest`や`HttpResponse`のインスタンスが必要ですが、
これらのクラスのインスタンスをユニットテストで生成するのは困難（ほぼ不可能のはず）です。  
  
そこで、ASP.NET では`HttpRequestWrapper`というクラスが実装されています。
`HttpRequestWrapper`は`HttpRequestBase`という抽象クラスから派生されています。  
`HttpRequestBase`は`HttpRequest`と同じプロパティ、関数を保有したクラスです。
対象となる処理の実装では`HttpRequestBase`を使用し、
`HttpRequestWrapper`で`HttpRequest`をラップしたインスタンスを使用することにします。
これらは`HttpResponse`でも同様です。

文章だとややこしいので、サンプルコードを実装してみました。  

## Controller(HttpRequestBase, HttpResponseBaseを使用する処理)
```cs
public class IndexController
    {
        public IndexController()
        {

        }

        public void createCookie(HttpRequestBase request, HttpResponseBase response)
        {
            if (request.QueryString == null)
            {
                throw new ArgumentNullException();
            }
            string value = request.QueryString["hoge"];

            var cookie = new HttpCookie("hoge");
            cookie.Value = "hoge" + value;
            response.Cookies.Add(cookie);
        }

    }
```

## aspx.cs
```cs
 public partial class Index : System.Web.UI.Page
    {
        private readonly IndexController  _controller = new IndexController();

        protected void Page_Load(object sender, EventArgs e)
        {
            _controller.createCookie(new HttpRequestWrapper(Request),
                                                     new HttpResponseWrapper(Response));
        }
    }
```

そして、ユニットテストコードでは以下のように`HttpRequestBase`から派生したMockクラスを作成し、
テストで必要となるプロパティや関数をOverrideして実装します。  

## Mockクラス
```cs
 public class HttpRequestMock : HttpRequestBase
        {
            private readonly NameValueCollection _queryString;
            public HttpRequestMock(NameValueCollection queryString)
            {
                _queryString = queryString;
            }

            public override NameValueCollection QueryString => _queryString;
        }

        public class HttpResponseMock : HttpResponseBase
        {
            private readonly HttpCookieCollection _cookies = new HttpCookieCollection();
            public override HttpCookieCollection Cookies => _cookies;
        }
```

## テストコード
```cs
[TestMethod]
        public void createCookieNormalCase()
        {
            // Arrange
            var requestMock = new HttpRequestMock(new NameValueCollection() { { "hoge", "12345" } });
            var responseMock = new HttpResponseMock();
            var sut = new IndexController();

            // Act
            sut.createCookie(requestMock, responseMock);

            // Assert
            Assert.AreEqual("hoge12345", responseMock.Cookies["hoge"].Value);
        }
```

## サンプルコード

今回の記事で作成した[サンプルコード](https://github.com/devshima/AspDotNetHttpRequestMocking)をGitHubにアップしました。
YellowfinでJWTを使ってSSOする

#Json Web TokenでのSSOログイン
先日のYellowfin9.5アップデートでJWTでのログインが可能となったそうなので試しにやってみました。
といっても[wiki](https://wiki.yellowfin.co.jp/pages/viewpage.action?pageId=17956865 "Yellowfin wiki")を見たらすぐできたのでそこまで難しくはなかったです。自サービスからJWTを作成すること自体はhttps://jwt.io/ にあるライブラリを使ったり、参考にさせていただいた[こちらの記事](https://qiita.com/Naoto9282/items/8427918564400968bd2b "【JWT】 入門")をご覧ください。


#使用するための設定
[wiki](https://wiki.yellowfin.co.jp/pages/viewpage.action?pageId=17956865 "Yellowfin wiki")に記載のある通り、管理→システム構成→認証→認証方法からJWTシングルサインオンのトグルを有効にします。
その後JWT Configurationから設定していきます。今回はURL ParameterにTokenを追加する方式を試します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223443/67fdc284-a348-6a7b-ced5-b9160c124ced.png)
せめてものセキュリティとして「JWT Validation Key」に「yellowfin」を入力して更新、必要最低限な「JWT User Id Attribute」にプロパティ名として「UserId」を入力して保存します。

#Tokenを使ってログインしてみる
https://jwt.io/ のフォームから今回設定したバリデーションキーをシグネチャーに設定し、ペイロードにUserIdとして初期ユーザーのユーザーIDを設定するとEncodedの部分にHeader、Payload、VerifySignatureそれぞれを暗号化したものがドットで繋がれて生成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223443/efad1e98-db97-0cae-ad9f-1007ed824c79.png)
ブラウザからYellowfinのログインページの後ろに「JWTLogin.i4?jwtToken=」のパラメーターを追加して、その後にEncodedにあった文字列をつなげます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223443/edc6c9b1-5a27-fb20-27b6-0160edaf03f0.png)
そのまま移動するとログイン後のページに遷移することができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223443/3feda26f-1d2f-a16a-25a1-6334f786e20b.png)

#所感
発行されたトークン自体を使ってログインするのはとても簡単ですが、JWTの発行部分を実装するほうが力がいりそうです。とはいえライブラリがあったりするのでそこまで大変ではなさそうですね。このJWTを使って新規ユーザーも作成できるそうなのですが、それは画面でやればいいんじゃ・・と思いつつ一斉にユーザー作成して用意するためには有効なのかなと。使い方によるのかな。
実際に結構ガチガチにするならJWTをCookieに保存させるのが一番ぽい気がします。また、ここでは触れてないですが、ログイン後に何を表示させるかといったことも[設定できる](https://wiki.yellowfin.co.jp/pages/viewpage.action?pageId=2294155 "ログインセッションオプションの定義")ようですので実装する際には参考にしたいです。
【Azure】「az webapp up」コマンドでエラー「The scale operation is not allowed for this subscription in this region.  Try selecting different region or scale option.」

※ 個人blogに投稿した記事（投稿日：2019/10/21）をQiitaに移行しました

Microsoft Leanの以下の演習内で引っかかった箇所があったのでメモ。

[演習 - ASP.NET アプリケーションを Azure SQL Database に接続する](https://docs.microsoft.com/ja-jp/learn/modules/develop-app-that-queries-azure-sql/5-exercise-connect-aspnet-to-azure-sql)

AppService内に.NET Coreアプリをデプロイするコマンド

``` 
az webapp up \
    --resource-group Learn-XXXX-XXXX-... \
    --sku F1 \
    --name $WEBAPPNAME
```

上記を実行すると、以下のエラーが発生。

```
The scale operation is not allowed for this subscription in this region. 
Try selecting different region or scale option.
```

どうも、デフォルトで設定されているリージョンではデプロイできない権限設定になっているようだったので、
` --location`オプションで許可されていそうなリージョンを設定してみてコマンド実行。

``` 
az webapp up \
    --resource-group Learn-XXXX-XXXX-... \
    --sku F1 \
    --name $WEBAPPNAME \
    --location eastus
```

無事デプロイされました。
[Rails]Formオブジェクト内でuniquenessを使用してエラーが発生した件

# はじめに
初めてパターンのエラーと本日遭遇したため記録のため記述します。
正しいかどうか大変不安ですので、間違い等ご指摘を下さると幸いです

#エラー内容
Formオブジェクト内でこんな感じにバリデーションを記述していたところ、エラーが発生しました。

```ruby

  with_options presence: true do
    validates :title,length:{maximum:25}
    validates :content
    validates :name,uniqueness:true
  end
```

![スクリーンショット 2021-04-30 12.41.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1128031/66078598-91e2-1941-8fa1-26fc84753a14.png)

# 原因
結論から言えば、uniquenessはFormオブジェクト内では使用できないからです。
Formオブジェクトはつい勘違いしてしまいますが、モデルとは違い直接モデルを触れることができないものです。ゆえに、以下のようにモジュールを読み込んでいます。

```ruby
class PracticesPtag
  include ActiveModel::Model
  #省略
```

# 解消方法
私の場合は、正しいかわかりませんが、uniquenessのみ直接モデルに書いてやることでエラーを解消させました。

#終わりに
正直。まだ腑に落ちない部分もあるため、より詳しい説明ができる方はコメントにて教えてくださると大喜びです！！！！
２段階初期化


クラスのイニシャライザには、型の整合性を保った初期化を実現するために、３つのルールがあります。

・指定イニシャライザはスーパークラスの指定イニシャライザを呼ぶ
・コンビニエンスイニシャライザは同一クラスのイニシャライザを呼ぶ
・コンビニエンスイニシャライザは最終的に指定イニシャライザを呼ぶ

スーパークラスとサブクラスのプロパティの初期化順序を守るため、指定イニシャライザによるクラスの初期化は次の２段階に分けて行われます。
１、クラス内で新たに定義されたすべてのストアドプロパティを初期化し、スーパークラスの指定イニシャライザを実行する。スーパークラスでも同様の初期化を行い、大元のクラスまで遡る。
２、ストアドプロパティ以外の初期化を行う

```
class User {
    let id: Int
    
    init(id: Int) {
        self.id = id
    }
    
    func printProfile() {
        print("id: \(id)")
    }
}

class RegisteredUser: User {
    let name: String
    
    init(id: Int, name: String) {
        // 第一段階
        self.name = name
        super.init(id: id)
        
        // 第二段階
        self.printProfile()
    }
}
```
【VB.Net】「区分オブジェクト」のようなクラスを作れないか試行錯誤

※ 個人blogに投稿した記事（投稿日：2019/10/10）をQiitaに移行しました

前回の[「区分オブジェクト」に関する投稿](https://qiita.com/shimamura_io/items/8dcfaa1462ac1e0c6332)に引き続いて関連した投稿を。
列挙型の区分ごとにプロパティを持たせる事ができないかなと思い、
実装してみたのが以下のような抽象クラスと具象クラスを使う形式。

``` vb
Public MustInherit Class Perfume

    Public ReadOnly Property myFavorite As Boolean
    Sub New(myFavorite As Boolean)
        Me.myFavorite = myFavorite
    End Sub

    Public Class Nocchi
        Inherits Perfume

        Sub New(myFavorite As Boolean)
            MyBase.New(myFavorite)
        End Sub

    End Class

    Public Class Kashiyuka
        Inherits Perfume

        Sub New(myFavorite As Boolean)
            MyBase.New(myFavorite)
        End Sub

    End Class

    Public Class AaChan
        Inherits Perfume

        Sub New(myFavorite As Boolean)
            MyBase.New(myFavorite)
        End Sub

    End Class

End Class
```

クラス名からインスタンスを生成するには`Activator.CreateInstance`、
区分の判定は`GetType`で列挙型と同様に行えます。

``` vb
Module Module1

    Sub Main()

        Dim myPerfume = createMyFavoriteMember("Nocchi")

        Select Case myPerfume.GetType()
            Case GetType(Perfume.Nocchi)
                ' ...
            Case GetType(Perfume.Kashiyuka)
                ' ...
            Case GetType(Perfume.AaChan)
                ' ...
        End Select
    End Sub

    Private Function createMyFavoriteMember(memberName As String) As Perfume
        Return CType(Activator.CreateInstance(
                                    Type.GetType("Enumeration.Perfume+" & memberName),
                                    New Object() {True}), Perfume)
    End Function
End Module
```

実行すると以下のようになります。

![20191010231631.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23789/3332c644-dda8-4974-d912-31bcd8379303.png)

うーん・・・具象クラスのコンストラクタを全部書く必要があるのと、  
`Activator.CreateInstance`でType名をセットする部分があまりイケてない感じがする・・・
プログラミング言語論：１．導入

### プログラミング言語論：導入

すべてのプログラミング言語は
* 精巧なシンタクス（構文： syntax）
* そのシンタクスの働き （意味：semantics)
* 使いやすい便利なライブラリ
* その言語ならではの慣例（例えば `'pythonic'`）
でできている。

本ページではプログラミング言語の仕組みと構造について掘り下げて解説する。

### 算術式の定義
次のように定義された算術式 (arithmetic expression) について考えてみよう。（BNF記法を使う）

```
Expr ::= Num  
       | '(' Expr '+' Expr ')'
       | '(' Expr '-' Expr ')'
```

`Expr`は整数リテラル、または括弧で囲まれた算術式の和や差を意味する。ほかの四則演算も同じように定義できるがコードが長くなるので省略する。

次は同じ定義をScalaで書いたコード。

```scala
sealed trait Expr
case class Num(n: Int) extends Expr
case class Sum(left: Expr, right: Expr) extends Expr
case class Sub(left: Expr, right: Expr) extends Expr
```

### 算術式の値を求めよう
演算式の値を求めるには式の定義だけでは不十分。まだ式の計算方法を定義してないのでそれも考えておこう。
式を計算した結果を`big-step semantics`で書いたら

```math
\frac{}{n \implies n}
```

```math
\frac{e_1 \implies n_1 \quad e_2 \implies n_2 \quad \bigotimes \in \{+, -\}}{(e_1 \bigotimes e_2) \implies n_1 \bigotimes n_2}
```

式の値を求める関数`interp`を`Scala`で作成すると:

```scala
def interp(e: Expr): Int = e match {
  case Num(n) => n
  case Sum(left, right) => interp(left) + interp(right)
  case Sub(left, right) => interp(left) - interp(right)
}
```
これで簡単な式は計算できるようになった。(`parser`による`parse tree`の作成は後で）

```scala
println(interp(Sum(Num(1), Num(2))))  // 3
```
VB.NETでJavaの「列挙型クラス」を模倣して「区分オブジェクト」を作る

※ 個人blogに投稿した記事（投稿日：2019/9/27）をQiitaに移行しました

[現場で役立つシステム設計の原則 〜変更を楽で安全にするオブジェクト指向の実践技法](https://www.amazon.co.jp/dp/B073GSDBGT)、読了しました。
Amazonのレビュー見ると結構賛否両論のようですが、
オブジェクト指向設計、ドメイン駆動設計の基礎固めとして最適では、と自分は感じました。

「CHAPTER2 場合分けのロジックを整理する > Javaの列挙型を使えばもっとかんたん」を読んで、
おお、JavaはEnumの値ごとにコンストラクタを付与したりできるのか・・・便利・・・
と恥ずかしながら初めて知りました。

.NETでも似たようなことをできないなかな、と探したら以下のようなMS公式リファレンスがありました。 
  
[enum 型の代わりに Enumeration クラスを使用する](https://docs.microsoft.com/ja-jp/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/enumeration-classes-over-enum-types)
  
上記と書籍のサンプルコードを真似してVB.NETで書いてみたのが以下のコードになります。
（書籍ではYen クラスを ValueObject 化していたのを端折って Integer にしてます）

## 本体
```vb
Public Interface Fee
    Function yen() As Integer
    Function label() As String
End Interface

Public Class AdultFee
    Implements Fee

    Public Function yen() As Integer Implements Fee.yen
        Return 100
    End Function

    Public Function label() As String Implements Fee.label
        Return "大人"
    End Function
End Class

Public Class ChildFee
    Implements Fee

    Public Function yen() As Integer Implements Fee.yen
        Return 50
    End Function

    Public Function label() As String Implements Fee.label
        Return "子供"
    End Function
End Class

Public MustInherit Class Enumeration
    Public Shared Function valueOf(Of T)(typeName As String) As T
        Return CType(GetType(T).GetField(typeName, Reflection.BindingFlags.Public Or Reflection.BindingFlags.Static Or Reflection.BindingFlags.DeclaredOnly).GetValue(Nothing), T)
    End Function
End Class

Public Class FeeType
    Inherits Enumeration

    Public Shared Adult As New FeeType(New AdultFee)
    Public Shared Child As New FeeType(New ChildFee)

    Private ReadOnly fee As Fee

    Sub New(fee As Fee)
        Me.fee = fee
    End Sub

    Public Function yen() As Integer
        Return fee.yen
    End Function

    Public Function label() As String
        Return fee.label
    End Function

End Class
```

## クライアント側

```vb
Module Module1

    Sub Main()

        Dim feeForAdult = feeFor("Adult")
        Dim feeForChild = feeFor("Child")

    End Sub

    Public Function feeFor(feeTypeName As String) As Integer
        Dim theFeeType = FeeType.valueOf(Of FeeType)(feeTypeName)
        Return theFeeType.yen
    End Function

End Module
```

実行してみましょう。

![20190927230703.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23789/ead4abd6-983e-f370-7df4-f4d43e9414f5.png)



値取れてますね。  
良い感じですが、リフレクションで変数名を指定するのはちょっと怖いです。以上。
【Jenkins】Warnings Next Generationプラグイン

# 前置き

個人blogに投稿した記事（投稿日：2019/6/14）をQiitaに移行しました。
当時、udemy で Jenkins についてのセミナーを受講していて、その中で得た Tips を投稿しました。


# 今回の話題

udemy のコース内で設定したCheckstyleとFindBugsのプラグインは、現在Deprecated=非推奨になっておりました。  

![20190614055303.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23789/2c0d7a9e-cc43-9228-9648-2a04faa44731.png)


調べたところ、現在は「[Warnings Next Generationプラグイン](https://github.com/jenkinsci/warnings-ng-plugin/blob/master/doc/Documentation.md)」を使用するのが良いようです。
  
# 導入手順
## 1.インストール
「Jenkinsの管理 > プラグインの管理 > 利用可能」から、「Warnings Next Generation Plugin」を探してインストールします。

## 2. 設定
「プロジェクト > 設定 > ビルド後の処理の追加」から  
「Record compiler warnings and static analysis results」を選択します。
追加された設定欄のToolで「Checkstyle」と「FindBugs」を選択し、保存します。

![20190614060058.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23789/4eba991b-6a6a-8f78-b261-22a4d58c5781.png)

![20190614060120.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23789/f6faeb2c-ed04-8763-37f8-67e783a2b2e2.png)

## 3. 結果の確認
ビルドが完了すると、プロジェクトページに  

* CheckStyle Warnings
* FindBugs Warnings

のリンクが表示されるようになります。
  
  
右下には　　

* CheckStyle Warnings Trend
* FindBugs Warnings Trend
* Aggregated Analysis Results

のグラフが表示されるようになります。

![20190614060547.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23789/d5c99196-f0a2-0681-bb38-508a1dd92f75.png)


↓CheckStyle Warningsの画面
![20190614060754.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23789/d29fad7f-1de8-caa0-fc21-f9be554cd0fc.png)


↓FindBugs Warningsの画面。バグの詳細も確認できています。
![20190614060850.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23789/85e2c38d-0d24-202d-c7d6-24a533027491.png)

  
以上、「Warnings Next Generationプラグイン」についてでした。
ゴールデンウィークだし、Dockerはじめてみない？

ゴールデンウィークこそおうちに籠って新しいことをはじめるチャンス！！
...ということで、今回は手っ取り早くDockerに触れてみる記事を書いてみたいと思います。

#Docker(どっかー🐳)ってなに？
→ **コンテナ型の仮想化技術**を用いて、**アプリケーションを開発・実行**するためのソフトウェアのこと。
VirtualBoxとかに比べて、リソースの使用率が低く、効率的にリソースをつかうことができます。

また、「VMをいちいち作ってOSをインストールしてNginxとか入れて...」とかいう面倒くさい作業が**コマンド一発**ぐらいで済むようにもなるので、いろいろめちゃくちゃ楽になります。

#よし、やってみよ！
だいたいコピペだけで動かせます。
##必要なもの
- CentOSが動くマシン
**インターネットに接続できて、sudoがつかえることが前提です。**
(仮想マシンでもいいですし、余ったノートパソコンでもいいですし、なんならEC2とかAzureVMでもいいです。
今回は CentOS 7 2009を使用していますが、CentOS 8でもDebianでも動きます。)

- Linuxのコマンド(yumとか)が一応できる知識 (ほとんどyumしか使わない)
- やってみよ！っていう気力

##手順
1. CentOSが操作できるようにします。
teratermでもなんでもいいです。

1. つぎのコマンドをコピペして、すでにDockerがインストールされてないことを確認します。

```
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
```
「そんなパッケージないよ」的なメッセージが出れば大丈夫です。

3.リポジトリを設定します。

```
sudo yum install -y yum-utils
```

```
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
```

```
sudo yum update
```

4.Docker本体をインストールします。

```
sudo yum install docker-ce docker-ce-cli containerd.io
```

途中でなんたらかんたら？って聞かれたら、とりあえず y と入力してEnterキーを押しておきましょう。
**これだけでDockerがインストールできちゃいました！**

5.Dockerを起動します。

```
sudo systemctl start docker
```
エラーが出たらもっかい1.からやり直してみよう。

6.最後におまじない(Dockerを一般ユーザでも動かせるように)しておきましょう

```
sudo usermod -aG docker $USER
```
おわり！

#とりあえずHello Worldしてみよ！
なんと便利なことに、DockerにはHello Worldを表示するだけのコンテナが用意されてます！
まずはこれをやってみましょう。

```
docker container run hello-world
```

上のコマンドをコピペして実行すれば、「Hello from Docker! なんちゃらかんちゃら！」っていう風に文章が表示されます。 

ここまでできれば、あなたもDocker使いのなかまいり！

この後は、他の方のとってもわかりやすい記事をご覧になったり、検索してみたり、本を買ってみたりしてみてくださいね！
(ちなみに私は「[たった1日で基本が身に付く! Docker/Kubernetes超入門](https://www.amazon.co.jp/%E3%81%9F%E3%81%A3%E3%81%9F1%E6%97%A5%E3%81%A7%E5%9F%BA%E6%9C%AC%E3%81%8C%E8%BA%AB%E3%81%AB%E4%BB%98%E3%81%8F-Docker-Kubernetes%E8%B6%85%E5%85%A5%E9%96%80-%E4%BC%8A%E8%97%A4-%E8%A3%95%E4%B8%80/dp/4297114283)」っていう本をみてDockerにハマりました。)

---
以上になります。
よいDockerライフを！
finalキーワード

オーバーライド可能な要素の前にfinalキーワードを記述することで、その要素がサブクラスでオーバーライドされることを禁止できます。

```
class SuperClass {
    func overridableMethod() {}
    
    final func finalMethod() {}
}

class SubClass: SuperClass {
    override func overridableMethod() {}
    
    // オーバーライド不可能なためエラー
    override func finalMethod() {}
}
```

クラス自体にfinalキーワードを付与することで、そのクラスを継承したクラスを定義することを禁止することができます。

```
class Class1 {}

class class1: Class1 {}

final class FinalClass {}

// 継承不可能なためコンパイルエラー
class class2: FinalClass {}
```
PHP class useのasについて

#名前空間のuseのasについて検証した。

名前空間についての基礎はこちら
[class 基本　名前空間](https://qiita.com/H-Toshi/items/afa21bf3f1533d262ec5)

##執筆のきっかけ
cakephpを触っているとよく

```php
namespace App\Model\Entity;

use Cake\ORM\Entity;

class hoge()
{
}
```
といった内容を見かけます。

あれ、useってasで別名（エイリアス）つけるんじゃ、、、

そう思って調べてみました。

##useのasは省略出来る
以下の記事にまとまっていました
参考：https://remotestance.com/blog/3064/

##そもそも名前空間とは
たくさんのファイルがあって、同名のクラスが重複されて使用されている場合、```requier```などで別ファイルを読み取ってクラスを使用した時に、クラス名が重複する場合がある。
そういった時に名前空間を使用すればクラスを呼び出す際に重複を防げる

##実際のコードで見てみる（それぞれのコードは同一のルート上にある装丁です）
**例1)**
[use.php]

```php
<?php 
namespace person\think\like1;
class like
{
    public function music(){
        echo 'bz'."\n";
    }
}
```

[use2.php]

```php
<?php 
namespace person\think\like2;
class like
{
    public function music(){
        echo 'Tokio'."\n";
    }
}
```

[use3.php]

```php
<?php 
require_once 'use.php';
require_once 'use2.php';
use person\think\like1; //use person\think\like1 as like1;と同じ意味
use person\think\like2; //use person\think\like1 as like2;と同じ意味

$like1 = new like1\like();
$like1->music(); //bz

$like2 = new like2\like();
$like2->music(); //Tokio
```

上記の例はuse.php, use2.phpでそれぞれ同名のクラスlikeを定義している。
use3.phpでそれぞれのファイルを読み込んだ後、クラスlikeを呼び出している。
上記例でもし```namespace```の記述がuse.php, use2.phpでなければ、use3.phpで呼び出した際に「エラーが出る or echoの結果が表示されない」となる。

##useのasについて
use3.phpのようにクラスを呼び出して使用したいファイルではuseを使用することで、クラスを呼び出す際の記述を簡潔に書ける。
asを使用することで呼び出すと時の名前を自由に設定できる。

例えば上記例ではasを使用していませんが

**例2)**
[use3.php]

```php
use person\think\like1 as bz;
use person\think\like2 as Tokio;

$like1 = new bz\like();
$like1->music(); //bz

$like2 = new Tokio\like();
$like2->music(); //Tokio
```
のように使用出来ます。

##結局as使うのと使わないのって何が違うの？
上記までの説明を踏まえると
asはuseを使用する際に自由に名前（エイリアス）をつける時に使用するが、特に必要がなければasを書かず
以下の例1のように
**例1抜粋**

```php
use person\think\like1; 
use person\think\like2; 

$like1 = new like1\like();
$like1->music(); //bz

$like2 = new like2\like();
$like2->music(); //Tokio
```
**like1**, **like2**を例２のように**bz**や**Tokio**という名前の代わりにそのまま使用出来るのでより簡潔に書けます。

##まとめ
asを使用するしないはどちらでも良いと思いますが、asは省略出来るということを押さえておくとフレームワークを使用する際に理解が進むと思います。
【Jenkins初期設定】Gmailへのメール送信で「javax.mail.AuthenticationFailedException」が発生

※ 個人blogに投稿した記事（投稿日：2019/6/7）をQiitaに移行しました

[前回の投稿](https://qiita.com/shimamura_io/items/8d1e82ffcd696bdc74eb)でJenkinsのコンテナは起動でき、初期設定を進めています。  
    
「Jenkinsの管理 > システムの設定 > トークンリファレンス > E-mail通知」にて、
Gmailのアカウントを設定してメール送信を確認するのですが、以下のエラーが発生。　　

```
javax.mail.AuthenticationFailedException: 535-5.7.8 Username and Password not accepted. Learn more at
535 5.7.8  https://support.google.com/mail/?p=BadCredentials 104sm807qtc.36 - gsmtp
```
  
この原因はエラー内のURLを確認すればすぐに解ることなのですが、
Googleアカウントがデフォルトでは不正なアプリからのログインを許可していないためです。  
  
[安全性の低いアプリと Google アカウント](https://support.google.com/accounts/answer/6010255)
  
アカウントの設定で「安全性の低いアプリのアクセス」をONにすると前述のエラーは発生せず、
Jenkinからのメールが受信できるようになります。 
当然セキュリティ上非推奨の設定なので、あくまで一時的に許可するのがよいでしょう。
Practical Malware Analysis Lab3 writeup

# Lab 3-1

## Q1: 静的解析
importをpestudioでみてみると、ExitProccessしか無いのでパッキングされてるかと思い、PEiDで確認すると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535664/50541103-6fa1-689c-bf4d-700f65f9f4a3.png)
PEncrypt 3.1 みたいなパッカーでパッキングされてる。
ただstringはそんなに暗号化されていなく、以下のようにアクセスしそうなドメインやレジストリパスが書いてある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535664/b9d53571-562f-4c24-1fe1-0c43266d7a9f.png)

## Q2: host-basedシグネチャ (動的解析)
まずマルウェア実行前の設定をする。
はじめに、procmonのフィルタでLab03-01.exeプロセスだけ監視するようフィルタリングする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535664/a4d49a61-2610-e03f-4da0-f5d35d959ee0.png)
次に、Regshotの1st shotを取っておく(1-2分ぐらいかかる)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535664/aa632fc7-4be1-6a6a-0678-7feb91850baf.png)
最後に、ProcessExplorer(procexp)を起動しておき、マルウェアを実行する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535664/efecb64d-3f0f-88e8-7204-81a5254a27f8.png)
そうすると、上記のようにprocmonにも色々現れるが、procexpには何もでない...
とりあえずregshotで2nd shotをして保存してみたあと、procmonから解析してみる。マルウェアが何を変更したかだけみれば、その変更内容をシグネチャにできるので、RegSetValue/WriteFileだけにOperationを絞ってみるが、解説とは違って自分の方にはこれが起きていなかった。
よく考えるとこれWinXP用の実行ファイルで自分はWin10使ってるのでそもそも実行がうまく行ってない...
とりあえず手法だけ理解できたので次行く。

## Q3: network-basedシグネチャ (動的解析)
FlareVMについてるFakenet-NGを起動(powershellでfakenetコマンド打つ)すれば、Wireshark/InetSim/ApateDNSの全機能使ってくれるらしいが、まぁWinXP用の実行ファイルなのでやっても結果得られない...


<br/>


# Lab 3-2
WinXPなので実行できないが、とりあえずDLLの扱い方だけ。

## Q1: マルウェアをサービスとしてインストールする
まず、どんな関数をExportしてるのかをpestudioで見る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535664/16e838bb-e3ad-b077-30e6-cff4290acdf8.png)
いかにもなInstallがあるので、rundll32.exeを使ってインストールしてみる。

```
rundll32.exe Lab03-02.dll, Install
```

procexp/procmonを使って実行すると `HKLM\SYSTEM\CurrentControlSet\Services\IPRIP` が見えるらしく、これがサービス名だとわかるので、

```
rundll32.exe Lab03-02.dll, installA IPRIP
net start IPRIP
```

とすればいいが、環境が違うのでできない。
LaravelでAjaxを実装する場合のリンク集

## はじめに

LaravelでAjaxを実装する際に、良いチュートリアルが存在せず、
Laravel内での解決方法もあまりなかったので、実装方法を別途探りました。

結論から言うと、Laravel内ではView/BladeでAjax用の機能を提供していないので、
jQuery等のJavaScriptのライブラリを組み込んでAjax部分は別途実装する必要あります。

その時に調べた情報のリンク集としてまとめました。
コードとかは気が向いたら、別途記事にする予定です。

## 参考
* [Laravel7 ajaxでviewを返す方法](https://halfpower.work/2020/12/12/laravel7-ajax%E3%81%A7view%E3%82%92%E8%BF%94%E3%81%99%E6%96%B9%E6%B3%95/)
* [【Laravel5】FormRequestのバリデーション結果をJSON APIで返す](https://qiita.com/junsan50/items/ec7f810decd3b82d3d76)
* [完全な手順！LaravelでAjaxコンテンツをつくる方法](https://blog.capilano-fw.com/?p=261)
* [【Laravel】LaravelでAjax（jQuery）を使用する](https://pointsandlines.jp/server-side/php/laravel-ajax)
* [Laravel、Ajaxを用いて動的なコメント閲覧画面の作成](https://www.merges.co.jp/archives/1980)
* [LaravelでAjaxを使う方法。サーバにPOSTしてResponseを返す](https://mintaku-blog.net/laravel-ajax/)
子画面への遷移が遅いので手動スクリプトで解決した件

#はじめに
forma-designerで作成した申請画面から、別ウインドウで開く子画面を表示する際のロード時間が非常に長かったので、手動で解決した話です。

#画面の構成について
forma-designerで作成した画面をIM_Workflowと連携させ、申請画面として表示しました。
画面は4つあり、初期に表示される大きい画面(親画面)と明細を入力する小さい画面(子画面)が3つあり、親画面上にある3つのボタンを押下すると対応したそれぞれの子画面を別ウインドウで表示するようになっています。

#発生した事象と状況
・バージョンは2018Summer
・明細入力画面を押下し、別ウインドウが開くが画面がすべて表示されるまでに10～12秒かかった。
・親→子に遷移するボタンはforma-designer標準アイテム(*1)の「ボタン（次へ）」を使用。
・子→親に遷移するボタンはforma-designer標準アイテム(*1)の「ボタン（戻る）」を使用。
・発生した問題の解消を試みるために子画面のアイテム数を減らしたものの、改善せず。

#原因
・現在でもわかっていません。
・親画面への返却用として使用している「ボタン（戻る）」を削除すると速度が大幅に改善された(3秒くらい)ため、これが原因？

#解決方法
遷移するボタンアイテムを「ボタン（戻る）」から「ボタン（イベント）」に変更しました。親画面に明細で入力した内容を反映させる必要があるため、
intra-mart社が公開しているクライアントサイドスクリプトAPI(*2)を使用し
以下のように実装しました。

```javascript:イベントボタンJS、データ取得部

// 明細テーブルの値を取得
var rowId = "";
var inputIdList = [];
inputIdList[0] = "colomn_nm1";
inputIdList[1] = "colomn_nm2";
inputIdList[2] = "colomn_nm3";
inputIdList[3] = "colomn_nm4";
inputIdList[4] = "colomn_nm5";
inputIdList[5] = "colomn_nm6";

// データを取得
var result = formaItems.product_80_table.getItemData.table_nm(rowId,inputIdList);
```
上記で取得したデータを以下で子画面の明細テーブル(hidden属性)にコピーします。

```javascript:イベントボタンJS、データ送信部
var args = {};
args.data = {};
var option = {};

for(var i=0;i<result.length;i++){
    args.data.column1[i] = result[i].column1;
    args.data.column2[i] = result[i].column2;
    args.data.column3[i] = result[i].column3;
    args.data.column4[i] = result[i].column4;
    args.data.column5[i] = result[i].column5;
    args.data.column6[i] = result[i].column6;
}
// 親画面の明細テーブルにデータをセット
window.opener.formaItems.product_80_table.getItemData.table_nm(args,option);

// 子画面のウインドウを閉じる
window.open("","_self").close();
```
#結果
この実装により、10～12秒もかかった子画面表示のロードが3秒ほどまでに短縮できた。

#参考
*1・・・forma-designer標準アイテム
forma-designerの画面で使用することができる、アイテムの一覧です。

https://document.intra-mart.jp/library/forma/public/forma_designer_help/item_help/app_item_list.html

*2・・・クライアントサイドスクリプトAPI
「ボタン（イベント）」やアクション設定等でformaアイテムのデータの送受信を行うなどの用途で使用可能なスクリプトが紹介されています。

https://document.intra-mart.jp/library/bis/public/bis_specification/texts/spec/csjs_script.html
オンラインで参加者のリアクションを集めるツールをGitpodで使えるようにしてみた

# はじめに

ハンズオンの時に参加者の反応を見るため、<a href="https://twitter.com/1ft_seabass">@1ft_seabass</a> さん作、オンラインで参加者のリアクションを集めるツールをGitpodで使えるようにしてみました。
GitpodはWorkspaceを作成する度にURLが変わりますので、TERMINALにアクセス先URLをQRコードで表示して、スマートフォンなどからアクセスしやすく改良しました。

https://gitpod.io/#https://github.com/kitazaki/nodered-online-reaction-app

![gitpod.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/5fb3823f-adf6-0754-2958-38c61585fefc.jpeg)

# オリジナルのツール

オリジナルのツールは<a href="https://enebular.com">enebular</a>のサービスを利用しています。

https://blog.enebular.com/samples/online-reaction-01/

https://blog.enebular.com/samples/online-reaction-02/

enebularは利用時間の制限(1時間)がありますので、長めのハンズオンの時は途中でカウンタがリセットされてしまうため、不便な場合があります。また、起動する度にHerokuのURLが変わるため、アクセス先URLをQRコードへ変換する手間が必要でした。

# Gitpodへの移植

enebularからNode-REDのフローをダウンロードします。ダウンロードしたフローはGithubのレポジトリへ保存(登録)します。

https://github.com/kitazaki/nodered-online-reaction-app/blob/main/flow.json

Gitpodの設定は.gitpod.ymlファイルで行います。設定方法はGitpodのドキュメントを参照します。

https://www.gitpod.io/docs/configuration

# .gitpod.ymlファイルの作成

ドキュメントに記載されているサンプルを参考にして、tasksとportsを設定します。

```yaml:.gitpod.yml
# Command to start on workspace startup (optional)
tasks:
#  - init: "npm install -g npm"
  - command: "cd && npm install -g --unsafe-perm node-red node-red-dashboard && mkdir .node-red && ln -s /workspace/nodered-online-reaction-app/flow.json ./.node-red/ && node-red flow.json"
    name: Node-RED
  - openMode: split-right
    command: "cd && npm install -g qrcode-terminal && echo $GITPOD_WORKSPACE_URL | awk -F// '{print $1 \"//1880-\" $2 \"/ui\"}' | qrcode-terminal"
    name: QR Code
# Ports to expose on workspace startup (optional)
ports:
  - port: 1880
    onOpen: open-preview
```

https://github.com/kitazaki/nodered-online-reaction-app/blob/main/.gitpod.yml

## tasks

TERMINALを2つに分けて、Node-REDのインストール・起動とQRコードの表示を並列で実行します。

### Node-REDのインストール・起動

オンラインで参加者のリアクションを集めるツールはnode-red-dashboardノードを使用しているため、Node-REDと合わせてnode-red-dashboardモジュールのインストールを行います。

https://github.com/node-red/node-red-dashboard

flow.jsonを所定の(ホームディレクトリ配下の.node-red)ディレクトリへ配置して、Node-REDを起動します。

### QRコードの表示

TERMINAL(コンソール)画面にQRコードを表示するツールはqrcode-terminalを使用しました。

https://github.com/gtanner/qrcode-terminal

## ports

Node-REDはポート番号:1880で起動しますので、portに1880を指定します。また、フローをプレビュー表示するため、onOpenにopen-previewを指定します。


# さいごに

ハンズオンの時は準備で忙しいので、少しでも手間が減ると助かります。
みなさまも良き Gitpod & Node-RED ライフを！
tailscale + mqttでリモート間ファイル共有

![diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/8b1de6bd-974e-13c2-5f5a-464fab086f19.png)


# 問題

リモート端末がある場合、ダイナミックDNSやらVPNやら色々設定した挙げ句、リモートとローカルのIPセグメントが同じだと（例: 192.168.0.xxx）IPがぶつかって通信できないとか、色々面倒。

プログラム的にファイルを共有するにも`scp`だとなんだし、手っ取り早くdropboxでやり取りしていた。ヘッドレスなlinux側なので`otherguy/dropbox`を使ってみたが、意外とCPUを常時食う。

## リモート端末への接続解決

VPNだと色々な呪縛から逃れられないので、[tailscale][1]に変える。
リモート側はRPiだったので、直接[ダウンロードに書いてある][2]ようにそのまま入れた。

ローカル側はdocker上に構成しているので、`network_mode: host`でも良いが、mosquittoをローカルでも使ってるし、mqttポートをデフォルトのままで使いたかったのでdocker上にtailscaleを置いて、そこにつなぐmosquittoブローカーを置いて、リモートからのデータを受けるようにしてみた。

[richnorth/tailscale][3]をまんまコピー。

```yml:docker-compose.yml

  tailscale:
    image: richnorth/tailscale:v0.99.1
    volumes:
      - "./tailscale/tailscale_var_lib:/var/lib" # State data will be stored in this directory
      - "/dev/net/tun:/dev/net/tun" # Required for tailscale to work
    cap_add: # Required for tailscale to work
      - net_admin
      - sys_module
    command: tailscaled

```

```sh
$ docker-compose up -d
$ docker-compose exec tailscale tailscale up
```

とするとリンクが表示されるので、ログインしてこのコンテナがtailscaleのプライベートネットワークに入るようにする。volumeで`/var/lib`へマウントしてるので永続化出来る。


## dropboxからmqttへ

RPi側では[Dropbox-Uploader][4]を使ってプログラム的にdropboxへファイルを送っていたが、これを止めてmqttでデータを送るようにした。

- 画像データはbase64に一回変えて文字として
- それ以外はJSONにして

本来はローカルにmqttブローカーを建てずに[shiftr.io][5]を使って視覚化をしたかったが、publish出来るデータサイズが64KBに制限されているので諦めた（画像が300KBぐらいある）。

> Enforced Limits
The client identifier length is limited to 64 characters.
The topic length is limited to 128 characters.
The topic format is limited to letters, numbers and the following special characters: .,:;-_$/+#.
The payload size of publish messages is limited to 64 KB.
The active subscriptions per connection are limited to 100.
The minimum keep alive interval is 1 second while the maximum is 5 minutes.


```yml:docker-compose.yml
  mosquitto:
    image: eclipse-mosquitto
    restart: always
    volumes:
      - ./mosquitto/config:/mosquitto/config
      - ./mosquitto/data:/mosquitto/data
      - ./mosquitto/log:/mosquitto/log
    user: "1000:1000"
    network_mode: service:tailscale
```

`network_mode: service:tailscale`としてやることでtailscaleネットワーク上で動作することになり、リモートからtailscale内のプライベートIPで1883ポートにデータが流せる。


![diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/13117f77-7122-938c-89ca-7deebfb69ccb.png)

## 解決したこと

- OpenVPNを除去
- ダイナミックDNSを除去
- dropboxを除去
- `otherguy/dropbox`を除去することによりCPU使用率低下（15％程度削減）
- listen gem除去

以前まではdropboxでファイルがsyncした際に[listen][6]で反応させていたが、mqttでメッセージを受け取ることをイベントと出来るので、全体がよりシンプルになった。（以前だと何にしてもファイルに落とし込んで、dropboxで同期させる必要があった）

[1]: https://tailscale.com/
[2]: https://tailscale.com/download/linux/raspbian-buster
[3]: https://rnorth.org/tailscale-docker/
[4]: https://github.com/andreafabrizi/Dropbox-Uploader
[5]: https://www.shiftr.io/docs/broker/mqtt-interface
[6]: https://github.com/guard/listen
オーバーライド

```
class クラス名: スーパークラス名 {
    override func メソッド名(引数) -> 戻り値の型 {
        メソッド呼び出し時に実行される文
    }
    
    override var プロパティ名: 型名 {
        get {
            return文によって値を返す処理
            superキーワードでスーパークラスの実装を利用できる
        }
        
        set {
            値を更新する処理
            superキーワードでスーパークラスの実装を利用できる
        }
    }
}
```

オーバーライドとは、スーパークラスで定義されているプロパティやメソッドなどの要素は、サブクラスで再定義することができること。

```
class User {
    let id: Int
    
    var message: String {
        return "Hello."
    }
    
    init(id: Int) {
        self.id = id
    }
    
    func printProfile() {
        print("id: \(id)")
        print("message: \(message)")
    }
}

class RegisteredUser: User {
    let name: String
    
    override var message: String {
        return "Hello, my name is \(name)"
    }
    
    init(id: Int, name: String) {
        self.name = name
        super.init(id: id)
    }
    
    override func printProfile() {
        super.printProfile()
        print("name: \(name)")
    }
}

let user = User(id: 1)
user.printProfile()

print("---")

let registeredUser = RegisteredUser(id: 2, name: "Yusei Nishiyama")
registeredUser.printProfile()




// 出力
id: 1
message: Hello.
---
id: 2
message: Hello, my name is Yusei Nishiyama
name: Yusei Nishiyama

```
開発する上で大事なこと

# 開発する上で大事なこと

commandや何らかの処理をする直前にどんな出力なのかを確認する。
実際に叩かれたcommandと実際にCLI上で入力されたコマンドが何かを確認する。
処理がどこまで進行しているのかをpythonでいうprint文を入れて実行することで進み具合がわかる。

これをすると関数に引数が引き渡されたかどうか、IF文に投げ込まれたかどうかがわかる。
一つ一つの処理を見る


一段一段のぼっていくことを確認していく。
すっ飛ばしていいくことはやめたほうが良い。

コーディングする上で大事なこと。
機能は誰が見てもわかるようにする。

コーディング力を上げるには
・実用的な何かを作る
・他人が実行することも想定した機能を作る
実用的な要素、エラー処理、テスト手法、が詰まっている
・参考コードに新しく機能を追加してコミットする
・コーディング力をつけるにはコードをかくのはもちろんエラーが出るパターンを覚えて打ち込みかたを磨いていく
・０から書く力は趣味としては必要になりますがお仕事にするときはサンプルコードなり誰かが意図をもってかきあげたコードを参考に別の機能を追加するならどう書くかを探りながら書き込んでいくとシステムの新しい形を把握しながら力が付けられる



コーディング現場でのレビュー内容
・インデントの統一(スペースなのかタブなのか)
・空白の統一(１つなのか２つなのか)
・変数の名前の付け方
・モジュール名の名前の付け方
# コーディングでの学び
・極力処理は簡単・簡素に
・コードは簡単な方が可読性も上がる
・PT・検証・Poc検証での作業を楽にするためにコードは簡単に短く書くことが重要
→バグを生む原因を作らない。
→テストでの検証項目が少なくなる。
・なるべくfor文やif文などのロジックは入れない方がいい。
→バグを少なくするため
・エラーコードを受け取ることが重要(awsエラーやそのシステムやサービス内のエラーコード)
→基本正常は「0」異常は「0」以外の数字
・動作可能かどうかという観点でもコーディング・検証をセットで行う。
・基本無駄な処理はいらない。
・機能を作る際にその機能は繰り返しが必要なのか否か
・作る途中でずれていくので都度都度軌道修正していく必要がある。
・基本検証する際はディレクトリ構造を保ったままの方法で行う。
・基本的に設計書にないものは省くか入れない。

# テスト試験表について
* 基本は第三者が仕様書を見てテストを行うため仕様書以外見ずにテストの操作ができないといけない。
* テスト観点としてブラックボックスとホワイトボックスという２つの観点がある。
ブラックボックスとは業務目線でのテスト観点
ホワイトボックスとはソースコードなどの開発者からの目線

# AWS環境での学び
## EC2
インスタンスタイプ、ノード数が変更できる
AZ(アベイラビリティゾーン)：複数のデータセンターから構成されている。
が複数対応可能

## EMR
マスターノードが親インスタンス
コアノードが子インスタンス
一度にあげられる台数制限が「10〜30」台くらいだと思っている。
インスタンスタイプとノード数によって変化する。
ステップ実行を行うことで分散処理をすることが可能
Spark,Hadoopなどの分散処理フレームワークを導入することでさまざまな処理が可能
awsのコマンドでステータスを確認する際にはスロットリングエラーが出るのでステータス確認の処理は分散して確認するのが良い。並列実行する際も同様になる。

## Redshift
接続時にはPostgresql(psql)が必要
aws endpointが必要
データベースパスワードが必要
データのロードとアンロードは割と簡単にできる。
## Athena
スキーマという概念はなくデータベースという概念飲みになる。
S3の出力先を指定しないとクエリの実行ができない。
## Glue
Athenaでの実行したDDLがGLueでメタデータとして確認できる。
## CodeCommit
Gitを利用してローカルリポジトリとリモートリポジトリのやりとりが可能となるのと同時にvscodeを使用するとdiffがわかるようになる。
メタデータ とは

## 勉強前イメージ

ファイルの中身とは別で、このデータがどこにあるかとかの情報って感じ・・・

## 調査

### メタデータ とは？

データそのものではなく、データに関する情報を記したデータを指します。
例えば文書のデータであれば、
文書の内容ではなく、文書の著者や作成日などがメタデータになります。
ITだけではなく、いろいろな分野でメタデータという言葉が使われています。

メタデータは、基本的にファイルの戦闘などにメタデータを保存する領域が用意されていて
決められた形式で保存されています。

## 勉強後イメージ

あんまりここから広げられなかった・・・
あと色んな分野があって。。
ただ、イメージと合ってたのはよかった。

## 参考

- [メタデータ](https://www.realize-corp.jp/glossary/metadata)
SCSSの導入検討

# SCSSのメリット
大きく分けて２つ
* ネスト記法
* `@mixin`によるCSS定義のコンポーネント化,`@extend`によるCSS定義の流用

## ネスト
### クラス＞クラス
```scss
.parent {
  
  .child {
     
  }
}
```

### クラス＞メディアクエリ
```scss
.grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  @media(min-width: 768px) {
    grid-template-columns: repeat(4, 3fr);
  }
}
```

### クラス＞:hoverなどの疑似クラス
```scss
.parent {
  
  &:hover {
     
  }
}
```

## メモ：`@extend`と`@mixin`の違い
### `@extend`の特徴
* 継承対象に拒否権はない
* 継承なので、宣言箇所の基底の定義になる

### `@mixin`の特徴
* コンポーネント化対象は、必ず`@mixin`の宣言が必要で、利用側は、`@include`での参照が必要。`@extend`とは対照的。
* 記述の持ち込みなので、宣言箇所にそのままロードされる
* 上記の性質から、`@extend`よりミクロなコードの流用が可能に。

### 多用は
`@extend`も`@mixin`も多用するとヤバイ香りがする。
`@extend`は継承対象に拒否権がないため、自由な変更ができなくなる可能性がある。
`@mixin`は宣言が必要なものの、ミクロな流用が可能になるため、乱用されると可読性が下がる可能性もある。

実務では適切なルール化が必要と思われる。

# CSSでも出来ること
## 変数宣言
```css
:root {
  --primary-color: #FF00FF;
}
div {
  color: var(--primary-color);
}
```

# 個人的な結論
利用しようかと思います。
やはり、ネストによる可読性の向上は魅力的です。
`@extend`や`@mixin`はもう少し情報収集が必要かもしれません。

# 参考
[なぜSassが必要なの？](https://stocker.jp/diary/why-sass/)
[SCSSでできること](https://www.syngram.co.jp/blog/6520)
[Sass(SCSS)のmixin, extendなどまとめ](https://qiita.com/one-a/items/2758511326c09200fded)
[プログラマーから見た、SCSSの正しい(かもしれない)使いかた](https://qiita.com/sasuraisan/items/9a9dfb281cfdf5a12bd3)
[sassのmixinとextend、ちゃんと考えて使わないとcssが地獄。](http://www.90zbear.com/web-develop/html-css/1161/)
[scssで＠mixinを使うのと、htmlでclass指定する何が違う](https://teratail.com/questions/265127)
[CSS カスタムプロパティ (変数) の使用](https://developer.mozilla.org/ja/docs/Web/CSS/Using_CSS_custom_properties)
iPhoneアプリ開発ソフト『Xcode』の基本

#「Xcode」の基本
##筆者について
こんにちは。このページを開いてくださったことを感謝します。私は４月に大学に入学して、ついこの間プログラミングを始めましたというだだの初心者です。こんな調子乗って記事を書いてしまっていいのかなという感じですが頑張って書かせていただきます。最後まで見てくださると大変嬉しいです。
##Xcodeとはなんなのか
まずXcodeというものがなんなのかということから説明したいと思います。
XcodeとはIOSアプリを開発するための環境です。このXcodeはMacOSでしか動かす事ができません。 Xcodeを使用してIOSアプリ開発をしたい場合はMacを購入することをお勧めします。最新バージョンXcode12.5の動作環境はmacOS Big Sur11以降となっているのであまり古いMacを買ってしまうと動作しない場合がありますので、新規購入される際は気をつけてください。その他動作環境についてはもっと詳しく書かれているサイトがありますのでそちらを参照してください。
##Xcodeでのアプリ開発
Xcodeにはアプリ開発でとても有用なツールがあり、それらはアプリ開発において強力なサポートとなります。
その中でも主要なツールについて解説します。
###１.テキストエディタ
テキストエディタにはソースコードを書いたり、メモを書いたりする事ができます。Xcodeはコードの自動入力、プログラム構文の強調、コードエラーを自動検出する機能、修正候補をあげてくれる機能などたくさんの機能が備わっています。
###2.デバッガ
デバッガを使うことによりプログラムの修正支援を受けたり、プログラムの動作に異常がないかなどをプログラムの実行途中に確認する事ができます。
###3.コンパイラ
コンパイラとはプログラム言語を機械語に直してくれる機能です。
###4.インターフェースビルダー
これを利用することでドラッグ&ドロップでボタンなどの部品を配置する事ができます
###5.IOSシュミレーター
実際のiPhoneのようなシュミレーターが立ち上がり、アプリの動作がちゃんと行われるかの確認をする事ができます
##Xcodeの画面構成
![スクリーンショット 2021-04-29 18.06.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1391275/7c6f7720-c813-a054-0aca-ebdc2e79d916.png)


Xcodeの画面構成は上の写真のようになっています。番号順に説明していこうと思います。

##①ナビゲーターエリア
上の画像では赤色のところとなっています
ナビゲーターエリアは編集するファイルを指定するエリアです
ナビゲーターエリアは３つの領域から構成されています。
上から順番にナビゲーターバー、本体領域、フィルターバーで構成されています
###ナビゲーターバー
ナビゲーターバーは本体領域に表示される項目を変える事ができます
###本体領域
ナビゲーターバーの選択によって表示される項目が変わります
本体領域には８種類の項目が表示されるようになっています
###本体領域に表示される8種類のナビゲーター
####①プロジェクトナビゲーター
ここのナビゲーターはよく使うナビゲーターです
プロジェクトのファイルを見ること、操作することができます
ここでファイルを選択するとエディタエリアにファイルの内容が表示されます
####②シンボルナビゲーター
プロジェクトで定義されている関数やメゾットを表示してくれます
ここを選択するとシンボルに当てはまる箇所がエディタエリアに表示されるようになっています
####③検索ナビゲーター
検索ができるナビゲーターです
検索方法などが細かく指定する事ができます
####④問題ナビゲーター
警告やエラーが表示されます
####⑤テストナビゲーター
XCTestのテストケースが表示されます。テストをすることもできます
####⑥デバックナビゲーター
Xcodeから実行したアプリのリソースの利用状況、各スレッドのメゾットや関数の呼び出し階層を表示します
####⑦ブレークポイントナビゲーター
デバックの実行時に処理を停止する位置のことをブレークポイントといい、ここではその条件などを設定できます
####⑧レポートナビゲーター
ビルド、実行、テストなどの各種履歴を表示します
もっと詳しい内容がエディタ領域に表示されます
###フィルターバー
本体領域の表示内容を絞り込む事ができます

##②エディタエリア
メインで作業をする場所です
選択したファイルによってのエディタが表示されます
ストーリーボードというところではレイアウトを見ながらアプリの見た目を作る事ができます
ストーリーボードはよく使うと思うので覚えておいた方がいいでしょう

##③ツールバー
シュミレーターを起動したりする事ができます

##④ユーティリティーエリア
エディターエリアで選択した項目についての情報が表示されたり、編集する事ができます。
エディタエリアにドラッグ&ドロップで部品を追加したりできる項目もあります
↑ここもよく使うと思います

##終わりに
今回初めてQiitaを書きました
拙い文章でほんとに読みにくかったと思うんですけど最後まで見てくださってありがとうございました
また書くと思いますのでその時もよろしくお願いします

##参考文献
https://blog.codecamp.jp/xcode_function

https://i-app-tec.com/ios/xcode-window.html#2
XCode12.5 のインストールが終わらない

## 状況
- XCode12.5をインストールするため、まずCatalinaをBigSurにアップデート
    - これはできた
- 次にAppStoreからXCodeを更新
    - 1時間半以上たっても終わらない

## 解決法
- ひたすら待つ
    - 一晩くらい
- 待ったのちに再起動

## それでも終わらない場合
- 自分の場合は一晩(9時間以上)たっても終わってなかった
- いったんMac再起動
- 再起動したらXCodeが12.5でした

## 備考
- 一時間半待った時に再起動したのですが、その時はダメでした（インストールできてなかった）
- 思い切って一晩放置しとくのがよさそう
DockerコンテナをつかったNodeJS開発・実行環境

# DockerをつかったNodeJS開発・実行環境

NodeJSの開発をしているとき、実行環境を個別に作って残しておきたかったり、Nodeバージョンをコロコロ変えたかったりしたいので、Dockerコンテナを使ってNodeJSの開発・実行環境を作れるようにしました。
実行のたびにクリーンなコンテナを立てて、実行終わったらコンテナごと消すやり方もありますが、今回はコンテナ立てたまま動かすやり方です。

使い方としては、

1. 開発始める前にコンテナ立てる
2. 開発中はコンテナ立てっぱなしで、execすることでNodeJSを実行する
3. コードの編集はホスト側(Windows/MacOS)でやる
4. コンテナ作り直したかったら`docker-compose down`で落として、`docker-compose up`する

という形を想定しています。


# Docker Composeでコンテナ立てて動かす

軽量なAlpine上でNodeJSのv16系を動かしたイメージにします。
以下のdocker-compose.ymlを作成。

```docker-compose.yml
version: '3'

services:
  app:
    image: node:16-alpine
    container_name: node-container
    tty: true
    volumes:
      - ./src:/src
    working_dir: "/src"
```

これをプロジェクトのルートフォルダにおいて、./src/以下にソースコードやpackage.jsonを置くようにします。
コンテナをたてて実行するときは、以下コマンド。

これで、コンテナが立ちっぱなしになります。

```bash:bash
docker-compose up -d
```

# 必要なライブラリをインストール（npm install）する

上のdocker-compose.ymlで、 `app:` というかたちで、名前がappのサービスを作ったので、そのサービスを指定することで、コマンドを実行できます。
`npm install` をしたいので、`docker-compose exec`を使い、

```bash:bash
docker-compose exec app npm install
```

で、さっき立てたコンテナ上でnpm installすることができます。

# execで立ってるコンテナ上でプログラムを実行

`npm install`と同じく、`docker-compose exec`を利用します。

```bash:bash
docker-compose exec app node main.js
```

もしくは、package.jsonをしっかり書いているようであれば、

```bash:bash
docker-compose exec app npm start
```

で、プログラムを実行できます。

# コード書いて開発していく

docker-compose.ymlのvolumesの欄で、./srcディレクトリをコンテナ内にマウントしてあるので、ホスト側(Windows/MacOS側)で編集した内容が、常にコンテナ内にも反映されるようになっています。
なので、Windows/MacOS上で./src/main.jsなどのソースコードをもりもり編集し、 `docker-compose exec app npm start` することで、もりもり開発していけます。

# コンテナ立てなおす

試行錯誤するうちにコンテナの環境が汚れてくることもあるので、その時はコンテナ立てなおします。
それも簡単で、docker-compose.ymlがあるディレクトリで、

```bash:bash
docker-compose down
docker-compose up -d
```

を実行すると、今まで使ってたコンテナを捨てて、新しいコンテナを立てなおすことができます。

# 備考 都度都度コンテナを立てて実行する

NodeJSのpackage.jsonをこんな感じにします。。
ポイントはscript.clean-startのところ。
node_modulesディレクトリを消して、モジュールインストールして、Nodeを実行する流れです。

```package.json
{
  "scripts": {
    "start": "node ./main.js",
    "clean-start": "rm -r ./node_modules && npm install && npm start"
  },
  "dependencies": {
  }
}
```

これで、以下のコマンドたたくと、コンテナ立てて、上記の処理を行い、終わったらコンテナを都度都度消してくれます。

```bash:bash
docker-compose run --rm app npm run-script clean-start
```

# 参考にしたリンク

https://qiita.com/nikadon/items/995c5705ff1171f7484d
https://docs.docker.jp/compose/compose-file.html