OmniAICreator/Qiita-1.07M huggingface dataset:
チャート式ruby-appendix-V(rubular)

\![Mac OS X-10.15.7](<https://img.shields.io/badge/MacOSX-10.15.7-brightgreen>) \![ruby-2.7.1p83](<https://img.shields.io/badge/ruby-2.7.1p83-brightgreen>) 


# 正規表現regular expression

文字情報を取り出す便利ツールが正規表現(regular expression)です．これって覚えようとして挫折したことないですか？私はRegExpを10年以上使えなくて，本を何冊もトライしたんですが，途中で諦めました．でもね．<http://rubular.com> でわずか10分でバリバリ使えるようになってました．コツは，やっぱりTDDです．


# rubular

| ![img](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151211/c463deb2-a22d-2af9-14e5-41c55fd77478.png)|
|:------------------------------------------------------------------------------------------------------------|
| Rubularの画面                                                                                               |

Rubularの画面を見てください．一番上に正規表現を入れます．左下にtest stringを入れます．そうすると右に抽出結果が出てきます．

まずはtest文字列として

    line = '* fix calc kpoints:50, in_plane:0.98, vertical:1.00'

を考えます．

これから数値の配列[0.98, 1.00]を取り出します．まず，取り出す文字列(capture everything enclosed)は

    (.+)

で取り出されます．any single caharacterを表す'.'と，一つ以上を表す(+)を入れています．これからいらん文字を外していくと考えてください．少し試行錯誤すれば，

```ruby
: in_plane:(.+), vertical:(.+)
```

なんかで数値だけが取り出せたでしょうか？　

正規表現ってたくさん覚えないといけないと思いがちですが，Regex quick referenceにまとめられている要素だけでできています．大きく分類すると，

-   範囲指定(左列上)，
-   位置指定子(左列下)
-   文字指定子(中列)
-   量指定子(右列)

です．さらに丸括弧()で抽出になります．あとは，そのアンチョコ（カンペ）を見ながら，試行錯誤するだけなんですね．どうです，TDDでしょ．


# rubyでの利用

rubyに組み込むには，

```ruby
line = "* fix calc kpoints:50, in_plane:0.98, vertical:1.00"

string = Regexp.new("\\* fix calc kpoints:50, in_plane:(.+), vertical:(.+)")
line =~ string
p [$1.to_f, $2.to_f] #=> [0.98, 1.00]

res = line.scan(string)
p res #=> [["0.98", "1.00"]]
p res[0].map(&:to_f) #=> [0.98, 1.0]

p m = line.match(string) 
#=> #<MatchData "* fix calc kpoints:50, in_plane:0.98, vertical:1.00" 1:"0.98" 2:"1.00">
p [m[1].to_f, m[2].to_f] #=> [0.98, 1.0]
```

などとします．それぞれにちょっとした特徴がありますが，どれを使ってもうまくいくときにはうまくいきます．


# tagつきのregexp

さらにこの頃，気がついた手法で，tagをつけるのがあります．

```ruby
string = Regexp.new('in_plane:(?<x>.+), vertical:(?<y>.+)')
res = line.match(string)
=> #<MatchData "in_plane:0.98, vertical:1.00" x:"0.98" y:"1.00">
irb(main): > res[:x]
=> "0.98"
irb(main): > res[:y]
=> "1.00"
```

`:x` とか `:y` というsymbolで取れます．

'=~' だとさらに

```ruby
irb(main):001:0> line = '* fix calc kpoints:50, in_plane:0.98, vertical:1.00'
=> "* fix calc kpoints:50, in_plane:0.98, vertical:1.00"
irb(main):003:0> /in_plane:(?<x>.+), vertical:(?<y>.+)/ =~ line
=> 23
irb(main):004:0> x
=> "0.98"
irb(main):005:0> y
=> "1.00"
```

対応した名前がついたローカル変数(local variables with corresponding names)になります．

えっとでも，数値を取り出すときはscanf("%i, %f")も便利です．

```ruby
p line.scanf("* fix calc kpoints:50, in_plane:%f, vertical:%f")
#=>[0.98, 1.0]
```

C言語と同じformatです．regexpで取り出すと文字列なんで，to\_fとかto\_iでfloat, intに変換する必要がありますが，scanfで取り出すとそのままのtypeで取り出されます．



------
 - **source** ~/git_hub/ruby_docs/chart_style_ruby/c05_rubular.org
Databricks Community Edition ~チュートリアル~



以前、Databricks Community Editionのクラスター立ち上げを記載させていただきました。

今回は初めてのチュートリアルを実際にワークスペースの中で動かしていこうと思います。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817530/a931bb14-cfde-62e6-0646-f94aabc4a944.png)


まず、最初のホーム画面があります。※ホーム画面ではない場合、左横タブにある![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817530/5001cbaf-b8e6-56d3-4607-94ab8f01fbb7.png)
このボタンを押下していただくと、上記の画面に遷移します。

ホーム画面になりましたら、Explore the Quickstart Tutorialの文字をクリックします。

すると、下記の画面に遷移します。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817530/c955f114-99d2-668f-ad11-eeae336a8352.png)



遷移しましたら、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817530/993c108e-cb3c-163e-8580-c21a368c78f6.png)


Notebook名の下にあるクラスター選択プルダウンをクリックして、このNotebookで動かすクラスターの選択をします。

※ちなみに、Notebook内では6.3versionのクラスター作成、動作推奨されています。ただ、7.2MLクラスターで動かしてみたところ、特に問題なく動きました。6.3よりも下のversionだと不具合が起きるかもしれないので、気をつけてください。あ、あと、6.3はなく、6.4のversionは存在します。



クラスターが作成されていなかった場合、前回書いた記事を参照していただければ幸いです。

https://qiita.com/kawana-satoshi/items/51e200c8633e47b59bef



その後、RunAllボタンを押すとNotebook内のコマンドが実行されていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817530/1e91a6e3-db9b-ac43-3f54-3c3898afacd3.png)






RunAllを押すと、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817530/ecf2374c-31f5-920d-8855-f3513438f34e.png)



上記のように、右の方に実行されているコマンドが表示されます。

この、チュートリアルで実行していることはDatabricks dataset内のデータを読み込んできて、それをもとに、テーブルを作成し、delta形式のファイルでdbfs上に保存されます。作成されたテーブルから、データチャートを表示させたりするような、Notebookとなっています。

コマンド実行前

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817530/066a0dd5-add7-979e-07ca-2e425de2d0b0.png)



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817530/7de1b0bc-7edf-1e61-25f6-4a81cd40e834.png)




コマンド実行後

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817530/7b861037-c362-2e51-7cb5-ab3ab8578437.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817530/6e6301bf-dd70-79ae-e9c7-264ad46b648b.png)


このように、テーブル、ファイルが作成されました。

動作確認としては他にもクラスターのタブから、動かしたクラスターを選択すると、様々な情報が載っているので、参考になると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817530/6cf04248-5e17-a847-1887-af3420e5fa46.png)




![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817530/0acef558-9ccb-e3d9-1728-65a8ac15afe2.png)




ちなみに、チュートリアルを再度、同じ環境で行うと、データが既にあるというエラーになってしまいますので、再度行うときは、作成したデータを削除してから、実行していただけたらと思います。

//削除コマンド   /該当するフォルダ、ファイルをパスを指定して削除される
dbutils.fs.rm("dbfs:/delta/",True)

上のコマンドを適当なNotebook上で実行していただきますと、dbfs配下のdeltaフォルダ含む以下のファイル、フォルダが削除されます。



以上が、Databricksチュートリアルの解説でした。

見ていただき、ありがとうございました。



株式会社メソドロジック

川名智士
【Java】==とequalsの違い

#プログラミング勉強日記
2020年11月10日
文字列の比較を行うequalsメソッドと`==`の使い方について備忘録として簡単にまとめる。

#`==`と`epuals`の違い
　早速本題に入る。int型やchar型などのプリミティブ型で2つの値が等しいかどうかを比較するときは`==`演算子を使う。String型などの参照型の場合はequalsメソッドで比較する。
　String型などの参照型の場合に`==`で比較すると、<b>参照先が同じかどうかを比較し</b>、参照先の値が同じかどうかを比較するわけではない。
　実際にサンプルコードで動かしてみる。

```java:サンプルコード
public static void main(String[] args) {
	// String型変数のstr1とstr2を同じ文字列で初期化
	String str1 = "hello";
	String str2 = "hello";

	if(str1 == str2)
		System.out.println("str1=str2 (==で比較) ");
	else
		System.out.println("str1≠str2 (==で比較) ");

	// 同じ文字列を追加
	str1 += "!";
	str2 += "!";

	if(str1 == str2)
		System.out.println("str1=str2 (==で比較) ");
	else
		System.out.println("str1≠str2 (==で比較) ");
	
	if(str1.equals(str2))
		System.out.println("str1=str2 (equalsで比較) ");
	else
		System.out.println("str1≠str2 (equalsで比較) ");
}
```

