OmniAICreator/Qiita-1.07M huggingface dataset:
Pythonでレイヤードアーキテクチャするときはimport-linterが便利だった

# 概要
Pythonで開発する場合でもレイヤードアーキテクチャーをベースとした設計をすることがあります。
その時、依存の方向性をチェックしたくなる時があります。

```
project_root/
  ├ infrastructure/
  │ └ db
  ├ interface/
  │ └ controllers
  ├ application/
  │ └ service
  └ domain/
    └ entity
```

例として上記の様なパッケージ構成を考えます。
依存の方向性を`infrastructure -> interface -> application -> domain`と言った形で定義しているとします。
開発時にルールを破っているインポートを自動でチェックするには[import-linter](https://github.com/seddonym/import-linter/)を使うと簡単に解決できます。

[サンプルのリポジトリ](https://github.com/taguchi8s/python-layerd-architecture-example)を用意しました。ソースコード全体はこちらを参照してください。

# 使い方

```shell
$ pip install import-linter
```

`setup.cfg`か`.importlinter`でレイヤーの定義と依存の方向性を定義します。
まずは`[importlinter]`のセクションでレイヤーの定義をします。

```
[importlinter]
root_packages =
    infrastructure
    interface
    application
    domain
```

`type = layers`はレイヤードアーキテクチャ用のルール設定です。
依存の方向性をレイヤーの順序で表現しています。

```
[importlinter:contract:1]
name = layered architecture contract
type = layers
layers =
    infrastructure
    interface
    application
    domain
```

[様々なオプション](https://github.com/seddonym/import-linter/tree/master/docs)があり柔軟なルールを構成することができます。
例えばflaskのパッケージのインポートを特定のレイヤーに限定したい場合などは、`include_external_packages`を有効にして下記のように`type = forbidden`で定義することができます。

```
[importlinter]
root_packages =
    infrastructure
    interface
    application
    domain
include_external_packages = True

[importlinter:contract:2]
name = Do not use `flask` outside the interface layer.
type = forbidden
source_modules =
    infrastructure
    application
    domain
forbidden_modules =
    flask
```



# チェックする

ルールの設定が完了したら以下のコマンドでチェックを行います。

```shell
$ lint-imports

pipenv run lintfix                                                                                                                            ✘ 1 main ✚ ✱ ◼
Skipped 2 files
=============
Import Linter
=============

---------
Contracts
---------

Analyzed 14 files, 15 dependencies.
-----------------------------------

Layered architecture contract BROKEN
Do not use `flask` outside the interface layer. BROKEN

Contracts: 0 kept, 2 broken.


----------------
Broken contracts
----------------

Layered architecture contract
-----------------------------

domain is not allowed to import application:

- domain.entity -> application.repository (l.5)


Do not use `flask` outside the interface layer.
-----------------------------------------------

infrastructure is not allowed to import flask:

-   infrastructure.db -> domain.entity (l.4)
    domain.entity -> flask (l.3)


application is not allowed to import flask:

-   application.repository -> domain.entity (l.4)
    domain.entity -> flask (l.3)

-   application.service -> domain.entity (l.6)
    domain.entity -> flask (l.3)


domain is not allowed to import flask:

-   domain.entity -> flask (l.3)
```

ルール違反を行なっているコードが存在する場合はエラーを表示してくれます。

CIツールに定義してPR時にチェックしてもらいましょう。
AnacondaとPythonのバージョン対応表 

# 概要

みんな大好きAnaconda。
自分は、Pythonの仮想環境を使いこなせない（何もしていないのになぜか壊れる）ので、
AnacondaのBaseに入っているPythonをそのまま使用することにしている。

ただ、いつも困るのが、Anacondaインストーラ名からPythonバージョンが判断できないこと。
Anacondaのインストーラを選択するときに迷うので、自分用のメモとして、最近リリースされたAnacondaのPythonバージョン対応表を作成した。

Windows 64bit版のみ確認したが、その他のOSについては未確認。

## バージョン対応表
|Anaconda          |python          |
|:-----------------|:--------------:|
|Anaconda3-2024.10-1 |Python 3.12.7   |
|Anaconda3-2024.06-1 |Python 3.12.4   |
|Anaconda3-2024.02-1 |Python 3.11.7   |
|Anaconda3-2023.09-0 |Python 3.11.5   |
|Anaconda3-2023.07-2 |Python 3.11.4   |
|Anaconda3-2023.07-1 |Python 3.11.3   |
|Anaconda3-2023.07-0 |Python 3.11.3   |
|Anaconda3-2023.03-1 |Python 3.10.9   |
|Anaconda3-2023.03-0 |Python 3.10.9   |
|Anaconda3-2022.10 |Python 3.9.13   |
|Anaconda3-2022.05 |Python 3.9.12   |
|Anaconda3-2021.11 |Python 3.9.7    |
|Anaconda3-2021.05 |Python 3.8.8    |
|Anaconda3-2021.04 |Python 3.8.8    |
|Anaconda3-2020.11 |Python 3.8.5    |
|Anaconda3-2020.07 |Python 3.8.3    |
|Anaconda3-2020.02 |Python 3.7.6    |
|Anaconda3-2019.10 |Python 3.7.4    |
|Anaconda3-2019.07 |Python 3.7.3    |
|Anaconda3-2019.03 |Python 3.7.3    |
|Anaconda3-2018.12 |Python 3.7.1    |
|Anaconda3-5.3.1   |Python 3.7.0    |
|Anaconda3-5.3.0   |Python 3.7.0    |
|Anaconda3-5.2.0   |Python 3.6.5    |


## 参考
Anaconda Individual Edition Installer Archive
https://repo.anaconda.com/archive/

Anaconda Documentation(Old package lists)
https://docs.anaconda.com/anaconda/packages/oldpkglists/

Wikipedia(Python)
https://ja.wikipedia.org/wiki/Python

## 更新履歴
2024/10/26:Anaconda3-2024.10-1を追加
2024/06/29:Anaconda3-2024.06-1を追加
2024/02/27:Anaconda3-2024.02-1を追加
2023/10/13:Anaconda3-2023.09-0を追加
2023/08/10:Anaconda3-2023.07-2を追加
2023/07/14:Anaconda3-2023.07-0、Anaconda3-2023.07-1を追加
2023/05/04:Anaconda3-2023.03-1を追加
2023/03/21:Anaconda3-2023.03-0を追加
2022/10/22:Anaconda3-2022.10を追加
2022/05/13:Anaconda3-2022.05を追加
2021/11/20:Anaconda3-2021.11を対応表に追加
2021/5/14:Anaconda3-2021.04とAnaconda3-2021.05を追加
R markdownで画像をfor loopで挿入する

r markdownで画像を表示させる場合，`knitr::include_graphics`を用いられることが多い．
しかし，　`knitr::include_graphics`を用いてknit時にfor loopで画像を表示させることはできない． これは， [knitrのレポジトリのissue](https://github.com/yihui/knitr/issues/1260)でも言及されており， `cat`を用いることで， この問題を回避できる．
pythonの`format`メソッドのような用途の`glue`を用いることで，loopを用いてrmarkdownに記載することができる． 

```
# 以下の例は画像が表示されない
```{r}
path <- "../hoge/fuga/"
image <- ["a", "b", "c"]
for i in (1:3){
  mage <- glue("{path}/image[i].png")
  knitr::include_graphics(image)
}
```


```
# forを用いて画像挿入可能
```{r, results='asis',  out.width = '80%'}
path <- "../hoge/fuga/"
image <- ["a", "b", "c"]
for (i in 1:3){
  image <- glue("{path}/image[i].png")
  cat("![](",image,")")
  cat("\n\n")
}
```
未経験から応用情報技術者に合格する！(2)午前問題対策編

#前書き
こんにちは！今回は応用情報技術者試験に未経験から合格するための記事を書いていきます！
前回は基本情報技術者よりも、応用情報技術者をあえて選んだ理由をあえて書きましたが、今回は午前問題の僕なりの対策方法について書いていきます。

#応用情報技術者の午前問題は？
まずは、午前問題のルールについて説明していきます。午前問題は全部で80問。最初の50問はテクノロジ系、51問目から60問目はマネジメント系、61問目から80問目はストラテジ系となっています。配点は全て均一であり、1問につき1.25点の100点満点です。60点以上獲得すれば合格ラインとなるので、80問中48問正解する必要があります。問題は全て4択でマークシート方式となります。試験時間は150分です。基本情報技術者試験の午前問題も形式は全く同じです。
ちなみに僕が受験した時は時計のない試験場がほとんどだったので、時計は持ち込んだ方がいいと思います。

#筆者が思う最大の試験対策
最大の試験対策は過去問に取り組むことです。あらゆるジャンルの問題で、過去問に類似した問題が出題されます。それどころか問題文、選択肢までも同じ問題が出題されることも多くあります。5割程度は過去問題とされています。過去問題に目を通していると、同じ問題に何回も出会すことでしょう。計算問題でも数字が全く同じ問題が出題されているので、こうした問題で時間短縮できるのは大きいと思います。問題集を買ってもいいですし、もちろん問題集も目を通しましたが、勉強が進むに連れて応用情報技術者ドットコムというサイトを用いました。問題と解説に加え、類似問題までアクセスできますし、1つの回を通しで回答する模擬試験や、複数回に跨ってジャンルを指定して回答することもできるので、手軽に勉強ができると思います。
https://www.ap-siken.com/

#それだけではあんまりなので・・・
しかし、過去問を解くというだけでは、理解が難しいこともありますし、そのまま進むと午後問題でつまづくこともありますので、他の勉強法も紹介していきます。未経験から始める場合は、まずはITパスポート試験や、基本情報技術者の午前問題対策から始めるのもありだと思います。応用情報技術者は過去問が多いとはいえ、文章が長い問題が多く、単語自体も難しい物が多いのでいきなり始めるとつまずく可能性が高いです。僕は最初基本情報技術者試験の勉強をしていたので、応用情報技術者試験にも割と楽に勉強に取り組めたと思います。また基本情報技術者試験の類似問題からも応用情報技術者試験で出題されていたので、ステップアップしやすいと思います。ITパスポートはかなり基礎的なのである程度知識のある人は飛ばしてもいいかもしれません。また基本情報技術者、応用情報技術者それぞれの教科書のような本を買うのもありです。
僕はキタミ式イラストIT塾を購入して何周か読みました。特にテクノロジ系の問題で分かりやすく書かれていますし、試験に関する知識も広くつけることができます。

#未経験から受けるなら得点源は？
未経験にとって得点源になるのがマネジメント系と、ストラテジ系です。この二つは社会人であれば聞いたことがある言葉から出題される問題も多く含まれていると思います。これらは合計30問ですが、8割は取りたいところです。ここで24問とってしまえば、テクノロジ系は半分程度得点できれば合格できます。マネジメント系は特に難度が低いと思います。監査に関する問題が3〜4問ありますが、ここは当たり前に選択肢を選べば正解できますし、計算問題もテクノロジ系に比べてはるかに優しい計算ばかりです。また過去問と類似した問題が多いのでここは確実に取りたいところです。

ストラテジ系は言葉を知っていないと手も足も出ない問題ばかりです・・・が、テクノロジ系は言葉の理解に加えてそれを応用的に用いないと解けない問題が多く含まれているのに対し、こちらは言葉さえ分かれば解ける問題が多いです。過去問題からそのままの問題も多く含まれていますし、このジャンルは勉強量がそのまま得点に直結することができるかなと思います。

#テクノロジ系をどうする？
たとえマネジメント系、ストラテジ系を全て正解したとしても、テクノロジ系で18問は正解しないといけません。しかしテクノロジ系は未経験からすると他のジャンル以上に聞いたことのない言葉が当たり前のように問題文、選択肢の全てに並んでしまいます。心が折れそうになります・・・

##テクノロジ系の得点源
難関のテクノロジ系の中でも最も得点しやすいと思うものは何かと言うと、情報セキュリティ系の問題です。6~8問は必ず出題される上に、セキュリティ系の問題は単純に言葉の意味を聞く問題も多く含まれています。更に午後問題でも情報セキュリティは必ず回答しないといけないので、対策すれば午後問題も含めてなかなかの得点に繋がるのではないのでしょうか。また情報セキュリティはテクノロジ系でも後半に配置されていることが多いですが、テクノロジ系の終盤、つまりセキュリティ系の後の問題はマネジメント系にも近い問題が多く含まれます。この辺りも合わせて得点できればかなり合格に近づくと思います。

##その他得点しやすい問題
テクノロジ系の計算問題は、応用情報技術者ドットコムなどで勉強している時は時間がかかる分スルーしてしまいがちですが、計算方法はわかるようにしておけば、本番では対応できると思います。本番は80問で150分の制限時間ですし、後半40問は知識、簡単な計算で解ける問題が多いので、確実に計算すれば得点できると思います。本番では電卓が使えないのに、やたらと桁数の多い問題が多いので、何度かは練習しておいた方がいいと思います。ちなみに計算問題すら、全く過去問と同じ物が出題されることがあるので、問題と正解自体には目を通しておいた方がいいと思います。

#終わりに
とはいえ、未経験にはやはり前半の40問は特に難しく感じます。僕は後半から解いたり、前半わからない問題はとりあえずすぐにスルーして、少しでも多く埋めることで心の動揺を抑えていました・・・前半でも、メモリの問題など暗記で解ける問題など、覚えれば解ける問題はしっかりと抑えておけば確実に得点を伸ばせると思います。あとは過去問と全く同じ問題を落とさなければチャンスは更に広がります！勉強してもなかなか頭に入らないところは、とりあえず過去問を目に焼き付けるという勉強法をとっていました・・・
僕は後半40問で30問正解できれば、前半40問を18問正解すればいいと思って試験を解いていました。こんな勉強法でも、最終的には8割近い得点で午前問題を突破できるようになりました。次回は午後問題について書いていきます！
[Blender×Python]   3D Bouncing Ballとその他アニメーション

#目次
0.振り出しにもどる動き
1.いったりきたりする動き
2.位置によって大きさを変える
3.3DのBouncingBall

#0.振り出しにもどる動き

![ezgif.com-gif-maker (9).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654004/d55bd82b-edb4-dfb0-0155-d33d311024db.gif)



```.py
import bpy
#動かしたいオブジェクトを準備する
bpy.ops.mesh.primitive_uv_sphere_add()

#変数の準備
x = 0
y = 0
z = 0
x_speed = 5

ob = bpy.data.objects["Sphere"]
frame_num = 0

for i in range(0,100):
    
    bpy.context.scene.frame_set(frame_num)
    
    #もし、オブジェクトのx座標が100より大きいならば
    if (x > 100):
        #スタート地点に戻す
        x = 0
    
    #オブジェクトのx座標をx_speedだけずらす
    x += x_speed

    ob.location = (x,y,z)
    ob.keyframe_insert(data_path = "location",index = -1)
    frame_num += 1
```


#1.いったりきたりする動き


![ezgif.com-gif-maker (10).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654004/157ac4c3-26df-c11b-17b1-b3912b1ba2c2.gif)


```.py
import bpy
bpy.ops.mesh.primitive_uv_sphere_add()

x = 0
y = 0
z = 0
x_speed = 5

ob = bpy.data.objects["Sphere"]
frame_num = 0

for i in range(0,100):
    
    bpy.context.scene.frame_set(frame_num)

    #オブジェクトのx座標が100より大きい、または、-100より小さいならば
    if (x > 100 or x < -100):
        #反転する
        x_speed *= -1 
    
    x += x_speed

    ob.location = (x,y,z)
    ob.keyframe_insert(data_path = "location",index = -1)
    frame_num += 1
```



#2.位置によって大きさを変える

![ezgif.com-gif-maker (7).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654004/21920741-ce43-0534-2c3c-f428f5e18d89.gif)


```.py
import bpy
bpy.ops.mesh.primitive_uv_sphere_add()

x = 0
y = 0
z = 0
x_size = 10
y_size = 10
z_size = 10
x_speed = 2
s = 3

ob = bpy.data.objects["Sphere"]
frame_num = 0

for i in range(0,120):
    bpy.context.scene.frame_set(frame_num)

    もしオブジェクトのx座標が30より小さいならば
    if(x < 30):
        s = 3
    もしオブジェクトのx座標が60より小さいならば
    elif(x < 60):
        s = 6 
    もしオブジェクトのx座標が90より小さいならば
    elif(x < 90):
        s = 9
    もしオブジェクトのx座標が120より大きいならば
    elif(x > 120) :
        x = 0
    
    x += x_speed

    ob.location = (x,y,z)
    #サイズをsに応じて変化させる
    ob.scale = (x_size * s,y_size * s,z_size * s)
    ob.keyframe_insert(data_path = "location",index = -1)
    ob.keyframe_insert(data_path = "scale",index = -1)
    frame_num += 1
```



#3.3DのBouncingBall

![ezgif.com-gif-maker (8).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654004/ecc16010-83b4-a66a-d2cc-0df5d9e68c56.gif)


```.py
import bpy
bpy.ops.mesh.primitive_uv_sphere_add()

#r = 円の半径
r = 10
#動き回る範囲
x_domain = 50
y_domain = 50
z_domain = 50
x = 0
y = 0
z = 0
x_speed = 7
y_speed = 3
z_speed = 5


ob = bpy.data.objects["Sphere"]
frame_num = 0

for i in range(0,100):
    
    bpy.context.scene.frame_set(frame_num)
    
    #それぞれの閾値に達したらボールの向きを反転させる
    if (x > x_domain-r or x < -x_domain+r):
        x_speed*= -1
    if (y > y_domain-r or y < -y_domain+r):
        y_speed*= -1
    if (z > z_domain-r or z < -z_domain+r):
        z_speed*= -1
    
    x += x_speed
    y += y_speed
    z += z_speed

    ob.location = (x,y,z)
    ob.keyframe_insert(data_path = "location",index = -1)
    
    frame_num += 1
```
VPCピアリング とは

## 勉強前イメージ

VPCで外部ネットワークと接続するときのなんとか・・・？

## 調査

### VPCピアリング とは

異なるVPCを接続することが出来ます。
複数のAWSのコンテンツをまとめたり、複数のAWS間で通信が行うことが出来ます。
異なるAWSアカウント(クロスアカウント)間でもVPCピアリングを行うことが出来ます
また、複数のVPCとピアリングすることがデフォルトで50まで出来ます

![複数のピアリングUntitled Diagram.drawio - diagrams.net - Google Ch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/b8e3476b-3a3a-00a3-1962-3abfcc2fa39d.png)


### 注意しないといけないこと

- CIDRブロックが重複しているVPC間のペアリングは出来ない

![ciderUntitled Diagram.drawio - diagrams.net - Google Ch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/768b1ad4-2645-32a3-2eb4-b788f341eece.png)

- 異なるリージョン間でのVPCペアリングはIPv6非対応

## 勉強後イメージ

外部ネットワークじゃなくて
VPC間のネットワーク通信をさせるためのものだった・・・
実際に作ってみた方がしっくり来るかも

## 参考

- [Amazon VPC同士の接続パターンまとめ (Whitepaper参照）](https://dev.classmethod.jp/articles/whitepaper-vpc-conectivity-options-02/)
- [VPCピアリングを作りながら学んでみた](https://dev.classmethod.jp/articles/handson-vpc-peering/)
- [Amazon VPCのピアリング接続](https://www.techcrowd.jp/datalink/peering/)
- [VPC ピア機能とは](https://docs.aws.amazon.com/ja_jp/vpc/latest/peering/what-is-vpc-peering.html)
Matlabのconv()をPythonで

matlabで畳み込みを計算するconv。
ガウシアンフィルターなんかでおなじみのやつ。

#numpy.convolve
matlabのconvはnumpy.convolveとほぼ同じ。

matlabの

```
conv(u,v,shape)
```

をpythonで書くと

```
numpy.convolve(u,v,shape)
```
となる。
shapeが 'full' 'same' 'valid' のいずれか、というのも同じ

ただし、u,ｖの長さが両方とも偶数で'same'のとき、返す範囲が1つだけ違うらしい。
まぁフィルタリングだとvはだいたい対称で長さは奇数なので、あまり問題にならないと思うけど。

#u,vの長さの少なくとも一方が奇数のとき
in Matlab

```matlab
x=1:10;
y=[0,1,0.5];

conv(x,y,'full')
conv(x,y,'same')
conv(x,y,'valid')
```

Matlab 出力

```
ans =
         0    1.0000    2.5000    4.0000    5.5000    7.0000    8.5000   10.0000   11.5000   13.0000   14.5000    5.0000

ans =
    1.0000    2.5000    4.0000    5.5000    7.0000    8.5000   10.0000   11.5000   13.0000   14.5000


ans =
    2.5000    4.0000    5.5000    7.0000    8.5000   10.0000   11.5000   13.0000
```

in Python

```python
import numpy as np

x = range(1, 11)
y = (0, 1, 0.5)

print(np.convolve(x, y, 'full'))
print(np.convolve(x, y, 'same'))
print(np.convolve(x, y, 'valid'))
```

Python 出力

```
[ 0.   1.   2.5  4.   5.5  7.   8.5 10.  11.5 13.  14.5  5. ]
[ 1.   2.5  4.   5.5  7.   8.5 10.  11.5 13.  14.5]
[ 2.5  4.   5.5  7.   8.5 10.  11.5 13. ]
```

どちらも同じ。

#u,vの長さが両方とも偶数のとき
in Matlab

```matlab
x=1:9;
y=[0,1,0.5,0.1];

conv(x,y,'full')
conv(x,y,'same')
conv(x,y,'valid')
```
Matlab出力

```
ans =
         0    1.0000    2.5000    4.1000    5.7000    7.3000    8.9000   10.5000   12.1000   13.7000    5.3000    0.9000

ans =
    2.5000    4.1000    5.7000    7.3000    8.9000   10.5000   12.1000   13.7000    5.3000


ans =
    4.1000    5.7000    7.3000    8.9000   10.5000   12.1000
```

in Python

```python
x = range(1, 10)
y = (0, 1, 0.5,0.1)

print(np.convolve(x, y, 'full'))
print(np.convolve(x, y, 'same'))
print(np.convolve(x, y, 'valid'))
```

Python 出力

```
[ 0.   1.   2.5  4.1  5.7  7.3  8.9 10.5 12.1 13.7  5.3  0.9]
[ 1.   2.5  4.1  5.7  7.3  8.9 10.5 12.1 13.7]
[ 4.1  5.7  7.3  8.9 10.5 12.1]
```

sameのとき、Matlabの方が出力が１つ長い
git command


#git init
git init 

git initはカレントディレクトリに空のリポジトリを作成します。

#git add
git add ファイル名

git add ディレクトリ名

git add .

git addは変更をステージにadd（追加）します。

ワークツリー　　→　　ステージ

# git commit
git commit

git commit -m "メッセージ"　　　　　　　　　 

git commit -v　　　　　　　　　　　　　　　　　　　　（変更点がエディタに表示される）

git commitは変更をcommit（記録）します。

ステージ　　→　　ローカルリポジトリ

#git status
git status

git statusは変更の状態を確認します。

（ワークツリー　　ステージ　　ローカルリポジトリ）のどこにいるか


#git diff
`ワークツリー　〜　ステージの差分`
git diff

git diff ファイル名

`ステージ　〜　ローカルリポジトリの差分`
git diff --staged

git diffは変更のdiff（差分）を確認します。

※diff　=　difference


#git log
git log

fit log --oneline　　　　　　　　　　　　　　　　　　　　 （最新の一行表示）

git log -n コミット数　　　　　　　　　　　　　　　　　　（最新のコミット数行表示）

git logはcommitの履歴を確認します。


#git push
git push リモート名 ブランチ名

例：git push origin main

git pushはローカルリポジトリの内容をリモートリポジトリに反映させます。

ローカルリポジトリ　→　リモートリポジトリ


#git fetch
git fetch リモート名/ブランチ名

例：git fetch origin/main

git fetchは、指定したリモートのブランチをローカルのブランチに取り込みます。

git fetch…リモートのmainブランチ　→　ローカルのorigin/mainブランチ


#git merge
git merge ブランチ名

git mergeは、カレントブランチに指定したローカルのブランチを取り込みます。

例：git checkout main　→　git merge origin/main

git merge…ローカルのorigin/mainブランチ　→　ローカルのmainブランチ



#git pull
git pull リモート名 ブランチ名

例：git pull origin main

git pullはローカルのカレントリポジトリに、リモートリポジトリの変更を取り込みます。

リモートのmainブランチ　→　ローカルのorigin/mainブランチ　→　ローカルのmainブランチ


git pull = git fetch + git merge



#git branch
`ブランチの表示`
git branch　　　　（ローカル）

git branch -a　　　（ローカル + リモート）

`ブランチの作成`
git branch ブランチ名

git branchはブランチの確認・作成をします。

#git checkout
git checkout 既存ブランチ　　　　（指定したブランチに移動）

git checkout -b 新ブランチ名　　　（指定したブランチを作成し、そのブランチに移動）

git checkoutはブランチを切り替えます。

#git reset HEAD
git reset HEAD .

git reset HEAD　ファイル名

git reset HEAD　ディレクトリ名

git reset HEADはステージした変更を取り消します。
【Nuxt.js】Nuxt.jsプロジェクトにプラグインを導入する

Nuxt.jsで外部プラグインを導入する際の手順をまとめておきます。


1 . 追加したいプラグインをインストール（今回は`vuejs-dialog`を例にします）

```terminal
npm i -save vuejs-dialog
```
package.jsonに追加されていることを確認！

```package.json
"vuejs-dialog": "^1.4.2"
```

2 . `plugins`フォルダ配下にファイルを作成する(ファイル名は任意)

※MacのコマンドなのでWindowsの方は読み替えて下さい。

```terminal
touch plugins/vuejs-dialog.js
```

3 . 下記のようにプラグインをVueで使うことを宣言する

```plugins/vuejs-dialog.js
import Vue from 'vue'
import VueDialog from 'vuejs-dialog'

Vue.use(VueDialog)
```

4 . 作成した`plugins/vuejs-dialog.js`を`nuxt.config.js`に登録する

```nuxt.config.js
plugins: [
    { src: '~/plugins/vuejs-dialog'}
  ],
```


**これで各Vueファイルからプラグインを使用できます!!!**
ちょっとニッチなNotionのショートカット②

#はじめに
↓前回の投稿
[ちょっとニッチなNotionのショートカット
](https://qiita.com/TerToEer_sho/items/5d65da0affc0cce72909)

---
|どこで|コマンド|機能|
|---|---|---|
|文末か文頭で|/ + c|文字の色・文字の背景色を選択|
|どこでも|/ + d|データベース|
|文中で半角スペースを空けて|@|メンション　※1|

※1
リマインダーやLink to page

##最後に
ページが縦に長くなる場合は、ページのはじめに`Table of contents`で目次をつけると遷移がしやすくなります。
Ubuntu 16.04.1 LTSのVM化

ノートパソコンにインストールしたUbuntu 16.04.1 LTSをVM化したときにはまったことをメモ

#Vmware converterが動かない
/etc/sudoersに以下を追記
username ALL=(ALL) NOPASSWD: ALL
※usernameはsudoできるユーザ名
#VMware converterが1%で止まる
すんなり進むには、
〇物理マシン
〇VMware converterが動作しているマシン
〇Vcenter
が相互に通信できる状態、かつ互いに名前解決できることが条件らしいです。
ただ、DNSがなかったり、hostsファイルをいちいち書かなきゃいけなかったりするのは面倒。
よって、VMware converterの、
Options
Helper VM Networkをeditして、
IPアドレスやDNSを指定して実行する
#VM化した後に、kernel panicで起動しない
普通にVM化して、パワーオンすると、
```
kernel panic not syncing vfs unable to mount root fs on unknown-block 0,0
```
となり起動しない。

これは、VM化する前でないと対処できない模様。
よって、VMware converterの、
Options
Date to copyをeditして、
Advancedをクリック、
Destination Layoutタブをクリック、
各Diskを選ぶと、
画面右下に「To Basic」がクリックできるものがあるので、クリック。

どうもVMware ConverterではLVMで不具合がある模様。
LVMを基本パーティションにしておいてconverterを進めるとうまくいった。

パワーオン後、エラーがでるけれどそのまま無事起動した。

/etc/sudoersをもとに戻すことを忘れないように。
いいね機能をLaravelとVue.jsで実装②



こちらの記事はパート2です。
前回の記事はこちらから↓↓
https://qiita.com/tanaka2020/items/8ec8ae0fdd3ad4409c74

## 実装
### 4.ルートの設定

routesディレクトリ内のweb.phpを編集

```
Route::get('/posts/{post?}/firstcheck', 'LikeController@firstcheck')->name('like.firstcheck');・・・１
Route::get('/posts/{post?}/check', 'LikeController@check')->name('like.check');・・・２
```
1.Vue読み込み時にLikeControllerのfirstCheck()アクション呼び出し
2.いいねボタンクリック時に記事id別にLikeControllerのCheck()アクション呼び出し

### 5.Vue Components作成

resouces
　|ーjs
　　｜ーcomponents
      　　　　｜ーLikeComponent.vue

``` vue
<template>
 <div>
  <button v-if="status == false" type="button" @click.prevent="like_check" class="btn btn-outline-warning">&#9825;</button><a v-if="status == false" href="#">{{count}}</a>
  <button v-else type="button" @click.prevent="like_check" class="btn btn-warning">&#9829;</button><a v-if="status == true" href="#">{{count}}</a>
 </div>
</template>

<script>
export default {
 props: ['post_id'],・・・１
 data() {
   return {
     status: false,・・・２
     count: 0,
   }
 },
 created() {
   this.first_check()・・・３
 },
 methods: {
   first_check() {
     const id = this.post_id
     const array = ["/posts/",id,"/firstcheck"];
     const path = array.join('')
     axios.get(path).then(res => {
       if(res.data[0] == 1) {
         console.log(res)
         this.status = true
         this.count = res.data[1]
       } else {
         console.log(res)
         this.status = false
         this.count = res.data[1]
       }
     }).catch(function(err) {
       console.log(err)
     })
   },
   like_check() {
     const id = this.post_id
     const array = ["/posts/",id,"/check"];
     const path = array.join('')
     axios.get(path).then(res => {
       if(res.data[0] == 1) {
         this.status = true
         this.count = res.data[1]
       } else {
         this.status = false
         this.count = res.data[1]
       }
     }).catch(function(err) {
       console.log(err)
     })
   },
 }
}
</script>
```

1.blade側はより投稿記事のidが渡されます。

```html
<like-component :post_id="{{$post->id}}"></like-component>
```
2.statusがfalseだといいねされていない状態です。
3.Vue読み込み時にLikeControllerのfirstCheck()アクションが実行されます。

### まとめ
status = false![スクリーンショット 2021-01-29 23.16.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639204/4b4d2316-e935-f3a6-474f-6d39ae3e33df.png)staatus = true![スクリーンショット 2021-01-29 23.16.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639204/c0ceab47-a9c7-e8fb-d745-d5dfb58acf9d.png)

今回はAxiousで実装しており非同期でLikeContorollerのアクションを呼び出して、いいね機能を実装しています。もっと簡単で出来る方法や綺麗な記述ありましたらご教授お願いします。
変数宣言からのKotlin解説

## はじめに
Kotlinをより深く、最初から学びたいと考え、Udemyで購入させていただきました。
これからKotlinを学び始める方等の手助けになれば幸いです。

## 記事の対象者
KotlinでAndroidアプリを始めたい方
Kotlinを使用しているが、再度知識を定着していきたいと思っている方

## Udemyで選択した講義
はじめての Kotlin【Java 知らなくてOK！丁寧な解説で Android に必要な Kotlin の基本を学習】
https://www.udemy.com/course/kotlin-beginner/

## 本講義を選択したのは
Udemyでセールやってるやーん。
英語のReferenceだとわからないから日本語で詳しく学びたいなーって思い、Googleでおすすめを調べた結果たどり着きました。

## 内容としては、
+ 変数宣言
+ null型
+ 制御構文(if式,when式)
+ ラムダ式
+ オブジェクト指向構文
などです。

具体的に少し記述してみます。

変数宣言は、『var』『val』を用いて宣言します。

```kotlin
//例
var 変数名: 型 = 任意の値

val 変数名: 型 = 任意の型
```
型推論などありますが、説明は省略させていただきます。

## 講座を受講してみて
実際に自分の知識が足りない部分が補われたりするので、これからはUdemyを益々活用して、学習に取り組んでいこうと考えております。

+ ラベルの使い方（講座を受講するまで忘れておりました。。）

本講座は、用語が説明されていない部分があるため、初学者の方は調べる必要性があるかもしれません。
SwiftUIでモーダル表示をしてみよう！

今回は、SwiftUIでハーフモーダルビューの作り方に関して紹介したいと思います。

# 動作
![RocketSim Recording - iPhone 12 mini - 2021-01-29 23.09.37.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595751/f65b9d36-82a4-d247-962d-6657e8becda0.gif)

「モーダルを表示」ボタンを押下→モーダル表示
「閉じる」or再度「モーダルを表示」を押下→モーダル非表示
の切り替えを行なっています。

# プログラム
```php:ContentView.swift
import SwiftUI

struct ContentView: View {
    @State var screenHeight: CGFloat = 0.0
    @State private var showHalfModal = false
    
    var body: some View {
        GeometryReader(content: { geometry in
            ZStack{
                Button(action: {
                    self.showHalfModal.toggle()
                }, label: {
                    Text("モーダルを表示")
                        .font(.largeTitle)
                })
                HalfModal(closedButton: $showHalfModal,
                          sizeY: screenHeight,
                          objectHeight: 400.0)
            }
            .onAppear(perform: {
                screenHeight = geometry.size.height  // スクリーンサイズ（縦幅）を取得
            })
        })
        .ignoresSafeArea(.all) // 上下のセーフエリアを無効化
    }
}

struct HalfModal: View {
    @Binding var closedButton: Bool
    let sizeY: CGFloat
    let objectHeight: CGFloat
    
    var body: some View {
        ZStack {
            RoundedRectangle(cornerRadius: 50.0)
                .foregroundColor(.red)
            VStack {
                Spacer()
                Button(action: {
                    closedButton.toggle()
                }, label: {
                    Text("閉じる")
                        .foregroundColor(.white)
                        .font(.largeTitle)
                })
                Spacer()
            }
        }
        .frame(height: objectHeight)
        .offset(y: closedButton ? sizeY-objectHeight :  sizeY)
    }
}

```

# プログラムの説明
## GeometryReaderで画面サイズ取得
`.ignoresSafeArea(.all)`でContentViewのSafeAreaを無効化、`geometry.size.height`で画面全体の縦幅を取得し、`screenHeight`変数に代入します。

## ZStackで同時に表示
`ContentView`と`HalfModal`をZStackで囲むことによって、一つの画面内に２つのViewコンポーネントを表示します。そして、HalfModal側で`offset()`（表示位置の移動）を宣言することで、画面下部にハーフモーダルが表示されるようになります。

## offsetで表示位置を変更

```php:Swiftは真偽値で処理を分岐できる
[Bool] ? [trueの処理]:[falseの処理]
```

といった処理を書くことができます。

ですから、

- true:y座標を「全体の縦幅」の位置に表示
- false:y座標を「全体の縦幅」-「モーダルの縦幅」の位置に表示



と指定してあげればアクションを起こす(=Bool値を変更する)と他のViewが表示される処理を実装することができます。

# ソースコード
https://github.com/r0227n/SwiftUI/tree/master/HalfModalView

GitHub上で公開していますので、参考程度にどうぞ。
Alter Linux(Xfce版)でDockerとGPU対応の開発環境を作る

# Alter Linuxで開発環境を作る
Arch Linux系ディストリビューション｢Alter Linux｣(Xfce版)の使用感が非常に良かったため、ノートPCにインストールして環境構築を行いました。
その際、躓いた点が幾らかあったので記録を残しておこうと思います。

## 筆者の環境
Alter Linuxのバージョン: RC3 (Xfce版)
PC:ASUS Zenbook Pro 14
i5-8565U,8GB,GTX1050-MaxQ

## Alter Linuxのインストール
[公式ページ](https://fascode.net/projects/linux/alter/)からイメージを落とし、balenaEtcherなどでUSBメモリに焼く。その後、UEFIから起動して、インストーラーに従って作業を進める。
以上でインストールは終わり(めっちゃ簡単)。

## VSCode
CommunityのOSS版と、AURの公式ビルド版の2種類が存在する。
(OSS版の初期設定では、拡張機能の検索先が公式版と異なるらしい。詳細は[こちら](https://blog.browniealice.net/post/code-oss_marketplace_issue_on_arch/))

```
[OSS版]
$ sudo pacman -S code
[公式ビルド版]
$ yay -S visual-studio-code-bin
```
OSS版については、Alter Linux付属のパッケージマネージャー(GUI)でもインストールできる。

## Docker
こちらもpacmanかGUIのパッケージマネージャーからインストール可能。

```
$ sudo pacman -S docker docker-compose docker-machine
```
GUIの場合は、｢docker｣で検索すると上記のパッケージが出てくるため、それぞれ選択してインストール。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591669/85a4cc59-27eb-cc1c-d146-d71d0db0416c.png)
また、VScodeの拡張機能｢Remote Container｣を使う場合は、ログインユーザーをdockerグループに追加する必要がある。
dockerグループへのユーザー追加は、セキュリティが低くなる恐れがある(詳細は[こちら](https://github.com/moby/moby/issues/9976))ようなので注意。

```
$ sudo gpasswd -a {ログインユーザー名} docker
```
デーモンの起動と登録も必要。

```
$ sudo systemctl enable docker
$ sudo systemctl restart docker
```

## Nvidiaドライバー
### インストール
pacman、GUIどちらでも可能。インストール後は再起動が必要。

```
$ sudo pacman -S nvidia-dkms nvidia-settings nvidia-prime
```
※nvidia-primeについては、CPUグラフィックとGPUを両方使いたい方だけでいいと思います。
### 問題
再起動後にターミナルでnvidia-smiで状態を確認すると、GPUが使われていない状態だった(メモリ使用量が0Bでかつプロセスがなにもない)。また、nvidia-settingが起動できなかった(ターミナルから起動してもエラーを吐く)。
### 解決策
AURのxfce4-sensors-plugin-nvidiaをインストールする。

```
$ yay -S xfce4-sensors-plugin-nvidia
```
原因は不明…LinuxのGPU関連はよくわからない…
今回は、ArchWikiのXfceのページを見て、運良く解決できた。
他のデスクトップ環境では起こらないと思う(未検証)ので、GPUを使うなら他のデスクトップ(Cinnamonなど)でもいいかもしれない。

## その他
### ブラウザ
初めからChromiumがインストールされている。
pacman、AURからChromeやFirefoxもインストールできる。
AURにはMicrosoft-edgeのDev版もあった(同期機能やChromeの拡張機能が使えない)。

### Optimus-manager
IntelとNvidiaのGPUを自動(手動も可)で切り替えてくれるソフト。AURからインストールできる。
電源接続時と非接続時、それぞれの起動GPUを選べたりもするので、GPU搭載ノートPCを利用している方におすすめ。

```
$ yay -S optimus-manager optimus-manager-qt
```
qtはGUIの設定やアイコンを追加するパッケージ。

### Timeshift
スナップショットを作成し、システムのバックアップを行うソフト。AURからインストールできる。

```
$ yay -S timeshift
```
GPUのドライバー関係をいじっていると正常に起動しなくなることがあったが、これを使うことで簡単に巻き戻すことができた。
起動時や一定期間ごとに自動でスナップショットを作成してくれるため、自身で作成しなくても安心できる点も素晴らしい。

### 日本語入力の設定
デフォルトで日本語入力にはMozcが使われている。筆者の環境ではアプリケーションメニューにMozcの設定が見当たらなかったが、以下のコマンドでGUIの設定メニューを呼び出すことができた。

```
$ /usr/lib/mozc/mozc_tool --mode=config_dialog
```
# ホームディレクトリの英語化
日本語のままだとパスの入力が面倒なので英語に変更。

```
$ LC_ALL=C xdg-user-dirs-update --force
```

## 最後に
Alter Linuxは、Arch Linuxのインストールの複雑さが解消され、Ubuntuなどと同じようにインストーラーで簡単にインストールできた。その上、Arch Linuxの豊富なリポジトリも利用できるため、ソフトやパッケージのインストールもスムーズだった。また、一部のアプリに関してはAlter LinuxのGUIアプリケーションからインストール可能で信頼性が高い。総じて非常に使いやすく、設定が容易なディストリビューションだった。
今後環境に変化があれば随時追記していく予定。

## 参考サイト
[Alter Linux公式サイト](https://fascode.net/projects/linux/alter/)
[Arch Wiki](https://wiki.archlinux.jp/)
機種変後のiPhoneでバイブレーション機能が動作しなくなった際の対応

#はじめに
iPhoneを機種変し、事前バックアップから復元をしたところバイブレーション機能が正常に動作しなくなりました。ググっても対応が出てこなかったので、その際の対応を記録しておきます。
※Appleサポートに電話して確認した内容のメモ書きです。

なお、docomo、au、softbankと言ったキャリアのショップで購入した場合でも、Appleサポートに連絡することになります。最寄りのAppleストアに行くか、電話で問い合わせましょう。

#iPhoneの構成を知っておく
iPhoneの構成は大まかに言って下記です。
バイブレーション機能が動作しなくなった場合に、疑われるのも以下の3つです。
>①データ部
>②ソフトウェア部
>③ハードウェア部

#被疑個所を特定する
##手順1：設定の確認
iPhoneの設定でバイブレーション機能をOFFにしている可能性がありますので、確認します。ONになっている場合でも、いったんOFFにし、再度ONにしてください。これで動作するようになった場合はここで終わりです。ダメな場合は手順2に進みましょう。
参考サイト:
<http://mobareco.jp/a83093/>
<https://appllio.com/iphone-how-to-set-vibration>

##手順2：iPhoneを工場出荷時の状態に戻す
まずはiPhoneを工場出荷時の状態に戻します。
※このときPCでしかバックアップを取得していない場合はiCloudにもバックアップを取得してください。
参考サイト：
<https://support.apple.com/ja-jp/HT201252>

データを復元せずに、新しいiPhoneとして使い始めてください。
この状態でバイブレーション機能が動作しない場合は②ソフトウェア部、③ハードウェア部に異常がある可能性があります。Appleサポートに連絡をして現状を伝え、ソフトウェアのチェックを受けてください。IMEIを聞かれますので、事前にメモしておくと良いでしょう。
※iPhoneの「設定」＞「一般」＞「情報」から確認できます。

②と③の場合はAppleサポートの指示に従ってください。私はハードウェア部の故障だったので、交換対応をお願いしました。

バイブレーション機能が動作する場合は手順3に進みましょう。

##手順3：データを復元する
バックアップからデータを復元して、もとのiPhoneの状態に戻します。ここでバイブレーション機能が動作しなくなる場合は、①データ部に異常があることになります。

再度iPhoneを工場出荷状態に戻して、バックアップデータの何が問題なのかを確認します。
流れとしては以下になります。
a：iCloudにバックアップをとる。
b：データを復元する際に、「写真」データを復元しない等、一部のデータを除いて復元する。
c：バイブレーション機能が動作するか確認する
d：動作しない場合は再度工場出荷状態に戻し、a～cを繰り返す。
e：動作する場合は除いたデータが異常データなので、そのデータはバックアップから復元しない。
例：写真データであれば、Googleドライブ等のクラウドストレージにアップロードしておき、そこからダウンロードする等、バックアップ以外を経由して復元する。

#終わりに
この問題はわりと多い？（Appleサポートに電話で質問した際には、写真データの欠落が原因でバイブレーション機能が動作しなくなる例が多いと聞きました）ようです。本記事を参照し、対応に困る人が少しでも減れば幸いです。
SQLでの複数列ユニークインデクスにおけるNULLの挙動について

SQLでユニーク制約を使用するとき、ANSI SQLではNULLを除いた値に対してユニーク制約がかかり、SQL ServerではNULLを含めてユニーク制約がかかることが知られています。この記事では、ユニーク制約のついた複数列インデクスにおけるNULLの挙動について見ていきます。

## PostgreSQL
環境: PostgreSQL 12

```sql
CREATE TABLE table_two_col (
  col1 int, -- Nullable
  col2 int  -- Nullable
);
CREATE UNIQUE INDEX Idx_table_two_col_col1_col2 ON table_two_col (col1, col2);

INSERT INTO table_two_col (col1, col2) VALUES (1, 1);
INSERT INTO table_two_col (col1, col2) VALUES (1, 1); -- error
INSERT INTO table_two_col (col1, col2) VALUES (1, NULL);
INSERT INTO table_two_col (col1, col2) VALUES (1, NULL); -- OK
INSERT INTO table_two_col (col1, col2) VALUES (NULL, NULL);
INSERT INTO table_two_col (col1, col2) VALUES (NULL, NULL); -- OK

SELECT * FROM table_two_col;
-- col1,col2
-- 1,1
-- 1,NULL
-- 1,NULL
-- NULL,NULL
-- NULL,NULL
```

## SQL Server
環境: SQL Server 2017

```sql
CREATE TABLE table_two_col (
  col1 int, -- Nullable
  col2 int -- Nullable
);
CREATE UNIQUE INDEX Idx_table_two_col_col1_col2 ON table_two_col (col1, col2);

INSERT INTO table_two_col (col1, col2) VALUES (1, 1);
INSERT INTO table_two_col (col1, col2) VALUES (1, 1); -- error
INSERT INTO table_two_col (col1, col2) VALUES (1, NULL);
INSERT INTO table_two_col (col1, col2) VALUES (1, NULL); -- error
INSERT INTO table_two_col (col1, col2) VALUES (NULL, NULL);
INSERT INTO table_two_col (col1, col2) VALUES (NULL, NULL); -- error

SELECT * FROM table_two_col;
-- col1,col2
-- NULL,NULL
-- 1,NULL
-- 1,1
```

### SQL Serverで、Filtered IndexによりANSI SQLの動作を再現する場合
Filtered Index(フィルター選択されたインデックス)を使用することにより、ANSI SQLのユニークインデックスのNULLの挙動を再現する方法がよく使用されています。

```sql
CREATE TABLE table_two_col (
  col1 int, -- Nullable
  col2 int -- Nullable
);
CREATE UNIQUE INDEX Idx_table_two_col_col1_col2 ON table_two_col (col1, col2) WHERE col1 IS NOT NULL AND col2 IS NOT NULL; -- この行のWHERE以降の部分

INSERT INTO table_two_col (col1, col2) VALUES (1, 1);
INSERT INTO table_two_col (col1, col2) VALUES (1, 1); -- error
INSERT INTO table_two_col (col1, col2) VALUES (1, NULL);
INSERT INTO table_two_col (col1, col2) VALUES (1, NULL); -- OK
INSERT INTO table_two_col (col1, col2) VALUES (NULL, NULL);
INSERT INTO table_two_col (col1, col2) VALUES (NULL, NULL); -- OK

SELECT * FROM table_two_col;
-- col1,col2
-- 1,1
-- 1,NULL
-- 1,NULL
-- NULL,NULL
-- NULL,NULL
```
Rotrics DexArm をLinux で動かす

Rotrics DexArm を入手しました。Ubuntu 20.04 で動かしてみる。
lsusb を使うと

~~~md
$ lsusb
STMicroelectronics Virtual COM Port
~~~

無事に認識できている。

~~~md
$ ls /dev/serial/by-id/ 
usb-STMicroelectronics_STM32F407ZG_CDC_in_FS_Mode_305C356B3439-if00
~~~

~~~md
$ ls -l /dev/serial/by-id/usb-STMicroelectronics_STM32F407ZG_CDC_in_FS_Mode_305C356B3439-if00 
lrwxrwxrwx 1 root root 13  1月 29 18:30 /dev/serial/by-id/usb-STMicroelectronics_STM32F407ZG_CDC_in_FS_Mode_305C356B3439-if00 -> ../../ttyACM0
~~~

下記コマンドを実行するとシリアル通信にも成功。

~~~md
$ screen /dev/ttyACM0 115200
~~~
こちらのリポジトリーのサンプルスクリプトを実行すればロボットは無事動く
https://github.com/Rotrics-Dev/DexArm_API

上記の例だとttyACM0にマウントされているので、パスを/dev/ttyACM0と書き換えること。
【cloud9】no space left on deviceとなった時の対応方法

#EBSのボリュームを増やす
https://qiita.com/ponsuke0531/items/edf2eee638202aa7f61f

ただボリューム増やしても即座に空きスペースが増えない。
ボリューム追加を反映させるためにはEC2インスタンスを再起動する必要がある

#EC2インスタンスを再起動させる
https://japan.cnet.com/release/30113741/#:~:text=AWS%E3%82%B3%E3%83%B3%E3%82%BD%E3%83%BC%E3%83%AB%E3%81%AEEC2%E3%83%80%E3%83%83%E3%82%B7%E3%83%A5%E3%83%9C%E3%83%BC%E3%83%89%E3%82%92%E9%96%8B%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82&text=%E5%86%8D%E8%B5%B7%E5%8B%95%E3%81%97%E3%81%9F%E3%81%84%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%82%92,Reboot%5D%20%E3%82%92%E3%82%AF%E3%83%AA%E3%83%83%E3%82%AF%E3%81%97%E3%81%BE%E3%81%99%E3%80%82&text=%E7%A2%BA%E8%AA%8D%E3%83%97%E3%83%AD%E3%83%B3%E3%83%97%E3%83%88%E3%81%8C%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C,%E3%81%99%E3%82%8B%E3%81%A8%E5%86%8D%E8%B5%B7%E5%8B%95%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82
git submodule updateでcloneできないときの対処方法

サブモジュールのあるリポジトリでサブモジュールをcloneしてくる場合は以下の様なコマンドを打つかと思います。

```
git submodule update --init
```

ただ、権限不足等で途中で失敗し、権限不足を解消してもう一度上記のコマンドを打ってもcloneしてくれないことがあります。

そんなときは、以下のコマンドを打つと解消されることがあります。

```
git pull --recurse-submodules
git submodule foreach --recursive git reset --hard
```
RubyでC言語を実行してみたった（Ruby拡張ライブラリことはじめ）

## はじめに

こんにちは。RubyでC拡張ライブラリを作らなければならないことになりそうです。
ここではその最初の一歩を踏み出します。

## やってみよう

まずは hello world を作ります。Hello world をC言語で書くと

```c
#include <stdio.h>

int main(void) {
    printf("Hello world\n");
}
```

みたいな感じになりますね。これをRubyで再現するのを目標にします。


### mkmfファイルを書く

Ruby の拡張ライブラリのための Makefile を作成するライブラリだそうです。`extconf.rb` という名前にするようです。今回は以下のような感じにします。

```ruby:extconf.rb
require 'mkmf'
create_makefile("hello")
```

### C言語のヘッダーファイルを作成する

`ruby.h` というファイルをincludeするように設定します。

```c:hello.h
#include "ruby.h"
```

### C言語のソースコードを書く

```c:hello.c
#include "hello.h"
#include <stdio.h>

void Init_hello(void)
{
  printf("Hello world\n");
}
```

これらは同じディレクトリに配置します。

```
.
├── extconf.rb
├── hello.c
└── hello.h
```

## 作ったる

それでは実行していきます。

```sh
ruby extconf.rb
```

Makefileが作成されたはずです。

```
.
├── extconf.rb
├── hello.c
├── hello.h
└── Makefile
```

makeします

```sh
make
```

`hello.o` と `hello.so` が作成されました。

```
.
├── extconf.rb
├── hello.c
├── hello.h
├── hello.o
├── hello.so
└── Makefile
```

## できた

この `hello.so` が作成されたRuby拡張ライブラリということになります。`irb` から呼び出してみましょう。

```
irb(main):001:0> irb
irb#1(main):001:0> require './hello.so'
Hello world
=> true
```

無事にHello worldが出力されました。成功です。
`irb -r ./hello.so` でも実行できます。


## Ruby拡張ライブラリを作るために必要な知識と資料

下記の資料が参考になりそうです。

* 公式資料 https://ruby-doc.org/core-3.0.0/doc/extension_ja_rdoc.html
* 英語の資料 https://github.com/silverhammermba/emberb
* mkmfリファレンス https://docs.ruby-lang.org/ja/latest/library/mkmf.html

C言語に触ったことはあるけど、RubyのC拡張はなかなか手が出ない人は次の記事も読んでみてください。

https://qiita.com/kojix2/items/b1525750065bfac1f44d

## おまけ

せっかく初めての拡張ライブラリ（バイナリファイル）を作成したので、少し中身を観察してみましょう。

### lddで共有ライブラリの依存関係をチェックする

```sh
ldd hello.so
```

```
	linux-vdso.so.1 (0x00007ffc0eb97000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2404384000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f240459e000)
```

### 逆アセンブルしてみる

```sh
objdump -d -Sl hello.so
```

今回、逆アセンブルというものを初めてやりましたが、思ったよりも元のコードの情報が残っているのですね。

```
〜中略〜
0000000000001120 <Init_hello>:
Init_hello():
/home/kojix2/Ruby/tmp/hello/hello.c:5
#include "hello.h"
#include <stdio.h>

void Init_hello(void)
{
    1120:	f3 0f 1e fa          	endbr64 
printf():
/usr/include/x86_64-linux-gnu/bits/stdio2.h:110
}

__fortify_function int
printf (const char *__restrict __fmt, ...)
{
  return __printf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __va_arg_pack ());
    1124:	48 8d 3d d5 0e 00 00 	lea    0xed5(%rip),%rdi        # 2000 <_fini+0xed0>
    112b:	e9 20 ff ff ff       	jmpq   1050 <puts@plt>
```

### シンボルをチェックする

```sh
nm -D hello.so
```

これは、ffiを使ってバインディグを作る時は、ときどき使いますね。一番最初に Init_helloが見えます。

```
0000000000001120 T Init_hello
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
                 w __cxa_finalize@@GLIBC_2.2.5
                 w __gmon_start__
                 U puts@@GLIBC_2.2.5
```

この記事は以上です。
Metabaseのクエリ結果をPythonで取得する

# はじめに

MetabaseのAPIをPythonで叩いてMetabaseで作成したクエリの結果を取得する方法のメモ。

# 環境

```
$sw_vers
ProductName:	Mac OS X
ProductVersion:	10.13.6
BuildVersion:	17G14042
```

```
$python --version
Python 3.7.3
```

# 事前準備

## Metabase

### インストール＆起動


公式のドキュメント（ https://www.metabase.com/start/oss/ ）に記載されているように

```
docker run -d -p 3000:3000 --name metabase metabase/metabase
```

これだけでMetabaseがローカルの環境で動きます。便利！
ただ、立ち上がるまでに時間がかかるので、```docker logs -f metabase```で起動が終わるまでみていた方が良さそうでした。
Chromeなどのブラウザで```http://localhost:3000```でアクセスできます。

### ユーザ作成

ユーザ名：dy@sample.com
パスワード：P@ssw0rd

としてユーザを作っておきます。

### DB

本来は既存のデータベース情報を登録して接続した上でクエリを投げますが、今回はサンプルとして用意されているものを使用するため、スキップします。

### クエリ

「照会する」→「簡単な質問」からクエリを作成します。
下図にあるようにMetabaseに付属しているSample DatasetにあるORDERSテーブルからテキトーにSELECTしておきます。

![metabase-question.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329888/f2e9cbe7-35bb-bd09-1572-bd2cde4fc9a0.png)

このとき、クエリの番号がURLの```/question/```の次の番号になります（今は1）。
このクエリ番号を使ってPythonから結果を取得します。

## MetabaseのPythonライブラリ

MetabaseはAPIが公開（ https://www.metabase.com/docs/latest/api-documentation.html ）されているので、ここにリクエストを投げればいいです。
ただPythonのライブラリがいくつかあるので、それを使います。
自分が調べた限り、現在3つライブラリがあります。

|  #  | ライブラリ名 | URL | 最終更新（2021年1月26日時点） | 
| ---- | ---- | ---- | ---- |
|  1  |  metabase-api  | https://pypi.org/project/metabase-api/ <br> https://github.com/vvaezian/metabase_api_python | 2021/01/18 |
|  2  |  metabasepy | https://github.com/mertsalik/metabasepy | 2020/10/30 |
|  3  |  metabase-py | https://github.com/STUnitas/metabase-py | 2020/5/28 |

今回は最終更新が直近であった```metabase-api```を使用します。
他のライブラリは試していないので、もしかしたらそちらの方が便利かもしれません。

```pip install metabase-api```でインストールしておきます。

# Pythonで取得する

```run.py``` を下の内容で作成します。

```run.py
from metabase_api import Metabase_API
import pandas as pd

mb = Metabase_API('http://localhost:3000', 'dy@sample.com', 'P@ssw0rd')

out = mb.post('/api/card/1/query/json')

df = pd.DataFrame.from_records(out)

print(df.head())
```

最初にMetabase_APIにドメイン、ユーザのメールアドレス、パスワードを渡して認証します。
そのあとの```mb.post```でクエリの結果を取得しています。
これはAPI一覧（ https://www.metabase.com/docs/latest/api-documentation.html#post-apicardcard-idqueryexport-format ）によると、クエリ結果を得るのにPOSTで```/api/card/:card-id/query/:export-format```を叩けばいいという仕様だったためです。
```:card-id```がクエリ番号です。
結果をpandasのDataFrameにしたかったので、json形式でフォーマットを指定しています。
outの中身はjsonのListになっているので、```pd.DataFrame.from_records```でpandasのDataFrameに変換しています。


```
$python run.py
```

実行するとMetabaseで表示されているクエリ結果を確かに得られました。

```
   ID  USER_ID
0   1        1
1   2        1
2   3        1
3   4        1
4   5        1
```
Ubuntu 20.04 で Java をインストール

(2022/10/17-18 追記)
コメントいただいて、jdk と jre のインストールコマンドが同じにになっていたミスを直しました。
また、Ubuntu 22.04 の場合の記事も書いていますのでこちらも参照ください。
「Ubuntu 22.04 で Java と maven をインストール」
https://qiita.com/nanbuwks/items/393089e2e62395d7f7ea

-----


Ubuntu において Java を使おうとするといろいろ選択肢がある。
一番安直にしようとするとどうしたらいいかな・・・

# 環境 

- Ubuntu Linux 20.04
- openjdk-11 (デフォルト設定)



# 何があるかな？


```

$ apt-cache search openjdk | grep jre
```

とすると、以下が得られた。

```
default-jre - 標準的な Java または Java 互換のランタイム
default-jre-headless - 標準的な Java または Java 互換のランタイム (ヘッドレス)
openjdk-11-jre - OpenJDK Java ランタイム - Hotspot JIT 版
openjdk-11-jre-headless - OpenJDK Java ランタイム - Hotspot JIT 版 (ヘッドレス)
openjdk-11-jre-zero - Alternative JVM for OpenJDK, using Zero
openjdk-8-jre - OpenJDK Java ランタイム - Hotspot JIT 版
openjdk-8-jre-headless - OpenJDK Java ランタイム - Hotspot JIT 版 (ヘッドレス)
openjdk-8-jre-zero - Zero/Shark を用いた OpenJDK 用の代替 JVM
openjdk-11-jre-dcevm - Alternative VM for OpenJDK 11 with enhanced class redefinition
openjdk-13-jre - OpenJDK Java runtime, using Hotspot JIT
openjdk-13-jre-headless - OpenJDK Java runtime, using Hotspot JIT (headless)
openjdk-13-jre-zero - Alternative JVM for OpenJDK, using Zero
openjdk-14-jre - OpenJDK Java runtime, using Hotspot JIT
openjdk-14-jre-headless - OpenJDK Java runtime, using Hotspot JIT (headless)
openjdk-14-jre-zero - Alternative JVM for OpenJDK, using Zero

```


# Java をインストール

jre でいい場合

```

# sudo apt install default-jre
```

jdk が必要な場合

```

# sudo apt install default-jdk
```

今回は、jdk が必要だったため後者を使いました。


```

$ sudo apt install default-jdk
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
・
・
・
以下のパッケージが新たにインストールされます:
  default-jdk default-jdk-headless default-jre libice-dev libpthread-stubs0-dev libsm-dev libx11-dev
  libxau-dev libxcb1-dev libxdmcp-dev libxt-dev openjdk-11-jdk openjdk-11-jdk-headless x11proto-core-dev
  x11proto-dev xorg-sgml-doctools xtrans-dev
アップグレード: 0 個、新規インストール: 17 個、削除: 0 個、保留: 66 個。
235 MB のアーカイブを取得する必要があります。
この操作後に追加で 251 MB のディスク容量が消費されます。
続行しますか? [Y/n] y
```
openjdk-11 が入った。かなりダウンロードする必要があるので、時間を十分に見積もろう。

# 確認

```

$ java --version
openjdk 11.0.9.1 2020-11-04
OpenJDK Runtime Environment (build 11.0.9.1+1-Ubuntu-0ubuntu1.20.04)
OpenJDK 64-Bit Server VM (build 11.0.9.1+1-Ubuntu-0ubuntu1.20.04, mixed mode, sharing)

```
となりました。(2020/01/29現在)
【Flutter】Android Studioでディレクトリが作れなくなった

#はじめに

今まで一度も起こったことがなかったのですが、新規Flutterプロジェクトを作成した際に
libフォルダにディレクトリを作成しようとした所、下記画像のようにPackageしか作れない。
![スクリーンショット 2021-01-29 19.20.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329865/9765dfcf-2584-faa2-b5d2-444e6150af9d.png)

今回は下記のようなディレクトリ構造をしたい。

>lib/
　├ util/
　├ screen/
　│　└ login/
　│　　└ login_scren.dart/
  

# Packageからネストしようとすると...

しょうがなくlibフォルダからscreenパッケージを作り、そこから[new] → [Package] → [login]と作成すると下記画像のようになる
![スクリーンショット 2021-01-29 22.15.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329865/1fdcc160-dd8d-928c-89ee-a489f942036b.png)

パスを確認してみると、想定通りの構造にはなっています。
/appname/lib/screen/login

# 解消法
libフォルダを右クリック。
[Mark Directory as] → [Unmark as Sources Root]の順にクリック
![スクリーンショット 2021-01-29 22.20.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329865/d0fb3b96-44c9-dea1-4687-1c10cd369bb0.png)

想定通りのディレクトリ構造になりましたね。
また右クリック[New]から[Directory]を選択することができるようになりました。
![スクリーンショット 2021-01-29 22.22.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329865/df5c7ea0-7ae8-3bb7-2cbb-a3513f8de48e.png)

# おわりに
筆者自身ディレクトリとパッケージの違いがあまりよくわかってないですが、これで見慣れた構造で開発できるようになりました。
ご指摘等ございましたらコメントお願いします:confounded:
Postgresqlでリストア時の設定

Postgresでダンプファイルをリストアしようとしたらやけに時間がかかったのでググったところ、時間を短縮するやり方があったのでメモときます。

1. postgresql.confを開く

```
psql -U postgres
```

```
postgres=# SHOW data_directory;
```
表示されるディレクトリを控える。

`cd`でそのディレクトリに移動

```
ls -a
```
**postgresql.conf** 発見

vscodeで開く

```
code -n postgresql.conf 
``` 


2.`fsync = off`にする
vscode上で「fsync」と検索して
`#fsync = on`となっている行を見つける
そこを
`fsync = off`にする

3.リストア

```
$ psql database名 < backup_file名
```
いいね機能をLaravelとVue.jsで実装①

投稿型のサイトを作成していて、
いいね機能を実装したいと思ったので作成しました。

## 環境
・PHP 7.4.9
・Composer version 1.10.13
・Laravel Framework 7.30.1
・vue/cli 4.3.1

## 流れ
1.投稿機能の実装(今回の記事では省略)
2.いいね機能用のdatabeseテーブルの作成
3.Vueコンポーネントの作成
4.Controllerの作成
5.ルート設定
6.view表示

## 実装
### 1.投稿機能の実装
　今回は省略！！

### 2.いいね機能用のdatabeseテーブルの作成
```
$ php artisan make:model Like -m
```

-mをつけることでモデルと一緒にマイグレーションファイルも作ってくれます。
※databaseの設定は省略します。設定はconfigフォルダdatabase.phpと.envを編集

**作成したマイグレーションファイルの編集**

```
public function up()
    {
        Schema::create('likes', function (Blueprint $table) {
            $table->id();
            $table->integer('posts_id');
            $table->integer('user_id')->unable();
            $table->integer('like')->default(0);
            $table->timestamps();
        });
    }
```
<font color="Violet">likeカラムの値が0か1かでいいねされているかを判断するように実装します</font>

**作成したモデルLike.phpの編集**

```
class Like extends Model
{
     protected $fillable = [
          'posts_id','user_id','like'
     ];
}
```
"fillable"はホワイトリストです。$fillableで指定したカラムは値が代入可能です。

**マイグレーションの実行**

```
php artisan migrate
```


### 3.コントローラーの作成
```
php artisan make:controller LikeController
```
Vueのコンポーネントから呼び出されるアクションを書いていきます。

```php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Post;//投稿機能のモデル
use App\Like;
use Auth;

class LikeController extends Controller
{
    //コンポーネント初期読み込み時(created)に呼び出される
    public function firstcheck($post) {
     $user = Auth::user();
     $likes = new Like();
     $like = Like::where('posts_id',$post)->where('user_id',$user->id)->first();
     if($like) {
          $count = $likes->where('posts_id',$post)->where('like',1)->count();
          return [$like->like,$count];
     } else {
          $like = $likes->create([
               'user_id' => $user->id,
               'posts_id' => $post,
               'like' => 0
          ]);
          $count = $likes->where('posts_id',$post)->where('like',1)->count();
          return [$like->like,$count];
     }
    }

    //いいねボタンを押した時に呼び出される
    public function check($post) {
     $user = Auth::user();
     $likes = new Like();
     $like = Like::where('posts_id',$post)->where('user_id',$user->id)->first();
     if($like->like == 1) {
          $like->like = 0;
          $like->save();
          $count = $likes->where('posts_id',$post)->where('like',1)->count();
          return [$like->like,$count];
     } else {
          $like->like = 1;
          $like->save();
          $count = $likes->where('posts_id',$post)->where('like',1)->count();
          return [$like->like,$count];
     };
    }
}
```

長くなってきたので次に続く。。。。。。
【初心者でもわかる】要素をピラミッド構造で並べる方法

#どうも7noteです。レイアウト案、ピラミッド編です。

3カラムで並べたり、均等幅で並べたり、行送りにしたり等様々な配置方法がありますが、ちょっとマニアックにピラミッド型に並べる方法を考えてみました。
誰かの参考になれば幸いです。

## ソース
```index.html
<p>
  <span>コンテンツ</span><br>
  <span>コンテンツ</span><span>コンテンツ</span><br>
  <span>コンテンツ</span><span>コンテンツ</span><span>コンテンツ</span>
</p>
```

```style.css
p {
  text-align: center;     /* 中央揃えにする */
}
p span {
  width: 160px;           /* 1要素の幅を指定 */
  border: 1px solid #000; /* 見やすいように線を入れる */
  text-align: center;     /* 文字を真ん中寄せにする */
  background: #CCC;       /* 背景色をグレーにする */
  display: inline-block;  /* インラインブロック要素にする */
  margin: 5px;            /* 余白を取る */
}
```

**結果**

![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/df536d13-f324-ba3d-c00a-0e815ed5054e.png)

## 解説

インラインブロック要素を中央揃えで並べて配置し、改行で1個、2個、3個と行を分けているだけですね。均等に綺麗になるように余白は全方向に同一に取っています。
**説明する必要もないくらい簡単な作りです。**

## まとめ

シンプルに作っていますので実用的に使うには親要素に最低幅を指定したり少し工夫がいるかもしれません。高さも揃いませんしね。
レベルアップしたものをまた考えて掲載できればと思います。

作ったはいいものの使い道がまだ思いついていないので、ぜひコメント等でいい使い道を一緒に考えていただきたいです。コメントお待ちしております！

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)
方言を翻訳しようともがいた(失敗作)

# 結論

失敗しました。改善すべき点を記録して、改善に取り組んでいます。
[苦しみの過程(github)](https://github.com/Bandolu/Hogen)

![output03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315665/776c9f66-583d-16cc-f2d9-2711b13953ce.png)

`<unk>`が「スガハッタ」に変換されている！~~錬金術かな？~~

## 原因
+ 方言訳はカタカナで書くことが殆ど
+ 形態素解析器はカタカナを分割しない
+ 1文＝1単語になった（画像のplotを見ると分かると思います）
+ 従って、`<unk>`に対応できない翻訳機となった

## 背景
+ 日英翻訳機が大量にある。他の言語もある。エスペラント語もある。
+ しかし、方言翻訳機はルールベースのものしかない（そもそも狙っている方言がマイナーなためか、翻訳機もない）
+ 今時自作するなら機械翻訳だよね！

## 使ったもの
+ ブラウザ(Chormeを使いました)
+ Google Colab
+ テキストエディタ

## やったこと
1. 方言アライメントを用意する（ネットサーフィンしまくりました）
1. アライメントをtsvに変換する(リポジトリ内 Hiraki_Sudahi.ipynbで実行可能です)
2. アライメントの方言訳がカタカナだったので、標準語をカタカナに開く**(ココが間違いだった)**
3. 参考ソースコードを用いてアライメントをベクトル化する
3. Tensorflowを用いて学習・予測する


### 参考にしたソースコード様

[kawasaki-kento/Transformer](https://github.com/kawasaki-kento/Transformer)
[SudachiPyで分かち書きしたきのメモ](https://qiita.com/dyamaguc/items/3e62541ac3add90bffa6)

#### 補足

良質なコーパスを入手できる環境などがありましたらコメント頂けると嬉しいです。
TensorよりTorchの方が楽かも知れないと思ったりしました。けど、ひとまずこれで一通り試したい所存。