OmniAICreator/Qiita-1.07M huggingface dataset:
【Linux入門】中野的Linuxのすゝめ 

こんにちは。最近Linux沼にハマったなっかのうです。

皆さんのお家に、サブ機として利用しているWin機、もしくは使ってない古いパソコンはありますでしょうか？

まあ誰しも１台くらいは余っているのではないでしょうか。

**そんなあなたに朗報です。**

**そのパソコンにLinuxを入れてみましょう！**

##Linuxとはなんぞや

Linuxとはなんぞやという人がほとんどだと思いますので説明していきます。

Linuxとは簡単にいえば「OSの一種」です。

OSと聞いて有名なのは、Windows、Mac OS。

AndroidやiOSなんかもOSの一種ですね。

そして、Linuxって何がいいかって、**無料なんです！**

無料って言うと語弊があるかもしれないですが、「オープンソース」なんです。

なので誰でも自由に入れることができるわけですね。（一部有料のものもあります。）

しかし、LinuxはLinuxという一種類ではありません。

いろいろな人が使いやすいように、Linuxといっても様々なLinuxがあります。

その様々な種類のLinuxのことを、「Linuxディストリビューション」といいます。

「Linux」という大きなベースの中に様々なトッピング（ソフトなど）を追加したのがまさにこれ。

####Linux＝「生地」で、ソフトウェア、ファイル＝「お好みの具材」というわけです。

![linux.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515312/e3c13666-9931-66a3-9930-61dec007e81b.png)

つまり、ピザと一緒でマルゲリータ、マヨコーンなど様々な種類があるわけですね。

そして、その完成済みのピザ（＝親となるLinuxのディストリビューション）をさらにアレンジすることもあります。


今回は、その色々あるLinuxの中で、3つのディストリビューションを紹介していきます。
推奨動作環境も一緒に載せますので参考にしてください。

##1.Ubuntu

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515312/6ea79c1d-012b-ce97-ae3d-fade4d9d38f8.png)
(引用:design.Ubuntu.com)

おそらく最も有名なLinuxディストリビューションで、いろいろな場所で使用されていてかつインストールも比較的簡単なものがUbuntuです。

初心者はまずインストールするべきLinuxはこれだと思います。

日本語環境も充実しているのでおすすめです。

推奨動作環境
- CPU 2Ghz デュアルコア
- RAM 4GB以上
- ROM 25GB以上