```:実行結果
str1=str2 (==で比較) 
str1≠str2 (==で比較) 
str1=str2 (equalsで比較) 
```
　String型変数のstr1とstr2を同じ文字列で初期化して、同じ文字列を追加したところ、`==`で比較した場合は`false`を返し、equalsメソッドで比較した場合は`true`を返している。String型は宣言時や初期化時には疑似的にプリミティブ型として扱われるが、文字列を追加したときには参照型として使われる。なので、値が同じであっても参照先が違うので`==`で比較するとfalseを返す。




#参考文献
[基本型の比較と参照型の比較](https://www.milk-island.net/document/java/kihon/h4/)
[【速習Java】”==”と”equals”の違い(否定の方法も解説)](https://www.sejuku.net/blog/21395)
クラス名を取得する便利な方法

# きっかけ
ViewController名をインスタンスに依存せずに取得、また定義も一箇所にまとめられないかと考えていました。

## 親クラスのstatic propety

当然ながらSuperと出力される

```.swift
class Super {
    static var name: String {
        String(describing: self)
    }
}

class Sub: Super {
    
}

print(Super.name)
print(Sub.name)
```
**出力**

Super
Super

## protocol extensionをつかって実現する

```.swift
class Super: NameConvertible {

}

class Sub: Super {
    
}

protocol NameConvertible {
    static var name: String { get }
}

extension NameConvertible {
    static var name: String {
        String(describing: Self.self)
    }
}

print(Super.name)
print(Sub.name)
```
**出力**

Super
Sub

# なぜこのような動きになるのか
**ProtocolのSelfはProtocolを採用した具体的な型**そのものを指すという言語仕様がキーになります。
つまりSelf.selfは
**Protocolを採用した具体的な型のメタタイプ**を指すことから、サブクラス名が返却されます。

```.swift
extension NameConvertible {
    static var name: String {
        String(describing: Self.self)
    }
}
```


# 使い所
- UITableViewCellなどに適用し、identifierの宣言を簡略化させたいとき。
- エラーメッセージやロギング向けにクラス名をインスタンスに依存せず取得し、かつ各クラスで実装せずに済ませたいとき。

# おわりに
staticなpropertyだけど継承が影響する少し不思議にも感じる動きですが、理由を理解すると便利です。
protocol extensionなので、UIKitのクラスなどに適用できるのがポイントかと思います。
とはいえ、今回のような本来静的な値をするくらいの、シンプルな利用くらいが良さそうです。
config.ruお前は何をしているんだ？

# はじめに
Sinatraで作成したアプリをHerokuにデプロイする際に、config.ruがないとダメというエラーが発生。
そこでconfig.ruを作成し、色々記述したところ問題なく動作した。
そもそもconfig.ruって何をしてるのか疑問に思い備忘録として残すことにした。

# config.ruのruって何
rackupの略らしい。

# rackupとは
Rackというライブラリ(gem)が提供するコマンド。

# Rackとは
WebサーバーとRubyやRuby製フレームワーク(RailsやSinatraなど)のインターフェース。
これがないとWebサーバーからのリクエストがアプリに届かない。
WebサーバーとRailsなどのフレームワークはお互い異なる言語で会話しているので、Webサーバーからお願いされてもフレームワーク側は何を言われているのか分からない状態。
Rackが間に挟まることによって、双方の言語を翻訳してリクエストとレスポンスのやりとりをできるようにしてくれるイメージ。

# config.ru
runにアプリのオブジェクトを渡すことによってRackが機能する。

# まとめ
RackはWebサーバーとアプリケーションサーバーの橋渡し。
デプロイしたときにエラーが出たのは、Webサーバーのリクエストにアプリケーションサーバーが答えられなかったため。
UnrealEngine4を日本語VisualStudio2019でコンパイルするとログが文字化けする件

#VS2019 16.6以降でなにかが起きた
日本語版VS2019 16.6以降でUE4をビルドすると、コンパイルエラーの文字が盛大に文字化けします。

![2020-11-10_16h56_42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464248/ce833f8e-0fa8-51c6-d6f9-6ca4aff0d53e.png)

VS2019 16.6で適用されたVS内のMicrosoft.MakeFile.Targetで chcp 65001 などのコマンドをつかってutf-8化が行われたのが原因です。
このファイルを見るとわかりますが、NMakeUseOemCodePageプロパティによって旧来の動作と新しい動作が切り替わるようになっているのがわかります。

#古い動作を使うようにUBTを修正する
このプロパティはプロジェクトファイルに設定することで動作が変わります。
UE4ではプロジェクトファイルは直接は弄らず、GenerateProjectFiles.bat (中はUBTの呼び出し) によって作成されるので
UBTに変更を加える必要があります。

```c#:VCProject.cs
			// Project globals (project GUID, project type, SCC bindings, etc)
			{
				VCProjectFileContent.AppendLine("  <PropertyGroup Label=\"Globals\">");
				VCProjectFileContent.AppendLine("    <ProjectGuid>{0}</ProjectGuid>", ProjectGUID.ToString("B").ToUpperInvariant());
				VCProjectFileContent.AppendLine("    <Keyword>MakeFileProj</Keyword>");
				VCProjectFileContent.AppendLine("    <RootNamespace>{0}</RootNamespace>", ProjectName);
				VCProjectFileGenerator.AppendPlatformToolsetProperty(VCProjectFileContent, ProjectFileFormat);
				VCProjectFileContent.AppendLine("    <MinimumVisualStudioVersion>{0}</MinimumVisualStudioVersion>", VCProjectFileGenerator.GetProjectFileToolVersionString(ProjectFileFormat));
/*----->*/		VCProjectFileContent.AppendLine("    <NMakeUseOemCodePage>true</NMakeUseOemCodePage>");  //これを追加
				VCProjectFileContent.AppendLine("    <TargetRuntime>Native</TargetRuntime>");
				VCProjectFileContent.AppendLine("  </PropertyGroup>");
			}

```


変更を適用したらGenerateProjectFiles.batでプロジェクトファイルの更新をおこなってください。

![2020-11-10_18h13_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464248/055310e5-87f7-af74-c4c5-059bb07df756.png)

正しいエラー文字列が表示されるようになりました。めでたしめでたし。

#追記

ビルドしたときに `Microsoft.MakeFile.targets` ファイルの中で `System32\chcp.com 65001 > NUL` がどうたらこうたらというエラーが出る場合もこれで解決します。

```plaintext:コンパイルエラー
1>C:\Program Files (x86)\(略)\v160\Microsoft.MakeFile.Targets(46,5): error MSB3073: The command "C:\WINDOWS\System32\chcp.com 65001 >NUL 
```


#謝辞&リンク



調査には @steel_code さんのこの記事に大変助けられました！ありがとうございます！
[VS2019でUE4のビルド時に日本語出力が文字化けする](https://qiita.com/steel_code/items/ad1fa34078582691300f)

Redditでも同じところで問題が出ているケースが報告されています。
https://www.reddit.com/r/unrealengine/comments/gphjjj/unable_to_compile_c_project_425/
googleフォーム各設定項目へのGASアクセスチートシート

GASからgoogleフォームを操作出来ることを知ったのですが、
一時的に触ってまたすぐ忘れそうなので、覚え書き。

#アクセスチートシート
![スライド1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211061/aec6342e-3de1-744e-9180-39186665f76f.png)

![スライド2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211061/ed3ff73c-a370-37e4-5545-8195155f6dc7.png)

![スライド3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211061/3b32ade1-50e8-9008-80a3-1d222f611758.png)


#補足
テストオプションはそれらしきAPIが存在しなさそう。そこが一番触りたかったんだけど🐊
https://teratail.com/questions/243305
LogicAppsを使ってMicrosoft Forms回答データをExcel(DB)に格納してみた

備忘録用に書きます。

#はじめに
LogicAppsの勉強を進めていくうちに、Microsoft Formsで作成したアンケートの回答データをExcelやDBに格納しておけば、PowerBIでの分析がはかどるのでは・・・と思いLogicAppsでFormsのデータをExcelに格納するフローを作成してみたので、やったことをつらつらと書いていきます。

#本記事の内容
・事前準備（Formの作成、Excelファイルの準備）
・LogicAppsでフローを作成
・Microsoft Formsで回答を送信して動作確認

#事前準備
1)Formの作成（例としてFF14のトレジャーハント実績を入力するFormを作成）
![forms.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301050/82687945-7909-384c-5ddf-5055fea60afa.png)

2)Excelファイルの準備
![table_excel (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301050/c920e362-6829-d45c-86d5-8fc41fd104d0.png)

#LogicAppsでフローを作成
1)Azureへログインし、新規にLogicAppを作成
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301050/ff36f5eb-9d3f-7463-d42c-af2d3acac70e.png)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301050/a8f0d610-b92b-a177-287e-a91532e878ad.png)

