OmniAICreator/Qiita-1.07M huggingface dataset:
スタイルシートクラス命名規則の迷いに終止符を打つ

<h1>
  class名命名規則
</h1>
<p>
  誰もがつまずくであろう、スタイルシートのclass命名規則。未だに正解が分からずにclass名をつけてる人がいるだろう。
</p>
<p>
  class名について調べても結局、抽象的な答えしか見つからない。ある程度の規則にそっていれば、あとは個人のやりやすういようにと。。
  なぜ、抽象的な答えしかないのか。<br>
  理由は、プロジェクトごと、企業ごとに命名規則が、設けられていたり、独自の命名規則を採用している。また、
  sassを使用できれば、BEM記法が定番であったりと、各環境が異なるため、一概にこの、class名の付け方が正解と言えないのです。  
</p>
<p>
  そこで今回は、class名をつけるのに困っている方に<br>
  ・class名の付け方<br>
  ・なにを意識しながら付ければいいのか<br>
  具体的な、答えを提示します。
</p>
<p>
  ＜想定読者＞　スタイルシートのclass名をつけるのに困っている人、始めたばかりの人<br>
  ＜想定読者＞  コンポーネントの機能ごとに細分化してclass名をつけていない人
</p>
<p>
  以下の理解が、まだだと感じた人は、以下を理解してから読み進んでください。<br>
</p>
<a href="https://www.monster-dive.com/blog/web_creative/20170525_000315.php">・class命名規則（BEM,OOCSS,SMACSSS、など）</a>
<a href="https://qiita.com/ftyabu/items/aa045c775a1e423ddc6a">・コンポーネントの理解</a>
<h2>
  ずばりclass名はどうすればいいのか。
</h2>
<P>  
  現在では、いくつかのclass命名規則が存在します。<br>
  しかし、規則が違っても、どの命名規則もコンポーネントの機能ごとに細分化を行い、その細分化したコンポーネントごとに、classを命名していくと言うことが理解できます。<br>
  この、「コンポーネントの機能ごとにclass名をつける」と言うことが、スタイルシートclass命名の迷いをなくす、最大のポイントです。<br>
  この、「コンポーネントの機能ごとにclass名をつける」と言うことができるようになればどの命名規則に直面しても、困る事はありません。<br>
  また、class名をつける際に、重要なのは
</P>
<ul>
  <li>予測しやすい</li>
  <li>再利用しやすい</li>
  <li>保守しやすい</li>
  <li>拡張しやすい</li>
  <li>コンポーネントでまとめる</li>
</ul>
<h3>
  ・予測しやすい
</h3>
<p>
  予測しやすい、と言うのは期待どうりに振舞うかどうか、と言うことです。他のルールが影響して、記述したルール通りの振る舞いを見栄えにならない
  または追加したルールが他のルールに影響を与えることがないようにすると言うこと。
</p>
<h3>
  ・再利用しやすい
</h3>
<p>
  スタイルがコピーアンドペーストされてふくらみ続けるCSSにならないためにも、再利用しやすいルールを持つ事は重要です。再利用しやすいルールと言うのは
  抽象的で、機能ごとに分離されている必要があります。遭遇したuiデザインのマーックアップ、CSSを一度作れば、再度同じようなUIに遭遇した
  ときに、わざわざ書き直す必要がないようにするのが理想です。
</p>
<h3>
  ・保守しやすい
</h3>
<p>
  新しいルールを追加、更新するときに既存のルールのリファクタリングを必要としない事が大事です。追加したルールによって、既存のルールを壊してしまうのは避けましょう。
</p>
<h3>
  ・拡張しやすい
</h3>
<p>
  自分と、自分以外のプロジェクトに関わる開発者にとってメンテナンス・管理がしやすいものであると言うこと。
</p>
<p>
  これらを、意識して細分化しclass名をつけてください。この意識は絶対にしてください。
</p>
<p>
  そして、「コンポーネントの機能ごとにclass名をつける」と言うことを理解し、できるようになるまで、<br>
  『OOCSSの規則でclass名をつけてください。』
  OOCSSを使用することで、オブジェクト思考でコンポーネントを簡単なclass名をつけるので、わかりやすくコンポーネントごとに細分化することができ
  また、コンポーネントの機能を英語でclass名にするで、余計な事は考えずにclass名を決められます。class名を英語にするのに困ったら<a href="https://qiita.com/manabuyasuda/items/dbb76ed36970bec95470">こちら</a>を参照してください。
  正しくコンポーネントごとに、細分化すると言う意識を理解していないのがclass命名で困る原因です。
  OOCSSで行う理由は、コンポーネントごとにclass名をつけるのが一番容易であること、またコンポーネントごと細分化することに慣れることができることです。  
</p>

<p>  
  そうすることで、class命名に困ることなくはなくなります。また、上記の五つの意識がOOCSSでできるように
  なれば、どの規則にも細かい規則に気をつければ、応用ができます。<br>
  働いている会社が、BEM記法を採用しているから、BEM記法だけで行うのではなく、一度OOCSSで、class名をつける基礎を固めることが重要です。
  そうすれば、今後class名をつけるのに困る事はないでしょう。

  目安として、コーディング練習ができるデザインを配布している命名
  することに、慣れました。是非この方法を試してみてください。
  実際に、私は三回これをこなすことで、コンポーネントごとに、細分化しそれらに、class名をつけることに慣れました。
</p>
<a href="https://usagidesign-e.com/download/#dl11">USAGI DESING</a>
<p>
  意識するのは、その各要素がなんの機能なのか、理解すること。スタイルを当てるためにclass名をつけることのないようにすること。<br>
  この理解ができていないと、よくないclass名をつけたり、class名をつけるのに時間がかかってしまいます。
  最期に、もう一度言います。「コンポーネントの機能ごとにclass名をつける」これが本当に大事です。
</p>
<h2>
  まとめ
</h2>
<p>
  スタイルシートclass命名に困っていたら、OOCSSでコンポーネントの機能ごとに細分化し、それにclass名をつけていく。
  コンポーネントごとに細分化することの大切さを理解する。
  ただ、今回紹介した方法は、どの場面でも使えると言うわけではありません。そのとき、そのときでclass命名の規則は変わります。
  どんな、状況、命名規則に遭遇しても困らないために、備えることのできる方法です。
</p>
JavaScript,8,条件分岐,if,else,初心者向け

8,条件分岐　if  else  

JS（JavaScript)で条件分岐をおこなってみましょう！


```
const score = 20;

if (score === 20)   score と20が一緒
if (score < 20)      score より20が大きいか
if (score > 20)      score より20が小さいか

const score = 10;

if (score === 20) {
  document.getElementById("test").textContent = "スコアは２０です"
} else if (score === 10) {
  document.getElementById("test").textContent = "スコアは1０です"
} else {
  document.getElementById("test").textContent = "スコアは２０ではないです"
}
```

もしこれなら次こうする
けど違ったらこれするもしくはこれか
違ったらこれする
point cloud library surface module について

## Lidarから取得した点群を面として再構築したい！
![Screenshot from 2020-12-16 18-42-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55095/b02da164-e850-72fd-df00-18cccd04c47e.png)

0. ここにLivoxで取得した点群があります。
1. pointcloud library (pcl) のsurface moduleを使って面としての再構築ができそう
2. いっぱい手法がある。どれがいいの？
3. 一個一個見ていこう。

## というわけで中身を見ていきます
surface module 
https://pointclouds.org/documentation/group__surface.html

#### Base Classたち
##### pcl::CloudSurfaceProcessing
点群の表面を綺麗にする機能。表面平滑化、穴埋め、アップサンプリングなどができる。
##### pcl::MeshProcessing
その名の通りmesh processのBaseClass
##### pcl::SurfaceReconstruction
点群をインプットして表面を生成する機能のBaseClass
##### pcl::MeshConstruction
点群をインプットして表面を生成する機能のBaseClass SurfaceReconstructionとの違いは？？


#### 具体的なアルゴリズムたち（各アルゴリズムの結果は追記）
##### pcl::ConcaveHull
https://ja.wikipedia.org/wiki/%E5%87%B8%E5%8C%85
なるほど、ゴムで包んだ感じの表面が得られる、と。
##### pcl::EarClipping
https://youtu.be/OVwpj6OCClg
三角形で埋めていく
##### pcl::GreedyProjectionTriangulation 
https://en.wikipedia.org/wiki/Greedy_triangulation
交差が生じないように一番近い頂点を結んでいく
##### pcl::GridProjection
http://www.pcl-users.org/file/n3567834/38.png
Grid 状になる。mesh ,surafceではないのかもしれない。
##### pcl::MarchingCubes
Voxcelをmeshに変換する手法。
http://www.sanko-shoko.net/note.php?id=js3z
http://www.paulbourke.net/geometry/polygonise/

##### pcl::MarchingCubesHoppe
具体的な説明が見つからず。結果がおかしいと訴える内容が検索によくヒットする（PCLの実装にバグが含まれていた時期があるのだと思います）。
##### pcl::MarchingCubesRBF
MarchingCubesHoppeとMarchingCubesRBFでは距離の取り方に違いがあるようです。詳細は省きます。
##### pcl::MovingLeastSquares
移動最小２乗法 (MLS)
##### pcl::OrganizedFastMesh
点群を2Dに一旦投影してその中での最近傍点を使って三角形を作る（のでしょうか？）

##### pcl::Poisson
http://vr.tu-freiberg.de/scivi/?page_id=365



##### pcl::TextureMapping
テクスチャーを貼るのだと思います。


### 雑感
mesh sarface reconstruction を調べてると　http://hhoppe.com/ この人の名前が何回も出てくる。すごい。
SQL*Plusにログインしようとしたらできなかった問題

