OmniAICreator/Qiita-1.07M huggingface dataset:
OpenShift 4.4を構築してアプリを動かしてみる

# 目次

## 1. ハードウェア準備
OpenShiftをインストールするハードウェア構成について記載しています。

https://qiita.com/takusonix/items/9be1cbf104c261d63721

## 2. ソフトウェア準備
VMWare ESXiのインストールメディアを作成します。

https://qiita.com/takusonix/items/8bb1923fb4c25241b83a

## 3. VMWare ESXi インストール
VMWare ESXiをインストールします。

https://qiita.com/takusonix/items/1e4a9b4572fa73e5e02c

## 4. VMWare ESXi 初期設定
VMWare ESXiのライセンス登録など、初期設定を行います。

https://qiita.com/takusonix/items/47a3cef411d8f4970474

## 5. 仮想環境構築
OpenShiftで使用する仮想スイッチを仮想マシンを作成します。

https://qiita.com/takusonix/items/aecfc2c1107c4454b010

## 6. 仮想マシン(CentOS)インストール
踏み台サーバ(bastion)にCenteOSをインストールします。

https://qiita.com/takusonix/items/33346c3840ac6a2ddc7f

## 7. 踏み台サーバ構築編
踏み台サーバ(bastion)に、dnsmasq, haproxy, nginxなどを構築します。

https://qiita.com/takusonix/items/8d339a4c2c1e9aae3561

## 8. OpenShift準備編
OpenShiftのmanifestやignitionファイルを作成します。

https://qiita.com/takusonix/items/5bb6558d922abffcb0f1

## 9. Bootstrap起動編
OpenShiftのBootstrapに対して、パラメータを指定して起動します。

https://qiita.com/takusonix/items/d110471fb978c6e64f59

## 10. Master起動編
OpenShiftのmaster-0, master-1, master-2に対して、パラメータを指定して起動します。

https://qiita.com/takusonix/items/367d8d330af425f8ee14

## 11. Worker起動編
OpenShiftのworker-0, worker-1に対して、パラメータを指定して起動します。

https://qiita.com/takusonix/items/35f15f996db59f5f8f54

## 12. OpenShift構築編
OpenShiftのクラスタ作成後、マシンCSRの承認とImageRegistryにパッチを適用し、Openshiftのインストールを完了します。

https://qiita.com/takusonix/items/6aec8842f9f8140c6332

## 13. アプリ構築編
Node.jsのアプリを実際に構築します。

https://qiita.com/takusonix/items/d00bd5078d3388992347
初めてのRuby On Rails　その1