2)空のロジックアプリをクリック
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301050/4c1d0998-995f-42b4-5e69-30250cdc7af8.png)

3)フローを作成
![画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301050/db6c28dc-9ef0-d305-ba47-02aa5f2753d6.png)

※式の部分は以下のように作っています。
addの式を選択
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301050/c5222140-3d78-f95a-08dd-c65c65fc246e.png)
変数は文字列として格納しているので整数に変換するintを入れる
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301050/47ada86d-e72b-c3ae-71a1-4d462777b147.png)
intの中に動的なコンテンツから変数のleftを入れる
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301050/6aa4c1a5-7e00-8919-2d3f-01b05bb3d062.png)
同じ手順で変数rightもadd式に入れて、更新をクリック

#Microsoft Formsで回答を送信して動作確認
1)事前準備で作成したFormで回答を送信する
2)LogicAppが正常に終了したことを確認
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301050/aaffc6c7-d007-2751-e6bd-4880614e025f.png)
3)Excelファイルにデータが格納されている事を確認
![画像3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301050/3d87baba-e648-dd45-df0e-6a72b04d35af.png)

データ格納先にDBを指定しても同じようにデータ格納されます。

#おわりに
応答データはMicrosoft Formsから以下のようにExcelで開くこともできます。
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301050/2aa9c2ca-123f-8958-360d-be0a61a1b7c6.png)

今回のように2つの回答のデータを足し算したり、データ変換したりする場合はLogicAppを使って自動化した方が楽かなと思います。
「軽量DDD」は軽量のDDDではない

# 「軽量DDD」とは
「軽量DDD」という言葉は『実践ドメイン駆動設計』の中で以下のように表現されています。

> 軽量DDDとは、DDDの戦術的パターンの一部だけをつまみ食いする方法で、ユビキタス言語を見つけ出して育てていこうなどという気は毛頭ない。おまけにこの手法は、境界づけられたコンテキストやコンテキストマッピングも使わずに済ませることが多い。技術面だけに注目して、技術的な問題だけを解決したがっているのだ。この方法にはメリットもあるが、戦略的モデリングを併用したときのような大きな見返りは得られない。
>
> ―――Vaughn Vernon (2013)、高木正弘訳 (2015)『実践ドメイン駆動設計』

DDDの戦術的パターンというのは、エンティティや値オブジェクト、リポジトリ等を指します。
「メリットもある」のですが、一方で**これらの実践がDDDに繋がるわけではない**のです。

# DDDとは
そもそもDDDとは一体どのような手法なのでしょうか？

今現在の自分の認識では、DDDとは**解決領域のモデルを洗練させる過程で、モデルをそのままの形でソフトウェアにも反映させることで、副次的にソフトウェアの品質を上げる**手法だと考えています。
つまり、**まずはモデル**であり、**次にソフトウェア**です。

では、どのようにモデルを洗練させるのでしょうか？
モデルを洗練させるためには、モデルをより深く洞察することが必要になります。
DDDにおいては、**実際に動くモデルを構築する**ことを通じて、モデルを更に深く洞察します。
この動くモデルこそがソフトウェアです。

つまり、DDDでは、

1. モデルを作る
1. モデルを基にソフトウェアを構築する
1. ソフトウェアの構築によるフィードバックからモデルを洗練する
1. 洗練されたモデルからソフトウェアを改善する
1. ソフトウェアの改善によるフィードバックからモデルを更に洗練する
1. 更に洗練されたモデルからソフトウェアを更に改善する
1. …

というループで**モデルの洗練**を通じて、副次的にソフトウェアの品質を上げるのです。

# 「軽量DDD」は軽量のDDDではない
「軽量DDD」が主軸に置くDDDの戦術的パターン、つまりエンティティや値オブジェクトなどは、DDDにおいてどのような役割を果たしているのでしょうか？

まず、これらの位置づけをEvansの言葉を借りて表現します。

> 「第2部：モデル駆動設計の構成要素」では、オブジェクト指向ドメインモデリングにおけるベストプラクティスのコアを要約して、基本的な構成要素の集まりを作り上げる。ここでは、**モデルと動作する実用的なソフトウェアとの間にある溝を埋めること**に重点を置く。ここで述べる標準的なパターンを共有することによって、設計に秩序がもたらされる。また、チームメンバーは互いの仕事をより容易に理解するようになる。標準的なパターンを使用することで、共通の言語に用語法が提供され、この共通の言語を使って、チームメンバ全員が、モデルと設計上の意思決定について議論できる。
> しかし、第2部でいちばん重要なのは、**モデルと実装を互いに整合させ、片方がもう一方の有効性を補強する状態を維持するような意思決定に集中すること**である。こうした整合性を維持するためには、個々の要素の詳細に注意する必要がある。こうした小規模の要素をていねいに作り上げれば、第3部と第4部で示すモデリングアプローチを適用するにあたって、開発者は、その基となる安定した土台を与えられるのだ。
> 
> ―――Eric Evans (2003)、今関剛他訳 (2011)『エリック・エヴァンスのドメイン駆動設計』（強調は筆者）

Evansは、エンティティや値オブジェクトといった実際のソフトウェアにおける構成要素に関して、その存在目的を「**モデルと（中略）ソフトウェアとの間にある溝を埋めること**」、「**モデルと実装を互いに整合させ**」ることとしています。

エンティティや値オブジェクトは、モデルをそのままの形でソフトウェアとして表現する際の、オブジェクト指向における「パターン」でしかありません。
つまり、DDDという思想の、さらに一部を補助する**詳細**です。

これらを用いるだけの「軽量DDD」は、やはりDDDではありません。

# 「軽量DDD」はDDDではないが、悪でもない
「軽量DDD」は軽量のDDDではありませんが、だからといって悪であるわけではありません。
何かしらのモデルをそのままの形でソフトウェアとして表現するという部分で、「軽量DDD」で挙げられるノウハウの部分は間違いなく利用できます。

ただし、**この何かしらのモデルの質が低ければ、同じ構造のソフトウェアの質も低くなります**。
そして、これこそが**ドメインモデル貧血症**の正体です。

# まとめ
DDDとは、前述の通り、解決領域のモデルを洗練させる過程で、モデルをそのままの形でソフトウェアにも反映させることで、副次的にソフトウェアの品質を上げる手法です。
モデルの洗練なくして、DDDは成り立ちません。
ゆえに、「軽量DDD」はDDDではない、ということを個人的には強く主張したいと思います。

「軽量DDD」と呼ばれているこれに、よりよい名付けが為されることを願います。

# 最後に

普段はTwitterでDDDについて考えていたりします。
もしよろしければフォローしていただけると嬉しいです。

記事への感想・指摘等もいただけるととてもありがたいです。