サイト:
日本語フォーラム[https://www.ubuntulinux.jp/](https://www.ubuntulinux.jp/)
公式[https://jp.ubuntu.com/](https://jp.ubuntu.com/)
##2.Linux mint

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515312/59a37651-7dc1-27c2-0e42-d7e029720327.png)
(引用:linuxmint-jp.net/)

こちらは先程のUbuntuよりも軽量で、古いパソコンを蘇らせるには最適なOSです。
日本語環境も充実しているのでこちらも安心です。
システム要件が低いので、古いCore2などのCPUを積んでいるパソコンなどでも動作します。

推奨動作環境
- CPU 記載なし
- RAM 1GB以上
- ROM 20GB以上

サイト:
日本語フォーラム[http://linuxmint-jp.net/](http://linuxmint-jp.net/)
公式[https://www.linuxmint.com/](https://www.linuxmint.com/)

##3.Q4OS

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515312/f2201f8e-2243-aceb-b056-64898f6bc4f4.png)

このOSは知名度はあまり高くありませんが、個人的にお気に入りなのでチョイスしました。

DebianというUbuntuと同じものがベースになっていて、なんと行っても、UIがWindowsと似ているので、Linuxにあまりなれていない人でも安心です。ただし、日本語導入でつまずきそうな部分がありそうなので、少しなれてから入れるのがおすすめです。

##まとめ

Linuxは沼にハマります。ハマる人には本当にハマります。

僕はハマるタイプでした。

なので、みなさんもハマってほしいと思いこの記事を作りました。（無慈悲）

Linuxライフ、始めてみませんか？
【React/Next.js】繰り返し文で生成したコンポーネント内のStateが更新されない件

## 結論
keyは一意にしましょう。

## 環境
* React 16.12.0

## 事象
1. 配列から`map`などを使って`useState`を使用しているコンポーネントを作成
1. 配列を並び替え
1. Stateが並び替え前のStateを保持している(泣)


例えば以下のような場合

```react
const = NameBox = (prop) => {
  const [name, setName] = useState(prop.name)
  return (
    <div> {name} </div>
  )
}

const Sample = () => {
  const names = [
    {id:1, name: "太郎"},
    {id:2, name: "花子"}
  ]
  return (
    <>
      {
        names.map((name, index) => (
          <NameBox name={name.name} key={index}/>
        ))
       }
    </>
  );
};
```

`names`をsortなど並び替えても、`useState`は走らず、`State`は更新されません。


## 原因
keyが同じだと更新されないらしい

```javascript
key={index}
```

ここがだめだったみたいです。
`key`を設定しないと怒られるのでいつも適当に`index`の値を渡していました。。。

## 再度 結論
keyは一意にしましょう。

例えばこう

```javascript
key={`${name.id}_${index}`}
```

`id`と`index`の組み合わせで`key`を作成する、とかですかね
testflightにアップするとITMS-90018: This bundle is invalid - The file extension must be .zip. 

#testflightにアップするとバイナリエラー
関わっていた案件の都合上[Monaca](https://ja.monaca.io/)というサービスを使っていた。
なのでtestflightへのアップは下記のようなコマンドで行った。

```console
xcrun altool --upload-app -f aaaaaaa.ipa -t ios -u sample@gmail.com -p password
```

Monacaでビルド→Monacaからipaファイルをダウンロード→👆のようなコマンドでtestflightにアップ。

するとtestflightへのアップロードは正常に終わりますが、、、

>Dear Developer,

>We identified one or more issues with a recent delivery for your app, "アプリ名" 0.0.5 (0.0.5). Please correct the following issues, then upload again.

>ITMS-90018: This bundle is invalid - The file extension must be .zip.

>Best regards,
The App Store Team

**このようなメールが届き、バイナリエラー。。。**


一体なぜ？？？！！！

#原因は全くエラーメッセージからは想像もつかない内容だった。。。
色々と検索してみたが、全くヒントになるような情報はなかった。。。

エラーメッセージの通りipaファイルをzip形式にしたりしたが、やはりダメだった:frowning2:

そんな中１つの記事に出会った

https://yoloabdo.medium.com/this-bundle-is-invalid-24-hours-of-error-3500e2322206

>That’s what I did, got it from an answer that says: Apple doesn’t allow using .App in your app name, I got stunned and looked to my app, and I was doing it, my app was XXX.App.

###結論、アプリ名が「.app」で終わるのはNG
と言うことでした！

**いやいや、エラーメッセージと全く関係なくね？zipがどうたらとか、何も関係あらへんやん！！**
インタープリタを作る その21

#概要

インタープリタを作ってみた。
avrインタープリター書いてみた。
加算addを実装する。

#投入するソース

9+2

```
avr.ldi(16, 0x09)
avr.ldi(17, 0x02)
avr.add(16, 17)
avr.out(1, 16)

```

#サンプルコード

```
	add: function(_Rd, _Rr) {
		var Rd = kan2(this.dataspace[_Rd]);
		var Rr = kan2(this.dataspace[_Rr]);
		var v = (Rd + Rr) & 0xff;
		this.dataspace[_Rd] = hen(v);
		var SREG = this.dataspace[this.sreg];
		this.PC++;
		this.dataspace[this.sreg] = SREG;
	},

```

#成果物

https://embed.plnkr.co/plunk/DbzS9AzTtPLz8meV

以上。
[Ruby]CSV.parseのheaders: trueありとなしでの比較

# 概要
CSV.parseに、headers: trueを渡した時とそうでないときでのデータ構造の違いを比較

headers: trueありの場合でしか使ったことがなかったので、このオプションがある場合とない場合で比較してみました。

rails consoleとrspecの```fixture_file_upload```を使って確認しています。


```cryptocurrency.csv
number,name,symbol
1,Bitcoin,BTC
2,XRP,XRP
3,Quant,QNT
```

## headers: trueなし
```
pry(main)> filepath = "/path/to/cryptocurrency.csv"

pry(main)> data = fixture_file_upload(filepath, "text/csv")

pry(main)> str = data.read
=> "number,name,symbol\n1,Bitcoin,BTC\n2,XRP,XRP\n3,Quant,QNT\n"

# 配列を要素に持つ配列で返ってくる
pry(main)> csv = CSV.parse(str)
=> [["number", "name", "symbol"], ["1", "Bitcoin", "BTC"], ["2", "XRP", "XRP"], ["3", "Quant", "QNT"]]

pry(main)> csv.class
=> Array

pry(main)> csv.count
=> 4




```

## headers: trueあり

```

pry(main)> csv = CSV.parse(str, headers: true)
=> #<CSV::Table mode:col_or_row row_count:4>

pry(main)> csv.class
=> CSV::Table

pry(main)> csv[0].class
=> CSV::Row

# row_countが4だけど、csv.countが３は何でだろうと思ったけど、csv.countはデータ行のカウントだけを返すのだと理解
pry(main)> csv.count
=> 3

pry(main)> csv.headers
=> ["number", "name", "symbol"]

# to_aで、CSV.parse(str)と同じ結果が返ってくる
pry(main)> csv.to_a
=> [["number", "name", "symbol"], ["1", "Bitcoin", "BTC"], ["2", "XRP", "XRP"], ["3", "Quant", "QNT"]]

pry(main)> csv[0]
=> #<CSV::Row "number":"1" "name":"Bitcoin" "symbol":"BTC">

pry(main)> csv[1]
=> #<CSV::Row "number":"2" "name":"XRP" "symbol":"XRP">

pry(main)> csv[2]
=> #<CSV::Row "number":"3" "name":"Quant" "symbol":"QNT">

pry(main)> csv[3]
=> nil

pry(main)> csv.each do |row|
pry(main)*   p row
pry(main)* end
#<CSV::Row "number":"1" "name":"Bitcoin" "symbol":"BTC">
#<CSV::Row "number":"2" "name":"XRP" "symbol":"XRP">
#<CSV::Row "number":"3" "name":"Quant" "symbol":"QNT">


```

headers: trueなしの場合は、CSVの各行が配列になって、それらが全て配列に入っているみたい。

headers: trueありの場合は、CSVの先頭行はヘッダー扱いで、データ行は、CSV::ROWというオブジェクトになって
```<CSV::Row "number":"1" "name":"Bitcoin" "symbol":"BTC">```のようなHashとなり、ヘッダーがKeyになるみたいだということが改めて分かりました。

row_countが4だけど、csv.countが３が一番もやっとしました。

row_countが４だから、csv[0]で、ヘッダーが返ってくるかと思ったら、そうでないし。

分かりにくなあと個人的に思いました。
Herokuデプロイ後にActionView::Template::Error (Mysql2::Error: Table --- doesn't exist):

課題アプリが完成したので、Herokuにgit push heroku masterしてアクセスしたところ

```
ActionView::Template::Error (Mysql2::Error: Table --- doesn't exist):
```

というエラーが。

訳すとテーブルが存在しませんよ、というエラーみたいですね。

そういえば振り返るとマイグレーションしてなかったかも。

```
heroku run rails:db:migrate
```

これをすれば解決ですね。

https://qiita.com/rm_rzr/items/8cf3f7227082ce7a3dc6
Rails controllerでdef newでインスタンス変数を定義する意義。

![スクリーンショット 2021-06-18 16.44.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1603537/f32484ca-42ce-72a6-51a6-725b8d771d1b.png)
記事にタグ付けをする簡単なアプリを作っていたところで、エラーが出ました。

![スクリーンショット 2021-06-18 16.44.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1603537/cf330b71-fe8a-248c-5693-22fe561f4917.png)

```app/controllers/tweets_controller.rb
class TweetsController < ApplicationController
  def index
    @tweets = Tweet.all.order(created_at: :desc)
  end

  def create
    @tweet = TweetsTag.new(tweet_params)
    if @tweet.valid?
      @tweet.save
      return redirect_to root_path
    else
      render "new"
    end
  end

  private

  def tweet_params
    params.require(:tweets_tag).permit(:message, :name)
  end
end
```

```app/models/tweets_tag.rb
class TweetsTag

  include ActiveModel::Model
  attr_accessor :message, :name

  with_options presence: true do
    validates :message
    validates :name
  end

  def save
    tweet = Tweet.create(message: message)
    tag = Tag.where(name: name).first_or_initialize
    tag.save

    TweetTagRelation.create(tweet_id: tweet.id, tag_id: tag.id)
  end

end
```

動きとしては投稿したときにストロングパラメーターでtweets_tagモデルに:message, :nameをpermitで値を渡します。

そしてapp/models/tweets_tag.rbが走るわけです。
[プリンシプルオブプログラミング] セオリーと基本原則

# プログラミングセオリー
プログラミングの最大の関心事は最高のコードを作り上げること。
最高のコードとは、拡張性が高く、余分な要素が無く、読みやすいコードのことです。
そのコードに到達するのは、3つの価値が重要になります。

- コミュニケーション
- シンプル
- 柔軟性

## 価値観を技術の選択に
上記に上げた価値を、技術の選択基準にしましょう。
プログラミングは、問題解決を目的としています。エンジニアとしては、技術を知る、理解する、覚えるというのは重要ですが、技術を知っていても「使える」ようにはなっていません。

## 価値観は原則を通じてコードに適用
価値観を判断に使用しましょう。技術や手法の適用、不適用などの判断が正確になります。
しかし、価値をそのままプログラミングに使用するには抽象的すぎます。なので、価値をプログラミングに橋渡しをする６つの原則を使用して、価値を適用しましょう

- 結果の局所化
- 対称性
- 繰り返しの最小化
- ロジックとデータの一体化
- 宣言型の表現
- 変更頻度

# シンプル
## コードの複雑性を排除する
コードから余分な複雑性を排除し、シンプルに保ちましょう。
余分な複雑というのは、問題解決をしようとし、どうにかコードを動かそうとして出来た「余分な複雑性」のことです。

## コードの複雑性は禍根となる
余分な複雑性に価値はありません。
ソフトウェアの動作に不安定さをもたらすどころか、コードの難読さが上がります。また、将来性の無いコードになります。
余分な複雑性を排除したコードはシンプルになります。完結なコードは障害が入る可能性が少なくなります。

# ロジックとデータの一体化
ロジックとロジックが操作するデータは近ければ近いほど良いコードになります。

## ロジックとデータの修正タイミングは同じ
ロジックとデータの修正は大抵の場合、同じタイミングで発生します。
なので、それらの処理が同じ部分や近い位置にあると修正も容易になります。

## データと操作は同じ場所に
ロジックとデータを、コード上で同じ場所に配置します。
初めからベストな場所なんてわかりません。のちに修正が入ることを見越して、同じ場所や近くにセットで置いておくことで、修正が容易になります。

# 対称性
## コードに一貫性を持たせる
対称性とは、ある操作に対して不変であるということです。対称性のあるコードとは、どこの部分に現れても同じように表現されるコードのことをいいます。

## 同じ部分を類推出来る
コードで対称性を特定し、明確に表現することができれば、格段に読みやすくなります。
また、対称性にすることによって、まったく同じ処理をしているコードの存在に気づくことが出来ます。それらを一個のコードで表現すれば、重複しているコードの量も減り、読みやすさがまた一段と上がります。

# 7つの設計原理
設計原理とは、コードに障害が入らないように定めた、コードの構造上の核心観点です。
この原則は、開発現場の分析した結果から導き出された、こうしたほうが良いという経験則です。
この原理は、コードレビュー時に使用します。

- 単純原理
- 同型原理
- 対象原理
- 透明原理
- 安全原理
- 線形原理

## コードの価値観が漏れない、ブレない
ソフトウェアの品質を担保するのにコードレビューはかなり有効です。
しかし、レビュワーがそれぞれ違う価値観を持っていたり、観点が違っていたりすると指摘が散漫になります。
レビューの観点に一貫性が無いと、品質は劣化します。そのため、この７原則に従ってレビューをすることでレビュワーの価値観、観点を統一して品質を担保出来るようにします。

### 単純原理

- シンプルにこだわる
- 自然なコードを書く
- 複雑なコードを書かない

### 同型原理
- 処理の形にこだわる
- 形の違うものに敏感になる
- 一貫性のあるコードを書く

### 対称原理
- コードの処理の対称性にこだわる
- 条件のあるものは反条件がある
- 命名の対称性にこだわる

### 透明原理
- 副作用を起こすコードを避ける
- 処理は一直線になるようにする
- 分岐の少ないコードを書く

### 安全原理
- コードや設計の安全性にこだわる
- 「例外的な処理」を考慮して書く
- 機能の必要十分を満たすまでは最小限にする
Rails アプリ名を変更する方法


##はじめに

Railsの学習をしている際、作成したいモデル名がアプリ名と被ってしまったため、アプリ名を変更することにしました。

脳死でファイル名をRenameしようと思いましたが、諸々不便が起きる可能性があると思い、調べながら変更をしました。

そのやり方をここにまとめようと思います。

####1: GemfileにrenameというGemを追加する

```Gemfile.
  gem 'rename'
```

ターミナル上で反映

```ターミナル.
$ bundle install
```

<br>

####2: データベースの削除

データベースを作成していた場合は削除します。

```ターミナル.
$ rails db:drop 
```

<br>

####3: アプリ名を変更するコマンドを実行

```ターミナル.
$ rails g rename:into 新しいアプリ名
```

<br>

####4: データベースを再構築

新しいアプリ名に`cdコマンド`で移動してからコマンドを実行

```ターミナル.
$ rails db:create
```

```ターミナル.
$ rails db:migrate
```

<br>

これで完了！


##さいごに

なにごとも初体験は脳死でやるのは良くないですね。
Laravel クエリビルダでSQLの絞り込み条件の括弧を表現する

# 目的

- LaravelのクエリビルダにてSQLのwhere句部分で括弧を使った条件記載をどのように表現するかをメモ的にまとめる

# 情報

- 下記のようなSQLがあったとする。

    ```sql
    select * from users 
    where admin_flag = 1
    and (test_user_flag = 1 or master_user_flag = 1);
    ```

# 方法

- 「情報」に記載されたSQLをクエリビルダに落とし込むと下記のようになる。

    ```php
    $query = User::select('*')
    ->where('admin_flag', '=', 1)
    ->where(function($query) {
        $query
            ->where('test_user_flag', '=', 1)
            ->orWhere('master_user_flag', '=', 1);
    })
    ->get();
    ```
MySQL　小数値だからといって、気軽にFLOAT型を使うと痛い目を見る

# 小数型を扱うときは気にしたほうがいい
面積を扱う機会があり、「mysql 小数」でググって出てきた記事をうのみにして実装したところ、以下のような現象が発生しました。

```sql
CREATE TABLE DATA (ID INT, MENSEKI FLOAT);
INSERT INTO DATA (ID, MENSEKI) VALUES (1, 2.1);
SELECT COUNT(*) FROM DATA WHERE MENSEKI >= 2.1;
--1件該当
SELECT COUNT(*) FROM DATA WHERE MENSEKI >= 2.1 AND MENSEKI <= 2.1;
--NOT FOUND !?
SELECT COUNT(*) FROM DATA WHERE MENSEKI <= 2.1;
--NOT FOUND !?
```

ただし、あらゆるレコードで発生するのではなく、小数点以下がゼロでないレコードでこの現象が発生します。

これは、以下のSQLを実行するとわかります。

```sql
SELECT MENSEKI + 0 FROM DATA;
--2.0999999046325684
```

要は、INSERTされた値は、SELECTで与えているリテラル値と違うんですね。
これは、FLOAT型が　IEEE754単精度浮動小数点数　で格納されているためです。

# 解決策
- DECIMAL(10,2) 型を利用したら、期待通り動作した
- FLOAT(10,2) と桁を指定したら期待通り動作した
- DOUBLE を利用したら期待通り動作した

# 追記
@reta さんコメントありがとうございます。
基本的に理由がなければ DECIMAL を利用すべきとご意見いただきました。
面積程度の値なら、浮動小数点を使う必要ないということだと思いました。

# まとめ
構築時にユースケースになくても、こういう単体テストはちゃんとやったほうがいい。
やらないと「バグ」って言われます・・・・
credential.yml.encが編集できない

Dockerで環境構築を行っており、今回本番環境をAWSのRDSにつないで構築しようとしていました。しかし、`credential.yml.enc`ファイルの編集ができず、躓いてしまったので共有します。遭遇したエラーを順番に記載していきます。


##docker-compose upできないエラー

まず、`credentail.yml.enc`ファイルの編集する前段階でdocker-composeすら立ち上がらない状態になりました。`database.yml`のproductionを下記のようにまず直すことでdocker-composeが立ち上げられる状態になりました。

```
before

production:
  <<: *default
  host: <%= Rails.application.credentials.rds[:host] %>
  database: <%= Rails.application.credentials.rds[:database] %>
  username: <%= Rails.application.credentials.rds[:username] %>
  password: <%= Rails.application.credentials.rds[:password] %>
```

```
after

production:
  <<: *default
  database: sanpomiti_app_production
  username: sanpomiti_app
  password: <%= ENV['SANPOMITI_APP_DATABASE_PASSWORD'] %>
```

##credential.yml.encが編集できないエラー
dockerコンテナの中でvimを使い、`credential.yml.enc`を編集しようとしますが、vimが立ち上がらず、`New credentials encrypted and saved.`のメッセージが出ました。

```
mac-no-MacBookPro:Sanpomiti_app mac$ docker-compose exec web bash
root@XXXXXXXXX:/sanpomiti_app# EDITOR="vim" bin/rails credentials:edit
New credentials encrypted and saved.
```
試しにbashにvimと打ち込むとvim自体立ち上がらず、vim自体がinstallされていないことが分かりました。installコマンドを実行し、無事解決しました。

```
apt update
apt install vim -y
```
あとは`EDITOR="vim" bin/rails credentials:edit`と入力した後、`credential.yml.enc`を編集し、`database.yml`を元に戻しました。

参考
https://qiita.com/YumaInaura/items/3432cc3f8a8553e05a6e
https://teratail.com/questions/210166
JavaScript初学者のさだまさし

こんにちは。
もしもさだまさしさんがjavaScriptを学んだらどうなるのか考えてみました。

※ネタ

ソース

```js:script.js
    function kanpaku(){
        console.log(関白)
    }
    kanpaku()
```



#「関白宣言」を試みる！しかし...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515312/34d9a8c6-248d-1c9a-bbed-5a9dde890b16.png)

これは関白失脚ですね...
unknown attribute 'email' for Staff::LoginForm.






Staff::LoginForm classに emailがないよと仰っておられます。最初はカラム名違いを疑いましたが、マイグレーションファイルは問題ないようです。![スクリーンショット 2021-06-18 18.37.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1286751/2695129e-768d-69b4-82d4-31aaf4a1bfef.png)


rails cでコンソールに入り、Staff::LoginForm.newを入力。


```ターミナル
NoMethodError (undefined method `attr_acceser' for Staff::LoginForm:Class)
Did you mean?  attr_accessor
               mattr_accessor
```
attr_accessorじゃないの？と仰られてます。attr_acceserをvscodeの検索窓で検索。

<変更前>

```login_form.rb
class Staff::LoginForm
  include ActiveModel::Model
  attr_acceser :email, :password
end
```


<変更後>

```login_form.rb
class Staff::LoginForm
  include ActiveModel::Model
  attr_accessor :email, :password
end
```

無事に解消しました。
オンプレからx86サーバーのNAT経由でPower Systems Virtual Serverへの通信を行う

オンプレミスからPower Systems Virtual Server（Power VS）に接続する際、VPNルータ等を置くことなく、なるべく簡易に繋ぎたい、という要件が時々あります。

Power VSに標準で払い出されるExternal IPも利用可能ですが、Power VSサービス側の共有Firewallを通るため、使えるポートが決まっていて個別のFirewallルールを設定できない等、制約があります。
https://cloud.ibm.com/docs/power-iaas?topic=power-iaas-network-security

x86に配置した仮想サーバーでDNAT+SNATする事で、端末 -> （インターネット）-> x86サーバー -> (Direct Link Connect)  ->  Power VS　の経路で通信できる事を確認しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59627/dd555e19-597d-5a7a-26d6-3ec283be8fd7.png)

この方法だと、x86仮想サーバーのSecurity Groups（無償のL4 Firewall機能）もかけられるので、クイックに繋ぎたい時には悪くない選択肢と言えるかもしれません。

下記が問題ない事が条件となります。
・プロトコルとしてNAT変換がOKである事。
・VPNを使わないので、通信がそのままインターネットを通る事。（プロトコルとして暗号化されているなら許容可能と考えます（下記の例では検証なのでhttpを使いましたが...））

事前準備
・x86仮想サーバーとPower VSをオーダーします。OSに直接パブリックIPが付いていた方がNAT設定しやすいと考え、x86はClassic環境にしました。
・x86とPower VSの間のDirect Linkは接続済みとします。手順は下記の項番2です。
https://qiita.com/y_tama/items/eb8d6e3d54197a569e25

#x86からPower VSは疎通している事を確認

今回はhttpで試すので、Power VS上のAIXにWebサーバーを立てました。
まずはx86から通信できることを確認します。


```:x86からcurlで確認
# curl http://192.168.150.195
This is AIX web server.
# 
```


#x86仮想サーバーでNAT設定
（下記のコマンドだと、OS再起動すると設定が消えますので、適宜、永続化してください）

まず、パケット転送を有効化します。

```:パケット転送を有効化
# sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1
# 
```

x86サーバーのパブリックIPアドレスに来たport 80の通信を、Power VSのIPアドレスにDNATします。

```:DNAT
iptables -t nat -A PREROUTING -p tcp -d 161.202.xx.xx --dport 80 -j DNAT --to-destination 192.168.150.195:80
```

また、Power VSからの戻りのパケットが戻れるよう、x86サーバーのプライベートアドレスにSNATしてPower VSに送ります。

```:SNAT
iptables -t nat -A POSTROUTING -p tcp -d 192.168.150.195 --dport 80 -j SNAT --to-source 10.129.177.42
```

iptables内容の確認。

```
# sudo iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DNAT       tcp  --  anywhere             tamavsi03.IBM.cloud  tcp dpt:http to:192.168.150.195:80

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
SNAT       tcp  --  anywhere             192.168.150.195      tcp dpt:http to:10.129.177.42
# 
```

#x86サーバーのSecurity Groups設定
port 80のインバウンドを許可します。下記では設定していませんが、Sourceに、クライアント端末に割り振られるグローバルIPのアドレス範囲を設定すれば、接続元を制限できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59627/913c545e-67d3-0e9b-2ddf-07072404b4c4.png)


オンプレミスの端末のブラウザから、x86仮想サーバーのグローバルIPアドレスを指定すると、AIXのwebサーバーが応答するようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59627/d64516f9-6da3-3f99-c291-71e1b4f247d3.png)
pyenv インストール　忘備録

###pyenv　インストール
***
経緯
インストールの際に、全然切り替えができなかくて、2.3時間かかってしまった。
（progateを見てやったんだけど、全然できへんやん、、、）
***

```
brew install pyenv

pyenv install 3.8.5

pyenv versions 
 * system (set by ~/.pyenv/version)
 3.8.5

pyenv global 3.8.5
 system (set by ~/.pyenv/version)
 * 3.8.5
python --version
 python 2.7.5

#あれ、、、、
#切り替わってないやん、、、、
```

***
#####切り替えることができた方法
上記の方法をしてから、以下をしていくと成功した。

```
pyenv int

# (The below instructions are intended for common
# shell setups. See the README for more guidance
# if they don't apply and/or don't work for you.)

# Add pyenv executable to PATH and
# enable shims by adding the following
# to ~/.profile and ~/.zprofile:

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)"

# Load pyenv into the shell by adding
# the following to ~/.zshrc:

eval "$(pyenv init -)"

# Make sure to restart your entire logon session
# for changes to profile files to take effect.
```
ここに書いてる通りやってみよ〜

```
vim .zprofile　
#以下を記述〜
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)"
#:wq で保存


vim .zshrc
#以下を記述〜
eval "$(pyenv init -)"
#wqで保存

```

ここで完了したと思ってたけど、ロードするおまじないを忘れてた自分ので一応書いておこーう

```
source .zshrc
sorce .zprofile

```

***
確認〜

```
python --version
3.8.5
```

2,3時間かかってしまった、、、
まぁ、解決できてよかった。
Raspberry Piで起動画面を完全に出さない

Raspberry Piでkiosk端末を作る際やcvlc/omxplayerなんかでデジタルサイネージ化するときに便利です。

## 起動画面を非表示

/boot/cmdline.txtの`rootwait`の後に`logo.nologo quiet vt.global_cursor_default=0`を追加
`console=tty1`を`console=tty2`に変更

```sh
$ sudo vi /boot/cmdline.txt
```

```text:/boot/cmdline.txt
console=serial0,115200 console=tty2 root=PARTUUID=4e354646-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait logo.nologo quiet vt.global_cursor_default=0
```

### 解説
#### console=tty1 -> tty2

起動ログの出力先をtty2に変更
※tty2がどこなのかよくわかってません。

#### logo.nologo

起動時のレインボースプラッシュを非表示にする

#### quiet

カーネルログ出力を出さない

#### vt.global_cursor_default=0

カーソルをチカチカさせない

#### ログインプロンプトを出さない

```sh
$ sudo systemctl disable getty@tty1.service
```
【Rails】form_withのsubmitボタンを画像にする方法

## はじめに

オリジナルアプリ作成の際に実装したので、アウトプットします！

## 実装したいこと

Railsのform_withのsubmitボタンを画像に変更する。

## 実装方法

image_submit_tagを使う！

```ruby:qiita.html.erb
<%= form_with(url: search_foods_path, local: true, method: :get, class: "search-form") do |f| %>
  <%= f.text_field :keyword, placeholder: '料理名で検索', class: 'input-box' %>
  <div class="search-button">
    <%= image_submit_tag("search.png", class: 'search-icon') %>
  </div>
<% end %>
```

## その他の方法

button_tag要素をしようして、typeにsubmitを指定する。
そして、ブロックでimage_tag要素を渡す！　

```ruby:qiita.html.erb
<%= form_with(url: search_foods_path, local: true, method: :get, class: "search-form") do |f| %>
  <%= f.text_field :keyword, placeholder: '料理名で検索', class: 'input-box' %>
  <%= button_tag type: :submit, class: "search-button" do %>
    <%= image_tag "search.png", class:"search-icon" %>
  <% end %>  
<% end %>
```

##参考リンク

https://railsdoc.com/page/image_submit_tag 
https://railsdoc.com/page/button_tag

##終わりに
間違い等あればご指摘いただけると嬉しいです！
How to return different value of mock function based on arguments in test in python?

While implementing unit test in python, we need to replace some of the functions with the mock objects and perform the necessary assertions. These mock objects can be configured to specify the return values. In addition to this, we can also specify the return values based on the arguments of the function that has been mocked.

For instance, let's assume ee have a function below that needs to be tested

```python
def dummy_function(param1, param2):
    return param1 + param2
```
Normally, the way we mock this function is 

```python
test_value = MagicMock(return_value="tested!")
```

Or if we want to call a function multiple times and return different output in each call it can be achieve as
 
```python
test_value = MagicMock(side_effect=["result1", "result2"])
```  

This will just return the value of the function without caring about the parameters provided to it.

However, we might also want to test based on the arguments of a functions such that `when function args is 'foo' then function return 'bar' else it returns something else`. 

In such situation, we can take the advantage of side_effect. Using side_effect we can control the behavior of our mock objects and instruct it to return something when the value is something. Let's look at how we can do this.

One way is to create a function with your own side_effect.

```python
from unittest.mock import MagicMock, patch

def args_based_return(*args, **kwargs):
    if args == (10, 10):
        return 20
    elif args  == (20, 20):
        return 40
    else:
        return Exception("exception occurred")

m = MagicMock(side_effect=args_based_return)
m(10, 10)
>> 20

m(40, 40)
>> exception occurred
```

Another way is by using the lambda function

```python
m = MagicMock()
m.side_effect = lambda *x: {
        (10, 10): 20,
        (20, 20): 40,
        (30, 30):  60
    }[x]

print(m(30, 30))
>> 60

print(m(20, 20))
>> 40
```
Flutterでシェア機能を持ったアプリを作成する

こんな感じのテキストをシェアするアプリを作ります（これはアプリと言っていいのか...？w）

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365643/38df8acd-19d1-d20e-d8ea-601b5ec3d5c3.png" width="250" />


シェアする機能を使うために、[share](https://pub.dev/packages/share) というライブラリを使います。

## pubspec.yamlにshareを追加する

```bash
# コマンドを実行する
$ flutter pub add share
```
or

```yaml
# pubspec.yamlに直接書き込む
dependencies:
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.2
  
  # 追加
  share: ^2.0.4
```

## AppBarのシェアアイコンで共有できるようにする

`Share.share()`に共有したいテキストを渡します。

```dart
@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: const Text('Share Sample'),
      actions: [
        // シェアボタン
        IconButton(
          icon: Icon(Icons.share),
          // シェアボタンをクリックしたときに呼ばれる処理
          onPressed: () => _share(),
        ),
      ],
    ),
  );
}