# Ruby On Railsとは
>オープンソースのWebアプリケーションフレームワークである。RoRまたは単にRailsと呼ばれる。その名にも示されているようにRubyで書かれている。またModel View Controller（MVC）アーキテクチャに基づいて構築されている。
　
[Ruby_on_Rails - Wikipedia](https://ja.wikipedia.org/wiki/Ruby_on_Rails)

初めてRubyに触れるので、Progateを使って学習してみました。忘れそうなことや頭を整理するために、記載しています。
[Ruby on Rails5 - Progate](https://prog-8.com/languages/rails5)

## Railsアプリケーションの作成
以下コマンドにより必要なファルダ等が作成される

```terminal:ターミナル
rails new app_name
```
### ツリー構造
　app_name/
　　　　├ app/
　　　　├ config/
　　　　├ db/
　　　　└ その他

## サーバーの起動
```terminal:ターミナル
rails server
```
###アプリ表示
サーバーを起動後に、ブラウザで`localhost:3000`にアクセス

## トップページの作成(新しくページを作るコマンド)
以下のコマンドにより自動で`top`というページが作成される

```terminal:ターミナル
rails generate controller home top
```
以下のように`generate`を`g`に省略可能

```terminal:ターミナル
rails g controller home top
```
home: コントローラー名
top: アクション名

##### ※すでにhomeコントローラーがある場合には別アクションでは使用不可

トップ画面`localhost:3000/home/top`にアクセスできる


## ページを表示するのに必要な3ファイル
1. ビュー(view)
1. コントローラー(controller)
1. ルーティング(routing)

### ビュー(view)
ビューとは、ページの「見た目」を作るためのHTMLファイルである
ブラウザとRailsのやりとりの中で、Railsからビューが返され、ページが表示される

#### ツリー構造
##### viewsフォルダの中に`homeフォルダ`と`top.html.erb`というファイルが作成される
　app/　アプリケーションのメインフォルダ
　　└ view/　ビューフォルダ
　　　　│ ┌──────────┐　　   　　
　　　　└ │ home/　　　　　　　│
　　　　　 │　 └ top.html.erb 　　│
　　　　　 └──────────┘
    
### コントローラー(controller)
ページを表示するとき、Railsの中ではコントローラを経由してビューをブラウザに返している

#### ツリー構造
##### controllersフォルダの中に`home_controller.rb`というファイルが作成される
　app/　アプリケーションのメインフォルダ
　　└ controllers/　コントローラーフォルダ
　　　　│ ┌──────────┐　　   　　
　　　　└ │ home_controller.rb　 │
　　　　　 └──────────┘

```terminal:ターミナル
rails generate controller home top
```

上記実行時に`home_controller.rb`というコントローラのファイルが作成される
ファイルの中に`topメソッド`が追加される
コントローラ内のメソッドを`アクション`と呼ぶ

```ruby:home_controller.rb
class HomeController < ApplicationController
  def top
  end
end
```

アクションは、コントローラと同じ名前のビューフォルダから、アクションと同じ名前のHTMLファイルを探してブラウザに返す

### ルーティング(routing)
ルーティングはブラウザとコントローラを繋ぐ役割を担う
送信されたURLに対して「どのコントローラの、
どのアクション」で処理するかを決める「対応表」のこと

ページが表示されるまでに、`ルーティング→コントローラ→ビュー`という順で処理

#### トップ画面`localhost:3000/home/top`にアクセスした時を例に考えてみよう

1. URL(home/top)に対応するHTMLファイルをリクエスト

##### ルーティング(対応表)

|URL|コントローラ|アクション|
|:-:|:-:|:-:|
|home/top|home|top|
|︙|︙|︙|

2.homeコントローラーのtopアクションを呼び出す
3.URLに対応したHTMLファイルを送信

#### ツリー構造
##### configフォルダの中に`routes.rb`というファイルが作成される
　　config/　設定情報に関するフォルダ
　　　│ ┌────────┐　　   　　
　　　└ │ routes.rb　　 　 │
　　　　 └────────┘

```ruby:routes.rb
Rails.application.routes.draw do
  get "home/top" => "home#top"
end
```

## まとめ
初めてRubyOnRailsを学習しました。
学習して、改めて整理すると意外とわかりやすいと思いました。これからも追加で記事を作成していきます。

##参考サイト
ディレクトリ構成図を書くときに便利な記号
https://qiita.com/paty-fakename/items/c82ed27b4070feeceff6
Markdown記法 サンプル集
https://qiita.com/tbpgr/items/989c6badefff69377da7
Qiitaのテーブルの書き方についてまとめた
https://qiita.com/zakuroishikuro/items/f33929eab9d55c5bd073
とりあえずconstしとけの罠－再宣言・再代入可能な場合

JavaScriptの基礎知識記事です。
「とりあえずconstで定義しておけば、再宣言・再代入できないから安心なんでしょ」と、今日の昼までは思っておりました。
しかし、その浅い認識でエラーが出てしまったので、備忘録として書いておきます。
同じように思っているJavaScript初心者の方に読んでいただければと思います。

# スコープ問題
## console.logクイズ-何が表示されるでしょう？
### ①グローバル変数を関数内で読込
以下のコードを実行するとどうなるでしょう？

``` index.js
const drink = "coffee";
  
const bitter = () => {
    console.log(drink);
};

bitter();
```
答えは、

```
coffee
```
です。

### ②グローバル変数と同名の変数を関数内で宣言
では、次の場合には？

``` index.js
const drink = "coffee";
  
const sweet = () => {
    const drink = 'cocoa';
    console.log(drink);
};
  
sweet();
```

答えは、

```
cocoa
```
です。

さっきはconstで代入していた変数を関数内でそのまま呼び出せたのに、関数内でもう一回同じ変数名で宣言できる！

### ③グローバル変数で定義した変数を、関数内で使用してから宣言
では最後に、次の場合はどうなるでしょう？

``` index.js
const drink = "coffee";

const salty = () => {
    console.log(drink);
    const drink = 'kobucha';
    console.log(drink);
};

salty();
```

答えは・・・

```
Uncaught ReferenceError: Cannot access 'drink' before initialization
```
エラーが返ってきます。
JavaScriptの仕様として、グローバル変数は関数内やブロック内でも読み込めますが、グローバル変数と同じ名前の変数を、関数やブロック内で宣言することもできます。
このあたり見るとわかるかと↓
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/block

そのため、①、②のような挙動になりました。

それでは、なぜ③でエラーが返ってきたのか。
最初のconsole.logでcoffeeと表示され、次のconsole.logでkobuchaと表示されても良いのでは？

JavaScriptではブロック内にconstがあると、書いた順番に関係なくそのブロック内の変数はすべてその定義された変数で上書きされてしまいます。ブロック内で定義した時点で、同じ変数名のグローバル変数はブロック内では読み込まれなくなります。

ただし、あくまでも上書きされるのは変数の存在だけです。代入処理は上から順番におこなわれていきます。だから「その変数は定義されていないよ」というエラーではなく、「その変数は初期化されていないよ」というエラーが返ってくるのです。

## 結論
スコープが変わると、constで定義していても同名で定義できてしまいます。グローバル変数と同じ名前の変数を関数内で定義してもエラーは出ずに上書きされてしまいます。気をつけようと思いました。

# リスト・オブジェクト
ついでに、constで定義したリストとオブジェクトの扱いも勘違いしがちかなと思ったので触れておきます。

``` index.js
const drink = ['coffee','cocoa'];
drink.push('kobucha');
console.log(drink);

const food = {
  lunch: 'peperoncino',
  dinner: 'karaagekun'
};
food['breakfast'] = 'protain';
console.log(food);

```

```
["coffee", "cocoa", "kobucha"]
{lunch: "peperoncino", dinner: "karaagekun", breakfast: "protain"}
```

リストやオブジェクトの中身をいじる処理は自由にできます。もちろん、再宣言しようとしたり、以下のようにリスト自体、オブジェクト自体を再代入しようとするとエラーが出ます。

``` index.js
const drink = ['coffee','cocoa'];
drink = ['coffee','cocoa','kobucha'];
```

以上です。
ちなみにたいていのパスタは昆布茶を入れるとおいしくなります。
それでは。
カレントディレクトリ以下に、「ディレクトリを指し示しているシンボリックリンク」が存在しているか調べる

もともと2014年4月28日に[別のところに書いていた記事](https://maraigue-memo.tumblr.com/post/84027129947)を、備忘的に持ってきたものです。

# 方法

```sh
find -type l -and -xtype d
```

`-xtype`の指定は、シンボリックリンクを辿った先のファイルがどのような属性であるかを調べる[^1]。そのため、ファイル自体がシンボリックリンクであり（`-type l`）、かつそれを辿った先がディレクトリである（`-xtype d`）という条件で検索すればよい。

# 経緯

「ディレクトリを書庫に格納するとき、シンボリックリンクが示すファイルは実体のほうを書庫に格納する」という方法で書庫を作りたかったのだが、その中にディレクトリを指し示すようなシンボリックリンクがあると不用意に書庫のサイズを大きくしてしまいかねないので、それを避けたかったのである。

[^1]: `-xtype`がこのような挙動になるには、`find`コマンドのデフォルトオプション（ファイルを列挙する過程ではシンボリックリンクも単にファイルとみなし、辿ることはしない。オプションを明示的に書くなら`-P`）を使っているという前提が必要である。詳細は例えば[Man page of FIND（OSDNによる日本語訳）](http://linuxjm.osdn.jp/html/GNU_findutils/man1/find.1.html)を参照。
CI(Bitrise * Fastlane)でSwift Package Managerをキャッシュする

一部のCocoaPodsをSwiftPMに移行した際に、
いろいろ調べたのでToDoを書いておきます

## 前提
CocoaPodsからの移行はXcodeGen導入済みProjectにて行いました。
XcodeGen導入済み環境でSwiftPMを導入する方法については[こちら](https://qiita.com/doihei/items/bc8309241dd7e8946547)

## やること
- Package.resolvedをgit管理下に置く
- Bitriseに環境変数を登録
- BitriseのCache Push Stepを定義
- Fastlaneのlane内でキャッシュを利用

## Package.resolvedをgit管理下に置く
プロジェクトファイルをgitから除外している場合、
Package.resolvedをgit管理下に置きます

```.gitignore:gitignore
# XcodeGen
*.xcodeproj
*.xcworkspace

# Cache SwiftPM for CI
!*.xcworkspace/xcshareddata/swiftpm/Package.resolved
```

## Bitriseに環境変数を登録
後述しますが、
BitriseのCache Push Stepに下記記述を追加することで、指定場所にcacheを保存することが可能です。

```{cache保存先} -> {Package.resolvedのPath}```

今回は、cache保存先を示す環境変数```BITRISE_SWIFTPM_CACHE_PATH```を、
Package.resolvedのpathを環境変数```SWIFTPM_PACKAGE_RESOLVED_PATH```を作成します。

![スクリーンショット 2021-02-26 15.36.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605495/a623b4f1-23de-4391-b8fa-deed98848d05.png)

## BitriseのCache Push Stepを定義
BitriseのCache Push Stepの```cache paths```に前述した通り
```{cache保存先} -> {Package.resolvedのPath}```
を追加します。

これにより、SwiftPMのcacheがpushされるようになります。

![スクリーンショット 2021-02-26 15.35.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605495/5a438d76-c6b8-f770-daea-0b8c49d4b0a6.png)


## Fastlaneのlane内でキャッシュを利用
gymの```cloned_source_packages_path```に```BITRISE_SWIFTPM_CACHE_PATH```を渡すことで、
SwiftPMのcacheを利用します。

```.:fastfile
    gym(
      workspace: "MyApp.xcworkspace",
      scheme: "MyApp",
      configuration: "Debug",
      export_method: "ad-hoc",
      cloned_source_packages_path: ENV["BITRISE_SWIFTPM_CACHE_PATH"],
    )
```

## キャッシュの確認方法
BitriseのSetting -> Manage Build Caches (BETA) からファイルをダウンロードして、
内部にSwiftPMのファイル群があればokです
[Rails] deviseを日本語化する方法

#前提
Railsにdeviseのgemを導入していること。

#日本語化する方法
##Gemfileに追記する
`gem 'devise'` の後に以下を追記して、 `bundle install` します。

```:Gemfile
gem 'devise-i18n'
```

##devise.rbを編集する

```:config/initializers/devise.rb
config.scoped_views = true
```

そして `rails s` でサーバーを再起動します。

##devise.views.ja.yml を作成する
以下を実行すると `config/locales` に日本語化ファイル（`devise.views.ja.yml`）が作成されます。

```
$ rails g devise:i18n:locale ja
```
rails db:createでエラー解決　Access denied for user 'root'@'localhost' (using password: YES) 

rails db:create をすると以下のようなエラーが

```
% rails db:create
Access denied for user 'root'@'localhost' (using password: NO)
Couldn't create 'TodoApp_development' database. Please check your configuration.
rails aborted!
Mysql2::Error::ConnectionError: Access denied for user 'root'@'localhost' (using password: NO)
```


database.ymlとmysqlのパスワードが一致していないことが原因らしい
https://qiita.com/naota7118/items/b62d71484e21d6739d68

前回の記事で設定したmysqlのパスワードを
database.ymlに設定し直した

成功

```
% rails db:create
Created database 'TodoApp_development'
Created database 'TodoApp_test'
```
WindowsでのNLS_LANGの設定方法

[NLS_LANGに関するFAQ](https://www.oracle.com/jp/database/technologies/faq-nls-lang.html)によると、レジストリ上に定義するか、環境変数に定義することになっているようだ。

# レジストリに定義する場合

NLS_LANGという名前のエントリがあるそうな。

### Oracleバージョン7の場合：

HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE

### Oracle Databaseバージョン8、8i、および9iの場合：

HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOMEx\

ここで、"x"はOracleホームを識別する一意の番号です。

HOME0は最初のインストールです。

### Oracle Database 10gの場合：

HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_

# 環境変数に定義する場合

「システム・プロパティでシステム環境変数またはユーザー環境変数として設定」とあるが、Windows 10ではおおよそこんな手順：

- スタートメニュー→設定
- 設定画面を開いたら、上の検索窓に「環境変数」って入力しちゃったほうが早い。

![Windowsの設定画面の表示例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45595/fe4cf662-db7f-f4be-0a77-573d1c87713f.png)

もしもwebサーバー上でphpとかサーバープログラムを動かすのであれば、「システム環境変数の編集」を選択することを強くおすすめする。（どっちを選んでも、開く画面が同じで、開いた画面上の操作によってユーザー環境変数化システム環境変数かを選択することになる。）

# ありがちなパターン

さすが、SHIFT THE ORACLEさんにちゃんと書いてあった。
[マルチバイト・キャラクタセット \- オラクル・Oracleをマスターするための基本と仕組み](https://www.shift-the-oracle.com/config/multibyte-characterset.html)

- Japanese_Japan.AL32UTF8 -- LANG=ja_JP.UTF-8 の場合
- Japanese_Japan.JA16SJIS または JA16SJISTILDE -- いわゆるSJIS、全角「～」の互換性対策のために後者を使うケースが有る。
- Japanese_Japan.JA16EUC または JA16EUCTILDE -- いわゆるEUC、全角「～」の互換性対策のために後者を使うケースが有る。

以上、個人的メモ。
歪度・尖度

・　歪度(非対称性の指標)
$$\alpha_3=\frac{E(X-\mu)^3}{\sigma^3}$$
これをXの確率分布の歪度(skewness)という。
$\alpha_3>0$ならば右の裾が長く、$\alpha_3<0$ならば左の裾が長い。これは$\mu$を中心にどちらの方向が優勢か（期待値）をみる。
$|\alpha|$はその程度を表す。正規分布で０になる。

```math
\begin{align}
E(X-\mu)^3&=E(X^3)-3\mu E(X^2)+3\mu E(X)-\mu^3\\
          &=E(X^3)-3\mu E(X^2)+2\mu^3
\end{align}

```
で計算する。

---

・　尖度（尖り具合の指標）
$$\alpha_4=\frac{E(X-\mu)^4}{\sigma^4}$$
これが中心の周囲の尖り具合、尖度(kurtosis)を表す。４次関数は中心から離れた部分を顕著に表す。
確率分布を考えたとき、中心近傍で４次関数の小ささに打ち勝つほどの確率分布をしている、そして遠くからの影響が少しでもある場合$\alpha_4$は大きくなる。つまり、確率密度の高いところで細く、低いところでは長い裾を引く。その場合全体としては尖っている。
一般に$\alpha_4-3>0$ならば正規分布より尖っている（定義の仕方で異なる場合がある）。
逆に$\alpha_4-3<0$ならば正規分布より丸く鈍い形をしている。

```math
\begin{align}
E(X-\mu)^4&=E(X^4)-4\mu E(X^3)+6\mu^2 E(X^2)-4\mu^3E(X)+\mu^4\\
&=E(X^4)-4\mu E(X^3)+6\mu^2 E(X^2)-3\mu^4
\end{align}
```
で計算する。
OnGUI() で重い処理をしたい

# 概要

　エディタ拡張で、ボタンをクリックときに重い処理をすると出るエラーの回避法について書いてあります。

# 背景

　[kumaS-nu/NuGet-importer-for-Unity](https://github.com/kumaS-nu/NuGet-importer-for-Unity) 
　↑のプロジェクトで、ボタンをクリックしたらインストールするようにしたらエラーが出て、動くけど気持ち悪かったので回避法を見つけました。また、このプロジェクトは以下の記事で宣伝しています。
[Unity のプロジェクトに NuGet のパッケージをインポートするエディタ拡張を作ったよ](https://qiita.com/kumaS-kumachan/items/92f5c7d3875ed6430877)

# エラー内容

　こんな感じのコードを書くと、`BeginLayoutGroup must be called first.` とエラーが起きる。

```csharp
public async Task OnGUI()
{
    using(new EditorGUILayout.VerticalScope())
    {
        // 重い処理の代わり。
        await Task.Delay(10000);
    }
}
```

# 解決法

　結局、スコープ内で待っているのが悪いので最後に待つようにすればいい。順番とかあるときはメソッドとして切り出せばいい。
　あと、例では `async`・`await` を使っているけどコルーチンにしても問題ない。

```csharp
public async Task OnGUI()
{
    var tasks = new List<Task>();
    using(new EditorGUILayout.VerticalScope())
    {
        tasks.Add(Heavymethod);
    }
    await Task.WhenAll(tasks);
}

private async Task Heavymethod()
{
    await Task.Delay(10000);
}
```

# あとがき

　やっぱり消せるエラーは無くした方がいい。対処しないといけないエラーを埋もれさせちゃうので。あと、Unity2019 以前はどうやってもエラーは起きるのでどうしようもない。（Unity 公式の C# のリファレンスのソースコードに「ここは私の部門じゃどうしようもないよ」とか書いてあった。）
modified:   todoapp (modified content, untracked content)  )というエラーが出た時にしたこと


#はじめに
`git add`をして`git commit -m "コメント"`をしようとすると次のエラーが出てきたので私の対応について書いていきたいと思います。

エラー

```
Changes not staged for commit:
  (use "git restore <file>..." to discard changes in working directory)
  (commit or discard the untracked or modified content in submodules)
        modified:   todoapp (modified content, untracked content)

)
```

##(1)このエラーについて
修正したtodoappというファイルが追跡できず、addできないと言っていますね。（not stagedというのはステージングのことです。git addでインデックスに登録することをステージングといいます。）

私の場合、このエラーはgitがディレクトリをファイルとみなしてしまったことが原因で生じてました。どういうことかというと、通常はディレクトリの下に直にファイルがあると思うのですが、指定したディレクトリとファイルの間に一つディレクトリをかませてしまっていました。

 - 通常
![空白の図.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1155442/62bc0dbf-fca5-8844-0afc-2241ba550596.jpeg)
 


 - 今回のエラー

![空白の図 (2).jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1155442/3badf1d5-95a4-3cd9-5a88-2ce89d0f663b.jpeg)

##(2)対処したこと

```
cd todoapp
```
で`todoapp`をカレントディレクトリにしました。これを`git add`してコミットすればうまくいきました。
Rails・Laravel・Docker・React環境構築一覧

本記事は、[Techpit](https://www.techpit.jp/)がQiitaで投稿している環境構築記事のまとめです。

今後も適時更新していきます(最終更新日：2021/2/26)

**「〇〇の環境構築も掲載してほしい！」**
**「〇〇のエラーが解決できない」**
等ありましたら、ぜひコメントしてください。

## 記事一覧表

### Ruby on Rails 
[0から Ruby on Rails の環境構築【macOS】 (Homebrew のインストールから Rails のインストールまで)](https://qiita.com/techpit-jp/items/1bcd0f4106330b5b827c)

[0からRuby on Railsの環境構築【Cloud9】(Rubyのバージョン変更からRailsのインストールまで)](https://qiita.com/techpit-jp/items/ac94b6ed80b77336fdf8)

### Laravel
[【最新版】はじめてのLaravel！Laradockを用いたLaravel開発環境構築](https://qiita.com/techpit-jp/items/304da8131fecd7619150)

### React
[React環境構築【Node.jsのインストールからCreate React Appまで】~macOS編~](https://qiita.com/techpit-jp/items/b4792f22ddc1155a1cb3)

[React環境構築【Node.jsのインストールからCreate React Appまで】~Windows編~](https://qiita.com/techpit-jp/items/984b80a795b7a6f6dd60)

### Docker
[🐳【すぐ開発を始めたい人向け】DockerをMacにインストールする手順🐳](https://qiita.com/techpit-jp/items/d17e2585888daa8d4bff)

[🐳WindowsでDockerを始める手順🐳](https://qiita.com/techpit-jp/items/f4a1319a909dd508f372)

[🐳Docker Toolboxのインストール🐳](https://qiita.com/techpit-jp/items/1fed1325bdbc62d216d3)


今後もプログラミング学習に役立つような情報を発信していきます！[アカウントをフォロー](https://qiita.com/techpit-jp)してお待ちください！
Java小テスト② 〜 for 編 〜

これは友達向けのJavaの小テストです。
Java初心者の文法腕試しでお使いくださいー！！

今日はfor文の小テストを作りたいと思います！

問題１：ミスを探しなさい。

```java
public static void main(String[] args) {
    for i = 0; i < 10; i++ {
        System.out.println(i);
    }
}

```


問題２：出力されるものは何か？

```java
public static void main(String[] args) {
    for(int i = 0; i < 100; i += 10) {
        System.out.print(i);
    }
}
```

問題３：以下を満たすプログラムを書きなさい。

- 100回繰り返す。
- 回数が3の倍数のときは, 「Fizz」を出力する
- 回数が5の倍数のときは. 「Buzz」を出力する
- 3と5の公倍数である場合は「FizzBuzz」を出力する
- それ以外は数字をそのまま出力する。


問題４：以下を満たすプログラムを書きなさい。

- 1から10を動く変数"i"
- 10から20を動く変数"j"
- 各 "i"と"j"に対して, "i + j"が問題3の状態を満たす
Flutter Firestoreでのwhereの条件の種類

# はじめに
<!-- 発端や概要を記載 -->
２週間ほど前にflutterを勉強し始めました。
firestoreからデータを持ってくるときにwhereで条件指定できるということはすぐにわかったのですが日本語の記事だと

```
Firestore.instance
      .collection(collection)
      .where("name", isEqualTo: "Michael")
```
みたいにisEqualToしか出てこなかったんですけど、[Cloud Firestore | FlutterFire](https://firebase.flutter.dev/docs/firestore/usage/#querying)⇦このサイトで初めてそれ以外の例を見つけてqueryという概念が絡んでくると言うことがわかりました。
flutter firestore where queryで調べると[Firestore queries on Flutter](https://stackoverflow.com/questions/48937864/firestore-queries-on-flutter)⇦ここで全部の例が載っていました。

```
Query where(
    String field, {
    dynamic isEqualTo,
    dynamic isLessThan,
    dynamic isLessThanOrEqualTo,
    dynamic isGreaterThan,
    dynamic isGreaterThanOrEqualTo,
    bool isNull,
  }) {..}
```

同じようにqueryを知らずにflutter firestore whereで調べて出てこないという人の助けになればと思います。
お互いに頑張りましょう！

<a id="#reference"></a>
# 参考文献
- [Firestore queries on Flutter](https://stackoverflow.com/questions/48937864/firestore-queries-on-flutter)
- [Cloud Firestore | FlutterFire](https://firebase.flutter.dev/docs/firestore/usage/#querying)
【備忘録】VMware-Workstation-PlayerにてGNS3環境構築

#はじめに
自前のLAPTOPにネットワークの検証環境が欲しくて
GNSを立ててみたのが始まりです。

#対象
・ネットワーク初学者から熟練者まで幅広い方
・検証環境がない方

#作業環境
・LAPTOP or Desktop
・Windows10

 
#構成ファイル/ダウンロードURL　
GNS3-2.2.3-all-in-one-regular.exe
https://www.gns3.com/software/download

GNS3.VM.VMware.Workstation.2.2.3.zip
https://github.com/GNS3/gns3-gui/releases/tag/v2.2.3

VMware-player-12.5.9-7535481.exe
https://www.manageengine.com/products/desktop-central/patch-management/VMware-Player-12-patches/VMware-player-12.5.9-7535481-patch.html

VMware-VIX-1.15.0-2985596 .exe
https://my.vmware.com/jp/web/vmware/details?downloadGroup=PLAYER-1200-VIX1150&productId=535
 
#手順
 下記URLを参考にして構築しました。
https://it-networking.jp/2019/01/17/1220.html
https://qiita.com/hymnofpeace/items/9e8ed8498b88a437b830
 
#注意点 
・GNS3とGNS-VMはversionが同じ必要がある。今回の場合は2.2.3で統一。
　今回はGNS３が自動アップデートがかかり、ダウングレード方法がわからず再構築する羽目になりました。

・Vmware-workstation-playerはversionが12のみ安定動作する。
　試しにworkstation15を入れてみたがGNS-VMが接続が安定しない現象が見受けられた。
　公式のヘルプにも同様の問い合わせが頻発。

・workstation-proではなくworkstation-playerを使用する場合はVmware-VIXのインストールが必須。

・構築時に遭遇したエラーの解決の際に役立ったサイト
https://gns3.com/community/discussion/gns3vm-error-while-executing-vmw
https://gns3.com/community/discussion/gns3-will-not-talk-to-vm-ware


・自動更新すると起動しないエラーが発生するため
edit >preferences>「automaticaly check for update」のチェックを外し自動更新を確認しないようにすることを推奨。

・スペックの低いPCだと仮想スイッチ、ルータはせいぜい2つまでが限界。
　冗長構成の検証程度なら耐えられるが
 　ダイナミックルーティング等の台数が多い検証はスペックが必要かも
Vue.jsのcomputedの書き方で学ぶJavascriptにおけるオブジェクトのメソッド定義

## はじめに
Vue.js(Option api)のcomputedの部分のコードを読む際にあれ、いつも自分が書いている書き方とちょっと違うと戸惑った経験はないでしょうか？

最近、いつも自分がよく書く書き方と異なる書き方がされていて、なんでこの書き方で大丈夫なんだろうと感じたことがあったので整理してみました。

## オブジェクトのメソッド定義の3通りの表現方法 

Vue.jsのcomputed, method ではオブジェクトのメソッド定義(=関数プロパティ)が利用されます。
その場合のメソッド定義(=関数プロパティ)の表現方法は主に下記の３パターンあります。
(Vue.jsというより、Javascript(ECMAScript)の仕様ですが)

1. アロー関数式を利用
2. function式を利用
3. メソッド定義のための省略構文を利用

オブジェクトのプロパティとして定義するため、1,2の場合は```コロン[:]```が必須ですが、3の場合はコロンの部分も省略できる構文であるためコロンは不要です。

### 3つの定義方法の違い
2,3の場合はfunction式として評価されますが、1はアロー関数として評価されます。

アロー関数は**「文脈に依存せず、宣言された時点で、thisを確定（＝束縛）する」**特徴があるので、1の関数式内でthisを利用すると、Vueインスタンスをthisとして解釈できずにエラーとなります。
(参考：[Vue.jsに書いてある「アロー関数は、this が期待する Vue インスタンスではなく・・・」とは？](https://qiita.com/_Keitaro_/items/d48733a19c10889e2365))
 
### コードでの例

```javascript


export default {
  name: 'SomeList'
  data () {
    return {
      contents: []
    }
  },
  computed: {
    // 1: アロー関数式を利用
    countOfInitialShowedContents: () => 10,
    // 2: function式を利用
    countOfContents1: function() {
      return this.contents != null ? this.contents.size : 0 
    },
    // 3: メソッド定義のための省略構文を利用
    countOfContents2 () {
      return this.contents != null ? this.contents.size : 0 
    },
}
```

## メソッド定義のための省略構文(a shorter syntax for method definitions on objects initializers)とは
アロー関数式とfunction式については多くの方にとって馴染み深い表現だと思いますので、
ここでは**「メソッド定義のための省略構文」** についてのみ記載させていただきます。

ECMAScript 2015から導入されたfunctionを利用したメソッド定義の省略形です。
このような表現で記述した場合は、↓のようにfunction式によるメソッド定義と同じように解釈されます。

**省略構文(↓のfunction式で定義した場合と同様に解釈されます)**

```javascript
const obj = {
  foo() {
    // ...
  },
  bar() {
    // ...
  }
}
```

**function式を利用した構文**

```javascript
const obj = {
  foo: function() {
    // ...
  },
  bar: function() {
    // ...
  }
}
```

## まとめ
私も3の表現でVueのdataやcomputedをよく記載していたのですが、どのような仕様で実現しているのかをきちんと理解しておらず利用していました。

今回、調べてみたことで今後は自分の中で確信を持ってコーディングをすることができそうです。

もし、同じような疑問を持った方の参考になれば幸いです。
それでは、素敵なVueライフを。

## 参考リンク
* [MDN:メソッド定義](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions)
* [【Vue.js】記法の違いまとめ](https://qiita.com/aiandrox/items/788c1846ef17094264a2)
* [Vue.jsに書いてある「アロー関数は、this が期待する Vue インスタンスではなく・・・」とは？](https://qiita.com/_Keitaro_/items/d48733a19c10889e2365)
7日目トリガーをボタンにしたピンクの音色再生その２

#7日目のアプリ 
トリガーをボタンにした音声再生その２

##画面キャプチャ
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/959530/e9812cb9-718a-eec9-d80b-ec207e970c15.gif" width=50%>


##以下の流れで作りました。
1. storyboadに複数ボタンを配置。
2. 上記要素をViewController.swiftへoptionドラッグして紐付ける
4. 紐付けができたら、ViewController.swiftでコードを書く

##できたこと
+ 複数のボタンをトリガーにした音声ファイルの再生方法がわかった。
+ ボタンのcurrentTitleを取得して、音声ファイル名に紐付けて再生する方法がわかった。
##書いたコードを共有します！

```
import UIKit
import AVFoundation

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    var player: AVAudioPlayer!
    
    func playSound(pressedKey: String) {
        
        let url = Bundle.main.url(forResource: pressedKey, withExtension: "wav")
        player = try! AVAudioPlayer(contentsOf: url!)
        player.play()
    }
    
    @IBAction func keyPressed(_ sender: UIButton) {
       
        playSound(pressedKey: sender.currentTitle!)
        
        
    }
    

}

```

##感想
func()のかっこ()の中は、変数的なものと、その変数的なものがIntなのかStringなのかみたいな型を記載すること。
例：　func playSound(pressedKey: String) 
で、
関数を呼び出すときに、()の中に、引数を入れること
例：　playSound(pressedKey: sender.currentTitle!)
ふむむ。
【Chatwork】スプレッドシートから指定時刻にメッセージを送信する

## はじめに
社内でチャットワークの利用者が増え、窓もたくさん増えてきたことにより、
チャットで定期報告や、会議のリマインドなどを促すBOTが欲しいと思いました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262021/4b5a461c-e590-a7b4-0504-864c3ed831a5.png)

## 前提
* [チャットワークAPI](https://developer.chatwork.com/ja/index.html)が使用可能であること。
* BOTメッセージ送信者のアカウントを、BOTを利用したい窓に招待すること。
    * （できれば）BOT専用アカウントがあること。
    * リマインドのBOTなので、普段使用者のアカウントを利用してしまうと、その人には通知が届かない為、専用のBOTアカウントを作成することが好ましいです。

## 画面と仕組み
利用者はスプレッドシートにアクセスし、**送信内容**と**予約時刻**を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262021/81b76588-45ed-2bfc-31b2-b85d126f272d.png)

下記に記載のプログラムを走らせることにより、
現在時刻が**予約時刻**を<font color="red">**過ぎれば**</font>、チャットが送信される仕組みになっています。
また、ログの時刻と予約時刻が同一なら、送信しないようになっています。

これを、トリガーなどで回せば、自動で送信できるシステムの完成です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262021/dc20a1cf-cd13-24a1-3413-5de25cf5eade.png)


## コード
```js
// シートを参照し、チャットを送信する
function chatwork_bot() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = spreadsheet.getSheetByName('シート1');
  var values = sheet.getRange("A2:C").getValues()

  var COL_MSG = 0 //A列
  var COL_TIME = 1 //B列
  var COL_LOG = 2 //C列

  for (var i=0; i<values.length; i++){
    var message = values[i][COL_MSG]
    var now_time = new Date()
    var send_time = values[i][COL_TIME]
    var log_time = values[i][COL_LOG]

    // メッセージが空白ならcontinue
    if (message == ""){
      continue
    }
    // 送信日時が空白ならcontinue
    if (send_time == ""){
      continue
    }

    // 日時が送信済み or 未達 or 時刻判定不可ならcontinue
    try{
      if (log_time != ""){
        if (send_time.getTime() == log_time.getTime()){
          continue
        }
      }
      if (send_time.getTime() > now_time.getTime()){
        continue
      }
    }catch(e){
      continue
    }

    // 送信
    sendMessage(
      'abcdef1234567890',
      0123456789,
      message,
    );
    sheet.getRange(i + 2, COL_LOG + 1).setValue(send_time)
  }
  return
}

// 引数より、発言者(BOT)、部屋、メッセージ内容が指定できる
function sendMessage(token,room_id,body){
  var params = {
    headers : {"X-ChatWorkToken" : token},
    method : "post",
    payload : {
      body : body
    }
  };
  var url = "https://api.chatwork.com/v2/rooms/" + room_id + "/messages";
  try{
    UrlFetchApp.fetch(url, params);
    return true;
  }catch(e){
    return false;
  }
}
```

## 懸念点
* 利用者にトークンIDが見えてしまう
* 利用者で共通のシートを利用することになる

これらの問題があります。トークンIDが見えないようにするには、
別シートにimportし、プログラムを走らせることで回避できます。


## さいごに
コードが長くなるので、要所のみを抑えたプログラムとなりますが、
today関数などを利用すれば、毎日送信することも可能ですし、
月初や月末、祝日など設定することも可能です。

ぜひ用途に合わせて使いやすい形に組み替えてみてください。
M1 MacへのHomebrewインストール手順

# 結論

2021年02月26日時点では、[Homebrew](https://brew.sh/index_ja)がM1(AppleSilicon)チップ対応済みとなっています

# 環境

* MacBook Air (M1,2020)
* macOS Big Sur バージョン 11.2.1
* zsh 5.8 (x86_64-apple-darwin20.0)
    * デフォルト状態でzshが利用されている想定

# 手順

基本的には公式の手順とインストール時のガイドに従うことで問題ありません

公式サイト：[Homebrew](https://brew.sh/index_ja)

#### 1. Homebrewのインストール

    
    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    

※ パスワードを何度か求められる場合もあります

####  2. zprofileへPATHを通す

    
    echo 'eval $(/opt/homebrew/bin/brew shellenv)' >> /Users/[ユーザ名]/.zprofile
    

`[ユーザ名]`にはインストール先のユーザ名を入れてください

#### 3. 現在の利用中のzshにも反映させる


    eval $(/opt/homebrew/bin/brew shellenv)


# 障害

#### 1. ディレクトリが存在しないエラー

エラー発生は以下の手順

> `3. 現在の利用中のzshにも反映させる`

> ```
> eval $(/opt/homebrew/bin/brew shellenv)
> ```

エラー内容は下記

```
$ eval $(/opt/homebrew/bin/brew shellenv)

shell-init: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
Error: The current working directory doesn't exist, cannot proceed.

```

原因は別の作業でカレントディレクトリを削除したため「ディレクトリが存在しません」と怒られました

本件は確実に存在するディレクトリに移動することで解消します

```
$ cd ~
```

※ どこでも良いです

# 補足

`Xcode`をインストール済み、かつ`Command Line Tools for Xcode`が未インストールの場合に自動で`Command Line Tools for Xcode`がインストールされるため若干時間がかかります。

よって、事前に`Command Line Tools for Xcode`をインストールすることをお勧めします

```
$ xcode-select --install
```

# 余談

まだまだ、すべてのパッケージがM1 Macに対応しているわけではないので
これからのそれぞれの対応に期待するところです
7つのアクション以外にViewを増やす方法

## はじめに

オリジナルアプリケーションを作成中に、疑問に思いました。
「7つのアクション以外にviewって作れるのか？」
初心者なら必ずこう思うはず、
そして、作れないことはないはず！！
調べてみたら作れました！！

忘れないために記事に残したいと思います。

やることは、以下の3つになります。
1.コントローラーへの記述
2.ルーティングの設定
3.ビューの作成

順を追って説明します。

## バージョン
・Ruby 2.6.5
・Rails 6.0.0

## コントローラーの設定

まずは、コントローラーに新しいアクションを設定します。

```ruby

def index
    @post = Post.includes(:user).order("created_at DESC")
    @post_like = Post.includes(:post_likes).sort {|a,b| b.post_likes.size <=> a.post_likes.size}
  end

  def new
    @post = Post.new
  end

  def create
    @post = Post.new(post_params)
      if @post.save
        redirect_to root_path
      else
        render :new
      end
  end

  def show
    @comment = Comment.new
    @comments = @post.comments.includes(:user)
    @comment_like = @post.comments.includes(:likes).sort {|a,b| b.likes.size <=> a.likes.size}
  end

  def edit
  end

  def update
    if @post.update(post_params)
      redirect_to post_path
    else
      render :edit
    end
  end


  def destroy
    if @post.destroy
      redirect_to root_path
    end
  end

  def indexabout
  end
# 以下省略

```

今回は、アプリケーションの概要説明みたいなページを作成しました。
1番下に記述されている、indexaboutが新しく設定したアクションです。
名前はなんでも大丈夫です。
説明が書いてあるだけのページなので、処理も書いていません。

## ルーティングの設定

次にルーティングを設定します。

```ruby
root to: 'posts#index'
  resources :users, only: [:show, :edit, :update, :destroy]
  resources :posts do
    collection do
      get 'indexabout'
    end
# 以下省略

```

7つのアクション以外のルーティングを設定するには、collectionかmember
これを使用すると、生成されるルーティングのURLと実行されるコントローラーを
任意にカスタムできます。

collectionとmemberの違いは？

collection→ルーティングにidがつかない
member→ルーティングにidがつく

この違いです。
例えば、ユーザー情報の編集ページには、idが必要ですよね。
そういったページを作成する場合は、memberを使います。
今回は、説明だけのページなのでcollectionを使いました。

ルーティングに記述を行った後にターミナルで確認すると

```
% rails routes
```

[![Image from Gyazo](https://i.gyazo.com/06a289691b6ac5bfb1ae89aaca2f0e51.png)](https://gyazo.com/06a289691b6ac5bfb1ae89aaca2f0e51)

しっかりと設定されているのがわかります。

## ビューの設定

最後にビューを設定します。

```ruby

<div class="what_index">
    <%= link_to "正解のない問題たちとは?",  indexabout_posts_path, class: :nav__btn %>
</div>
```
リンク先の指定をしてあげる。

[![Image from Gyazo](https://i.gyazo.com/0ff6615aca91ecdabdae2e4587a336f7.png)](https://gyazo.com/0ff6615aca91ecdabdae2e4587a336f7)

該当箇所にビューの設定を行い、
作成したビューに記述すれば完了です。

これで、7つのアクション以外にもビューが作成できました。

初心者のため、まだまだ誤った記述があるかもしれません。
見つけた方はコメントを残していただければ幸いです。
ExMan Command Line Toolを使わずにZXPをインストールする方法

# はじめに

AdobeアプリケーションのExtension（通称 CEP：Common Extensibility Platform）を作成しインストールさせる際、ExMan Command Line Toolを使う方法があるが、使わずにインストールする方法があるので、その手順をまとめる。

尚、これからExtensionを作成しようと考えている方は、[こちら](https://qiita.com/Takkiii0204/items/7b539972cd4bdaab73d4)を参照すること。

# 手順

1. **.zxp**ファイルの拡張子をを**.zip** に変更
2. **.zip** を解凍し、解凍先を**extensions** フォルダにする

```sh
# Windowsの場合
C:\Program Files (x86)\Common Files\Adobe\CEP\extensions\
# MacOSの場合
~/Library/Application Support/Adobe/CEP/extensions/
```

以上。
RailsのSQLインジェクション対策まとめ

## find、find_by
普通に使っている分にはSQLインジェクションは発生しないのであまり気にする必要なし。

(参考)
[ActiveRecord::Base#find is SQL injection free? - Rails - Ruby-Forum](https://www.ruby-forum.com/t/activerecord-base-find-is-sql-injection-free/136784)

## シンプルなwhere句
```rb
#  NG
User.where("name='#{params[:name]}'")
# OK
User.where(name: params[:name])
User.where("name = ?", params[:name])
```

## 複数条件で検索
```rb
# NG
User.where("name = #{params[:name]} or age < #{params[:age]}")

# OK
User.where("name = ? or age < ?", params[:name], params[:age])
```

## Likeを使ったあいまい検索
```rb
# NG
User.where('name LIKE ?', "%#{params[:name]}%") 

# OK
User.where('name LIKE ?', "%#{sanitize_sql_like(params[:name])}%") 
```

## 参考
- [RailsにてSQLでのワイルドカード文字をエスケープしてくれるsanitize_sql_likeは何をしているのか - Qiita](https://qiita.com/QWYNG/items/3ea4a55fd1867ff20041)
- [Railsのセキュリティ対策で調べた事 - Qiita](https://qiita.com/sutetotanuki/items/5eda6bbb5532dd64529a)
- [RailsでSQLインジェクションの対策：whereやsanitize_sqlメソッド - 株式会社ルーター](https://rooter.jp/programming/ruby/rails_use_where_or_sanitize_sql_methods_to_avoid_sql_injection/)
【rails】モデルに定義するメソッドのselfについて

モデルにメソッドを書く際に、”self.メソッド名”と書くことがあるかと思います。
まだ完全には理解できていませんが、わかった内容を記事にまとめます。

#モデル
```ruby:cook.rb
class Cook < ApplicationRecord
  def self.ranks
    Cook.find(Like.group(:cook_id).order(Arel.sql('count(cook_id) desc')).limit(9).pluck(:cook_id))
  end
end
```
とある記事を参考にして、いいねのランキング機能を実装しました。
ですが、このコード省略は以下のように省略できます。

```ruby:cook.rb
class Cook < ApplicationRecord
  def self.ranks
    find(Like.group(:cook_id).order(Arel.sql('count(cook_id) desc')).limit(9).pluck(:cook_id))
  end
end
```
何が変わったのかというと、3行目の'Cook'を外しました。

#なぜ省略できるのか
今回の記事のポイントはここです。まず、2行目のselfについて。
selfとは"自分自身"という意味なので、今回の場合、selfはCookを指します。（ここでのCookは１行目class CookのCookです）
説明文書的に表現すると、「selfの実行主体はCookである」ということです。
そして３行目のCook.find~の「findの実行主体もCook」です。
つまり、
#####"self.メソッド名"と"self.メソッド名の中で実行しているメソッド"の実行主体が同じであれば、省略可能
となります。

#最後に
そもそもほとんど記事のコピペでランキング機能を実装してしまったのがダメでしたね。コピペでコードを使うのは良くないことを実感しました笑
また、selfが表しているものについては何となく理解できてきた気はしますが、どんなときにselfを使うのかはボンヤリしています。。。

以上です！ありがとうございました！
xcode x opencv (ld: symbol(s) not found for architecture arm64) などが出た時の対処法

## 概要
xcode 上でopencv を使ったとき、

```
ld: symbol(s) not found for architecture arm64
```

すなわちライブラリ見つけられない問題。
及び


```
expected identifier xcode opencv
```

opencvとxcodeのマクロ衝突問題に悩まされた。


## 解決法

ググったらたくさん出てくるが、
自分の場合は（結局）

一つ目の `undefined symbol` 問題に関しては、

```
brew reinstall opencv
```
が必要だった。。。


二つ目の　`マクロ衝突`問題に関しては、

https://blog.csdn.net/fk1174/article/details/70118348
このポストに救われた。

```
NOをNO_EXPOSURE_COMPENSATOR = 0に変更
```
[Slack] Slack APIで特定のチャンネルにメッセージを送る方法


# はじめに

Slack APIで特定のチャンネルにメッセージを送る方法を紹介致します。


## Slack APIで特定のチャンネルにメッセージを送る方法

①チャンネルを生成する。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619610/41b3b18b-d8d7-0aaa-7ab5-a127870d3331.png)

②APIのアプリケーションを開き、「Create New App」をクリックする。
https://api.slack.com/apps
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619610/e5266d01-8f01-e147-7424-b18e4a37238a.png)

③アプリケーションの名前を記載し、「Create  App」をクリックする。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619610/3301228c-3c5f-ee2f-41bd-f83476f02aef.png)

④「Incoming Webhooks」を選択する。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619610/21b50b6b-3e98-5677-b4bb-4ad804efdddf.png)

⑤Incoming Webhooksを活性化し、「Add New Webhooks to Workspace」をクリックする。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619610/39058107-5727-2936-bea9-fe52d64ab1df.png)

⑥メッセージを受け取るチャンネルを選択し、「Allow」をクリックする。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619610/62e1b67e-cbbd-01ba-1dc1-2138a1f0e9c2.png)

⑦サンプルコードをコピーする。
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619610/5935e2f4-edd3-5fb0-ff16-b93cd23b0249.png)

⑧サンプルコードを実行し、メッセージを確認する。
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619610/0fe42496-dd13-079f-f495-f0fac457d155.png)
Railsアプリの標準言語を日本語に設定する

# 環境
macOS Big Sur Ver11.2.1
Rails6.0.0
Ruby2.6.5

# 目的
Railsで開発中のアプリケーションの標準言語を日本語に変更すること。
これにより、エラーメッセージが日本語表示されること。
※今回のアプリではdeviseを導入しているので、deviseによるデフォルトのメッセージも日本語化します！

# 手順
### ①アプリケーション自体の言語設定を日本語にする
以下の一文を追加

```ruby:config/application.rb
require_relative 'boot'

require 'rails/all'

Bundler.require(*Rails.groups)

module アプリ名
  class Application < Rails::Application

    config.load_defaults 6.0

    # 日本語の言語設定を追記する
    config.i18n.default_locale = :ja

  end
end
```

### ②必要なGemのインストール
Gemfileに以下のgemを追記して、ターミナルでbundle installする。
すべての環境に適用されるよう、最下部とかに記述する。
参考：[rails-i18n](https://github.com/svenfuchs/rails-i18n)

```ruby:Gemfile
# アプリケーションの日本語対応用gem
gem 'rails-i18n'
```

**ここまででアプリの設定は完了！**

### ③deviseの言語設定
上記までの作業である程度の日本語化は完了しますが、deviseを導入してユーザー管理機能を構築しているので、deviseに関係するエラーメッセージはまだ英語表記のはず。
そこで、config/locales内にdevise.ja.ymlファイルを作成する。
ファイルの中身は、コピペでOK！
[devise-i18n](https://github.com/tigrish/devise-i18n/blob/master/rails/locales/ja.yml)
これでdeviseに関連する部分はすべて日本語化されます。

### ④独自に追加したカラムなどの日本語化
deviseを導入していてもusersテーブルに独自にカラムを追加している場合は、これまでの作業を実施しても独自カラムの表記は英語のままです。
おそらくほとんどの場合は上記までの作業では不十分なはず。
ここからは、自分で設定用ファイルを作って、設定も自分で記述していく必要がある。

ということで、*config/locales*に、「ja.yml」というファイルを作成し、その中に自分で設定を記述していく！
例えばこんな感じ。

```ruby
ja:
  activerecord:
    attributes:
      user:
        nickname: ニックネーム
        birthday: 生年月日
      item:
        name: 商品名
        explain: 商品の説明

  # フォームオブジェクトを用いている場合
  activemodel:
    attributes:
      order_shipping:
        postal_code: 郵便番号
        prefecture_id: 都道府県
        token: カード情報   
```

attributesは属性、userはモデルのファイル名（フォームオブジェクトならクラスのファイル名）、nicknameはモデルやクラスで定義している属性名といった感じでしょうか。
**モデルやクラスの継承先に気をつけて記述をしてください！**
記述したらサーバーを再起動して、エラーメッセージが全て日本語化できているか確認してください。


*以上、Railsアプリケーションの日本語化の手順でした。*
[Spring Boot] ローカルでsmpメールをテスト


# はじめに

ローカルでsmpメールをテストする方法を紹介致します。


## docker

``` docker
docker run -p 80:80 -p 25:25 maildev/maildev
```

## build.gradle

``` java
dependencies {
...
   implementation 'org.springframework.boot:spring-boot-starter-mail'
}

test {
...
   String activeProfile = System.properties['spring.profiles.active']
   println "zone: $activeProfile"
   systemProperty "spring.profiles.active", activeProfile
}
```

## config

``` java
@Slf4j
@Configuration
public class CoreConfigration {


    @Value("${projects.properties.email-host}")
    String emailHost;

    @Value("${projects.properties.email-protocal}")
    String emailProtocal;

    @Value("${projects.properties.email-port}")
    int emailPort;

    @Bean
    public JavaMailSenderImpl mailSender() {
        JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
        javaMailSender.setProtocol(emailProtocal);
        javaMailSender.setHost(emailHost);
        javaMailSender.setPort(emailPort);
        return javaMailSender;
    }
...


}
```

## yaml

``` yaml
spring:
  profiles: local

projects:
  properties:
    email-host: localhost
    email-port: 25
    email-protocal: smtp
    email-from: serviceteam@company.com
```

## mailservice

``` java
@Service
public class MailService {

    @Autowired
    @Qualifier("mailSender")
    JavaMailSenderImpl javaMailSender;

    @Value("${projects.properties.email-from}")
    String from;


    public void sendHtml(String to, String subject, String content) throws MessagingException {
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
        messageHelper.setFrom(from);
        messageHelper.setTo(to);
        messageHelper.setSubject(subject);
        messageHelper.setText(content, true);
        javaMailSender.send(mimeMessage);
    }}
```

## test

``` java
@SpringBootTest(classes = {ServiceMonitorApplication.class, MailService.class, JavaMailSenderImpl.class, ProjectProperties.class}, webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@Slf4j
class MailServiceTest {

    @Autowired
    MailService mailService;

    @Autowired
    ProjectProperties projectProperties;

    @Test
    public void test() throws MessagingException {
        mailService.sendHtml(
                "asd@asd.net",
                "こんにちは",
                "<b>Asdasd</b> <a href='http://google.con'> google</a>"
        );
    }
}
```

## 実行

``` java
spring test start

-Dspring.profiles.active=local 

gradle :test --tests "com.....MailServiceTest.test" -Dspring.profiles.active=local'
```
[Javascript] うるう年かどうかを確認するJS


# はじめに

うるう年であるかを確認するJS方法は様々です。
ですが、今回Dateを利用して簡単に解けたというのがポイントです。


## Dateを利用して簡単

``` javascript
function isLeapYear(year) {
  return new Date(year, 1, 29).getDate() === 29;
}

isLeapYear(2024)
true
isLeapYear(2100)
false
```
[Windows] netuseコマンドで共有フォルダーにアクセスする方法


# はじめに

このたびデータベースからデータを取得し、それをCSVに変換するパワーシェルスクリプトを作成しました。
そして、上記のパワーシェルスクリプトをコマンドで実行したとき問題はありませんが、Windowsが提供するスケジュールでは動作しませんでした。
原因は正確にはわかりませんが、解決方法としてまずファイルサーバーに接続した後、コピーを試みるとファイルをコピーすることができました。


## net use使い方

``` 
# 様式
net use \\サーバー\パス /user:ユーザー パスワード
# 例
net use \\192.168.1.3\test /user:idtest password1234
# ファイルコピー
xcopy C:\Users\Administrator\temp\test\*.csv  \\192.168.1.3\test -y
```
【Xcode】unable to build chain to self-signed root for signerの解決方法

平穏な開発ライフを過ごしていた、ある日突然それは訪れました😇

```
Warning: unable to build chain to self-signed root for signer "Apple Development: HogeHoge (0000000000)"
/Users/Hoge/Library/Developer/Xcode/DerivedData/hoge-app-hogehogehogehoge/Build/Products/Debug-iphoneos/hoge-app.app: errSecInternalComponent
```

当時の俺「そんなに時間掛からないかな😏」

この時私はこのエラーに一ヶ月弱悩まされることをまだ知らなかった...

##試してできなかった方法

試したこと|結果
---|---
再起動|何回再起動してもだめだった
キーチェーンのリセット|バックアップをとって証明書を再度インストールしたけどだめだった。
Xcode再インストール|Xcode関連ファイルを全て削除した上で再インストールしたけどだめだった。
キーチェーンのロックとロック解除繰り返し|stackoverflowで見かけた方法だけどだめだった。
キーチェーンのロック解除コマンド|これも同様にだめだった。
キーチェーンをロックしてビルド|ビルド時にポップアップが出て許諾してもだめだった。
証明書信頼設定をシステムデフォルトに変更|これは最初からシステムデフォルトだった。
証明書の秘密鍵のアクセス制御に、codesignとxcodeを追加|これも追加したがダメだった。追加されてない場合は許可ダイアログが出るので関係なさそう。
OSのアップデート|BigSurにしたらわんちゃん治るかなって思ったけど無理だった。
プロビジョニングファイル削除→再度インポート|これも意味なかったみたい。
carthageのキャッシュ削除からの再ビルド|carthageのライブラリの署名のところでエラーが出るからわんちゃんって思ったけど関係なさそうだった。

##解決方法
https://developer.apple.com/account/resources/certificates/list
上記のリンクから既存のDevelopmentやDistributionのCertificatesを削除後に、新規に作成しなおします。
プロビジョニングファイルも同様に作成しなおしてください。
この方法であっさりと解決できてしまいました。

##最後に
codesignコマンドで手動署名する際、sudoしたら正常に署名できましたが、sudo無しだと上記のエラーが発生しました。
このことから、今回のエラーは既存の証明書の権限周りに不具合が出たと考えています。
同様のエラーが発生した同志の助けになることを願っています。
ではまた👋
Couchbase Server アーキテクチャ解説: Queryサービス

# はじめに
本記事では、Couchbase Serverの各種サービスの中から、Queryサービス（Quuery Service）について解説します。

Queryサービスの役割を理解することは、Couchbase Server管理者にとって必要であるばかりでなく、JSONデータベースの検討において、適切なテクノロジーを選択する上でも重要です。

Couchbase Serverは、ドキュメント指向型に分類されるNoSQLでありながら、N1QLというSQLをJSONに対して拡張したクエリ言語を用いて、JSONデータに対するクエリを実行することができます。

本記事を読むことによって、Queryサービスの内部機構について理解を深めることにより、N1QLについて、より具体的なイメージを持っていただければ幸いです。

# Queryサービスとは

Queryサービスは、N1QLクエリ言語によるクエリをサポートします。

# Queryサービスの構成要素

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/3533ce2b-bd12-5f08-e696-1c69d22edf30.png)

Queryサービスは次の３つの要素から構成されています。

- リスナー
- クエリプロセッサ
- データストア

### リスナー
クエリ要求を受信します。

### クエリプロセッサ
有効なステートメントであるかどうかを判断するために、受信されたクエリに**パーサー**を適用します。また、利用可能な実行パスを評価する**オプティマイザー**を用いて、待ち時間が最も短いパスを決定します。さらに、決定された待ち時間が最も短いパスを使用によってクエリ実行プランを生成します。計画を一連のオペレーターにまとめます。**実行エンジン**は、オペレータを受け取り、それを実行します。

### データストア
データソースへのアクセスを提供します。
(図にある通り、Couchbase Serverストアは、Couchbase Serverの**データ**、**インデックス**、**認証情報**を処理するために使用されます。また、他のデータストアとして、**ローカルファイルシステム**等も含まれます。）

# クエリの実行
Queryサービス内部の処理順序と、他のサービスとの関連を以下に示します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/a1ef83ce-29dc-d54e-1ba2-d5af9bc3c550.png)

- クエリプロセッサは、解析ルーチンを実行して、リクエストされたステートメントを検証の上、実行プランを作成します。 
- 次に、Indexサービスにアクセスして、関連するインデックスに対してスキャン操作を実行します。
- 次に、Dataサービスにアクセスしてフェッチ操作を実行し、返されたデータを結合操作で使用します。
- Queryサービスは、Filter、Aggregate、Sortなどの追加の処理を実行して操作を続行します。

上図の通り、可能な場合、処理は並行で実行されます。

# 最後に
本記事の内容が、Couchbase Server管理者の方だけでなく、JSONデータベースを検討されている方にも、活用いただけるようであれば幸いです。

一つの記事で、全体を敷衍することは不可能ですが、適宜、下記の関連情報を参考としていただきますよう、お願いします。

# 関連情報

[NoSQL/JSONデータベースCouchbase理解・活用へのロードマップ](https://qiita.com/yoshiyuki_kono/items/4c9cd1115efc5807b49f)

https://docs.couchbase.com/server/current/learn/services-and-indexes/services/query-service.html
【JavaScript】JavaScriptの非同期処理について

#プログラミング勉強日記
2021年2月26日

#同期処理とは
　同期処理は、コードを順番に処理していって、1つの処理が終わるまで次の処理は行われない。同期処理では、実行している処理は1つだけとなるので直感的な動作になる。
　しかし、1つの処理が終わるまで次の処理ができないことによっての問題点も存在する。具体的には、同期的にブロックする処理があると大きな問題が生じる。JavaScriptでは基本的にブラウザのメインスレッドで実行されるので、メインスレッドが他の処理でいっぱいになってしまうと表示が更新されなくなってしまいフリーズしたような状況になる。これは、メインスレッドが表示の更新といった処理を行っているためである。

#非同期処理とは
　非同期処理でもコードを順番に処理していくが、1つの非同期処理が終わるを待たずに次の処理を行うことができる。なので、非同期処理では同時に実行している処理が複数ある。
　JavaScriptにおける非同期処理には、<b>コールバック、Promise、async/await</b>の3種類ある。JavaScriptにおいての多くの非同期処理はメインスレッドで実行される。

　JavaScriptでは一部の例外を除いて、非同期処理が並行処理として扱われる。並行処置は、処理をある一定の単位ごとに分けて処理を切り替えながら実行することである。なので、非同期処理であってもその処理の実行中に重い処理があると非同期処理の切り替えが遅れる可能性もある。
　そのため、非同期処理の中でもメインスレッドとは別のスレッドで実行できるAPIが存在する。これによって、排他的に複数の処理を同時に実行することのできる並列処理をすることができる。
　そうはいっても、基本的な非同期処理はメインスレッドで実行されているという性質を知ることは大切である。

#参考文献
[JavaScriptの非同期処理を理解する その1 〜コールバック編〜](https://knowledge.sakura.ad.jp/24888/)
[非同期処理:コールバック/Promise/Async](https://jsprimer.net/basic/async/)
mysqlエラー対処忘備録(rootへの権限付与)

db環境設定で最も基本的なアクセス権限の付与について　

```
~ % mysql -u root
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

~ % mysql -u root -p
Enter password: 
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

```

rootにアクセス権限がないようだ...

https://qiita.com/yummy888/items/25621bc1451f218e010a
この記事を参考にしよう。

```
 % mysql.server stop 
Shutting down MySQL
.. SUCCESS! 

~ % mysqld_safe --skip-grant-tables
2021-02-26T03:02:12.6NZ mysqld_safe Logging to '/usr/local/var/mysql/MacBook-Pro.local.err'.
2021-02-26T03:02:13.6NZ mysqld_safe A mysqld process already exists
```
...。mysqld_safe A mysqld process already existsとはなんぞや？


この記事を参考にしよう。
mysqld_safe A mysqld process already existsの対処法【MySQL】
https://yaba-blog.com/mysqld_safe-a-mysqld-process-already-exists-mysql/

mysql.server stop だとMySQLが勝手に再起動するらしい
mysql.server statusで確認。

```
~ % mysql.server stop 
Shutting down MySQL
.. SUCCESS! 
~ % mysql.server status
 SUCCESS! MySQL running (53818)
```
たしかに、再起動されている。

```
~ % brew services stop mysql
Stopping `mysql`... (might take a while)
==> Successfully stopped `mysql` (label: homebrew.mxcl.mysql)
```




再度こちらの記事に戻るhttps://qiita.com/yummy888/items/25621bc1451f218e010a#%E6%A8%A9%E9%99%90%E7%A2%BA%E8%AA%8D

権限なしでアクセス

```
 ~ % mysqld_safe --skip-grant-tables
2021-02-26T03:22:53.6NZ mysqld_safe Logging to '/usr/local/var/mysql/MacBook-Pro.local.err'.
2021-02-26T03:22:53.6NZ mysqld_safe Starting mysqld daemon with databases from /usr/local/var/mysql
```
成功

mysqlへ接続

```
~ %  mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 8.0.22 Homebrew

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 
```

-以下記事通り

権限確認

Userテーブル削除

rootユーザーを作成し、権限付与

mysqld_sefe プロセス終了
 ps
-> 現在実行されているプロセス一覧表示

KILL (PID)
-> プロセス終了

```
~ % mysql.server start
Starting MySQL
. SUCCESS! 
yuto@MacBook-Pro ~ %  mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.22 Homebrew

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 
```

またrootアカウントで作業するのは抵抗がある場合MySQLユーザーの作成を行います。
セキュリティ設定（rootのパスワード変更等）

```
~%mysql_secure_installation
```
https://qiita.com/fuku_tech/items/a380ebb1fd156c14c25b
PowerShell 正規表現でCSV中の「,LTD」を含む項目をダブルコーテーションで囲む

NETEnum4 というソフトでネットワーク機器の一覧をCSV出力するとベンダー名に含まれる「,LTD」のところで列がずれてしまう。カンマが含まれるベンダー名を「""」で囲む作業をPowerShellを使って一括で行う方法をメモとして残しておきます。

# 前提条件
* PowerShell バージョン 5.1
* 変換するファイルは拡張子 csv でひとつのフォルダに保管されている（例: C:\CSVフォルダ）
* フォルダの中の csv ファイルをすべて処理して上書きする

## 作業
PowerShell を開いて保存フォルダに移動する 
`cd C:\CSVフォルダ`

コマンド入力して Enter
`dir *.csv | %{(gc $_) -replace ',([^"][^,]*,\s*LTD[^,]*),',',"$1",' | Out-File -Encoding OEM $_}`

これでとりあえず「,LTD」を含むベンダー名はほぼ「""」で囲むことができた。
ただし「, Inc」や「Co.,」や他にもこれらの組み合わせで2つ以上カンマがあるベンダー名もあり対応できず。

最終的に行頭から5個目のカンマの後ろと、行末から4個目のカンマの前に「"」を追加するようにして完了

`dir *.csv | %{(gc $_) -replace '^([^,]*,[^,]*,[^,]*,[^,]*,[^,]*,)(.*)$','$1"$2' -replace '^(.*)(,[^,]*,[^,]*,[^,]*,[^,]*)$','$1"$2' | Out-File -Encoding OEM $_} ` とすることで対応

最後の Out-File は　-Encoding OEM をつけておかないと文字コードが UTF-16LE となってExcelで普通に開けません
ZenHubのSprint機能

弊社Amaziaではバックログの管理にZenHubを使用しています。
これまでSprint期間中のタスクをまとめるためにMilestoneという機能を使っていましたが、Sprintという専用機能が追加されたようなので、設定してみました。

# Milestoneとの違い

Sprintはあらかじめ決められた期間（よくあるのは2週間）を繰り返し実施するため、最初にスケジュールを選択すると、自動的にそれ以降のSprintを作成してくれます。

![スクリーンショット 2021-02-24 17.18.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128744/6328ea86-5916-e8b5-5d60-30fd82aae78d.png)

はじめに3回分のSprintが作成されて、それ以降はSprintが完了するたびに先のSprintが自動で作成されるようです。

> ZenHub will automatically create 3 Sprints. New Sprints will be created continuously as each Sprint ends:

これまではSprintのたびにMilestoneを手動で作成して期間を指定する必要があったので、自動化されるとかなり楽ができそうです。

# Sprint計画の仕方

SprintへのIssueの追加はfilterなどで一括選択して `Set Sprint` ボタンからSprintを選択する。

![スクリーンショット 2021-02-24 17.31.23_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128744/6ffe3d3b-452b-2f99-ce1c-7e132cc6caab.png)

もちろん個別のIssueから選択することも出来ます。

![スクリーンショット 2021-02-24 17.32.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128744/000e47c0-4f98-60c2-0ddd-0135afa0958d.png)

この辺はMilestoneやReleaseの使い方と同じですね。

# 便利機能

Sprintの設定で2つのオプションが選択出来ます。

- Move unfinished Issues to the next Sprint
- Automatically build new Sprints from the backlog

## Move unfinished Issues to the next Sprint

Sprintの期間中に完了しなかったIssueを自動的に次のSprintに引き継いでくれる機能です。
Sprintをまたいだ場合は前後の両方のSprintに所属した状態にになるようです。
これまでのMilestoneではどちらに所属させるか悩むことがありましたが、より実態に近い管理ができるようになりました。

## Automatically build new Sprints from the backlog

あらかじめ決められた Story point にあわせて自動的にSprintに含めるIssueを決定してくれる機能です。
前のSprintが完了したタイミングで指定したPipelineのIssueからStory pointの上限に達するまで自動的にIssueを追加してくれるようです。

単一プロダクトの組織では便利な機能だと思いますが、弊社のように複数のプロダクトを並行開発する環境では使い所が難しいと思います。

# 課題

現状では一度決めたスケジュールからの変更が出来ないようなので、GWや年末年始でスケジュールがズレる場合に対応出来なさそうです。

# まとめ

これまでMilestoneを使っていて使いづらいと感じていた点が解消されていると感じました。
まだ荒削りな印象ですが、積極的に使っていきたいと思います。