[@hidollara](https://twitter.com/hidollara)
Windows に Anaconda なしで PyStan をインストールする

Windows で PyStan を動かしたい場合は Anaconda を使うのが最も簡単で、公式ドキュメントにも Anaconda を使用したインストール方法が記載されている。
[PyStan on Windows — PyStan documentation](https://pystan.readthedocs.io/en/latest/windows.html)

Anaconda を使わない場合の次の選択肢としては、WSL 2 などを使って Linux 仮想環境の上で PyStan を動かすことを検討するだろう。

しかしそれすらもかなわない、 **Anaconda も Linux 仮想環境も使えない Windows で PyStan を動かしたい場合** はどうしたらいいのか？

## 環境
Amazon EC2 で立てた Windows Server 2019 で試したが、Windows 10 でもだいたい同じだろう。(適当)

あまり関係はなさそうだけど、コマンド実行するときは PowerShell を使っている。

## Python をインストールする
まずは Python をインストールする。

今回は Python 3.8.6 をインストールした。
普通にインストーラをダウンロードしてきてポチポチするだけなので割愛する。

[Python Release Python 3.8.6 | Python.org](https://www.python.org/downloads/release/python-386/)

## C++ コンパイラをインストールする
PyStan は実行時に C++ コンパイラを使うのでインストールする必要がある。

公式ドキュメントによると「MSVC compiler is not supported.」とのことだったのだけれど、MinGW-w64 で試してみてもうまくいかなかった・・・。[^mingw-w64]
そしてサポートされていないらしい Microsoft Visual C++ の方ではうまく動いたので、今回はこちらの方法について書く。

[^mingw-w64]: MinGW-w64 をインストールしてパスを通して distutils.cfg でビルド時の compiler=mingw32 オプションも設定したのだけど、他に何が必要だったのだろうか。

ダウンロードページから「Build Tools for Visual Studio 2019」インストーラをダウンロードして実行する。(下の方のメニューにある)
[Download Visual Studio 2019 for Windows & Mac](https://visualstudio.microsoft.com/ja/downloads/)

インストーラが起動したら「C++ Build Tool」にチェックを入れてインストールする。

## Cython と NumPy をインストールする
PyStan のインストール時に必要になるので、あらかじめ Cython と NumPy をインストールしておく。

``` console
$ pip install cython numpy
```

## PyStan をインストールする
2020年11月時点での最新版は 2.19 だが、うまくいかなかったので、2.17 を入れる。[^pystan2.19]

[^pystan2.19]: pystan==2.19 だとインストールはすぐに終わるが、import すると「ImportError: DLL load failed while importing _api」などとエラーが出て使えない。インストール時にビルドが実行されていないように見えるが、詳細はわからない。

``` console
$ pip install pystan==2.17.1.0
```

## 動作確認
簡単なサンプルコードを実行してみる。

``` python
from pystan import StanModel

model = StanModel(model_code="parameters {real y;} model {y ~ normal(0,1);}")
print(model.sampling().extract()["y"].mean())
```

エラー無く 0 っぽい数値が表示されれば成功。

## おわり
Windows なにもわからない。

そしてこの記事は一体誰に需要があるのか？？？
【Vue】親から子へのデータ受け渡しでsetterを使う方法。v-modelとwatchプロパティの活用

Vueで親から子テンプレートに受け渡したデータ（変数）をsetterで操作する方法について。

Vueの単一テンプレ内でsetterを使う場合はcomputedを使ったが、親から子にデータを受けわたす場合は**watchプロパティを使う**。


computedを使ったgetterとsetterについては[こちら](https://qiita.com/yuta-38/items/a48cfbe7c88cc9f42e30)


##考え方

単一テンプレートの場合はcomputedにgetterとsetterを記述すればいいが、子へ受け渡した場合、その変数はpropsで宣言されるため、computedでも宣言するとエラーになる。

このため、watchプロパティを使って変更有無を監視し、値を更新するよう設定する。


**▼propsとcomputedの併用で発生するエラー**

```:エラー
[Vue warn]: The computed property "value" is already defined as a prop.
```

▽コード事例
親から引き継いだデータはpropsで宣言する必要があるため、computedで再度セットすると重複となる。

```js:エラー発生コード事例
<script>
export default {
  props:{
    value: {}
  },
  data(){
    return{
      childText: undefined
    }
  },
  computed:{ 
    value:{
      get(){return this.value},
      set(x){this.value = x}
    }
  }
}
</script>
```



##watchを使ったセッター

```js:
<script>
export default {
  props:{
    value: {}
  },
  watch:{
    value:{
      immediate: true,
      handler(x){
        this.childText = x
      }
    }
  }
}
</script>
```

watchプロパティの中でpropsで定義した変数valueを監視している。


・`immediate: true`
これがあるとページロードの段階からvalueの内容が適用される。
逆に、これがないと、なんらかの変化があるまで受け渡されたデータは表示されない。

・`handler(引数){処理}`
指定した変数のネストした値の変化も監視する。
handlerがない場合は、指定した変数のみで入れ子になったデータの変更は感知しない。

・`this.childText = x`
変数valueの値を引数xで渡して、別の変数'childText'に代入している。

大元の変数(value)を直接編集せずに間接的に変更しているためsetterの役割となる。



<br>
##フルコード

以下のような親となるparents.vueと子となるchild.vueでデータを受けわたす例。

```js:parents.js
<template>
  <div>
    <childTemplate v-model="text" />
  </div>
</template>

<script>
import childTemplate from "./child"

export default {
  components:{
    childTemplate
  },
  data(){
    return {
      text: 'Default message'
    }
  }
}
</script>
```


・`import childTemplate from "./child"`
child.jsのファイルをテンプレート名childTemplateでインポート。
実際に使う場合は、componentsプロパティで宣言することも必要。

.jsや.vueなど拡張子は省略可能。


・`<childTemplate v-model="text" />`
v-modelを使って、子テンプレート(childTemplate)にデータを渡す。
inputタグにv-modelを使った場合、変数はvalueになる。


<br>

```vue:child.js
<template>
  <div>
    <input v-model="childText">
    <p>・childText： {{childText}}</p>
  </div>
</template>

<script>
export default {
  props:{
    value: {}
  },
  data(){
    return{
      childText: undefined
    }
  },
  watch:{
    value:{
      immediate: true,
      handler(x){
        this.childText = x
      }
    }
  }
}
</script>
```

・`props:{ value: {} }`
propsで親から受け取った変数を宣言する。データ受け渡しで必須の記述。


・`childText: undefined`
setterで大元の変数を代入する別の変数を用意しておく。

あとはwatchプロパティで変数valueを監視し、監視中の変数を上で宣言した変数に代入すれば完了。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/0efcb108-d5b8-6901-0b8c-99d3a96ff39a.png)


↓　テキスト編集

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/08972713-8687-115f-65e1-bccd64414510.png)

想定通りデータバインディングができている。
MariaDBをインストール(CentOS8)

記事を読んで、「いいじゃね？」って思ったらLGTMお願いします。

# 前提条件
・dockerで構築したCentOSでMariaDBをインストールする
・CentOSのバージョンは以下

```
$ cat /etc/redhat-release
CentOS Linux release 8.2.2004 (Core)
```

# MariaDBをインストールする

リポジトリを追加する

```
$ wget https://downloads.mariadb.com/MariaDB/mariadb_repo_setup
$ chmod +x mariadb_repo_setup
$ ./mariadb_repo_setup
```

インストールする

```
$ yum install MariaDB-server MariaDB-client
```

# インストール出来たか確認する

```
$ mariadb --version
mariadb  Ver 15.1 Distrib 10.5.7-MariaDB, for Linux (x86_64) using readline 5.1
```

# 初期設定をする

初期設定スクリプトを実行する

```
$ /usr/bin/mysql_secure_installation
```

新しいパスワード設定以外はすべてEnterを押す
以下のように新しいパスワード設定では新しいパスワードを設定する

```
New password:
Re-enter new password:
```

その後のすべてEnterを押す

# ログインする

以下のコマンドでログインする
ログイン時にパスワードを聞かれるので、設定したパスワードを入力する

```
$ mariadb -u root -p
```
[WSL2導入]  Win10でVScodeを使ってコーディングするため(?)のWSL2導入メモ

Ryzen3950xでマシンを自作して、意気揚々とWSL2の導入を進めていたところ、BIOSの仮想化が有効化されておらずこけてしまったのでトラブルシューティングを含め導入の流れを備忘録として。

基本的には以下の参考文献(2)の流れに沿って導入を行いました。

参考
(1)[【WSL / WSL2】VSCode×WSLでWindows上にLinux開発環境を構築](https://qiita.com/_masa_u/items/d3c1fa7898b0783bc3ed)
(2) [Windows 10 用 Windows Subsystem for Linux のインストール ガイド](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10)

## 導入環境
OS: Windows10　バージョン2004 (Build 19041.264)
CPU: AMD Ryzen3950x

## WSL1のインストール→WSL2にアプデ
・ PowerShellを管理者権限で開き（スタートメニュー右クリックから）、

```PowerShell:PowerShell
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
```
を叩いてWSLを有効化。

```
Path          :
Online        : True
RestartNeeded : False
```

・ 必要条件
必要条件として、x64システム: ver.1903以降, build18362以上など、ARM64のような他のシステムにも条件があるので確認が必要。
 
・仮想マシン機能の有効化
管理者としてPowerShellを開いて

```PowerShell:PowerShell
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
```

```
展開イメージのサービスと管理ツール
バージョン: 10.0.19041.572

イメージのバージョン: 10.0.19041.572

機能を有効にしています
[==========================100.0%==========================]
操作は正常に完了しました。
```
# いよいよディストリビューションのインストール
Microsoft StoreでUbuntuを見つけてインストール→実行。

```Ubuntu:Ubuntu
WslRegisterDistribution failed with error: 0x80370102
Error: 0x80370102 ??????????????????????????????????????
```

？？？

ネットで情報を漁ると、ハイパーユーザ権限が必要などの情報が。
しかし何を試しても解決せず。
呆然としつつインストールガイドをスクロールしていると...


>インストールがエラー 0x80070003 またはエラー 0x80370102 で失敗した
コンピューターの BIOS 内部で仮想化が有効になっていることを確認してください。 これを行う方法の手順は、コンピューターによって異なりますが、最も可能性が高いのは CPU 関連のオプションの下です。- [参考(2)](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10)

書いてありましたね。

早速BIOSを起動。ASUS製のマザボ"TUF Gaming"を使用しているので[ASUSサポート](https://www.asus.com/jp/support/FAQ/1038245/)を参考に仮想化を有効化して再起動。

もう一度UBUNTUを起動...!!

```Ubuntu:Ubuntu
Installing, this may take a few minutes...
Please create a default UNIX user account. The username does not need to match your Windows username.
For more information visit: https://aka.ms/wslusers
Enter new UNIX username: *****
New password:
Retype new password:
passwd: password updated successfully
Installation successful!
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 4.19.128-microsoft-standard x86_64)
```

あざす！
これから色々と細かい設定や環境を作っていきたいと思います。

素人の備忘録（初投稿）ですが誰かしらの参考になれれば幸いです。
【Ruby On Rails】HerokuにおけるDBのリセット方法

備忘録です。

#背景
herokuのデータベースをリセットし、何も登録がされていない綺麗な状態から、本番環境が動作するか確認したかった。
しかし、ロールバックし編集を加えたマイグレーションファイルが混在する状態でheroku run rails db:migrateコマンドをしたため、We are sorry but something went wrong.と表示された。
そのため、データベースリセットすることにした。

#heroku上データベースのリセットについて
正しいリセット方法

```terminal
% heroku run rails db:reset DISABLE_DATABASE_ENVIRONMENT_CHECK=1
```

#間違ったリセット方法
私は、初めの頃はこの様コマンドを入力し実行をしていました。リセットされませんでした。

```terminal
% heroku run rails db:reset

rails aborted!
ActiveRecord::ProtectedEnvironmentError: You are attempting to run a destructive action against your 'production' database.
If you are sure you want to continue, run the same command with the environment variable:
DISABLE_DATABASE_ENVIRONMENT_CHECK=1

```

DISABLE_DATABASE_ENVIRONMENT_CHECK=1という環境変数を入れないとproductionのデータベースが破壊されてしまう恐れがあるそうです。
PHPのインストール(CentOS8)

記事を読んで、「いいじゃね？」って思ったらLGTMお願いします。

# 前提条件
・dockerで構築したCentOSでPHPをインストールする
・CentOSのバージョンは以下

```
$ cat /etc/redhat-release
CentOS Linux release 8.2.2004 (Core)
```

# 既にPHPがインストールされていないか確認

既にPHPがインストールされているか確認

```
$ yum list installed | grep php
```

もし、インストールれていれば削除する

```
$ yum remove php*
```

# PHPをインストールする

```
$ yum install epel-release
$ yum install https://rpms.remirepo.net/enterprise/remi-release-8.rpm
$ yum remove php-*
$ yum install php74
```

# PHPがインストールされているか確認する

```
$ php74 -version
PHP 7.4.12 (cli) (built: Oct 27 2020 15:01:52) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
```
/var/tmp・/tmpっていつ消えるの？

## 勉強前イメージ

/ver/tmpは30日、/tmpは10日とか？
裏でcron走ってた記憶有るけど、正しく覚えてない

## 調査

### そもそも/ver/tmp・/tmpって？

どちらも一時ファイルを置くテンポラリーのディレクトリ。
/ver/tmpは再起動しても消えないが、/tmpは消える

### /ver/tmp・/tmpの違い

#### /ver/tmp

- 一時的ファイルを必要とするプログラムで使用出来る
- 再起動してもデータが消えることはない
- /tmpより間隔が開くが、定期的に処理される

- 参考 : [FHS（Filesystem Hierarchy Standard(ファイルシステム階層標準）](https://www.pathname.com/fhs/pub/fhs-2.3.pdf) より抜粋

```
5.15.1. Purpose
The /var/tmp directory is made available for programs that require temporary files or directories that are preserved between system reboots. Therefore, data stored in /var/tmp is more persistent than data in /tmp.
Files and directories located in /var/tmp must not be deleted when the system is booted. Although data stored
in /var/tmp is typically deleted in a site-specific manner, it is recommended that deletions occur at a less
frequent interval than /tmp.
-------------------
5.15.1. 目的
var/tmp ディレクトリは、システムの再起動の間に保存される一時的なファイルやディレクトリを必要とするプログラムのために利用できるようになっています。そのため、/var/tmp に保存されているデータは、/tmp に保存されているデータよりも永続的です。
var/tmpにあるファイルやディレクトリは、システムの起動時に削除してはいけません。ただし、/var/tmp に保存されているデータは
の中の /var/tmp は通常、サイト固有の方法で削除されます。
tmpよりも頻繁に間隔を空けてください。
```


#### /tmp

- 一時的ファイルを必要とするプログラムで使用出来る
- 再起動するとデータが消える
- 参考 : [FHS（Filesystem Hierarchy Standard(ファイルシステム階層標準）](https://www.pathname.com/fhs/pub/fhs-2.3.pdf) より抜粋

```
3.17.1. Purpose
The /tmp directory must be made available for programs that require temporary files.
Programs must not assume that any files or directories in /tmp are preserved between invocations of the
program.
-------------------
3.17.1. 目的
tmp ディレクトリは、一時的なファイルを必要とするプログラムで利用できるようにしなければなりません。
プログラムは、プログラムの呼び出しの間に /tmp 内のファイルやディレクトリが保存されていると仮定してはなりません。
```

### 設定情報

CentOS7では、
/var/tmp , /tmp のデータは systemdのデーモンで `systemd-tmpfiles-clean.timer` があり、こいつが消してるらしい
以下の設定ファイルに記載されている

```
cat /usr/lib/tmpfiles.d/tmp.conf
==========
...

# Clear tmp directories separately, to make them easier to override
v /tmp 1777 root root 10d
v /var/tmp 1777 root root 30d

...
==========
```

## 勉強後イメージ

どこでデータ削除されてるか知らなかった。
CentOS6,7でどこで削除されるかは違うらしい。
基本的には/var/tmpで置いてる。


## 参考

- [/tmp/ディレクトリ下のファイルはいつ削除される？](https://www.itmedia.co.jp/help/tips/linux/l0609.html)
- [【テンポラリファイル】/tmpと/var/tmpの違い](https://japan.cnet.com/release/30129729/)
- [Filesystem Hierarchy Standard](https://www.pathname.com/fhs/)
- [OS稼働中に/tmpの内容が消える現象への対処](https://koty.hatenablog.com/entry/2018/04/16/175747)
【入門者向け】Canvas入門講座#1 塗りつぶそう【JavaScript】

#問題1
赤色でcanvasを塗りつぶしなさい。
なお、以下のHTMLを使うこと。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>問題1</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
$(() => {
    // ここにプログラムを書く
});
</script>
</head>
<body>
<canvas id="my-canvas" width="500" height="300"></canvas>
</body>
</html>
```

#答え

```html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>問題1</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
$(() => {
    const ctx = $('#my-canvas')[0].getContext('2d');
    ctx.fillStyle = '#ff0000';
    ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
});
</script>
</head>
<body>
<canvas id="my-canvas" width="500" height="300"></canvas>
</body>
</html>
```

こんな感じで塗りつぶせると思います。
![ダウンロード (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163605/838694da-fe09-57e1-3bbe-d87e0706369d.png)



#解説
まずはコンテキストを取得しましょう。
このコンテキストを使ってcanvasに描画します。

```js
const ctx = $('#my-canvas')[0].getContext('2d');
```

次に色を赤色で指定します。

```js
ctx.fillStyle = '#ff0000';
```

最後に塗りつぶします。
この<b>fillRect</b>というメソッドは頻繁に使うので覚えておきましょう。
ctx.canvasのようにコンテキストのプロパティに
コンテキストを取得したcanvasがあるので、これも知っておくとよいでしょう。

```js
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
```
【入門者向け】Canvas入門講座#0 ガイダンス【JavaScript】

#はじめに
qiitaってレベル高い記事が多いですよね。:thinking:
「初心者向け」って記事もかなり難しいものが多いように思います。

そこで、入門者向けのcanvasの記事を書いてみようと思います。

<b>簡易ペイント作成をゴール</b>にします。:hugging:
これが全部できれば、
「canvas？知ってますよ！canvasでペイント作ったことありますよ。」ってイキれます(笑):nerd:

#リンク
ここから問題のページへ飛べるようにしておきます。
###基本編
<a href="https://qiita.com/PG0721/items/f06d0cb80513cf48da91">問題1 塗りつぶそう</a> 
<a href="https://qiita.com/PG0721/items/bce191754781b2400733">問題2 線分を描こう</a> 
<a href="https://qiita.com/PG0721/items/1b5900fe492da5db0d40">問題3 三角形を描こう</a> 
<a href="https://qiita.com/PG0721/items/9acc823073285da2f420">問題4 三角形を塗りつぶそう</a> 
<a href="https://qiita.com/PG0721/items/b333b764af78de747193">問題5 五角形を描こう</a> 
<a href="https://qiita.com/PG0721/items/6bc66bbe718091673791">問題6 五角形を塗りつぶそう</a> 
<a href="https://qiita.com/PG0721/items/0ca7cda560d265a39588">問題7 円を描こう</a> 
<a href="https://qiita.com/PG0721/items/ae955643ccfad7e7bc53">問題8 円を塗りつぶそう</a>
<a href="https://qiita.com/PG0721/items/3079d9f1073c32ef764c">問題9 画像を貼りつけよう</a> 
###イベント・アニメーション編
<a href="https://qiita.com/PG0721/items/0ece2aa0943918e3fcb7">問題10 円をボタンを押して動かそう</a> 
<a href="https://qiita.com/PG0721/items/282c76e939a39ca3d7c4">問題11 円をタイマーで動かそう</a>
<a href="https://qiita.com/PG0721/items/5dc801173ae08b6e2493">問題12 円をマウスドラッグで動かそう</a>
###画像処理編
<a href="https://qiita.com/PG0721/items/e098b7b4bd9be5252c71">問題13 グレースケールしてみよう</a> 
<a href="https://qiita.com/PG0721/items/93f3c4b9ebcb9bb741f3">問題14 2値化してみよう</a> 
<a href="https://qiita.com/PG0721/items/70785dbd989a53a6e1fa">問題15 モザイクしてみよう</a>
###卒業編
<a href="https://qiita.com/PG0721/items/7e785859f2397f1341eb">問題16 マウスドラッグで線を引いてみよう</a>
<a href="https://qiita.com/PG0721/items/e2648ed637ee795bd265">問題17 マウスクリックで四角形を作成してみよう</a>
<a href="https://qiita.com/PG0721/items/108b8f4d2844535aaf7f">問題18 canvasに描いた内容を保存、復元してみよう</a>
<a href="https://qiita.com/PG0721/items/74d65143a6553420b8ae">問題19 簡易ペイントを作ってみよう</a>

#対応ブラウザ
Google Chromeのみ。
Chrome以外でも動くかもしれませんが

#前提知識
HTMLがちょっと分かる。
JavaScriptがちょっとわかる(for文,if文が理解できるぐらい)
jQueryでイベント処理できる。(ボタンをクリックした処理が描ける程度)
これぐらい方を対象にしています。

#canvasってどう書くの？

htmlファイルに以下のように書きます。

```html
<canvas></canvas>
```

明示的にサイズ指定する場合は、以下のように書きます。

```html
<canvas width="500" height="300"></canvas>
```
通常、スタイルではなくプロパティのwidth,heightを使います。

#canvasって何ができるの？
線分を書いたり、多角形を塗りつぶしたり、画像を貼りつけたりすることができます。
また、行列を使って描いたものを平行移動、回転、拡大ができます。

#ゴール
最終的に作ることになる「簡易ペイント」の仕様を記載します。
・マウスドラッグで線分群が描けること
・マウスクリックで四角形が作成できること
・マウスクリックで円が作成できること
・線分群、四角形、円の色を選択できること
・線分群、四角形、円の太さを選択できること
・四角形、円がマウスドラッグで動かせること
・四角形、円が削除できること
・描いた内容を保存できること
・保存した内容を復元できること

今はできる気がしないかもしれませんが、頑張っていきましょう。:kissing_smiling_eyes:
AWS Amplify で Next.js アプリを作成する際のビルド設定

#1. 本記事は
```terminal
create-next-app
```
で作成したNext.jsの各種ファイルをgithubにアップロードし、AWS Amplifyでデプロイするパイプラインを作成する際に躓いたポイント（ビルド設定）のメモ。

#2. Next.js 各種ファイルを github にアップロード
1. githubで新たにリポジトリを作成する
2. terminalを開きファイルを保存したい場所へ移動（以下terminalでのコマンド）
3. package.json内の"build"に追記する:point_left:ここ注意！ 

```json
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  },
```

を

```json
  "scripts": {
    "dev": "next dev",
    "build": "next build && next export",
    "start": "next start"
  },
```
に編集します。
4. `create-next-app [アプリ名]`　ローカルに各種ファイルを作成
5. `git init`　.gitファイルの作成
6. `git remote [リポジトリのurl]`　でリモートリポジトリを記憶
7. `git add .`　で全てのファイルをコミット対象に
8. `git commit -m [コメント]`　でコミット
9. `git push remote origin master`　でmasterブランチへプッシュ

#3 リモートリポジトリとAmplifyをつなぐ
1. AWSマネジメントコンソールを開き、`サービス`から`AWS Amplify`を選択
2. `アプリを作成`を押下
3. 「From your existing code」で`GitHub`を選択し`Continue`を押下
4. 「GitHub 認証が成功しました。」と出たら、「リポジトリ」のプルダウンメニューから作成したリポジトリを選択し、`次へ`を押下
5. 「リポジトリ」のプルダウンメニューから`master`を選択し、`次へ`を押下
6. 「Select a backend environment」でバックエンド環境を選択（なければ作る）
7. 「Select an existing service role or create a new one so Amplify Console may access your resources.」はデフォルトのロールを選択。
8. 「ビルドの設定」:point_left:ここ注意！ 

```yaml
  artifacts:
    baseDirectory: build

```

を

```yaml
  artifacts:
    baseDirectory: out

```
に変えます。

9．`次へ`を押下
10．`保存してデプロイ`を押下

#4. 祈って待つ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431877/33dbd046-1c17-089a-6d5a-2ebf3bf66c49.png)

画像にあるようなページに遷移したらあとはプロビジョンから検証まで進んでくれることを祈るだけ..
全ての工程が終了したら左側にある`https://master...`のurlを押してみましょう。これが今作成されたNext.jsアプリのurlになります。
自作ドメインの設定もAmplifyのコンソールから行うことができます。

#5 まとめ
注意するのは「:point_left:ここ注意！」と書いた2点。
ビルドのフェーズで静的なhtmlを作成する際に`next export`というコマンドが必要になり、それらのファイルの出力先を`out`とする必要があるそうです。
Mapbox SDKにおけるAttribution の扱い

## はじめに
地図におけるAttributionの表記は重要でありながら、なかなかわかりにくいと思われます。そこで、Mapbox SDKを使用時における取り扱い方法をここで簡単に説明します。

## Attribution?
Mapbox SDKを使って[Mapbox](https://www.mapbox.com/)が提供する地図を表示すると、標準で地図下部にMapboxのアイコン等=Attributionが表示されます。使用するSDKによって表示の仕方は変わりますが、[Mapbox GL JS](https://docs.mapbox.com/mapbox-gl-js/)を使用した場合には以下のように表示されます ([Mapbox GL JS Playground](https://docs.mapbox.com/playground/gl-js-usage/)のスクリーンショット)。

![attribution.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85105/d339ee70-3f9f-d470-0e4e-efd32d576ebc.png)

左下のアイコンを"Mapbox wordmark"、右下の文字列を"Text attribution"と呼びます。

## いつ表示するの？
以下のケースでそれぞれ表示する必要があります。

- Mapbox wordmark: Mapboxにホストされたカスタムスタイル、カスタムタイルを使用したとき
- Text attribution: Mapboxが作成したスタイル（[Mapbox Streets](https://www.mapbox.com/maps/streets)等）やタイル([Mapbox Streets v8](https://docs.mapbox.com/vector-tiles/reference/mapbox-streets-v8/)等)を使用したとき

詳細は[こちら(英文)](https://docs.mapbox.com/help/how-mapbox-works/attribution/)をご参照ください。

つまり、Mapbox Streetsスタイルを使用した場合は「Mapboxが作成したスタイル」が「Mapboxにホストされ」ているので両方が表示されているのが正しいということになります。

## その他のケースは？
それ以外のケースでは以下のようになります。

|ケース|説明|
|:--|:--|
|自前のTilesetをStreetsスタイル上に表示|"Mapbox wordmark"、"Text attribution"共に必要|
|自前の地図をMapboxにTilesetとしてアップロード、[Studio](https://studio.mapbox.com/)で編集しMapbox GL JSで表示|"Mapbox wordmark"を表示、"Text attribution"は不要。ただし、自前の地図をプロバイダから購入し、かつそのプロバイダがAttributionを要求している場合はそれを表示|
|自前の地図を自前のサーバにアップロード、Mapbox GL JSで表示|"Mapbox wordmark"、"Text attribution"共に不要。ただし、自前の地図をプロバイダから購入し、かつそのプロバイダがAttributionを要求している場合はそれを表示|


## 見た目を変えてもいいの？
また、Attributionの色や表示位置は変更することが認められています。

> Note: You can adjust the font color and size of the attribution to match your theme, but attribution must be legible. You may not style the Mapbox wordmark.


SDK毎に設定方法が異なるので次回以降で各SDKでの設定をコードを交えながら見ていきます。
UniTaskで湯婆婆を実装してみる

## はじめに
@Nemesis さんのJavaで湯婆婆を実装してみるのUnity / UniTask版です。

-  [C#で湯婆婆を実装してみる](https://qiita.com/Nemesis/items/c7192a7c510788d2cba2)


Text Mesh Proですべての常用漢字を使えるようにします。
こちらの記事を参考にしました。


- [UnityのText Mesh Proでほぼ全ての日本語を表示させる](https://qiita.com/kgsi/items/08a1c78b3bee71136156)

## コード


``` C#
using UnityEngine;
using Cysharp.Threading.Tasks;
using TMPro;

public class Yubaba : MonoBehaviour
{
    [SerializeField] TMP_InputField keiyakusho;

    async UniTask Start()
    {
        keiyakusho.text = "契約書だよ。そこに名前を書きな。";
        await keiyakusho.OnSelectAsync();
        keiyakusho.text = "";
        var name = await keiyakusho.OnEndEditAsync();
        var text = "フン。" + name + "というのかい。贅沢な名だねぇ。";
        keiyakusho.text = text;
        var newNameIndex = Random.Range(0, name.Length);
        var newName = name[newNameIndex];
        text += "\n今からお前の名前は" + newName + "だ。\nいいかい、" + newName + "だよ。\n分かったら返事をするんだ、" + newName + "!!";
        keiyakusho.text = text;
    }
}

```

## 実行結果
![ezgif-1-5376bb388e07.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80699/4dfdcb57-f473-0808-c9bf-9a640717fe72.gif)
30分で実装シリーズ自作言語もどき編

#30分で実装シリーズ自作言語もどき編
この記事の目標
30分で自作言語もどきを実装する
うぷ主の環境

- macOS Big Sur 11.0.1
- Node 12.16.3

手順
1. 自作言語の構文を考える
2. トランスパイル先の言語を決める
3. ファイルを読みこむ
4. トランスパイラを作る
5. トランスパイラをビルドする

トランスパイラとか難しい言葉がありますが80行ほどで実装できます
早速作っていきましょう
##1. 自作言語の構文を考える
今回はjavascriptをベースにします
構文は
```log "Hello World";```
logでコンソールに出力
命令の間にスペースと文末に;は必須です
今回はとりあえずHello Worldだけにします
コンセプトは
pythonのように簡単な構文で
javascriptを書くなので
名前はjpyとします
##2.トランスパイル先の言語を決める
今回はjavascriptです
トランスパイラもjavascriptで書きます
##3.ファイルを読みこむ
Nodeには標準でファイルの入出力の機能が提供されているのでそれを利用します
スマートに書きたいのでES6で書いたのをES5にbabelでトランスパイルします
まずはモジュールを読み込みます

```javascript:index.js
import fs from 'fs';
```
まずはファイルの有無を判定する関数を作ります
あったらtrueなかったらfalseを返します

```javascript:index.js
const check = (file) => {
    let hasfaile = false;
    try {
        fs.statSync(file);
        hasfaile = true;
    } catch (err) {
        hasfaile = false;
    }
    return hasfaile;
}
```

次はファイルを読み込みます
先ほどの関数を使ってfileがあったら読み込みます
読み込んだ結果を文字列で返します

```javascript:index.js
let inpfile = "";
const read = (file) => {
    if (check(file)) {;
        inpfile = fs.readFileSync(file, 'utf8');
    }
    return inpfile;
}
```

##4.トランスパイラを作る

今回の難所です

まず対応表を作ります

```javascript:index.js
let jpy_command = ["log "];
let js_command = [['console.log("', 1, '");\n']];
```
次に変数を用意します

```javascript:index.js
let out = "";//出力結果
```
次にファイルを読み込みます
改行を消して
;ごとに区切ります

```javascript:index.js
let inp = (read('src/index.jpy').replace(/\n/g, '')).split(/;/);
```
次は"を区切ります

```javascript:index.js
for (const i in inp) {
      inp[i] = inp[i].split(/"/)
}
```

これでトークン化的なことをした二次元配列が作成できました
最後にトランスパイル部分を作れば完成です
処理の流れは
1. 読み込み結果を一つずつ取り出す
2. jpyの命令を含んでいたら
3. javascriptの命令に変換して変数に追記
です

```javascript:index.js
for (const i in inp) {
    for (const u in jpy_command) {
        if (~inp[i][0].indexOf(jpy_command[u])) {
            for (const f in js_command[u]) {
                if (typeof js_command[u][f] == 'number') {
                    out += inp[i][1]
                } else {
                    out += js_command[u][f]
                }
            }
        }
    }
}
```

最後にfileを出力します
buidl_jpyを言うフォルダにbuild後のfileを出力をします
build_jpyがあったら出力
build_jpyがなかったらディレクトリを作成後出力と言う処理にします

```javascript:index.js
if (check('build_jpy')) {
    fs.writeFile('build_jpy/build.js', out, function(err) {
        if (err) { throw err; }
        console.log('build成功');
    });
}
else{
    fs.mkdir('build_jpy', (err) => {
        if (err) { throw err; }
        fs.writeFile('build_jpy/build.js', out, function(err) {
            if (err) { throw err; }
            console.log('build成功');
        });
    });
}
```

##5. トランスパイラをビルドする
ここまでくればあとは楽勝です
babelのインストールだけです
```npm init -y```
```npm install @babel/core @babel/cli @babel/preset-env```
```touch babel.config.js```
今回はES5に変換できればいいのでbabelの設定は最小限です

```javascript:babel.config.js
const presets = [
  [
    "@babel/env",
  ],
];

module.exports = { presets };
```
babelを実行してES5に変換しましょう

```./node_modules/.bin/babel src --out-dir dist```

最後に実行しましょう
```node dist/index.js```
完成

##まとめ
いつかプログラミング言語を作ってみたいと思っていましたが
そんな技術は残念ながら持ってないプログラマーによる自作言語もどきの作り方でした
svg と javascript でモーフィング

# はじめに
html5 でアクションに応じたアニメーションを作るには

1. css で animation プロパティを使う
2. svg の animation タグを使う
3. javascript の setInterval 関数を使う

といった方法が考えられます。上のものほど、実現は簡単ですが、微妙な調整がむづかしくなり、下に行くほど、細かい調整は可能ですが、実装がめんどくさくなります。

今回は、2で実現する方法を調査しました。

# サンプル
svg領域をクリックすると、白いポリゴンが青いポリゴンに変化するサンプル
[https://ft28.github.io/samples/polygon_to_circle/index.html](https://ft28.github.io/samples/polygon_to_circle/index.html)
を作成しました。

[L51-L67](https://github.com/ft28/samples/blob/main/polygon_to_circle/main.js#L51-L67)がアニメーションを定義している部分になります。

**begin** を各ポリゴンごとに少し変更することで、左から順に実行するアニメーションを実現しています。また、同じポリゴンに関する形状変更のアニメーションと色変更のアニメーションの **begin** を同じにすることで、ポリゴンに関するアニメーションが同期するよう調整しています。

```
L53 animatePolygon.setAttribute('begin', "screen.click + " + index + 's');
...
L62 animateColor.setAttribute('begin', "screen.click + " + index + 's');
```

この**begin**の他、**dur** などの値を調整することで、アニメーションAが終わった後に、アニメーションBを開始するなど、より複雑なアニメーションを作成可能です。

モーフィングアニメーションのためには、変更前ポリゴンを構成する点の数と、変更後のポリゴンを構成する点の数が一致していなければ、アニメーションがおかしくなるので、[L15](https://github.com/ft28/samples/blob/main/polygon_to_circle/main.js#L15) で、変更前の点の数が、変更後の点の数よりも少ない場合には、変更前のポリゴンに適当な点を追加する処理を行ってます。

# まとめ
[http://snapsvg.io/](http://snapsvg.io/) のようなライブラリを使わなくても、この程度のアニメーションならばもっと簡単に実装できますが、ライブラリで実現できる以上のことが必要となり、結局、素のsvg と javascriptで実装したついでに、調査内容をまとめてみました。

# 参考URL
[SVG 1.1 仕様 （第２版） 日本語訳:19 アニメーション] (https://triple-underscore.github.io/SVG11/animate.html)
共変・反変の備忘メモ

## はじめに
自分ではまだ使ったことない、ライブラリのソースコードでたまに見かける共変・反変についてどういった挙動をするのかは知っていたが、具体的な使い方のイメージがよくわからなかったので簡単なメモとして残した

## 共変
例

```scala
trait List[+A] 

sealed trait Animal 
case class Dog(name: String) extends Animal
case class Cat(name: String) extends Animal

val dogs: List[Dog] = ??? 
val cats: List[Cat] = ???
val animals: List[Animal] = dogs
val animals2: List[Animal] = cats
```

### 状況
* `trait List[+A]`の宣言によって`List`が生み出す型は、型のサブタイプの関係性を維持する
* 具体例でいうと「`Dog`は`Aniaml`のサブタイプ => `List[Dog]`は`List[Animal]`のサブタイプ」

### 使用されるケース
* outputの型として使うのが便利になるケース
* 上記の例でいうと最終的に`List`が得られる状況が大事で具体的な`List[Dog]`という型に関心がないケース

## 反変
例

```scala
trait Show[-A] {
	def show(value: A): Unit = ???
}

val animal: Show[Animal] = ???
val dog: Show[Dog] = animal
val cat: Show[Cat] = animal
```

### 状況
* `trait F[-A]`の宣言によって`F`が生み出す型のサブタイプの関係性が逆転する
* 具体例でいうと「`Dog`は`Animal`のサブタイプ => `Show[Dog]`は`Show[Animal]`のスーパータイプ」

### 使用されるケース
* 共変の逆でinputの型として使うのが便利なケース
イメージが難しいが以下の記事が使うケースとしてイメージしやすかった
[Scalaの変位指定をすると、何が嬉しいのか。反変編 - Re.Ra.Ku tech blog](http://techblog.reraku.co.jp/entry/2016/06/12/135411)


## 終わりに
基本はメモ程度の内容なので、大したこと書いてないですがとりあえず、忘れたときにでも見返して思い出す程度のことが書かれてはいる
反変は特にイメージ難しいので忘れたらまた見返したい
さくらエディタでハイフン無しの郵便番号にハイフンを入れる

# やった理由
新しい年賀状のアプリに以前使っていたアプリで出力した住所録のcsvをアップロードしようと思ったところ、以前使っていたアプリから出力したファイルの郵便番号にはハイフンが入っていなかった。
新しいアプリに入れる際、条件に「郵便番号(ハイフンあり)」となっていたため、楽に一括でハイフンを入れたかった。

# 実施イメージ

## 実施前

```
9000000
9010154
9000002
9020067
9000029
```

## 実施後

```
900-0000
901-0154
900-0002
902-0067
900-0029
```

# さくらエディタの設定

| 設定項目 | 設定内容 |
|:-:|:-:|
| 置換前 | (^\d{3}) |
| 置換後 | $1- |

## 説明

### 置換前

| 設定項目 | 設定内容 |
|:-:|:-:|
| ^ | 文字の先頭 |
| \d | 10進数字 |
| {3} | 直前のパターンの n 回の繰り返し（今回は10進数字（\d）が3文字） |
| () | パターンをグループ化 |

上記の検索により、行の先頭から数字3文字を検索します。

### 置換後

| 設定項目 | 設定内容 |
|:-:|:-:|
| $1 | パターン1つ目をそのまま使う |
| - | ハイフン（-）を入れたいため、設定 |

上記の置換により、置換前で検索（^\d{3}）した数字3文字の後ろにハイフン（-）を付けることができます。

# ハマったポイント

いっつもハマるんですが・・
置換前に設定した内容をそのまま置換後に使う（置換後に「^\d{3}-」を設定）と、

```
^d{3}-0000
^d{3}-0154
^d{3}-0002
^d{3}-0067
^d{3}-0029
```

と悲しい結果に。
そのまま正規表現を置換後に使うと、文字列として置換されてしまうので、置換前に検索をグループ化して、検索結果を置換語に持ち回る、みたいなイメージですかね。

# 最後に

郵便番号の修正なんて多分年に1回しか使わないだろうなぁ…と思いつつ、**ある数字の文字列の間に何かを入れる**をしたい場合に使えるかな～と思います。

Qiita初投稿で、Markdownについて調べたり、設定内容を調べたりして頭の整理になりました。

# 参考にしたページ様

[まれによく使う正規表現](https://qiita.com/ken97/items/9276f59f3148bb8fbe67)
[正規表現で置換時にマッチした文字をそのまま使う](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)
[Markdown記法 チートシート](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)
データカタログにデータベース(Db2)を登録する。

##「接続」の作成

画面右上の「カタログに追加」から「接続」をクリック。
![スクリーンショット 2020-11-10 15.29.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295123/e0127507-de32-1dcb-5ba1-cd7dc28aefb9.png)

---

今回、以下リンクで作成済みのDb2が表示されるので、こちらを選択する。
https://qiita.com/Shumpei_Kubo/items/b6fd9153262cac4773e3
![スクリーンショット 2020-11-10 15.30.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295123/8778e1d4-c6b8-b8d1-f153-83c2d9d6e260.png)

---

各種情報はすでに入力されているため、「作成」をクリックする。
![スクリーンショット 2020-11-10 15.30.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295123/2958ec7e-3b0f-45ec-9520-290c8d8cad98.png)

---

「接続」というタイプの資産「Db2-qiita」が作成されました。（「最新の追加」というタブをクリックすると出てきます。）
![スクリーンショット 2020-11-10 15.44.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295123/f8fda978-afbf-d480-f35d-753a5cc3b94f.png)

---

##「接続された資産」の作成

画面右上の「カタログに追加」から「接続された資産」をクリック。
![スクリーンショット 2020-11-10 15.45.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295123/7354cf4c-b44a-6c24-ca43-d48a8ca3def2.png)

---

画面左側の「ソースの選択」をクリック。
![スクリーンショット 2020-11-10 15.47.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295123/ef7f8b77-9d95-a9ad-ee30-76c9fe0d92f8.png)

---
画面左側の「Db2-qiita」をクリック。
![スクリーンショット 2020-11-10 15.48.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295123/ddf33243-95e6-8d7c-72d0-045bfd2ac822.png)

---
この場合は、テストデータを作成した「QNF96649」をクリック。
![スクリーンショット 2020-11-10 15.49.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295123/7a0f5cbb-43ab-470d-6127-63162f6c940d.png)

---
作成済みのデモデータである「DEMODATA」をクリック。
![スクリーンショット 2020-11-10 15.50.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295123/d276af46-fffa-f9f8-5802-1ea8e92a12ce.png)

---
「作成」をクリック。
![スクリーンショット 2020-11-10 15.51.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295123/4614d05f-7372-45e5-9aea-78f9e3b96432.png)

---

情報を入力し、「作成」をクリック。
![スクリーンショット 2020-11-10 15.52.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295123/cd093ce3-5633-67d3-e721-0adf28873be3.png)
![スクリーンショット 2020-11-10 15.53.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295123/c56d96c8-00e1-959e-1b0e-ccdf1d18b014.png)

---
画面右上に、データ資産として登録された旨が表示されます。
![スクリーンショット 2020-11-10 15.54.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295123/02252218-cece-6b49-500d-3ff699d22252.png)

---
データ資産として、先ほど作成した「DEMODATA-of-Db2-on-IBMCloud」がデータカタログに登録されていることがわかります。
![スクリーンショット 2020-11-10 15.56.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295123/48c8ec2d-17a6-8e6a-b32d-8ac5f73160ef.png)

---
当該データをクリックすると、登録されているDb2の情報のプレビューがみられることがわかります。
個人情報っぽいですが、https://hogehoge.tk/personal/ で生成された擬似個人情報です。
![スクリーンショット 2020-11-10 15.57.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295123/5550b04f-6269-d1a8-6f1f-37bacde44aa9.png)
Builder Pattern

#
<font color="#00f">複雑なプログラムの組み合わせ（組成）を、user が意識することなく行うパターン<br>複数のコンストラクタが必要であったり、引数の数の組み合わせが多いするコンストラクタをプログラムの外部化する場合にも使える</font>

このページではBuilder Patternについて記載します。

[Design Pattarm MENU](https://qiita.com/old_cat/items/852d980bedb9100dd7e3)

##
以下のクラス構成で確認します

|クラス|説明|
|-----|----|
|abstract Builder.class|複数メソッドを定義する|
|samBuilder1.class|Builder.classを実装する|
|samBuilder2.class|   同じ  |
|Director.class   |Builderの複数メソッドを組成する|
|user(Main.class)|動作を確認|
＊user　他の開発者がこのパターンを利用する、という意味合いを含みます

```java:Builder.class
abstract class Builder{
  abstract void line1();
  abstract void line2();
  abstract void msg(String msg);
}
```
```java:samBuilder1.class
class samBuilder1 extends Builder{
  void line1(){System.out.println("|||||||||||||");}
  void line2(){System.out.println(".............");}
  void msg(String msg){System.out.println(msg);}
}
```
```java:samBuilder2.class
class samBuilder2 extends Builder{
  void line1(){System.out.println("=============");}
  void line2(){System.out.println("~~~~~~~~~~~~~");}
  void msg(String msg){System.out.println(msg);}
}
```
```java:Director.class
class Director{
  Builder builder;
  Director (Builder builder){this.builder=builder;}

  void construct(String msg){  // ここに複雑なコンストラクタを記述したり、メソッドを組み合わせる
    builder.line1();           // A
    builder.msg(msg);          // B
    builder.line2();           // C
  }                            // A~Cの順番を変えることで出力が変更する。メソッドを組み上げる例 
}
```
```java:user(Main.class)
public static void main(String[] args){
  samBuilder1 sam1 = new samBuilder1();
  Director dc1 = new Director(sam1);
  dc1.construct("Builder");

  samBuilder2 sam2 = new samBuilder2();
  Director dc2 = new Director(sam2);
  dc2.construct("builder");
}}
```
userにはBuilderの具体的なメソッドは見えない