void _share() => Share.share('共有するテキスト');
```

これで`AppBar`のシェアアイコンをクリックすると、共有するためのボトムシートが表示されます。

`r（Hot reload）`または`R（Hot restart）`したときに以下のエラーが発生したら、一度アプリを止めて`flutter run`を実行すれば、エラーが消えると思います。

```
E/flutter (28335): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: MissingPluginException(No implementation found for method share on channel plugins.flutter.io/share)
E/flutter (28335): #0      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:156:7)
E/flutter (28335): <asynchronous suspension>
```

また、シェアするテキストが空だと、エラーが発生します。

```
'package:share/share.dart': Failed assertion: line 40 pos 12: 'text.isNotEmpty': is not true.
```

## 全体のコード

```dart
import 'package:flutter/material.dart';
import 'package:share/share.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Share Sample',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Share Sample'),
        actions: [
          IconButton(
            icon: Icon(Icons.share),
            onPressed: () => _share(),
          ),
        ],
      ),
    );
  }

  void _share() => Share.share('');
}
```
FlutterのforEachで「async/await」を使う

早速結論ですが、`Future.forEach`を使います。

```dart
// 例: idでItemオブジェクトを取得してリストに格納する。
Future loadItems() async {
  
  List<Item> items = [];

  await Future.forEach(_ids, (id) async {
    // findByIdメソッドで、DBまたはWebAPIからitemオブジェクトを取得する。
    Item item = await _itemRepository.findById(id);
    items.add(item);
  });
  
  ...
}
```

最初は以下のように実装していたので、forEachの処理が終わる前に次の処理が呼ばれてました...。

```dart
// Bad！！
Future loadItems() async {
  
  List<Item> items = [];

  _ids.forEach((id) async {
    Item item = await _itemRepository.findById(id);
    items.add(item);
  });
  
  ...
}
```
【kotlin】when式

#■When式とは
if文のような条件分岐する時に使うもの
分岐させる条件が多い場合when式の方がコードがシンプルになります。
他言語で言うswitch文です。

####■基本の書き方
引数と値が一致すればそれ専用の処理が行われる。

``` kotlin
//基本の形
when(引数) {
   値a -> 値aの時の処理
   値b -> 値bの時の処理
   値c -> 値cの時の処理
}