##SQL*Plusにログインしようとしたらできなかった問題

登録したユーザー名、パスを入力しログインを行おうとしたところエラー発生。


##原因
SQL*Plusがそもそも起動していなかった。

##解決方法
<1>SQL*Plusをデータベースに接続せずに起動します。
`$ sqlplus /nolog`

<2>管理者アカウントでログインします。
`SQL> CONNECT SYS AS SYSDBA
Enter password: SYS_password `

<3>データ・アクセス操作可能な状態にします。
`SQL> STARTUP`

再度`sqlplus`で入り、ユーザー名　パスワードが通ればOK。

##おまけ
「あれ、ユーザー名覚え間違えたかな？」と思って
ユーザー名確認やパス変更も最初行おうとしたのでその方法も。

<1><2>までは手順一緒。

・パスワード変更を行うコマンド
`SQL> ALTER USER ユーザー名 IDENTIFIED BY パスワード ACCOUNT UNLOCK;`

・ Oracleのすべてのユーザーを確認するコマンド
`SQL> SELECT * FROM ALL_USERS ORDER BY USERNAME;`

##参考

[SQL*Plusを使用したパスワードのロック解除および変更](https://docs.oracle.com/cd/E96517_01/ntdbi/using-sql-plus-to-unlock-and-change-passwords.html)
[データベースの起動（SQL*Plus版）]
(https://www.atmarkit.co.jp/fdb/ref/ref_oracle/startup.html)
mix credoのエラー結果に対してどうすべきか調べる。

```
% mix credo -a
Checking xx source files ...

  Code Readability
┃
┃ [R] → Modules should have a @moduledoc tag.
┃       lib/project_web.ex:1:11 #(ProjectWeb)

```

と言う結果がでた場合下記の方法で調べることができる。
(`@moduledoc`が存在しないことによるエラーの例です。）

```
% mix credo explain lib/project_web.ex:1:11
```
WordPressでカテゴリーのアーカイブにカスタム投稿の記事も表示させる

ワードプレスのテーマtwentytwentyを基盤に、カテゴリーのアーカイブページにカスタム投稿の記事も一覧表示させる実装を行ったので、備忘録的にこの記事を残す。

# 環境情報

PHP：version 7.3.12
WordPress：version 5.5.3
WPテーマ：twentytwenty

# 作業

通常はポストタイプ名が post の投稿のみ表示される仕様のようだ。

```functions.php
// カテゴリーのアーカイブにカスタム投稿の記事も表示させる
function add_customtype_archive( $wp_query ) {
    if ( is_admin() || ! $wp_query->is_main_query() )
        return;

    if ( $wp_query->is_category() || $wp_query->is_tag() ) {
        $wp_query->set( 'post_type', array( 'post', 'カスタム投稿タイプ' ));
        return;
    }
}
add_action( 'pre_get_posts', 'add_customtype_archive' );
```

「カスタム投稿タイプ」の部分を表示させたい投稿のポストタイプ名に変更してお使いください。
Ubuntu20.04でLogicoolのトラックボールマウスTM-150rをホイール可能に

# はじめに
私はLogicoolのトラックボールマウスTM-150rを愛用しています。
Ubuntu20.04でもTM-150rにホイール機能を付けたくて色々調べてたらできたのでメモとして残します。
具体的には、マウスの左ボタンの上部にある小ボタン（左小ボタン）を押しながらカーソル移動でスクロールできるようにしました。
# 下調べ
まず、以下のコマンドでTM-150rのidを調べました。

```bash
$ xinput list
```
そしたら

```
↳ Logitech USB Trackball                  	id=11	[slave  pointer  (2)]
```
と出たので、TM-150-rのidは11だということがわかりました。

次に左小ボタンの番号を特定するために以下のコマンドを打ちました。

まず、マウスは何も押さずに

```bash
$ xinput query-state 11
```
11が先程特定したidです。すると出力は

```
2 classes :
ButtonClass
	button[1]=up
	button[2]=up
	button[3]=up
	button[4]=up
	button[5]=up
	button[6]=up
	button[7]=up
	button[8]=up
	button[9]=up
ValuatorClass Mode=Relative Proximity=In
	valuator[0]=2427
	valuator[1]=902
	valuator[2]=119
	valuator[3]=833
```

こんな感じになると思います。すべてupの状態です。次は特定した左小ボタンを押しながら```xinput query-state 11```を実行して

```
ButtonClass
	button[1]=up
	button[2]=up
	button[3]=up
	button[4]=up
	button[5]=up
	button[6]=up
	button[7]=up
	button[8]=down
	button[9]=up
```
となり、8がdownになっていることから左小ボタンの番号は8だとわかりました。

# Ubuntuの設定の書き換え

ボタンの特定ができたので、/etc/X11/xorg.confを書き換えをします。
私の場合、xorg.confは未発行だったのでtouchコマンドでxorg.confを作成しました。
作成したらviコマンドで以下に書き換えるだけです。

```
Section "InputClass"
        Identifier      "Marble Mouse"
        MatchProduct    "Logitech USB Trackball"
        Driver          "libinput"
        Option          "ScrollMethod" "button"
        Option          "ScrollButton" "8"
        Option          "MiddleEmulation" "on"
EndSection
```
この8が下調べで調べた左小ボタンの番号です。最後に```reboot```したら設定完了です。
右小ボタンにしたい場合も同様の手順でボタン番号を特定し、設定できると思います。
wiresharkでhttp通信をキャプチャする

HTTP通信をキャプチャすることで，

- Ethernetヘッダ
- IPヘッダ
- TCPヘッダ
- 実通信内容

をバイト列として確認することができます．

## 手順

- loopbackインターフェースの通信をキャプチャする
- localhostにブラウザからアクセスする
- "http" で通信をフィルタする

### loopbackインターフェースの通信をキャプチャする

wiresharkを起動し，loopbackインターフェースを選択してキャプチャを開始します．

![](https://i.imgur.com/ZZZKs5z.png)

### localhostにブラウザからアクセスする

今回は，PHPで簡易なHTTPサーバを起動します．

```
$ mkdir html
$ echo 'hello, wireshark' > html/index.html
$ php -S localhost:8080 -t html/
```

```
$ php -S localhost:8080 -t html/
Listening on http://localhost:8080
```


### "http" で通信をフィルタする

httpでフィルタすると，該当の通信が確認できます．

![](https://i.imgur.com/m4ThnoV.png)

プリアンブルは含まれないので，バイトコードは(0x000)から始まります．

これは，ループバックアドレス同士で通信した際に利用される送信先MACアドレスです．

![](https://i.imgur.com/NABKLqK.png)

上記のように情報をクリックすると，該当するバイト文字列が強調表示されます．逆も同様です．

## 環境情報

- Ubuntu 18.04 LTS
- Wireshark 2.6.10
Checkn1xでiosを脱獄する方法

![checkn1x.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956361/2393512d-8076-7c8f-36b7-2448d37b9f13.jpeg)


#脱獄とは
既存のiosでは、できないことや普通とは違った動作をさせることです。様々なことができるようになる代わりに、デメリットもあります。
保証が受けれなくなったり最悪の場合スマホが起動しなくなるので、脱獄する場合は、自己責任でお願いします。
##Checkn1xについて
Checkn1xは[asineth0氏](https://github.com/asineth0)が簡単にmacがなくてもcheckra1nを起動できるようにしたもの。他にもbootra1nなどがありますが今回はcheckn1xの入れ方について話します。
##導入方法
###必要なもの

- [Rufus](http://rufus.ie/)
- [Checkn1x 1.1.4](https://github.com/asineth0/checkn1x/releases/download/1.1.4/checkn1x-1.1.4.zip)

まずRufusをここからインストールしてください。次にCheckn1xをここからインストールすべての作業が終わったらCheckn1x.zipを解凍してください。次にRufusを起動し先ほど解凍して出てきた.isoを選択し書き込んでください。次に起動方法です。
##起動方法
一度パソコンの電源を落とし起動するときにF12を連打してください変なものが出てきたらUSBを選択してください。あとはchecra1nと同じ方法で使えます。
わからないことがあるひとはコメントお願いします。
has_manyで中間テーブルから親モデルの別のassociationを取ってきたい

## 概要
Railsを使用してデータを扱う際、殆どこんな機会は訪れない（別の方法などで代替できることがほとんど）ですが、どうしよもない事情で中間テーブルから関連付けを貼る必要があったので備忘録としてメモっておきます。


## 事前知識

```ruby
class User < ApplicationRecord
   has_many :group_users
   has_many :groups, through: :group_users
   has_many :comments
end

class Group < ApplicationRecord
  has_many :group_users
  has_many :users, through: :group_users
  has_many :comments
end

class Comment < ApplicationRecord
  belongs_to :user
  belongs_to :group
end

class GroupUser < ApplicationRecord
  belongs_to :group
  belongs_to :user
end
```

このようなクラスが存在しているとします。
通常であればGroupUserという中間テーブルを起点として何かすることはほとんどないですし、あったとしてもUserやGroup経由でCommentを取得することができるので、困ることはほとんどありません。

一方、GraphQLを使用していたり、何かアソシエーションのタイミングで整ったデータが欲しいなどの稀な事情でGroupUserのインスタンスからgroupとuserが絞り込まれたcommentの一覧が欲しい場合があったりしました。

普通にthroughをして取得しようとすると、例えば下記のようなコードになります。

```ruby
class GroupUser < ApplicationRecord
  belongs_to :group
  belongs_to :user
  has_many :comments, through: :user #groupでもいい
end
```
ただ、この方法だとthroughしたどちらかのカラムの値では絞り込まれますが、もう片方のカラムでは絞り込みが行われません。

どちらでthroughしたとしても、userかgroupのどちらかでの絞り込みしか行われず、意図した値は取得できません。


## 解決策

じゃあどうするのかというと、socpeを使います。

```ruby
class GroupUser < ApplicationRecord
  belongs_to :group
  belongs_to :user
  has_many :comments,->(group_user) { where(group_id: group_user.group_id) }, through: :user #groupならuserでwhere
end
```
has_manyはスコープの引数として自分自身だけは取ることができます。なので、このようにすることでgroup_userインスタンスのgroup_idとuser_idを持ったコメントの一覧を取得することができます。

どうしても中間テーブルを起点にして取得しなければいけない状況になった場合に役立てば幸いです。
Google Analytics4で社内IPからのアクセスを除外する

## GA4からビューが消えてしまった！困った
今までのUniversal Analytics(以下UA)までだと、プロパティ以下にビューがありました。ビュー毎にフィルタをかけたり、目標設定をしたりしていましたよね。そして、割と大事で皆が必ず行う設定の1つに「社内IPを除外することで、開発者が頻繁にアクセスするレコードを除外する」というのがあります。Google Analytics4(以下GA4)でも同じ設定必要です…が、GA4ではビューがなくなってしまいました。どうしたら良いのでしょうか？

## GA4のビュー＝データストリーム
GA4からでは、実質的なビューとして「データストリーム」というものに置き換わっています。
詳しくは以下のGoogleのページを見ていただくと、概念が解ると思います。
https://support.google.com/analytics/answer/9303323

## 社内IPからのアクセスを除外するフィルタを作るには？
管理画面→プロパティ→データストリーム→タグ付けの詳細設定から可能になっています。

![Screenshot from 2020-12-16 18-52-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293892/30eb55ce-e884-cb17-c92c-945eca10e066.png)

![Screenshot from 2020-12-16 18-35-27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293892/fa1b8547-c738-1549-4e87-8bb1c4cc0880.png)


タグ付けの詳細設定に行くと「内部トラフィックの定義」なるものが存在します。
![Screenshot from 2020-12-16 18-35-54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293892/e7d5d339-edf2-fafd-c45a-8409647c0f38.png)

コチラをクリックして、開くと、以下の画面のように社内IPアドレスを定義できます。

![Screenshot from 2020-12-16 18-36-25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293892/aa51dcc0-516d-5f2e-65b0-df396aa6c1cc.png)

ただ、コレを定義しただけでは、除外されません。
プロパティのデータ設定からこんな感じで、フィルタを適応してあげて下さい。
GA4からはフィルタは一律プロパティに適応されるようになっています。
![Screenshot from 2020-12-16 18-49-51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293892/ef71fe4a-5959-bfec-4b7b-80262dbd2695.png)


## 社内アクセスも含めたデータストリームと、社内アクセスを含めないデータストリームを作っておくと便利

設定変更のテストや、最終確認の際に、ちゃんとデータがGA上に有るか確認したいですよね。そのために、UA時代から、社内アクセスも含めたフィルタなしのビューと、社内アクセスを除外したビューの2種類を作っていた人も多いと思います。
同じ事をGA4でする場合は、**「内部トラフィックの定義」をしたデータストリームと、していないデータストリームの2種類を用意しておく**と良いと思います。
AWS 一つのEBに複数ドメイン割り当てる方法

A.com ← 割り当てたいドメイン
ORG.com ← 本来のEBのドメイン

```
Route53 (A.comをcloudfrontに向けて設定)
↓
cloudfront (オリジン：ORG.comに向けて、CNAMEでA.comを設定。ACMもA.comのものを使う)
↓
EB (ドメイン設定はORG.com)
```

順番的には下から構築していけば楽なはず

EB(というかEC2)側で、phpだったら$_SERVER["SERVER_NAME"]すると "A.com" が取得出来ます。
X410がキーボードを英字配列で認識するのを直した話

VcXsrvでは問題なく動いてたのに、X410にしたらキーボードを英字配列で認識するようになった。

```
$ sudo dpkg-reconfigure keyboard-configuration
```

叩いて、
`generic 105-key (Intel) PC > Japanese > Japanese`
でその後の選択肢もデフォルトのものを選ぶ。

```
W: mkconf: MD subsystem is not loaded, thus I cannot scan for arrays.
W: mdadm: failed to auto-generate temporary mdadm.conf file.
```
と出るが無視。

その後Windowsを再起動したら直った。
どこまで再起動したらいいかは分からないが、設定をしただけでは直らなかった。

X410にしたところVcXsrvの時には発生していたEmacsを長時間起動していると、いつの間にか死んでる問題は発生しなくなったように見える。
一方、タスクバーにEmacsが表示されないとう新しい問題が…
【MySQL】テーブルを丸ごとバックアップする


###やりたいこと
テーブルの中の情報も含めて、同じテーブル（バックアップ用）を作成すること

###SQL
**既存のテーブル→「info」
新規のテーブル→「info_bk」**

```
/*1.テーブル定義を複製する*/
CREATE TABLE info_bk LIKE info;

/*2.複製したテーブル定義を確認する*/
show full columns from info_bk;

/*3.既存テーブルのデータを新規テーブルに挿入する*/
INSERT INTO info_bk SELECT * FROM info;

/*4.新規テーブルの中身を確認する*/
select * from info_bk;
```

###解説
**1.テーブル定義を複製する　CREATE TABLE info_bk LIKE info;**
[infoテーブル]をもとに、新しく[info_bk]という箱が作成されます。

中身のデータは入っていませんが、インデックスやプライマリーキーなどもコピーして作成されます。

以下のSQLを使うと、データの移行も含めて、新しいテーブルができますが、インデックスやプライマリーキー、デフォルト値は再設定が必要になります。

```
CREATE TABLE info_bk SELECT * FROM info;
```

**3.既存テーブルのデータを新規テーブルに挿入する　INSERT INTO info_bk SELECT * FROM info;**
[info]テーブルのデータを、[info_bk]テーブルの中に追加できます。

VALUESをselectの前に書きたくなってしまいますが、このinsert文については、VALUESは必要ありません。
info_bkとinfoのカラムの数が一致する必要があります。（1でテーブルを複製しているので、カラム数は一致していますね。）

以上です！

最後まで読んでいただいた方、ありがとうございました。
「Pythonで学ぶアルゴリズム　第4弾：素数」を参考にSymPy LiveとWolframAlphaとgoogleでやってみた。

(オリジナルポスト)
https://qiita.com/Yuya-Shimizu/items/5f00e085c8052c115604

##SymPy Liveで
https://live.sympy.org/
入力
print([i for i in sieve.primerange(1, 100)])
出力
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

##WolframAlphaで
入力
100までの素数
https://www.wolframalpha.com/input/?i=100%E3%81%BE%E3%81%A7%E3%81%AE%E7%B4%A0%E6%95%B0&lang=ja
出力
2 | 3 | 5 | 7 | 11 | 13 | 17 | 19 | 23 | 29 | 31 | 37 | 41 | 43 | 47 | 53 | 59 | 61 | 67 | ... | 97 (25 整数)

##googleで
入力
100までの素数
https://www.google.com/search?q=100%E3%81%BE%E3%81%A7%E3%81%AE%E7%B4%A0%E6%95%B0&rlz=1C1CHBD_jaJP908JP908&oq=100%E3%81%BE%E3%81%A7%E3%81%AE&aqs=chrome.1.69i57j0l4j0i395l3.6254j1j7&sourceid=chrome&ie=UTF-8
出力
よく取り上げる、暗記テストに出がちな素数は、1〜100まで、「2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97」の25個です。
Pinterestのように写真を表示する

#はじめに

絶賛ポートフォリオ製作中の駆け出しエンジニアです


インスタグラムのような古着専用の写真投稿サイトを作っています


その時に写真の投稿一覧画面でPinterest(https://www.pinterest.jp/) というサイトのように写真を並べるために奮闘しましたので備忘録として残したいと思います

#コード

## before

```ruby:post.html.erb
 <div class = contents-row >
    <% @items.each do |item| %>
      <ul class='item-lists'>
          <li class='list'>
              <%= link_to items_path(item.id), method: :get do %>
                <%= image_tag(item.image, class:"item-img") %>
              <% end %>
          </li>
      </ul>
    <% end %>
  </div>
```

```css:post.scss
.contents-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  margin: 0 auto;
  width: 95vw;
}

.item-lists {
  margin: 5px;
}

.list {
  width:25vw;
}

.item-img {
  width: 100%;
  height: auto;
  border-radius: 30px;
  vertical-align: bottom;
}
```

## after

```ruby:post.html.erb
 <div class = contents-row >
  <ul class='item-lists'>
    <% @items.each do |item| %>
          <li class='list'>
              <%= link_to items_path(item.id), method: :get do %>
                <%= image_tag(item.image, class:"item-img") %>
              <% end %>
          </li>
    <% end %>
  </ul>
  </div>
```

```css:post.scss
.contents-row {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 0 auto;
  width: 95vw;
}

.item-lists {
  column-count: 3;
  column-gap: 15px;
  column-fill: auto;
 }
 
.list {
  width:25vw;
}

.item-img {
  width: 100%;
  height: auto;
  border-radius: 30px;
  vertical-align: bottom;
  margin: 5px;
}
```


#行ったこと

• 【html】　ulタグがeach文の中に入っていたのでeach文の外に出した
• 【css】　item-listsにcolumn-countなどを記述し、それに合わせてそれぞれ調整した

#参考サイト

https://designsupply-web.com/media/suplog/1862/

https://www.pinterest.jp/
iPhoneの画面ロックを解除する方法


<h2>方法 1:iTunesでiPhoneのロック画面を解除<h2>
<p>操作手順 1:iTunesを立ち上げます。iTunesのインタフェースにiPhoneデバイスアイコンが表示されるまでお待ち下さい。iPhoneアイコンをクリックし、「概要」＞「iPhoneを復元」をクリックし、iPhoneが初期化され、そのロック画面も解除されます。</p>
<img src="https://www.aiseesoft.jp/images/ios/iphone-recovery-mode-itunes-window.jpg" alt="iTunesでiPhoneの画面ロックを解除">
<p>操作手順 2:iPhoneをiTunesに同期したことがない場合、iPhoneをリカバリーモードに入る必要があります。</p>
具体的な方法なら、<a href="https://www.aiseesoft.jp/tutorials/restore-locked-iphone.html">iPhone ロック解除の使い方</a>までご参考ください。
<h2>方法 2:ロック解除ツールをご利用</h2>
<p><a href="https://www.aiseesoft.jp/iphone-unlocker/">Aiseesoft iPhone ロック 解除</a>はiPhoneのリカバリーモード、DFUモード、ブルースクリーン、リンゴループ、真っ暗画面、ロック画面などの不具合を修復することができるので、iPhoneのロック画面を解除するには、おすすめ。</p>
<img src="https://www.aiseesoft.jp/images/iphone-unlocker/remove-passcode-step2.png" alt="iPhone ロック解除"/>

具体的な方法なら、<a href="https://www.aiseesoft.jp/iphone-unlocker/tutorial.html">iPhone ロック解除の使い方</a>までご参考ください。
Splunkで日本のCOVID19感染状況を表示する（NHKオープンデータ）


[新型コロナ データ一覧](https://www3.nhk.or.jp/news/special/coronavirus/data-widget/)
でオープンデータとして、コロナウィルス感染者数のデータが公開されるようになった。

データは
https://www3.nhk.or.jp/n-data/opendata/coronavirus/nhk_news_covid19_domestic_daily_data.csv
など

#取り込み

ヘッダーをみると
`日付,国内の感染者数_1日ごとの発表数,国内の感染者数_累計,国内の死者数_1日ごとの発表数,国内の死者数_累計`
となっていたのでそのままだとSplunkで処理できないので、一応

`date,infected_daily,infected_accum,death_daily,death_accum`
として取り込んでみる。

```configuration:props.conf
[ NHK_CSV ]
pulldown_type=true
PREAMBLE_REGEX=日付
FIELD_NAMES=date,infected_daily,infected_accum,death_daily,death_accum
TIMESTAMP_FIELDS=date
TIME_FORMAT=%Y/%m/%d
SHOULD_LINEMERGE=true
LINE_BREAKER=([\r\n]+)
CHARSET=UTF-8
NO_BINARY_CHECK=true
category=Structured
disabled=false
```

![取り込み.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130729/d6238563-92ce-5e71-b134-4c3624023361.png)

で準備する。

#グラフ

```javascript:graph.spl
sourcetype="NHK_CSV" earliest=0
| table _time ,infected_daily,infected_accum,death_daily,death_accum
```

![グラフ１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130729/ed1ccb8e-5da0-bd4c-729a-f8b7ef339f8a.png)

infected_accumを対数のオーバーレイ表示にしている。

#定期的にとる。

https://qiita.com/toshikawa/items/ab8eeb4bb997b64bc0af#inputconf%E7%94%A8
を参考にしてもらえれば。

```python:get_csv.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import requests

headers={'accept': 'text/csv', 'content-type': 'text/csv'}
url = 'https://www3.nhk.or.jp/n-data/opendata/coronavirus/nhk_news_covid19_domestic_daily_data.csv'

response=requests.get(url,headers=headers)
response
```
という簡単なスクリプトで十分だと思う。

```configuration:inputs.conf
[script:///opt/splunk/etc/app/ourapp/bin/get_csv.py]
disabled = 0
index = foo
interval = 86400
sourcetype = NHK_CSV
```
とかで読み込み。　

すいません、検証していません。:sweat:どなたか動くやつをお願いします。

#まとめ
GOJASで発表した時はNHKのデータを使用しました。その時はビミョーな感じでしたが今回きちんとした形で利用ができるようになりました。

日本語ヘッダーCSVはどこかで加工しないとSplunkで読み込めないので、

1.ダウンロードした時に加工
2.Splunk側で加工

としないといけないのが厳しいですね。:sweat:

今、また広がりつつあるので、データを持ってきてみてみてはいかがでしょうか？
【Unity】MonoBehaviourの初期化に Awake() Start()は使用しない

PONOS Advent Calendar 2020の20日目の記事です。
前日記事:[@MilayYadokari](https://qiita.com/MilayYadokari) [読みやすいソースコードの作り方]
翌日記事:[@FW14B](https://qiita.com/FW14B) [【Unity】32bitアーキテクチャを切り捨てれば開発効率が上がる]

# 便利なイベント関数
UnityのMonoBehaviourに用意されているイベント関数。
記述しておけば特定のタイミングに自動で呼び出され、非常に便利です。
ところが、何も考えずに利用を続けると大きな落とし穴に成長してしまいます。
そこで今回は初期化に関する関数 Awake()と Start()について、一記事書いていきます。

記事投稿時点での使用 Unity 2019.4.8f1

# Unityの気分次第
全てのオブジェクトをAwake()やStart()で初期化していると、
ディレクターやマネージャー等の管理者的な上位クラスよりも、大量に配置されている敵キャラ等の末端クラスの方が先に初期化される場合があります。結構順番がランダムです。
もし末端クラスで上位のクラスを参照していれば、ゲームを再生する度に nullが出たり出なかったりといった事態に陥ります。

それぞれのイベント順序は明確に決まっていますが、同じイベント関数はどのオブジェクトから呼び出されるのか保証されていません。

イベント順序は公式マニュアルで↓
https://docs.unity3d.com/ja/2019.4/Manual/ExecutionOrder.html

また、自動呼び出しなので任意のタイミングで初期化ができません。

# 実行順の指定はできるが…
![スクリーンショット 2020-12-16 15.57.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538884/526859ba-ad7f-9811-2a53-1ceeb24fbd9a.png)
Edit → ProjectSettings → Script Execution Order からスクリプト毎に実行順を
指定できます。
ですがこの方法では新規スクリプトを作成する度に設定する必要があり、数が増えてくるとこのウィンドウでは扱いきれなくなるのでオススメできません。

プロジェクト全体での順序より、とあるシーンのとあるオブジェクト群での順序を明確にできればそれで良いといった場合の方が多いと思います。

# 手動で行えばいい
対応策はごく単純です。
Unityに自動で呼び出させていたところを手動で呼び出すようにすれば良いだけです。

```C#
public class SceneInitializer : MonoBehaviour
{
    [SerializeField] PlayerChara playerChara = default;

    void Awake() // Start()でも良い
    {
        // オブジェクトを順に初期化(変数は一例)
        masterData.Initialize();
        playerChara.Initialize();
        enemyManager.Initialize();
        // 完了後は不要なので自壊
        Destory(this);
    }
}

public class PlayerChara : MonoBehaviour
{
    // Awake()は書かずに自作関数を
    public void Initialize() {}
}
```

具体的にはシーン初期化用のスクリプトを用意し、Awake()はそこだけに記述する。
そのAwake()内で各オブジェクト群の初期化処理を意図通りの順番で記述すればOK。
シーンの初期化が完了すれば初期化用スクリプトをDestroyすればスッキリ済みます。

ヒエラルキーの各所にバラバラと配置してあるオブジェクトも、ここで一元化することができます。

また動的にオブジェクトを生成する場合も、生成されたオブジェクトのAwake()は使わず、生成元で初期化処理を呼ぶようにします。

# 非同期処理に向けてのアレンジ
```C#
public class SceneInitializer : MonoBehaviour
{
    [SerializeField] PlayerChara playerChara = default;

    IEnumerator Start()
    {
        yield masterData.Initialize();
        yield playerChara.Initialize();
        yield enemyManager.Initialize();
        Destory(this);
    }
}

public class PlayerChara : MonoBehaviour
{
    // 戻り値をIEnumerator型にしてコルーチンに対応
    public IEnumerator Initialize()
    {
        yield break;
    }
}
```
Start() は戻り値の型をIEnumeratorにすることでコルーチン化させることもできます。
各初期化処理の方も IEnumerator にすることで、アセットの非同期読み込みなどの完了を待たせられます。
AddressableAssetsは読み込みが非同期なので、待機させる処理がどこかしら必要になってくると思います。

# 後の禍根にならないよう
新機能の実装などでは都度テストしながらになるため、勝手に呼び出される Awake()で済ませがち。
意図した機能を作ることに注力するので、くっつけるだけで動作するAwake()はよく使います。
ですがそのまま忘れて見返すことなく開発が進み、同じ構造がどんどん増えてくると…

早めの見直し&対応を心がけたいところです。
【初心者】PHPで文字を大文字/小文字に変換する

# PHPで小文字を大文字に変換したい
そんな時は…

```php
mb_strtoupper(文字列)
```

# 大文字を小文字にしたい時
```php
mb_strtolower(文字列)
```
これを使用する。

少しずつPHPでできることが増えてきたと思う。
FirebaseCloudMessagingのログをBigQueryにアウトプットする

FirebaseCloudMessagingでの配信のレポートはBigQueryにエクスポートすることができます。今回BigQueryへのエクスポートの設定でつまずいたポイントがあったためそれについて紹介します。

# 結論

結論として、以下の設定をすることでBigQueryへFirebaseCloudMessagingのレポートが出力されるようになります。

## 1. BQエクスポートを設定

まず、Firebaseの設定 > 統合 > BigQueryから以下の様にCloud Messgingとの連携を有効にします。

![fcm-test-app_-_BigQuery_-_Firebase_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74514/c14a1cfe-406e-2f76-eaf1-082d840de5a8.png)


## 2. firebase-setup用のユーザに権限を付与

続いて、以下の様にIAMの設定を行います。

```
メンバー名: firebase-setup@system.gserviceaccount.com
役割: BigQuery Data Editor
```

# 躓いた点

以下のドキュメントに従い、BQエクスポートを設定するだけではだめだで上記2の手順のようにfirebase-setup用のユーザに権限を付与する必要がありました。

[https://firebase.google.com/docs/cloud-messaging/understand-delivery?hl=ja#bigquery-data-export](https://firebase.google.com/docs/cloud-messaging/understand-delivery?hl=ja#bigquery-data-export)

# エクスポートされるデータについて

実際にexportされるデータは以下のようなスキーマにてexportされます。

[https://firebase.google.com/docs/cloud-messaging/understand-delivery?hl=ja#what-data-exported](https://firebase.google.com/docs/cloud-messaging/understand-delivery?hl=ja#what-data-exported)

# まとめ

FirebaseCloudMessagingでの配信のレポートのBigQueryへのexportには、エクスポートの設定だけでなくIAMの設定になるので注意しましょう。
macのIntellij(JDBC)からwindows認証でSQLServerに接続する方法

# 概要

Intellij(DataGrip)ではJDBCドライバーを利用し各DBに接続することができます。今回はSQLServerにWindows認証方式で接続する方法について調べたので紹介します。

# 環境

- macOS Catalina 10.15.7
- SQLServer 2016

# 結論

### JDBCドライバー

JDBCドライバーとして以下のjTDSを利用します。

- [http://jtds.sourceforge.net/](http://jtds.sourceforge.net/)

### オプション

URLに以下のようにuseNTLMv2とdomainのオプションを指定します。その他userやpasswordはいつもどおり入力します。

```markdown
jdbc:sqlserver://ホスト名;useNTLMv2=true;domain=ドメイン名
```

# 詳細

## SQLServerの認証方法

SQL Serverには２種類の認証モードがあります。それが以下の2種類です。

- Windows認証: Windowsのドメインで認証する
- SQL Server認証: 作成したユーザー・パスワードで認証する

## SQL Srever認証の場合の接続方法

URLには以下のようにホスト名のみを指定し、userやpasswordを入力することで接続できます。

```markdown
jdbc:sqlserver://ホスト名
```

## Windows認証の場合の接続

改めましてjdbcからWindwos認証でSQLServerに接続する場合、jTDSを利用し、以下のようにuseNTLMv2とdomainを指定することで接続できます。

```markdown
jdbc:sqlserver://ホスト名;useNTLMv2=true;domain=ドメイン名
```

## オプションについて

Windows認証でSQLServerに接続する場合、付与する必要のあるオプションについて説明します。

### useNTLMv2

NTLMはWindownsの認証方式の一つです。そのためこの認証方式が利用できる場合においてuseNTLMv2オプションをtrueとすることでNTLMv2を利用したWindows認証にて接続ができるようになります。

NTLM認証が無効になっている場合はこちらの方法が利用できないため注意が必要です。Windows認証に関しては以下をご参照ください。

[https://docs.microsoft.com/ja-jp/windows-server/security/windows-authentication/windows-authentication-overview](https://docs.microsoft.com/ja-jp/windows-server/security/windows-authentication/windows-authentication-overview)

### domain

domainはActive Directoryのドメインです。接続するSQLServerが所属するドメインを指定する必要があります。

# まとめ

macのIntellij(JDBC)からwindows認証でSQLServerに接続する方法を紹介しました。接続したいよと思った方のご参考になれば幸いです。
ブログをNuxtContentに移行したときの覚書

# ブログをNuxtContentに移行したときの覚書

最近GatsubyからNuxtへ置き換えたのでそのときの覚書です。

## 画像表示

通常のマークダウンの記法ではNuxtCountent上で画像を表示できない。  
画像を表示する場合はグローバルコンポーネント作成してマークダウン上で指定する必要があります。  

以下issues参照  
https://github.com/nuxt/content/issues/106

でも、可能な限り通常のマークダウンエディタで見える形にしたい。
→RemarkのPluginで置換する。

置換は以下のようなPluginを作成する。  
以下の例では仮の文字列にしていますが、実際はimgタグを作成したコンポーネントへ置換するようにしました。

``` ts
/**
 *置換処理
 *
 * @param {*} text
 * @returns
 */
const ReplaceText = (text: any) => {
  return text.replace('ReplaceTest', 'ReplaceTestResult')
}

module.exports = attacher

function attacher() {
  return transformer

  /**
   *対象ノードのテキストを変更する。
   *
   * @param {*} tree
   * @param {*} file
   * @returns
   */
  function transformer(tree: any, file: any) {
    for (let i = 0; i < tree.children.length; i++) {
      const item = tree.children[i]
      if (item.type === 'paragraph') {
        for (let j = 0; j < item.children.length; j++) {
          const child = item.children[j]
          if (child.type === 'html') {
            child.value = ReplaceText(child.value)
          }
        }
      }
    }

    return tree
  }
}
```

nuxt.configのcontent.markdown.remarkPluginsに作成したPluginを追加。

``` ts
  content: {
    markdown: {
      remarkPlugins: ['~/remarkPlugins/myPlugin.ts'],
    }
  },
```

NuxtContent公式ページでのRemarkpluginの設定方法  
https://content.nuxtjs.org/ja/configuration#markdownremarkplugins

## Feedの設定

NuxtContent公式ページでFeedの設定方法があるので参照。  
https://content.nuxtjs.org/ja/integrations#nuxtjsfeed

## 静的ページ生成

nuxtのgenerateで全ての処理が実行されないため`$content`はasyncData以外で使わない。  
(別のメソッドで使用すると`$content`が空となる)

generate.routesで動的ページを設定する。  
https://content.nuxtjs.org/ja/advanced


## metaタグとtitle

headプロパティを設定する。  
その際にasyncDataの返却値と同じ名前のプロパティを作っておくと参照できます。

``` typescript
//asyncDataの返却値
article: any
head() {
    return {
      title: 'title',
      meta: [
        {
          hid: 'description',
          name: 'description',
          content: this.article.description,
        }
    }
}
```

headプロパティについて  
https://ja.nuxtjs.org/docs/2.x/configuration-glossary/configuration-head/
Sprockets::DoubleLinkError を解消した方法

やんばるエキスパートというオンラインスクールにて教材に取り組んでいた時の出来事です。
## Sprockets::DoubleLinkErrorの出現

Railsのメッセージ投稿アプリを作成しており、その中でstylesheetsフォルダのcssファイルをscssファイルに拡張子を変更し、動作確認を行ったところ、「Sprockets::DoubleLinkError」が出現しました。

## 原因はcssファイルとscssファイルの干渉

stylesheetsフォルダ内にcssファイル、min.cssファイル、scssファイルの３つが存在しており、cssファイルとscssファイルが干渉してエラーが起こっていたようです。

cssファイルとmin.cssファイルを削除し、動作確認を行った所、エラーは解消されました。

しかし、、、

## 拡張機能Easy Sassにも注意

VScodeを再起動すると、再度cssファイルとmin.cssファイルが生成されていました。
拡張機能にEasy Sassを入れており、どうやらこいつが悪さをしていたようです。
Easy Sassを無効化した所、cssファイルとmin.cssファイルは自動生成されなくなりました。

そして、エラーも出ず、問題なく動作できるようになりました。
【教材】JavaScriptの教材を作ってみました2

※当方駆け出しエンジニアのため、間違っていることも多々あると思いますので、ご了承ください。また、間違いに気付いた方はご一報いただけると幸いです。

半人前のくせに、偉そうに教材を作ってみました。

###学べる技術

- 繰り返し構文
- 多次元配列

##問題１

```js
console.table(array);

 //[ [1], [2, 3], [4, 5, 6], [7, 8, 9, 10] ]
```
この様な結果が返る配列arrayを繰り返し構文を用いて作ってください。(見やすいように半角スペースを入れてますが不要です)

##問題２

```js
let x = ["a", "b", "c"];
let y = ["d", "e", "f"];
let z = ["g", "h", "i"];
```
上記の様な配列があるとします。

下記の様な結果が返る配列X,Y,Zを繰り返し構文を用いて作ってください。

```js
console.log(X);
console.log(Y);
console.log(Z);

//["a", "d", "g"];
//["b", "e", "h"];
//["c", "f", "i"];
```

##問題１　回答例

```js
let array = [];
let inArray = [];

let num = 1;
for (let i = 1; i < 5; i++) {
  for (let g = 0; g < i; g++) {
    inArray.push(num);
    num++;
  }
  array.push(inArray);
  inArray = [];
}
console.table(array);
```

##問題２　回答例

```js
let x = ["a", "b", "c"];
let y = ["d", "e", "f"];
let z = ["g", "h", "i"];

let X = [], Y = [], Z = [];

const array = [x, y, z];
const array2 = [X, Y, Z];

for (let i = 0; i < 3; i++) {
  for (let g = 0; g < 3; g++) {
    array2[i].push(array[g][i]);
  }
}
console.log(X);
console.log(Y);
console.log(Z);
```

※あくまで駆け出し半人前エンジニアが作った回答となります。あまり鵜呑みにしないで下さい。
【Unity】32bitアーキテクチャを切り捨てれば開発効率が上がる

[PONOS Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ponos)の21日目の記事です。
昨日は@UdonLoveさんの「Monobehaviourのイベント関数をなるべく使わない」でした。

### はじめに
時間のない方のために先に結論を言っておきます。

**ビルド対象から32bitアーキテクチャを排除すれば、サイズが小さくなりビルド時間も短縮できる！**

以下、それについて紹介している記事になります。


### Architecture設定の警告
Uity2019.4で開発中のある日、
PlayerSetingsのiOSビルド設定にて警告が出ていることに気付きました。
![スクリーンショット 2020-12-16 14.28.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538709/df18b09f-a231-6487-a7ef-701ed6804585.png)
日本語にすると「ARMv7(32bits)は非推奨かつUnity2020.1から項目削除されますよ」という内容です。

このArchitectureという項目についてはデフォルトのまま「Universal」にしていたのですが、それだとARM64(64ビット)とARMv7(32ビット)のどちらも有効になっていたようです。

### 32ビット切り捨て

数年前なら兎も角、流石にもう32ビットの端末は切り捨てて良いだろうと考えます。
Apple A6を使ったiPhone5/iPhone5c/iPad4以前の機種が該当しますが...もういいですよね？

![スクリーンショット 2020-12-16 14.29.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538709/9d537223-782b-e2b6-533e-de04374f0aed.png)

Architectureという項目を「Universal」から「ARM64」に変更しました。

これで警告も消えたし、スッキリいい気分！
その時はそれだけで満足していました。

### アプリサイズ減

そして翌日、いつものように端末ビルドを手動で行っていると、あれ？もう終わってる...
アプリサイズもいつもより小さい気がする...

ということで、調査してみた結果が以下の表になります。

|Architecture設定   |Universal|ARM64|比較|
|:---:|:---:|:---:|:---:|
|Unity iOS端末ビルド時間|7分|7分|変わらず|
|Xcode Archive時間|11分|6分|45%減|
|ipaファイル作成時間|17分|9分|47%減|
|Archiveサイズ|1.32GB|0.74GB|44%減|
|ipaファイルサイズ|78.4MB|61.1MB|22%減|
|アプリサイズ|74.8MB|58.3MB|22%減|

※MacPro(Late2013)での計測です。

### それよりもビルド時間減

アプリサイズが小さくなったことも嬉しいですが、ビルド時間がほぼ半減！というのがとても嬉しいです。
無駄な待ち時間が減り、作業が捗ります。

もちろん、本当に32ビットアーキテクチャの端末を切り捨てちゃっていいか否かは方針にもよるので、事前にチーム内でご相談ください。

以上

明日は@caramel_cafeさんです。
Webhookについて簡単に調査

#Webhookとは
アプリケーション同士を連携させるための機能。
　
##もうちょっと詳しく
<b>アプリケーションでイベントが実行された際、他のアプリケーションに対してリアルタイムでURLを通知する仕組みです。</b>
（ 例えば、Slackに通知が入った時にGmailにも通知が来るみたいな感じ ）

<b>URLでの通知方法はHTTP通信</b>を使ったものです。やっている事は<b>POSTリクエスト</b>です。
※ POSTリクエスト ・・・・ データをアップロードするための送信
　
###例え話
なんとなくの流れで言うとこんな感じ
　

<b>Slack にあらかじめ Gmailアドレスを登録　　　　　　ピザハ○トに会員登録（Gmail登録）
　　　　　　　　↓　　　　　　　　　　　　　　　　　　　　　　　↓
　　　　　Slackに通知が入る　　　　　　　　　　　　　　　　ピザを注文
　　　　　　　　↓　　　　　　　　　　　　　　　　　　　　　　　↓
　　　登録してあるGmailに通知　　　　　　　　　会員の〇〇さんから「注文入りました〜」
　　　　　　　　↓　　　　　　　　　　　　　　　　　　　　　　　↓
　　　 　　Gmailに通知が来る　　　　　　　　　　　Gmailに通知「注文受け付けました〜」</b>
　

（ ※ この例えは雰囲気で書いたので間違っていると思うけど書きたかったです ）
　
　
###注意点
気をつけなければいけない事は、送信先と受け取り先でのデータ形式が違うと扱えない事。
そのためにデータの変換が必要になってきます。
どうするのかと言うと......
　
単純に<b>変換してくれるサービス</b>使いましょって話になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/836751/2468f3d2-8d68-4746-169e-8f87a1a1d487.png)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/836751/a63ec808-5750-8bee-0dc1-32a810306fa7.png" width="320">

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/836751/2fd27183-e6aa-b05a-84e4-bf9563e59ad1.png)

などなど色々な中間コネクタがあります。
　
　

##参考
https://sendgrid.kke.co.jp/blog/?p=1851
https://qiita.com/soarflat/items/ed970f6dc59b2ab76169
https://kintone-blog.cybozu.co.jp/developer/000283.html
https://help.zoho.com/portal/ja/kb/salesiq/admin-guide/webhooks/articles/webhook%E3%81%A8%E3%81%AF#Webhook
QGISのProcessingで実行するPythonスクリプトにも型を付けよう


## はじめに
今回でProcessing周りの記事を書くのも３回目[^1]  [^2]となりました。
QGISのProcessing便利ですね。QGISのバージョンが上がるにつれて、アルゴリズムも増え、UIの改善も進み、どんどん使いやすくなっているように感じます。
私自身ものすごくProcessingのお世話になっていて、ベクタ・ラスタデータを使って何かしようと思った時や、相談を受けて支援をしようとしたときには、真っ先にProcessingの中の機能で解決できないか探すクセがついています。そして、大抵見つかり、解決できない場合もあるにせよ、何かしら解決の糸口になることが多いです。
さて、今回はProcessingというよりは、Processingスクリプトを書くときのPythonについて、思ったことを書こうと思います。

また、今回の記事を書くにあたって、執筆時点(2020/12/16)で、LTSとなっている`QGIS3.10`を対象としています。

[^1]: [QGISのprocessingを使ってパンシャープン画像作ってみた](https://qiita.com/Zero_Kohaku/items/e24bcb7e8e67ca08f988)
[^2]: [QGISのprocessingでできそうなこと](https://qiita.com/Zero_Kohaku/items/cd0d2f8648a8ff7a5616)

## Pythonで型を付ける

Pythonは動的型付け言語ですので、コードを書くときに型を意識することはあまりないと思います。ただ、Python3.5で[PEP484](https://www.python.org/dev/peps/pep-0484/)[^3]が実装されたことによって、Python3.5以降をターゲットに書いたPythonコードには、型を記述できるようになっています。
[^3]: 日本語訳は[こちら](https://qiita.com/t2y/items/f95f6efe163b29be59af)が参考になります。
こんな感じです。

```python:型を書いたコード
def sum(a: int, b: int) -> int:
    return a + b

class Point2D:
    def __init__(self, x: float, y: float) -> None:
        self.x: float = x
        self.y: float = y

p = Point2D(0.0, 0.0)
```
```python:型を書かないコード
def sum(a, b):
    return a + b

class Point2D:
    def __init__(self, x, y):
        self.x = x
        self.y = y

p = Point2D(0.0, 0.0)
```

どうでしょうか。
私的な感想になってしまいますが、型を書いたコードのほうが、型を書かないコードよりも`sum`という関数を呼んだときの戻り値が整数であることや、`Point2D`クラスのx, y属性は小数であることが、パッと見ただけでもわかりやすいと思います。
QGIS3.10に組み込まれているPythonのバージョンは`3.7.3`なので、このような型が書いてあるPythonコードを実行することができます。


## Processingで型を付ける
では、Pythonコードに型が記述できるようになったことで、Processingがどうなるかというと、Processingアルゴリズムを実行した結果がベクタレイヤなのかラスタレイヤなのか把握しやすくなります。

例えば、Pythonコードの中でProcessingのアルゴリズムを実行しようとすると、以下のような感じになります。

```python:代入変数に型の記述あり
from typing import Dict

# インターセクトの実行例
params: Dict[str, Any] = { ... }
interect_layer: QgsVectorLayer = processing.run("native:intersection", params)['OUTPUT']

# ラスタ計算機の実行例
params: Dict[str, Any] = { ... }
calc_layer: QgsRasterLayer = processing.run("qgis:rastercalculator", params)['OUTPUT']
```
```python:代入変数に型の記述なし
# インターセクトの実行例
params = { ... }
intersect_layer = processing.run("native:intersection", params)['OUTPUT']

# ラスタ計算機の実行例
params = { ... }
calc_layer = processing.run("qgis:rastercalculator", params)['OUTPUT']
```
どうでしょうか。
Processingアルゴリズムを実行する場合、`processing.run()`に、実行したいアルゴリズム名と対応するパラメータを引数として渡せばよいので、汎用的に書ける反面、処理結果がベクタレイヤなのかラスタレイヤなのか、ぱっと見よくわからないの状態になっているように思います。これに対して、受け取った結果を代入する変数に`QgsVectorLayer`や`QgsRasterLayer`といった型を書いておくことによって、処理結果を把握しやすくなっているのではないでしょうか。


## おわりに
型をスクリプトの中に書くことによって、従来よりもコードの記述量が多くなってしまうのは確かですが、やはりコードというのは書く時間よりも読む時間の方が長いことを考えると、振り返った時に何をやっているのか、少しでも把握しやすくあるべきだと思います。
型を書かなくても特に問題にはならないですが、型を書いた方が後々幸せになれると思うので、どっちでもいいのであれば型を書いたほうがいいと思います。

特に、複雑なProcessingスクリプトを作ろうと思うと、どうしても一つのPythonスクリプトファイルのコード量が多くなる傾向にあります。それを避けようとしたとしても、アルゴリズム自体が細分化され、結局のところ`processing.run()`で呼び出して、処理結果を変数に代入し、次の入力へ...という感じになってしまいます。

あれ？この変数のデータはラスタだっけ？ベクタだっけ？と混乱を減らすためにも、型は書いておきたいですね。
さくっとテスト用のS3が欲しい。minioをdocker-composeで起動し、初期bucketがある状態を作る。

多分これが一番速いと思います。
ディレクトリ配下に複数のディレクトリを配置するとそれがbucketになるのを使います。

```docker-compose.yml
  s3:
    image: minio/minio
    volumes:
      - "./docker/s3:/s3"
    ports:
      - "9000:9000"
      - "9001:9001"
    environment:
      MINIO_ACCESS_KEY: test_key
      MINIO_SECRET_KEY: test_secret
    entrypoint: sh
    command: -c "mkdir -p /s3/bucket-test && /opt/bin/minio server --console-address ':9001' /s3"
```

http://localhost:9001/ にアクセスし、上記の key, secret でログインできることを確認する。

## 参考

https://github.com/minio/minio/issues/4769
positionを使用しているｐ要素を左揃えのままデバイスの中央に配置する方法

こんにちは。[niina](https://twitter.com/niina_design)です。

先日メインビジュアルの画像上に配置するコピーライトを、左揃えのまま中央に配置する方法がわからず苦悩していました…
問題になっていたのは、中央配置したいコピーライト部分のh2要素にposition指定をしていたため、margin: 0 auto;が効かないということでした。
解決策がわかったので備忘録として記録しておこうと思います。

##positionを使うと要素が浮いたような状態になる##

今回の場合は、メインビジュアルの最下部にコピーライトを置きたかったので、コピーライトの位置をpositionで指定することにしました。

```html:html
<div class="mv">
  <h2 class="mv-copy">コピーライトです</h2>
</div>
```

```css:css
.mv {
  position: relative;
}

.mv-copy {
  position: absolute;
  bottom: 0;
}
```

何も知らなかった私は安易に.mv-copyにmargin: 0 auto;すれば左揃えのまま、中央配置にできるもんだと思っていました。

が、実はpositionを使った場合、marginは効かなくなってしまうのです。
何故か？？
それはpositionを使うことで、その要素自体が浮いたような状態になってしまうからです。

##positionとtransformで要素を移動させよう##

それでは中央に配置するためにはどうすればいいのでしょうか。
そこで使うのがpositionとtransformです。
実際に見ていきましょう。

```css:css
.mv-copy {
  position: absolute:
  bottom: 0;
  left: 50%; /*まずは要素を左に50%移動させる（要素の最左部がど真ん中にくる）*/
  transform: translateX(-50%); /*余分に左に移動してしまった要素の半分だけ右に戻す*/
```

これで完成です。
大量の画像ファイルをパワポに貼り付ける【python-pptx】

#概要
画像ファイルを１スライド１枚ずつ貼り付けたパワーポイントを生成するpythonスクリプトを書きました。
Web会議で撮影したPC画面のスクリーンショット画像を他の人と共有するときに、大量の画像ファイルをそのまま共有するのは見づらくて良くないと思ったので作りました。
#環境
macOS Catalina 10.15.7
python3.8.0
Microsoft PowerPoint for Mac, バージョン16.43(20110804)
#インストール

```
pip install python-pptx
pip install Pillow
```
#方針
指定したディレクトリの中の画像ファイルを１スライド１枚ずつ貼り付けたパワーポイントファイルを作成します。
python-pptxを使って、pythonでパワーポイントオブジェクトを操作します。
画像をセンタリングして貼り付けるために、画像サイズを取得する必要があるので、Pillow（PIL）で取得します（参考：[python-pptxで画像をセンタリングする](https://qiita.com/shimajiroxyz/items/f57efa222765ac9eea39)）。
画像がスライドからはみ出さないように、画像がスライドよりも横長のときは横幅めいっぱいに貼り付け、縦長のときは縦幅めいっぱいに貼り付けるようにします。

#コード

```Python
from pptx import Presentation
from PIL import Image
import os

#スライドサイズ
#4:3 (default) 9144000x6858000
#16:9 12193200x6858000
SLIDE_WIDTH, SLIDE_HEIGHT = 12193200, 6858000
#スライド中心のX、Y座標（左上が原点）
IMG_CENTER_X, IMG_CENTER_Y = SLIDE_WIDTH/2, SLIDE_HEIGHT/2
#スライドのアスペクト比
SLIDE_ASPECT_RATIO = SLIDE_WIDTH / SLIDE_HEIGHT

#出力ファイル名
OUTPUT_FILE_PATH = "test.pptx"
#画像の格納ディレクトリ
IMG_DIR = "./data/"

#受け取ったプレゼンテーションオブジェクトにスライドを追加し、追加されたスライドオブジェクトを返す。
def add_slide(prs):
  #白紙スライドの追加(ID=6は白紙スライド)
  blank_slide_layout = prs.slide_layouts[6]    
  slide = prs.slides.add_slide(blank_slide_layout)
  return slide

#画像をスライド中心に貼り付ける
def add_picture(slide, img_file):
  #画像サイズを取得してアスペクト比を得る
  im = Image.open(img_file)
  im_width, im_height = im.size
  aspect_ratio = im_width/im_height
  
  #スライドと画像のアスペクト比に応じて処理を分岐
  #画像のほうが横長だったら横めいっぱいに広げる
  if aspect_ratio > SLIDE_ASPECT_RATIO:
    img_display_width = SLIDE_WIDTH
    img_display_height = img_display_width / aspect_ratio
  else: #画像のほうが縦長だったら縦めいっぱいに広げる
    img_display_height = SLIDE_HEIGHT
    img_display_width = img_display_height * aspect_ratio
  #センタリングする場合の画像の左上座標を計算
  left = IMG_CENTER_X - img_display_width / 2
  top = IMG_CENTER_Y - img_display_height / 2
  
  #画像をスライドに追加
  if aspect_ratio > SLIDE_ASPECT_RATIO:
    slide.shapes.add_picture(img_file, left, top, width = img_display_width)  
  else:
    slide.shapes.add_picture(img_file, left, top, height = img_display_height)  
    
  return slide
  


#スライドオブジェクトの定義
prs = Presentation()
#スライドサイズの指定
prs.slide_width = SLIDE_WIDTH
prs.slide_height = SLIDE_HEIGHT

#img画像のファイル名を取得
img_files = os.listdir(IMG_DIR)
#pngで終了するファイル名のみ抽出。貼り付けたい画像の拡張子に応じて変える
img_files = [name for name in img_files if name.endswith(".png")]
#昇順にソート（この順番でスライドに貼り付けられる）
img_files.sort()#昇順にsort

for name in img_files:
  path = IMG_DIR + name
  slide = add_slide(prs)
  add_picture(slide, path)
#pptxファイルを出力する
prs.save(OUTPUT_FILE_PATH)
```
#おわりに
最近Web会議をする機会が多いので、とりあえずスクショだけ取っといて、あとで人と共有するときには便利なスクリプトかと思います。
自分で見返したり、メモを残したりするときにも便利な気がします。
何らかの効率化の助けになると幸いです。
画像を一括でトリミング【python】【Pillow】

#概要
たくさんの画像から指定された座標をトリミングするpythonスクリプトを書きました。
#背景
Web会議の画面をスクショするときに、議論に遅れないようにとりあえず全画面スクショするのですが、あとで人に共有するときには、ツールバーなど画面上の余計な情報は消したいので、作りました。
数枚程度ならMacのプレビューなどでやってもよいですが、しばしば１００枚くらいのオーダーになるので、プログラムで一括でできると便利だと思いました。
#環境
macOS Catalina 10.15.7
python 3.8.0
#インストール

```
pip install Pillow
```
今回はPillowを使います。OpenCVでもできます。
#コード

```Python
# -*- coding: utf-8 -*-
import sys
from PIL import Image
import os

#トリミング前の画像の格納先
ORIGINAL_FILE_DIR = "./org_data/"
#トリミング後の画像の格納先
TRIMMED_FILE_DIR = "./cut_data/"

#画像パスと、左上座標、右下座標を指定して、トリミングされたimageオブジェクトを返す。
def trim(path, left, top, right, bottom):
  im = Image.open(path)
  im_trimmed = im.crop((left,top,right,bottom))
  return im_trimmed
  
  
if __name__ == '__main__':
  #もしトリミング後の画像の格納先が存在しなければ作る
  if os.path.isdir(TRIMMED_FILE_DIR) == False:
    os.makedirs(TRIMMED_FILE_DIR)
    
  #トリミングする左上の座標
  left, top = 0, 50
  #トリミングする右上の座標
  right, bottom = 2880, 1800
   
  #画像ファイル名を取得
  files = os.listdir(ORIGINAL_FILE_DIR)
  #特定の拡張子のファイルだけを採用。実際に加工するファイルの拡張子に合わせる
  files = [name for name in files if name.split(".")[-1] in ["png","jpg"]]
  
  for val in files:
    #オリジナル画像へのパス
    path = ORIGINAL_FILE_DIR + val
    #トリミングされたimageオブジェクトを取得
    im_trimmed = trim(path, left, top, right, bottom)
    #トリミング後のディレクトリに保存。ファイル名の頭に"cut_"をつけている
    im_trimmed.save(TRIMMED_FILE_DIR+"cut_"+val, quality=95) #qualityは95より大きい値は推奨されていないらしい
```

実際に使うときは、トリミング前、後の画像の格納先を用意し、ディレクトリをソースコード中で相対パスで指定してください。
その後プログラムを実行してください。
#おわりに
スクショをとるときにいちいち領域を選択するのは、枚数が多くなると面倒なので、全画面スクショしてあとから切り取る、というのは割と需要があるかと思います。
僕はWeb会議の画面をスクショして、この方法でトリミングしたあとに、[pythonでパワーポイントに貼り付けました](https://qiita.com/shimajiroxyz/items/4316608a01eb91543faa)。
なにかのお役に立てれば幸いです。
画像を回転、拡縮してからトリミング【python】【OpenCV】

#概要
画像の回転、拡縮、トリミングを一括で行うコードを書きました。
#背景
コマどりムービーを効率的に作るために、書きました。
コマどりムービーを作るときに、とりあえず広めに撮影しておいて、後でトリミングしたくなることがあると思います。
撮影途中に三脚にぶつかってしまったりすると、それまでの画角を再現しようとしても、微妙に角度、サイズがずれることもあります。
そのようなズレを補正しつつトリミングを行うために、画像を回転、拡縮してからトリミングを行うコードを書きました。
#コード

```Python
# -*- coding: utf-8 -*-
import sys
import cv2
import os
import numpy as np

ORIGINAL_IMG_DIR = "./"
TRIMMED_IMG_DIR = "./cuttest/"
if __name__ == '__main__':
  #トリミングする領域の左上座標
  startX = 963
  startY = 736
  #トリミングする領域のサイズ
  width = 2270
  height = 1450
  # 回転させたい角度（正の値は反時計回り）
  angle = -0.1
  # 拡大比率
  scale = 1.0
  
  #対象ディレクトリ内のファイル名を取得 
  files = os.listdir(ORIGINAL_IMG_DIR)
  #加工したい画像拡張子のファイルを抽出
  files = [name for name in files if name.split(".")[-1] in ["png","jpg"]]
  for val in files:
    src_mat = cv2.imread(ORIGINAL_IMG_DIR+val,1)
         
    # 画像サイズの取得(横, 縦)
    size = tuple([src_mat.shape[1], src_mat.shape[0]])

    # dst 画像用意
    dst_mat = np.zeros((size[1], size[0], 4), np.uint8)

    # 画像の中心位置(x, y)
    center = tuple([int(size[0]/2), int(size[1]/2)])

    # 回転変換行列の算出
    rotation_matrix = cv2.getRotationMatrix2D(center, angle, scale)
           
    # アフィン変換
    img_dst = cv2.warpAffine(src_mat, rotation_matrix, size, dst_mat, flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_TRANSPARENT)

    dst = img_dst[startY:height+startY, startX:width+startX]
    cv2.imwrite(TRIMMED_IMG_DIR+val, dst)
    print('cut '+val)
```
上記では、先に画像の回転と拡縮を先に行っており、トリミング領域の左上座標は、この回転、拡縮後の画像に対して指定されます。
したがって極端な回転や拡縮を行った場合には、想定とトリミング位置がずれる可能性があるので注意してください。
トリミング領域の左上画像を元画像での位置と合わせたい場合には、startX, startYに対して回転行列をかけてください(試していませんがnumpyなどを使えばできるかと思います)。

参考サイト
[サイズ変更・回転・切り抜き](https://axa.biopapyrus.jp/ia/opencv/image-crop.html)
【Ruby】ifのない条件式の？（クエスチョンマーク）の意味。三項演算子の使い方。

個人メモです。

以下のように、ifがなく、`?`（はてな）と`:`(コロン)が記述された式の意味を理解する。

・`x = y == "aaa" ? v : w`

##三項演算子
`?`（はてな）と`:`(コロン)を使った式は、if else文の省略形で三項演算子と呼ぶ。

以下の２つの処理は同じものとなる。

```ruby:通常
if 条件式
  戻り値1
else
  戻り値1
end
```

```ruby:三項演算子
条件式 ? 戻り値１ : 戻り値２
```

(1)条件式、(2)戻り値１、(3)戻り値２の３つの項目があるため、三項演算子と呼ぶ。


<br>
##参考演算子の実例
条件式がtrueの場合は戻り値１が返る。

```ruby:
x = 10
x == 10 ? "Yes" : "No"

=> "Yes"
```

条件式がfalseの場合は戻り値２が返る。

```ruby:
x = 10
x != 10 ? "Yes" : "No"

=> "No"
```


<br>
##`x = y == "aaa" ? v : w`の処理内容
これは、三項演算子の結果を変数xに代入する処理となる。

```ruby:
y = "aaa"
v = "Yes"
w = "No"

x = y == "aaa" ? v : w

p x
=> "Yes"
```

`y == "aaa"`がtrueなので前方の戻り値`v`を`x`に代入する。
JSON と YAML(or TOML) の使い分け

JSON か YAML どっちを使うべきだろう、となったときの個人的な判断基準。現実には様々な制約があったりするので必ずしもこの基準に従うのが良いとは限らないが、目安にはなると思う。

# JSON

- 機械: read & write
- 人間: read-only

人間が読むこともあるが、編集はしなくて済むような用途が向く。Web API の応答などはおおむねこの性質を持ち、事実広く採用されている。デバッグ時や緊急対応時には、テキストエディタで人間が編集する道も残されているのがテキストフォーマットである JSON の利点である。

# YAML

- 機械: read-only
- 人間: read & write

主に人間が作成や編集を行い、機械は読むだけといった用途に向く。翻訳定義のような静的データや、アプリケーションの設定ファイルなどは JSON よりも YAML が良い。機械から書き出す場合は、最初に雛形を生成するだけに留めるのが無難である。

# TOML

- 機械: read-only
- 人間: read & write

TOML は利用経験が浅いためあまりはっきりしたことは言えないが、ほぼ YAML と同等の用途と思って良さそうである。 YAML よりもいくらかシンプルで、人間が編集するという観点ではこちらの方が若干やりやすい。後発なだけに言語やライブラリのサポートはまだこれからといった印象だが、環境が整っているなら YAML の代わりにこちらを採用しても良さそうだ。ただ YAML 特有の機能を利用したいのであれば自然と YAML になるだろう。

# 機械も人間も read & write な用途には何が良いか

JSON を採用の上、人間が編集するためのインターフェースを用意し、実際にファイルを編集するのは機械とすることで、人間側の write 需要をできるだけ減らすのが最も無難だと思う。人間用のコメントが欲しければ、コメントも JSON 構造の中に含めてしまうという策がある。

YAML も検討の余地はあるが、機械が編集する際に人間のための表現（コメントなど）が失われたりしないように気を付ける必要がある。

TOML に関しては経験が浅くなんとも言い難いが、こちらも YAML 同様、機械での編集時に人間のための表現が壊れる可能性が高そうに見えるのが懸念点だ。
javascriptにおけるテキストエリアへの追加と削除

#1.はじめに
まずはhtmlコードの型

```
<input type="text" id="text1">
<input type="button" value="追加" onclick="addText();">
<input type="button" value="削除" onclick="deleteText();">
<br>
<textarea id="area1"></textarea>
```

次にjavascriptのコードの型

```
<script>   
    function addText() {
 
    }

    function deleteText() {
        
    }
```

#2.プロセス

①まずは追加ボタンの入力値を代入。
　※.valueでタイプした値を取得できる。

```
var ta1 = document.getElementById("text1").value;
```

②入力した値をテキストエリアに代入していく。
  ※"+="で次々に代入していける。 
  ※"\n"　で改行

```
document.getElementById("area1").value += ta1  + "\n";
```

③テキストを変数に代入して、変数の値を空白にする。


```
function deleteText() {
  let ta2 = document.getElementById("area1");
  ta2.value = "";
}
```

#3. 完成形
 
```
function addText() {
  var ta1 = document.getElementById("text1").value;
  document.getElementById("area1").value += ta1;
}

function deleteText() {
  let ta2 = document.getElementById("area1");
  ta2.value = "";
}
```

以上
【Ruby】uniqメソッドで重複する要素を除外する。

個人メモです。

uniqメソッドを使うと重複する要素を排除することができる。

- 非破壊処理。 
- ブロックを使って、各要素を処理したあとで比較できる
- 重複する場合は、最初の要素が残る。（後ろの要素を削除）


##配列の場合

```ruby:
arr = [1, 4, 5, 3, 5, 6, 1, 3, 2, 2, 1, 1, 1]
arr.uniq

=> [1, 4, 5, 3, 6, 2]


##非破壊の確認
p arr
=> [1, 4, 5, 3, 5, 6, 1, 3, 2, 2, 1, 1, 1]
```

<br>
**▼処理後の値**
ブロックを使うと処理後の値を比較できる。削除するのは該当する元の値。（※処理後ではない）

・`オブジェクト.uniq{|変数| 処理}`

例えば、文字列が入った要素を、`to_s`で全ての要素を文字列にしてから比較する。

```ruby:
arr1 = [1, 3, 2, "2", "3", 1]

arr1.uniq{|i| i.to_s}
=> [1, 3, 2]
```

| 元の値 | 1 | 3 | 2 | "2" | "3" | 1 |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| 処理後  | "1"  | "3"  | "2"  | "2" | "3" | "1" |
| 残る要素  | ○  | ○  | ○  | ×  | ×  | ×  |

よって出力は重複なしか１つ目に該当する元の値`[1, 3, 2]`となる。



<br>
##オブジェクトの場合
オブジェクトで値が重複している要素の削除もできる。

・`オブジェクト.uniq{|変数1, 変数2| 処理}`

- ブロックは必須
- 変数は２つ必須。変数１にキー、変数２に値が入る。
- 出力は配列になるため、`to_h`でオブジェクト（シンボル）に戻す。

###シンボルにする場合

```ruby:
obj = {:a=>1, :b=>2, :c=>3, :d=>2, :f=>3}
obj2 = obj.uniq{|x,y| y}
=> [[:a, 1], [:b, 2], [:c, 3]]}

obj2.to_h
=> {:a=>1, :b=>2, :c=>3}
```

<br>
###ハッシュにする場合
ハッシュにしたい場合は、`to_h`メソッドのブロックでキーに`to_s`を適用し文字列にする。

```ruby:
obj = {:a=>1, :b=>2, :c=>3, :d=>2, :f=>3}

obj.uniq{|x,y| y}.to_h{|k ,v| [k.to_s, v]}
=> {"a"=>1, "b"=>2, "c"=>3}
```