//処理が複数行の場合は{}をつける。
when(引数) {
   値a -> { 値aの時の処理
            値aの時の処理2 }

   値b -> { 値bの時の処理
            値bの時の処理2 }

   値c -> { 値cの時の処理
            値cの時の処理2 }
}

```

####■結果を返す事ができる。
when式の結果を返し変数に入れたりできる。

``` kotlin
var num = 3
//when式の結果を変数に入れ込んでる。
var value =  when(num) {
      0 -> "0です。"
      1 -> "1です。"
      2 -> "2です。"
      3 -> "3です。"
}

printlin(value)
//結果: 3です。

```

####■カンマ,を使い複数の値で同じ処理に分岐させる。
値,値で複数の値を設定できる。

``` kotlin
var num = 3

var value = when(num) {
     //,を使い複数の値を設定してる。
      0,1 -> "0か1です。"
     //,を使い複数の値を設定してる。
      2,3 -> "2か3です。"
     //,を使い複数の値を設定してる。
      3,4 -> "3か4です。"
}

println(value)
//結果: 3か4です。
```

####■inによる範囲指定での判定方法
▼in 値a..値b
引数が1~5の間と言った実装ができる。

▼引数の範囲が重なっていれば上から先に実装される
0~5と4~9などの事

``` kotlin
var num = 12

var value = when(num) {
     //0~5の値を設定
     in 0..5 -> "0~5の値です。"
     //6~10の値を設定
     in 6..10 -> "6~10の値です。"
     //11~15の値を設定
     in 11..15 -> "11~15の値です。"
}

println(value)
//結果: "11~15の値です。"
```

####■引数のないwhen式
引数を持たないので
今までの値aなどの候補を条件式に変える。
whenの横の()がいらない

``` kotlin
var num = 12

when {
　  //条件式にする。
  num == 3 -> println("3です。")
  //条件式にする。
  num == 5 -> println("5です。")
  //条件式にする。
  num == 12 -> println("12です。")
}

//結果: 12です。
```

####■when式を関数に入れ込む

Function with an expression body」を利用している。

``` kotlin
//関数に直接when式を入れ込んでいる。
fun get(num: Int) = when(num) {
   0 -> println("0です。")
   2 -> println("2です。")
   3 -> println("3です。")
   else -> println("それ以外")
}
//関数で引数を入れwhen式を呼び出している。
get(3)
//結果: 3です。
```
【AWS】クライアント～API Gateway～Lambda～S3における、上手くいった型変換表および実装例


# 概要

https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/lambda-proxy-binary-media.html

> AWS Lambda プロキシ統合からバイナリメディアを返すには、base64 で Lambda 関数からのレスポンスをエンコードします。

LambdaおよびLambdaプロキシ統合利用時（今回はAPI Gateway）は上記のように、base64にエンコードしておく必要がある。
このようなやり取りの作法にもとづきながらクライアント側から横断的に纏めた型変換特化ドキュメントを、半分自分用に掲載する。

# 環境

```
クライアント側nodejs:v14.15.5
Lambda：Node.js 12.x
```

# 本ドキュメント想定対象

* 自分。「こういう変換すれば上手くいきました」と他の人に見せたりコードを再確認する時。
* Lambdaプロキシ統合でバイナリファイルを取り扱おうとして躓いている人
* AWS構築時に「他の人のデータ型のやり取り成功例を見たい」と思ってる方

# 各連係における、バイナリファイルの型表


| ローカル⇔クライアント | クライアント⇔API Gateway | API Gateway⇔Lambda | Lambda⇔S3(AWS側ストレージ） |
|:-:|:-:|:-:|:-:|
| File(blob)⇔File(blob) or base64(String)  |  base64(String)⇔base64(String) | base64(String)⇔base64(String)  | base64(String) or File⇔File  |


上記のようにAPI叩いたり返す時に文字列でやり取りすることで、他の引数と同じようなやり取りが可能となり上手くいった。

# 微妙に躓いた各型変換


##File(アップロードされたファイル)→base64(String)、ブラウザ上の動作を想定。

https://developer.mozilla.org/ja/docs/Web/API/FileReader/readAsDataURL

> メモ: blob の result は、先に Base64 でエンコードされたデータの前にある Data-URL の宣言を削除しておかないと、直接 Base64 としてデコードすることができません。 Base64 でエンコードされた文字列のみを受け取る場合は、先に結果から data:*/*;base64, を削除しておく必要があります。

```
// "data:*/*;base64,base64文字列" → "base64文字列"
    var base64result = this.contents.split(",")[1];
```

##base64(String)→Buffer、node.js内部の動作を想定。

https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings

```
    var bufContents = Buffer.from(contents, "base64");
```


##Buffer→base64(String)、node.js内部の動作を想定。

https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings

```
    buf.toString('base64')
```



##base64(String)→File(blob)、ブラウザ上の動作を想定。

https://qiita.com/kke1229/items/5fb05b3a5381cfbcd9be

この方のコードを参考にさせていただきました。多謝。

```
//Base64とMIMEコンテンツタイプからBlobオブジェクトを作成する。
function toBlob(base64, mime_ctype) {
  var bin = atob(base64.replace(/^.*,/, ""));
  var buffer = new Uint8Array(bin.length);
  for (var i = 0; i < bin.length; i++) {
    buffer[i] = bin.charCodeAt(i);
  }
  // Blobを作成
  try {
    var blob = new Blob([buffer.buffer], {
      type: mime_ctype
    });
  } catch (e) {
    return false;
  }
  return blob;
}
```
Flutterの便利なDropDownButton

FlutterではデフォルトでDropDownButtonがありますが、↓こちらのライブラリを使ったほうが便利です。

https://pub.dev/packages/dropdown_search2

理由はプロパティが多くて、デフォルトの装飾が綺麗だからです。装飾はもちろん変えられます。


※１点だけ注意があります。

こちらのライブラリのデフォルトでは、ドロップダウンのメニューと選ばれた値の間に隙間があるので、

popupSafeArea: PopupSafeArea(
                    top: false,
                  ),
で消してあげましょう。



![S__51494914.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1007371/1c52b54e-8162-e051-3085-9476a55d04f2.jpeg)
【初学者による】Ruby on Rails 5から6のバージョンアップの注意点

# どういう記事か
今まで5で開発していたけど6にしてみたい、という初学者向け記事。
細かい追加機能とかはいいから
バージョンアップするうえで最低限の知識だけが知りたい、という方向け


より詳細な変更点は有識者の素晴らしい記事を参照ください

https://qiita.com/ryohashimoto/items/622c3bcfb3336cb9317e


#  最低限憶えておくこと
```yarn``` と ```webpacker```が標準採用されたため、
これらがインストールされていないとrails sなどのタイミングでエラーが発生します

#### yarn
**Node.jsで使うパッケージマネージャー**

**Node.js**で動作するJavaScriptフレームワーク、ライブラリ、プラグインなどのパッケージのインストールを簡単にしたり、バージョンの不整合が起きないように管理するためのツール。

yarnと似た**npm**という子もいるが、ほぼ同じ機能

####ちなみにNode.jsとは
JavaScriptでサーバーサイドの処理を可能にさせるプログラム
本来Javaはフロントエンドの言語だけど
サーバーサイドの処理もできたらいいな、という要望をカタチにしたスゴイやつ


####Webpacker
**Webpack**をRailsに良い感じに取り込めるgem

**Webpackとは**
JSファイルやCSS、画像などを一つのファイルにまとめるためのツール（モジュールバンドラー）


###まとめ
yarnはJSライブラリのインストールおよびバージョン管理ため、
WebpackerはJSファイルを


# インストール方法
じゃあこの二つをどうすればいいの

###yarn

```:ネイティブOS(自分のパソコンの場合)
①　$ npm install -g yarn
②　プロジェクトフォルダに移動 $ cd ~~)
③　$ yarn set version berry
④　$ yarn set version latest  (最新バージョンへの更新)
```

参照：https://yarnpkg.com/getting-started/install#about-global-installs


```:cloud9などクラウドIDEの場合
source <(curl -sL https://cdn.learnenough.com/yarn_install)
```

###Webpacker

gemをインストール

```ruby:Gemfile
gem 'webpacker', github: "rails/webpacker"
```

```
$ bundle install
```

プロジェクトにwebpackerをインストール

```
$ rails webpacker:install
```
サマーインターンの面接を受けて評価されたこと、学んだこと

#自己紹介
iOSエンジニアを目指している大学生で23卒です。

サーマーインターンの選考で面接を受けてきました。
どういうことを評価されたり学んだのか、これからどう勉強していこうってことを記事にしたいと思います。

###努力の方向性は合っているのか
サービスを作るとかGitHubで草生やすとか、アウトプットをしまくる。
これは正解で、実際評価されて、これからもアウトプットを続けようと思いました。

###チーム開発
gitやらDiscode使って、チーム開発をしていると言ったら、評価されました。
したことない方は、就活本番までに経験しておくと評価上げられるかも。

###アンテナを張る
iOSでいうところの「WWDC2021」で興味あったことを答えられる様にしておくとか。
しっかり情報収集しようと思いました。

###デザインの勉強
デザインの重要性を学びました。
デザインをこれまであまり勉強していなかったので勉強しようと思いました。
クライアント側は全員やったほうがいいかも。
iOSだとHIGとか、本だと「なるほどデザイン〈目で見て楽しむ新しいデザインの本。〉」とか？

###新卒に求められる力
2つ教えて貰えました。
#####1つ目はiOSでいうSwiftUIとか「先見の明」があるかどうか。

#####2つ目は熱意すなわち、「アウトプット」をしているかどうか。

です。
ここら辺を意識して、これからも勉強を続けたいと思いました。



###おわりに
・実際に面接をして凄く勉強になりました、受けたことない人は受けよう。
・訊かれなかったけど、アーキテクチャとかそういうところも勉強しておこう。
オラクルSQLの知識習得 


# 今週の学習課題
・ オラクルSQLの知識習得
　（先週はMySQLベースで学習してしまったのでやり直し）

# 学習内容・結果
#### 1. SQLの種類
　　-DDL(データ定義言語)
　　　・CREATE
     　　　・ALTER
     　　　・DROP
　　–DML(データ操作言語)
　　　・INSERT
     　　　・SELECT
   　　　・UPDATE
     　　　・DELETE
　　–DCL(データ制御言語)
　　　・BEGIN
　　　・COMMIT
　　　・ROLLBACK

#### 2. 式・条件
　　–CASE(値で分岐)
　　–CASE(条件で分岐)

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
　　
#### **《DDL/データ定義言語》**
情報を定義する際に使用するSQL。

●**CREATE**　
CREATEはテーブルを作成することができる。多くのオプションも存在する。
 > **CREATE** TABLE RECEPTION (
    **RECEPTION_ID** NUMBER(10) NOT NULL, --受付番号
    **MEMBERS_ID** NUMBER(10) NOT NULL, --会員番号
    **CREATE_DATE** DATE,             --作成日
    CONSTRAINT PK1 PRIMARY KEY(RECEPTION_ID)
);

●**ALTER**
ALTERは定義を追加・変更することができる。
 >**ALTER** TABLE RECEPTION ADD (
    **UPDATE_DATE** DATE,             --更新日
);　　

●**DROP**
DROPはテーブルを削除することができる。
 >**DROP** TABLE RECEPTION;

#### 《DML/データ操作言語》
情報を操作する際に使用するSQL。

●**INSERT(登録)**　
INSERTは情報を登録できる。この登録した情報1件1件をレコードといい、
1回のINSERTで1レコードを登録する。

 > INSERT INTO RECEPTION (RECEPTION_ID, MEMBERS_ID, CREATE_DATE, UPDATE_DATE) VALUES (1, 1, SYSDATE, SYSDATE)

SYSDATE：現在日付で、処理を行った日付を入力可能

●**SELECT(検索)**　
SELECTはテーブルからレコードを取得できる。

>SELECT RECEPTION_ID, MEMBERS_ID, CREATE_DATE, UPDATE_DATE FROM RECEPTION;
)-- * を用いることで全カラムを指定することが可能
SELECT * FROM RECEPTION;
-- 特定のカラムだけ取得することも可能
SELECT RECEPTION_ID, MEMBERS_ID FROM RECEPTION;

●**UPDATE(更新)**　
UPDATEはカラムの値を更新できる。

>UPDATE RECEPTION SET MEMBERS_ID = 2, UPDATE_DATE = SYSDATE WHERE RECEPTION_ID = 1;

●**DELETE(削除)**　
DELETEはレコードを削除できます。

>DELETE FROM RECEPTION WHERE RECEPTION_ID = 1;

####《DCL/データ制御言語》
情報操作を制御する際に使用するSQL。。

●**BEGIN（トランザクションを開始）**　
トランザクションとは一連の処理のかたまりを指す。
一連の流れで、一箇所でもエラーになればそれまでの処理をすべてもとに戻せるようにする役割を果たす。
このトランザクションを開始させるSQLがBEGIN。

●**COMMIT（トランザクションを確定）**　
トランザクションを開始したら終了を伝える必要がある。
この終了を伝える指示がCOMMITである。
DBの設定により、オートコミット設定がONになっている場合、1SQLを実行するたびに自動でCOMMMIT処理がなされる。

●**ROLLBACK（トランザクションを取り消す）**　
トランザクションを開始した以降の処理をすべて取消。
オートコミット設定がONになっている場合、ROLLBACK指示は無効とされる。

####《CASE/値で分岐》
「値」で分岐した結果を返す方法。
>SELECT 
 　CASE 列名 
  　　WHEN 値1 THEN 結果1 
  　　WHEN 値2 THEN 結果2 
  　　ELSE 結果3
 　END 
FROM table1;

####《CASE/条件で分岐》
「条件式」を使う事ができるため幅が広がる。
WHENで条件式を記述し、SELECTしたい結果をTHENのあとに記述します。「CASE」の最後は「END」でしめくくるのがルール。

>SELECT 
 　CASE 
  　　WHEN 条件1 THEN 条件1の結果
  　　WHEN 条件2 THEN 条件2の結果
 　 　ELSE 条件1,2以外の結果
 　END 
FROM table1;



# 来週の目標
SQLの復習・学習
最終的にはCRUD・TRUNCATEを習得
残り一週間のためもっと多くの知識を詰め込んでいく。
最大公約数と最小公倍数の処理をpythonで書く

### 最大公約数と最小公倍数

ってなんだっけ？
と言う小学生レベルの算数も怪しい私自身に説明するつもりで書く

・最大公約数
24 36とあった時にどっちでも割れる数で一番大きいもの

例えば共通で割れるものとして2, 3, 4, 6, 12とかやっていって
この場合は12が一番大きいので12が答えとなる

大体はすだれ算を使ってやる
こんなやつ↓

| 2 | 24 | 36 |
|:-:|:-:|:-:|
| **2**  | 12  | 18  |
|  **3** | 6  | 9  |
|   |  2 |  3 |


縦に2 * 2 * 3とやれば最大公約数が求められる

・最小公倍数
24 36とあった時どちらも足していって最初に共通の数字が現れたもの
以下の場合は72が共通の数字が現れるので72となる

| 24 | 48 | **72** |
|:-:|:-:|:-:|
| 36  | **72**  | 108  |

すだれ算を使ってやった場合は
左と一番下を全て掛け合わせる
2 * 2 * 3 * 2 * 3 = 72

| **2** | 24 | 36 |
|:-:|:-:|:-:|
| **2**  | 12  | 18  |
|  **3** | 6  | 9  |
|   |  **2** |  **3** |


ここでユークリッド互助法と言うやり方がある
かっこいい名前がついているが方法としては簡単
最大公約数を求める場合はまず2つのうち大きい方を小さい方で割って剰余を求める

`36 % 24 = 1 ...12`

それを更に小さい方で割ってあまりを求める

`24 % 12 = 2 ...0`

あまりがゼロになった時点で割った数が最大公約数

次に最小公倍数だがこれはまず2つの数を掛け合わせる

`36 * 24 = 864`

次に出した積を最大公約数でわる

`864 / 12 = 72`

このユークリッド互助法を使ってpythonで最大公約数と最小公倍数を求めようとするとこうなった

```python
l = input('Enter two number: ')
l = l.split()
a = max(l, key=int)
b = min(l, key=int)
a, b = int(a), int(b)

def do_gcd(a, b):
    if a == b:
        #return False
        return a
    
    while True:
        if a % b == 0:
            break
        else:
            a, b = b, a % b
    return b

do_gcd(a, b)

c = do_gcd(a, b)
c = int(c)
print("最大公約数" ,c)

def do_lcm(a, b, c):
    return a * b // c

do_lcm(a, b, c)
d = do_lcm(a, b, c)
print("最小公倍数" ,d)
```

```:実行結果
Enter two number:  24 36
最大公約数 12
最小公倍数 72
```

スペース区切りで数字を2つ入れるとそれぞれ結果を返してくれる

ちなみに結構苦労して書いたが、mathを使うと最大公約数をわずか2行で求められることが判明^^;
便利なものはどんどん使っていこうと言う教訓であった

```python
import math
math.gcd(24, 36)
```

```:実行結果
12
```

-20210618 追記
以下のように書けばもっと簡単に書けるよとユーザさんよりご指摘いただく。

>修正点① そもそも引数をmaxとminで判定するのは不要
>修正点② 2つの引数が同じだった場合の最大公約数はFalseじゃない
>修正点③ while Trueで無闇に無限ループ回さなくていいじゃんね

私には絶対思いつかないコードである(苦笑)
(@StrawBerryMoonさん有益な情報ありがとうございます。)

いただいたアドバイスを元に修正したコードは以下の通り

```python
l = input('Enter two number: ')
l = l.split()
a, b = int(l[0]), int(l[1])

def do_gcd(a, b):
    while b != 0:
        a, b = b, a % b
    return a

do_gcd(a, b)

c = do_gcd(a, b)
c = int(c)
print("最大公約数" ,c)

def do_lcm(a, b, c):
    return a * b // c

do_lcm(a, b, c)
d = do_lcm(a, b, c)
print("最小公倍数" ,d)
```
【Java】Apache POIで印刷時のシートの拡大縮小の設定が上手くいかなかった原因

# 概要
Apache POIを使用して、エクセル帳票を出力する処理の実装を行っている際に、
印刷時の拡大縮小の設定を処理内で行ったが、上手く設定されない事象が発生した。

# 上手くいかなかった際の処理


```Java:FailedExample.java
    workbook.cloneSheet(0, "TestSheet");

    sheet = workbook.getSheetAt(1);
    // 印刷時タイトル設定
    sheet.setRepeatingRows(new CellRangeAddress(0, 2, -1, -1));
    sheet.setRepeatingColumns(new CellRangeAddress(-1, -1, 0, 9));

    // 印刷時の拡大縮小の設定
    PrintSetup ps = sheet.getPrintSetup();
    ps.setScale((short)40);
```
上記のように先に印刷時のタイトルの設定を行ってから、拡大縮小の設定を行っていた。
そうすると、なぜか出力されるエクセルに拡大縮小の設定が反映されなかった。

# 上手くいった際の処理


```Java:FailedExample.java
    workbook.cloneSheet(0, "TestSheet");

    sheet = workbook.getSheetAt(1);

    // 印刷時の拡大縮小の設定
    PrintSetup ps = sheet.getPrintSetup();
    ps.setScale((short)40);

    // 印刷時タイトル設定
    sheet.setRepeatingRows(new CellRangeAddress(0, 2, -1, -1));
    sheet.setRepeatingColumns(new CellRangeAddress(-1, -1, 0, 9));
```
先に拡大縮小の設定を行い、後にタイトルの設定を行うよう、先ほどと処理の順番を入れ替えると、
拡大縮小の設定が反映されていた。
要求図


**SysMLで使用するダイアグラム**

要求blockをツリー構造で細分化して表現する

**block間の関係は**
　包含関係 <\<contain>>
　複製関係 <\<copy>>
　派生関係 <\<deriveReqt>>
　満足関係 <\<satisfy>>
　検証関係 <\<verify>>
　洗練関係 <\<refine>>
　追跡関係 <\<trace>>
　理由関係 <\<rationale>>

例えば
モデルが要求を満たすときに　<\<satisfy>>　を使う
要求をこのテストで検証するとき　<\<verify>>　を使う
要求の理由や根拠は　<\<rationale>>　の吹き出しを入れる
レコード共有設定の参照

本記事では制限されたアクセス権限を特定のルールやロールに応じて緩和する機能および共有先グループ（公開グループ）の作成方法について説明します。
1.ロール階層
2.共有ルール
3.手動共有
4.公開グループ

詳しく設定はリンクをご参照ください
https://www.synergy-marketing.co.jp/cloud/synergylead/support/act-recordshare-settings2/
FlutterでiOSエミュレーターにFCMでプッシュ通知ができない現象

同じところで長時間ハマる人が一人でも減るように書いておきます。

Flutterで一通り機能の開発を終え、Androidエミュレーターでの動作確認を完了し、iOSエミュレーター上で動作確認を始めると通知がどうしても受信できない現象に遭遇。

一日半かけて以下の文章にたどり着きました。

[FCM via APNs Integration](https://firebase.flutter.dev/docs/messaging/apple-integration/)
>For iOS; you must have a physical iOS device to receive messages.
>Firebase Cloud Messaging integrates with the Apple Push Notification service (APNs), however APNs only works with real devices.

プッシュ通知は実機でないと動きません！

このページも含めて何度となく見返していたのに、冒頭の注意書きを見落としていました。こんな重要なことは上のCaution欄の中に書いて欲しかった:cry:

（独り言：iOSの通知周り、証明書やらXCodeやら、やること多過ぎ！複雑過ぎ！:unamused:）
【Power BI】過去の自分を超えろ！実績データからセットの件数をカウント2021バージョン

※2021年6月26日追記

本日、DAX Boot Camp#11に久々に参加させて頂き、こちらの件について発表させて頂いたのですが、
DAXというよりモデリングの問題というダメ出しを各方面から頂いたので、頑張ってモデリングから考え直し中です。


##ちょっぴり前進できたような気がしていた去年の自分

去年の夏、DAX Boot Camp#1に参加させて頂き、こんな記事を書きました。

[DAX Boot Camp#1に参加してまた少し前進できた件](https://qiita.com/3book_777/items/7e79b71b60dead9eaba3)

アイス屋さんの販売実績データから、5商品のセットが何セット販売された実績をカウントするというもの。

以前だったら裏（Power Query）で対応していたものが、DAXでできるようになったぜ！ﾄﾞﾔ！！という記事です。

##過去の自分に教えてもらう・・・？

さて先日、営業さんからこんな依頼がきたんですよね。

『以前集計してもらったセットの件ですが、セットを増やしましたので、そちらの集計もお願いできますでしょうか。セットの内容は添付いたします。』

添付ファイルを開くと・・・

な、なんと、セットが**50種類**に！！！
なんで？なんでそんなに作った？？
しかも、セットによって商品数がバラバラだよ！！

泣きながら、「そう言えば、前に集計した時ってどうやったんだっけ？」って自分のQiita記事を読み返しました。
・・・・ﾊｯ
何故あれだけﾄﾞﾔｧな感じで書いた内容のことが身についてないんじゃ・・・？過去の自分に負けとるやないけ・・・

でも、背に腹は代えられん・・・・と自分のQiita記事を見ながら集計を進めていったのですが、
アレ、このやり方だとマスタをそれぞれ別に作らなくちゃならないし、いちいちRelatedで列追加ってメンドウだし、しかもなんでIDごとのテスト数を実績データに列追加してるんじゃ・・・？
と要修正ポイントが。

やっぱりほんとにちょっとづつだけと、成長してるのね、あたい！！

##実績データからセットの件数をカウント2021バージョン

去年のわたしのQiita記事を参考にしてくださった方がいたらごめんなさいm(__)m（いないか・・・）
セットの数が50種類になっても（なんとか）耐えられる方法を考えましたので、改めてこちらをご参照ください。

###【やりたいこと】
●200ほどある商品を組み合わせてセット販売を行ったが、どれくらいセットが売れているのか集計したい。（セットの種類は50）

●ただし、実績データ（販売履歴）ではセットではなく、単品でのデータになっている。

●実績データの、販売日・営業所コード・店舗コード・顧客番号を使用して、顧客が同時に購入したアイテムを抽出可能。

実績データはこんな感じ。![Qiita1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221359/d80acc15-9e98-e3a2-e88b-2acfdb37a80f.png)
セットのマスタはこんな感じで用意します。
![Qiita2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221359/99e91a29-845c-4b81-bcae-e85681532b30.png)
セットに含まれる商品名の行に1を入れます。
こうすることによって、セットのマスタを1つにすることができます。

####①裏（Power Query）で実績データにセットのフラグをマージする。
去年のあたいは、Related関数を使って、フラグ列を追加していたのですが、そんなこと50回もやってられるかい！！というわけで、裏でマージして、列を展開。

以前、これもQiita記事で「裏でやるか、表でやるか？」というのを書いたんですが、その一つの解としては、「効率がいい方でやる！」ですね。
####② SUMMRIZE関数を使用して、購入商品数テーブルを作成
IDでグループ化して、ID数をカウントすると購入商品数が集計できる。

```
商品数 = ADDCOLUMNS(SUMMARIZE('Data',Data[ID]),"商品数",CALCULATE(COUNTROWS(Data)))
```

まぁこれも裏でやってもいいかなとも思います。
####③IDごとにセットに含まれる商品を何個買っているかカウントするテーブルを作成
さて、ここが今回のキモでございます。
こんな感じで実績データをSUMMRIZEして、IDごとに各セットに含まれる商品を何商品購入したかを集計するテーブルを作成します。

```
SetT = 
ADDCOLUMNS(
    SUMMARIZE('Data','Data'[ID]),
    "S1",CALCULATE(COUNTROWS('Data'),'Data'[S1]=1),
    "S2",CALCULATE(COUNTROWS('Data'),'Data'[S2]=1),
    "S3",CALCULATE(COUNTROWS('Data'),'Data'[S3]=1),
    "S4",CALCULATE(COUNTROWS('Data'),'Data'[S4]=1),
    "S5",CALCULATE(COUNTROWS('Data'),'Data'[S5]=1),
```
こんな感じで延々50行分書きます・・・
####④各テーブルをリレーションします。
![Qiita4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221359/1ac25074-cffd-5857-a4d0-e228ce445021.png)
去年は実績データと商品数テーブルをリレーションしましたが、2021バージョンはSetテーブルと商品テーブル、Setテーブルと実績データをリレーションします。
####⑤セット商品を全て購入しているIDをカウントするメジャーを書きます。
例えば、S1セットは4商品のセットなので、S1セットを購入していると考えられるお客は、SetテーブルのS1=4で、商品数=4のIDということになります。
なので、この条件をカウントするメジャーを書けばいいわけです。

```
S1数 = CALCULATE(COUNTROWS('SetT'),'SetT'[S1]=4,'商品数'[商品数]=4)
```

これも、延々50個書けたら、完了です・・・・。

##過去の自分を超えろ！ひとつのやり方で満足しない！
今回、こんな感じでできましたが、もしかしたらもっといい方法が見つかるかもしれません。
ひとつのやり方で満足せずに、他にもやり方ないかな？っていつも考えるくせが必要ですね。
git　コマンド集　ブランチ、マージなど



##git ファイルへの変更を取り消す
```
$ git checkout -- ファイル名
$ git checkout -- ディレクトリ名

・全変更を取り消す
$ git checkout -- .
```

##git ステージした変更を取り消す
```
$ git reset HEAD ファイル名
$ git reset HEAD ディレクトリ名
＊注意：ワークツリーのファイルには影響しない！！

。全変更を取り消す
$ git reset HEAD .
```


##git 直前のコミットをやり直す
```
*注意：リモートリポジトリにPushされたコミットにはしてはいけない！
$ git commit --amend
```


##git リモートを表示する
```
$ git remote

・対応するURLを表示する
$ git remote -v
```


##git リモートリポジトリを新規追加
```
$ git remote add リモート名 リモートURL
```


##git リモートから情報を取得する/fetch
```
$ git fetch リモート名
$ git fetch origin
```


##git リモートから情報を取得する/pull
```
$ git pull リモート名　ブランチ名
$ git pull origin master

。上記コマンドは省略可能
$ git pull

・これは下記コマンドと同じこと
$ git fetch origin master
$ git merge origin/master

・最終的に内容の確認はcatを使用して確認してみる。
cat ファイル名
```

##git リモートの詳細情報を表示する
```
$ git remote show リモート名
$ git remote show origin
```

##git リモート名を変更・削除
```
・変更
$ git remote rename 旧リモート名　新リモート名

・削除
$ git remote rm リモート名
```

##git ブランチを新規追加する
```
$ git branch ブランチ名
```

##git ブランチの一覧表示
```
$ git branch

・ずべてのブランチを表示する
$ git branch -a
```

##git ブランチを切り替える
```
$ git checkout 既存ブランチ名

・新規ブランチを新規作成して切り替える
$ git checkout -b 新ブランチ名
```

##
```
$ git merge ブランチ名
$ git merge リモート名/ブランチ名
$ git merge origin/master
```

##git コンフリクト
```
<< HEAD ~ ==　　　　　　　　　　　　//HEADの変更部分
== ~ >> ブランチ名　　　　//ブランチ名の変更部分

改善は、<<  ==  >> 左の記述を削除する  
```

##git　ブランチを変更/削除
```
・現在作業しているブランチ名変更
$git branch -m 新ブランチ名

・強制削除
$ git branch -d ブランチ名
```
GetComponentsInChildrenで親オブジェクトを除いて取得する方法

Unityを触り始めてつまずいたGetComponentsInChildrenについて

GetComponentsInChildrenは親オブジェクトも取得してしまうので子オブジェクトのみ取得する方法

```c#:Test1.cs
    using System.Linq;

    public GameObject parent;//親オブジェクト
    private void Start()
    {
        List<GameObject> child = new List<GameObject>(parent.GetComponentsInChildren<GameObject>())
            .Select(item => item.gameObject)//TransformをGameObjectに変換
            .Skip(1)//親オブジェクトをスキップ
            .ToList();//Listに変換
    }
```
見やすくするために改行しているが、Linqを使えば1行で取得できる

Unityを使い始めたころはこのように書いていた

```c#:Test2.cs
    public GameObject parent;//親オブジェクト
    private void Start()
    {
        GameObject[] child = new GameObject[parent.transform.childCount];//子オブジェクトの数で初期化
        for(int i = 0; i < child.Length; i++)
        {
            child[i] = parent.transform.GetChild(i).gameObject;//子オブジェクト取得
        }
    }
```
Kotlinでのワイドニングについて

###▼ワイドニング
互換性がある型において、値範囲の狭い型から広い型へ変換すること
例）Int型→Long型、Float型→Double型へ変換する（32bitから64bitへ）
これをワイドニングという。

Kotlinでは、ワイドニングを自動でしてくれないため、手動でやる必要がある
ワイドニングをするためには、**型サフィックス**を利用するか、**toデータ型()メソッド**を使う。

●型サフィックスの場合

```kotlin
var a:Float = 1.2  //エラー
```
↓

```kotlin
var a:Float = 1.2f  //Float型として認められ、ワイドニング成功
```

●toデータ型()メソッドの場合

```kotlin
var a = 10
var b:Long = a.toLong()
```
変換したい型をtoのあとに入れてあげることで、変換できる
Play Asset Deliveryを使ってみた

「apk + 拡張ファイル」でアプリを公開していたのですが、aab対応が必要になり拡張ファイルは使えないので代替機能として何かないか確認したらPlay Asset Deliveryが該当したので試してみました。

150MBを超えるアプリを公開することは稀だと思いますが、参考にする記事がかなり少なかったのでこれから使ってみようと考えている人の助けになれば幸いです。

## 動作確認環境
Macbook Pro macOS Catarina 10.15.7
Android Gradle Plugin 4.1.3
AndroidStudio 4.1.3
Pixel3 Android OS 11

#1 PlayCoreLibraryの導入

```
// In your app’s build.gradle file:
...
dependencies {
    // For Kotlin users also import the Kotlin extensions library for Play Core:
    implementation("com.google.android.play:core-ktx:1.8.1")
    ...
}
```

https://developer.android.com/guide/playcore?hl=ja#kotlin

#2 プロジェクトに必要なファイルと設定を追加
- プロジェクトのルートディレクトリに Asset Pack のディレクトリを作成。
    - 今回は拡張ファイルの代替機能として用意するのでディレクトリ名を asset_expansion としています。
- Asset Pack のディレクトリに build.gradle ファイルを作成して、下記のコードを入力します。
    - 配信タイプは [install-time], [fast-follow], [on-demand] の3種類ありますが今回はインストール時に一緒に取得したいので install-time を指定しています。

```
apply plugin: 'com.android.asset-pack'

assetPack {
    packName = "asset_expansion" // Directory name for the asset pack
    dynamicDelivery {
        deliveryType = "install-time"
    }
}
```

- プロジェクトのアプリの build.gradle ファイルで、下記のように、プロジェクト内の各 Asset Pack の名前を追加します。

```
// In the app build.gradle file:
android {
    ...
    assetPacks = [":asset_expansion"]
}
```

- プロジェクトの settings.gradle ファイルに、下記のように、プロジェクト内のすべての Asset Pack をインクルードします。

```
// In the settings.gradle file:
include ':app'
include ':asset_expansion'
```

- Asset Pack のディレクトリにサブディレクトリ src/main/assets を作成します。
- アセットを src/main/assets ディレクトリに配置します。ここでもサブディレクトリを作成できます。アプリのディレクトリ構造は次のようになります。
    - build.gradle
    - settings.gradle
    - app/ ←これは必須ではないようです。
    - asset_expansion/build.gradle
    - asset_expansion/src/main/assets/アセットファイルを配置

- 今回はサンプルとしてasset_expansion/src/main/assets/配下にmovie/sample.mp4を配置しておきます。

- 以上で前準備は完了になりますのでビルドしてコンパイルエラーにならないことの確認をお願いします。

# メディアファイルを読み込んでみる
適当なActivityやFragmentからasset_expansionが保持しているメディアファイルを読み込んでみます。

```
val packageContext = createPackageContext(applicationId, 0)
val assetManager = packageContext.getAssets()
val inputStream = assetManager.open("movie/sample.mp4")
```

上記ではInpurStreamを取得しているだけなのでExoPlayerやVideoViewで読み込めるように path を取得するようにします。

```
inputStream.buffered().use {
    it.copyTo(context.openFileOutput("tmp.mp4", Context.MODE_PRIVATE))
}

context.getFileStreamPath("tmp.mp4").absolutePath
```

あとはメディアプレイヤーに上記の absolutePath を渡してやればOKです。

# AndroidStudioのrunの設定を変更
Android Studioのタブメニューから **run -> Edit Configurations** を選択して、
**General -> Installation Options -> Deploy** を **APK from app bundle** へ変更すれば実行時に asset_expansion のデータもインストールしてくれます。


# あとがき
最初公式を見た時は断片的な情報だと思ってうまく動いてくれるか！？なんて思いましたが、コード組んでみたら公式通りであっさり動いてくれました😇

コードを組んだあとは最初、bundletoolをhomebrewを使ってインストールしてコマンドでちまちまaabファイルからapksファイルを生成してインストールなんてやっていましたが、AndroidStudioの設定を変更すればコマンドの操作が必要なかったことが分かってだいぶ時間無駄にしたな〜なんて密かに思ったりしていました。

#公式
https://developer.android.com/guide/playcore/asset-delivery?hl=ja