OmniAICreator/Qiita-1.07M huggingface dataset:
WindowsでXAMPPにPHP8.0.0β2をインストールする

先日[PHP8.0.0α1でJITを試したとき](https://qiita.com/rana_kualu/items/73c346b3feadfa3a5b21)はPHP8をXAMPP経由で起動することができなかったのですが、今回動かすことができたので、その方法の共有です。
今回試したのはPHP8.0.0β2です。

# XAMPPインストール

まずローカルのXAMPPを削除。
[公式サイト](https://www.apachefriends.org/jp/index.html)からWindows向けXAMPPの最新版をダウンロードしてインストール。
既にPHP7.4.x版が入っているようなら、そのままでもいけると思います。


# PHP8.0.0インストール

[Windows版ダウンロードページ](https://windows.php.net/qa/)から`VS16 x64 Thread Safe`をダウンロード。
適当に解凍。
`path\to\xampp\php`ディレクトリにだばぁ！と上書き。
`php.ini-development`を既存の`php.ini`に上書き。
`extension=mbstring`とか`date.timezone`とかを好きに設定する。

# Apacheの設定

`path\to\xampp\apache\conf\extra\httpd-xampp.conf`をエディタで開く。
`php7ts.dll`を`php8ts.dll`に置換。
`php7apache2_4.dll`を`php8apache2_4.dll`に置換。
`php7_module`を`php_module`に置換。

# 起動

XAMPPコントロールパネルから起動。
`http://localhost`にアクセス。
これでPHP8.0.0が動いているはず。

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/d7dde9dc-edea-2c8b-67ce-9f0114d39694.png)


# 注意点

`httpd-xampp.conf`の`php_module`がポイントです。
ここを過去の類推から`php8_module`にすると何故か動きません。

これ[UPGRADING](https://github.com/php/php-src/blob/php-8.0.0beta2/UPGRADING#L780)にしっかり書かれているので、きちんと調べればわかります。

では何故α1でJITを試した時には気付かなかったのかというと、[PHP8.0.0α1のUPGRADING](https://github.com/php/php-src/blob/php-8.0.0alpha1/UPGRADING)には全く書かれてなかったからなんじゃ！
[PHP8.0.0α2のUPGRADING](https://github.com/php/php-src/blob/php-8.0.0alpha2/UPGRADING#L637)からしれっと追加されています。

ちなみに、この設定はApacheからPHPを呼び出すときの設定なので、Apacheを使わず直接コマンドラインからPHPを呼び出すのであれば不要です。
先日のJIT実験は、そうやって直接PHPを呼び出したということです。


# Apache経由のJITが死ぬ

ということで今度はApache経由でのJITを試してみようと思ったわけですが、なんか動きませんでした。
`opcache.jit_buffer_size`が設定されていると、何故かApache経由でアクセスするとERR_CONNECTION_RESETになって死にます。
これもコマンドライン経由だときちんと動くので、おそらくこれも`httpd-xampp.conf`あたりの問題だと思うのですがよくわかりませんでした。
XAMPPかApacheかどこかがサンプル設定上げてくれるとありがたいんですけどね。


# PHP CS Fixerが死ぬ

PHPのデフォルトをPHP8にすると[PHP CS Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer)がエラーを吐くようになります。
VSCodeだと`PHP CS Fixer: php general error.`としか言わないから何が原因なのかわからねえ。

直接実行すればメッセージを確認できます。

```bash
$ "path\to\php\php.exe" "path\to\php-cs-fixer-v2.phar"
PHP needs to be a minimum version of PHP 5.6.0 and maximum version of PHP 7.4.*.
```

ええ…
現行最新の[v2.16.4](https://github.com/FriendsOfPHP/PHP-CS-Fixer/releases/tag/v2.16.4)を使ってもこう言われます。
[RCが出たらまた来て](https://github.com/FriendsOfPHP/PHP-CS-Fixer/pull/5034)だそうです。ひどい。
バージョン見て門前払いじゃなくて、せめて動かせるけど保証はしない、ってなりませんかね。

VSCodeのPHPフォーマッターは[たくさんあります](https://marketplace.visualstudio.com/search?term=php%20formatter&target=VSCode&category=Linters&sortBy=Relevance)が、その多くはPHP CS Fixerのラッパーです。
従ってPHP CS Fixerが対応しないことにはまともに開発できないため、まだまだ環境を切り替えるには早いですね。
自力で整形しているフォーマッターのプラグインがあるのかはよくわかりませんでした。

どうしても早く使いたいなら、自力で対応している[PHPstorm](https://blog.jetbrains.com/phpstorm/)などを使ってみるといいかもしれません。
Windows10のノートPCが勝手に再起動するのはタッチスクリーンとタッチパッドが原因だった

#何の記事？

Deep learningやスクレイピングを行う際に、数日間連続でプログラムを走らせ続けないといけないことがあります。その際に問題となるのが、「Windows10が勝手に再起動してしまう問題」です。もちろんプログラムも勝手に中断されてしまい、残念なことになります。

検索してみると、
・PCを放電してみる
・PCの温度変化をモニタリングする
・Windows updateの実行を回避する
あたりが対策として挙げられているのですが、これらの対策ではうまくいかなりこともしばしばです。

今回、タッチパッドの設定を変更することにより再起動を防止できたので、備忘録です。

#機種
ThinkPad p53、Windows10 professional


#行ったこと
スタートボタンを右クリックして、デバイスマネージャーを開きます。
ヒューマンインターフェイスデバイス > HID準拠タッチスクリーン > ドライバ > デバイスを無効にする
を選択します。これでタッチスクリーンが無効になりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620139/4073e116-7995-7d62-3648-b3cee4005eea.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620139/d85c7c60-796b-f676-5a3e-81fbd34c0720.png)

同様に、その下にある、HID準拠タッチパッドも無効にしておきます。
この２つを行っておくことにより、マウスを接続しない限り、マウスカーソルを動かせなくなります。

すると、あら不思議、頭を悩ませていた「勝手に再起動」が起こらなくなりました。


#まとめ
静電気などにより勝手に画面の操作が行われていたということなのかも知れません。「勝手に再起動問題」に悩まされている人は、一度試してみられると良いと思います。タッチパッド・タッチスクリーンを無効にする操作は機種によって異なりますので、それぞれに最適な方法を選んで下さい。


#おまけ
その他、再起動を防ぐための基本的な対策を、メモしておきます。（どこにあるかいつも思い出せないので）

1.　電源オプション
コントロールパネル > システムとセキュリティ > 電源オプション > コンピューターをスリープ状態にする
を「適用しない」に変更

2.　Windowsの設定 > 更新のセキュリティ > 更新を7日間一時停止
をクリック。詳細オプションから、更新しない期間を最大35日まで延長可能。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620139/2c003ffa-d980-2222-ab75-7d96ce292004.png)
pip install ○○○でエラー Command errored out with exit status 1:

##実行コマンド

```
$ pip install ○○○
```

##エラー内容

```
Command errored out with exit status 1:
...
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
```

##解決策1
```
$ pip3 install ○○○
```

##解決策2
〜/.bashrcに下記のエイリアスを追加する。

```
alias pip=pip3
```
ターミナルを再起動してbashrcを再読み込み後

```
$ pip install ○○○
```
Unity 3D入門 #18 [マウスカーソルを中央にキープしつつカメラを移動する]

FPSゲームなどでマウスを使用してカメラを回転させることがあります。

その際、同じ方向にカメラを回転させ続けるとマウスカーソルが画面端にぶつかり、それ以上マウスが動かずにカメラを動かせなくなる状態が発生しました。
この不具合に対して、マウスカーソルを中央に置きつつ、マウスカーソルの移動量の入力を受け付けたいと考えました。

```
if(Cursor.lockState == CursorLockMode.None){
    newAngle.y += ((Input.mousePosition.x - lastMousePosition.x) * y_rotate);
    newAngle.x -= ((Input.mousePosition.y - lastMousePosition.y) * x_rotate);
    // x_rotate, y_rotate -> カメラの移動スピード調整用変数

    // カメラがmixup以上に上を向かず、mindownよりも下を向かないようにする調整
    newAngle.x = Mathf.Min(newAngle.x, maxup);
    newAngle.x = Mathf.Max(newAngle.x, mindown);
  
    this.gameObject.transform.localEulerAngles = newAngle;
}

// マウスポインターが中央から離れすぎた場合
if(Mathf.Abs(Screen.width/2-Input.mousePosition.x) > 50 || Mathf.Abs(Screen.height/2-Input.mousePosition.y) > 50){
    Cursor.lockState = CursorLockMode.Locked;
    lastMousePosition = Input.mousePosition;
}else{
    Cursor.lockState = CursorLockMode.None;
    lastMousePosition = Input.mousePosition;
}
```

上のコードはマウスカーソルが中央から50以上離れたときに、マウスカーソルを中央に戻すコードとなります。
これをカメラにアタッチすることで、マウスが画面端にぶつかることなくマウスの入力を受け付けることができます。

Cursor.lockState = CursorLockMode.Locked はマウスポインターを画面中央に配置し、そこから動かなくする命令(実行するとマウスポインターは見えなくなる)
Cursor.lockState = CursorLockMode.None はマウスポインターを動かせる状態にする命令

このコードはつまり、Cursor.lockState = CursorLockMode.Locked によってマウスポインターを画面中央に移動させ、Cursor.lockState = CursorLockMode.None で画面中央からマウスを動かせるようにするというものです。
Ruby on Rails 6にforeman導入メモ

## gem導入

```ruby:Gemfile
gem 'foreman', group: :development
```

## Procfile.devを実行するbin/server作成

```bin/server
#!/bin/bash -i
bundle install
bundle exec foreman start -f Procfile.dev
```


## コマンドを実行するProcfile.dev作成

```Procfile.dev
web: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
webpacker: ./bin/webpack-dev-server
```

## bin/serverの権限変更

```
chmod 777 bin/server
```


## サーバースタート

```
bin/server
```
ViewControllerを使った画面切替で複数Viewを切り替えられるようにする

## 結論から言うと

AnyViewを使えばよかった話（よくはない）

## チュートリアルから

勉強をはじめたばかりです。ということで、この間チュートリアルは一通りやりました（理解したとは言えない）

やりたいことは、[Interfacing with UIKit](https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit)でやる画面切替で、SwiftUIのViewを複数使うこと。
画面をスワイプで切り替えるだけなら簡単やんけ、と思って調べてみたが、なかなかいい方法がなかったので、チュートリアルのコードを下記のように変えてみた。


```swift:元のPageView.swift

var viewControllers: [UIHostingController<Page>]
@State var currentPage = 0

init(_ views: [Page]) {
    self.viewControllers = views.map { UIHostingController(rootView: $0) }
}

var body: some View {
    ZStack(alignment: .bottomTrailing) {
        PageViewController(controllers: viewControllers, currentPage: $currentPage)
        PageControl(numberOfPages: viewControllers.count, currentPage: $currentPage)
            .padding(.trailing)
    }
}
```


```swift:修正PageView.swift

@State var currentPage = 0
var viewControllers: [UIHostingController<AnyView>] {
    var _views: [AnyView] = []

    // ここらへんで突っ込みたいビューの初期化をする
    _views.append(AnyView(CustomView1()))
    _views.append(AnyView(CustomView2()))
    return _views.map {UIHostingController(rootView: $0)}
}

var body: some View {
    ZStack(alignment: .bottomTrailing) {
        // PageViewControllerのほうはAnyViewを引数で取れるようにしておく
        PageViewController(controllers: viewControllers, currentPage: $currentPage)
        PageControl(numberOfPages: viewControllers.count, currentPage: $currentPage)
            .padding(.trailing)
    }
}
```

## 最後に

勉強中なので、できればAnyViewじゃなくて指定Viewだけを渡せるようにしてあげたいけど、どうすればいいのかわかりません。
（そもそもListの型をinterfaceで指定したい、という気持ちなだけなのです。。。）
よいやり方などをご存知の方がいらっしゃいましたら、ご教授いただけると助かります。。。
Unity 3D入門 #17 [音について]

3Dの音の減衰に関して
https://styly.cc/ja/tips/unity_3dsound/

複数のAudioSourceをアタッチする際

```
AudioSource[] audio_source;
void Start(){
    audio_source = this.GetComponents<AudioSource>();
}
void Update(){
    audio_source[0].Play();
    audio_source[1].Play();
}
```

参考URL：https://squmarigames.com/2018/12/19/unity-beginner-audiosource/
RSS/AtomをSlackに通知する

# これはなに？

前半は

- フィード ( [RSS](https://ja.wikipedia.org/wiki/RSS) / [Atom](https://ja.wikipedia.org/wiki/Atom_%28%E3%82%A6%E3%82%A7%E3%83%96%E3%82%B3%E3%83%B3%E3%83%86%E3%83%B3%E3%83%84%E9%85%8D%E4%BF%A1%29) ) をSlackに通知する方法です。

後半は

- iOSエンジニア向けにおすすめの フィードアドレス の紹介になります。

# 環境設定をする

Slack ワークスペースに RSS アプリを追加する必要がありますので、本家を参考に行ってください。

- [Slack に RSS フィードを追加する | Slack](https://slack.com/intl/ja-jp/help/articles/218688467-Slack-%E3%81%AB-RSS-%E3%83%95%E3%82%A3%E3%83%BC%E3%83%89%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B)

# /feed コマンドの使い方

```
# フィード (RSS/Atom) を登録する
/feed subscribe [フィードのアドレス]

# 登録済みのフィードと、その固有のIDナンバーを確認する
/feed list

# フィードの登録を解除する
/feed remove [IDナンバー]

# ヘルプを表示する
/feed help
```

## GitHub.com にある OSS の通知を受け取る

GitHubはフィードに [Atom](https://ja.wikipedia.org/wiki/Atom_%28%E3%82%A6%E3%82%A7%E3%83%96%E3%82%B3%E3%83%B3%E3%83%86%E3%83%B3%E3%83%84%E9%85%8D%E4%BF%A1%29) を使用しています。
URLの末尾に `.atom ` を追加したものが、フィードのアドレスになります。

※手始めに`ブラウザ` か `$ curl [フィードのアドレス]` で正しく表示されるか（対応しているか）を試してから、Slack通知の設定を行うと遣りやすいです。

### GitHub Releases の通知を受け取る

```
# https://github.com/fastlane/fastlane/releases の通知を受け取る場合
/feed subscribe https://github.com/fastlane/fastlane/releases.atom
```

- CocoaPods
    - `/feed subscribe https://github.com/CocoaPods/CocoaPods/releases.atom`
- Carthage
    - `/feed subscribe https://github.com/Carthage/Carthage/releases.atom`
- fastlane
    - `/feed subscribe https://github.com/fastlane/fastlane/releases.atom`
- XcodesOrg/xcodes
    - `/feed subscribe https://github.com/XcodesOrg/xcodes/releases.atom`
- xcpretty/xcode-install
    - `/feed subscribe https://github.com/xcpretty/xcode-install/releases.atom`
- Firebase
    - `/feed subscribe https://github.com/firebase/firebase-ios-sdk/releases.atom`

### Commit がされたら、通知を受け取る

```
# https://github.com/fastlane/fastlane/commits/master の通知を受け取る場合
/feed subscribe https://github.com/fastlane/fastlane/commits/master.atom
```

## Apple Developer や Swift.org、Firebase などの通知を受け取る

- News - Apple Developer
    - `/feed subscribe https://developer.apple.com/news/rss/news.rss`
- Releases - Apple Developer
    - `/feed subscribe https://developer.apple.com/news/releases/rss/releases.rss`
- Swift.org
    - `/feed subscribe https://swift.org/atom.xml`
- WebKit.org
    - `/feed subscribe https://webkit.org/feed/`
- Firebase
    - `/feed subscribe https://firebase.googleblog.com/feeds/posts/default?alt=rss`
    - `/feed subscribe https://github.com/firebase/firebase-ios-sdk/releases.atom`
≪CSSデザイン案≫途中で色の変わる下線のもうワンランク上の下線「文字数分だけ色が変わる下線」

# どうも7noteです。文字数に比例しておなじだけ下線の色が変わる方法。

どうも7noteです。
この記事は以下へ引っ越しました。

https://naruweb.com/coding/underline-color/
プログラミング未経験の中学生がswift独学で勉強始めてみた！/変数・定数・データ型

#はじめに
現在公立の中学校に通っている１５歳のAoki Renです。
僕は昔から自分の手で作ったモノで誰かを笑顔にすることが好きで、それを職業としてできたらいいなと考えています。そして、僕はもう７月に受験が終わり時間があるので高校入学までにアプリを作れるようなって、人を笑顔にさせたいと思ったのでswiftをこれから勉強します。
プログラミングは全くやったことがないのですが自分なりに前進できるように本気で取り組んでいきます。そのアウトプットや自分の振り返りができるようにQiitaでやっていけたらいいなと思っています。また、僕の記事を読んで1人の人でも多くの為になっていただければ幸いです。
まだ具体的に作るものは決まっていませんがサッカーを頑張っている弟の為に何か作れたらいいなと思っています。

#Swift勉強第１回/変数・定数・データ型
###１.変数とは
はじめに、変数を使って自分の名前を出力していきたいと思います。
まず、変数とは、`データを扱う時に使う記憶場所（メモリアドレス）`に、好きな名前をつけることです。データと言うのはメモリ上に記憶され、メモリアドレスで管理されています。コンピュータがそれを管理する分にはいいのですが、プログラマがデータを扱う時にメモリアドレスを使うと大変です。
そこで、プログラミングではプログラマがメモリアドレスに分かりやすい名前（変数名）を付けることができます。この、変数という技術によって、　プログラマはメモリアドレスではなく、自分で決めた名前でデータにアクセスすることができるのです。

では実際に変数を使ってみましょう。今回は変数名をnameにしてみます。そして変数nameにRenと言う値を入れてみます。

```swift

var name = "Ren"
//var 変数名 = "値"
print(name)
```
実行すると「Ren」と出力されます。ちなみにvarは「variable（変数）」の略です。

#2.定数とは
同じく定数を使って自分の名前を出力していきたいと思います。
まず、定数は変数とイメージは殆ど変わらず、違いと言ったら変数は途中で読み読み書き可能ですが定数は途中での読み書きは初期化の時のみでその後はデータが出来ません。また、宣言の仕方が異なり変数は`var`、定数は`let`を宣言時に付けます。

```swift
let name2 = "Ren"
print(name)
```
こんな感じになります。printを使って出力していきます。

```swift
//変数
var name = "Ren"
print(name)

name = "Aoki"
print(name)
//変数は途中で値の書き換えが可能


//定数
let name2 = "Ren"
print(name)

//⬇️エラーが発生します
name2 = "Aoki"
print(name)
//定数は途中で値の書き換えが出来ない
```

#３.データ型とは
データ型とは、あるデータがどのような性質のもので、どのように取り扱うべきかを定めたもので、典型的なものには整数型や文字列型などがあります。それぞれの変数や値のデータ型に応じて、それを適切に扱うためのプログラムコードが生成・適用されています。

以下の型が基本的なものになります。

```swift

//文字列
var member: String = "Aoki Ren"

//整数
var age: Int = 15

//Double: 64bitサイズの浮遊小数点型
var height: Double = 170.6

//Float: 32bitサイズの浮遊小数点型
var weight: Float = 51.4

//真偽値
var isMan: Bool = true
```
しかし、Swiftでは型を推測してくれるため上の記述はFloat以外は簡略化できます。（型推論）
下のように簡略化できます。

```swift
var member = "Aoki Ren"
 
var age = 15
 
var height = 170.6
 
var weight = 51.4
 
var isMan = true
```

実は数値型にはもっと細かな種類がありますが、もう少し慣れてきたら勉強していくことにします。

#さいごに
以上、変数・定数・データ型についてまとめてみました。
プログラミング全くの初心者ですが、これからも前進していきます。最後までご付き合いありがとうございました。
次回は構造体・クラスなどをまとめていきたいなと思っています。
Railsのactionのfilter(before_actionとか)で沼にハマった

- 20分くらいハマった。 

## やったこと

- それぞれのfilterにかかった時間を図るために、`print_start_time`と`print_end_time`を複数回呼び出す設定にしようとした。

```rb:my_controller.rb
class MyController < ApplicationController
  before_action :print_start_time
  before_action :action1
  before_action :print_end_time

  before_action :print_start_time
  before_action :action2
  before_action :print_end_time

  def print_start_time
    puts('### start time ###')
    puts(Time.now)
  end
  
  def print_end_time
    puts('### end time ###')
    puts(Time.now)
  end

  def action1
    ...
  end

  def action2
    ...
  end
end
```


## どうなった？

挟み込まれたfilterは以下のようになった
(binding.pryで止めて_process_action_callbacksでfilterを順々に見れる)

```
> _process_action_callbacks.send(:chain).map{|c|puts "#{c.kind} - #{c.filter}"} 

before - action1
before - print_start_time
before - action2
before - print_end_time
```

## つまり？

- 同じfilterを複数回呼ぶと、callbackが後の場所に再定義され、元々定義されたものは消えてしまうようだ。


## 参考

- https://github.com/rails/rails/issues/20687

> looking at implementation of AbstractController::Callbacks, it can be seen they are created using define_method so it's expected that next call will redefine the callback. so I guess it's expected behaviour

- https://guides.rubyonrails.org/action_controller_overview.html#filters

> Calling the same filter multiple times with different options will not work, since the last filter definition will overwrite the previous ones.
Sentryのissue一覧をcsv形式でexportする


# 概要
Sentryのissue一覧をAPIで取得し、csvファイルに変換する方法について紹介します。

Sentryの画面上にはissueを一括でダウンロードするような機能がなく、
issueの詳細を確認するためにはissue毎に毎回詳細画面を開かなくてはなりませんが、
Sentry APIを使用することにより、JSON形式で一覧データを取得することが可能です。


# Sentry API
公式のAPI Referenceはこちらです。
https://docs.sentry.io/api/

issue一覧取得エンドポイントの他に、event一覧、詳細を取得するエンドポイントやステータス更新用エンドポイント等も用意されているようです。

## issue一覧取得エンドポイント
### URL
`GET /api/0/projects/{organization_slug}/{project_slug}/issues/`


### Query parameter

| key | value | description | 
|:-- |:-- |:-- |
| statsPeriod | `"24h"`, `"14d"`, or `""` | 対象期間 |
| shortIdLookup |  有効にする場合: `1`  | このパラメータを有効にし、shortId(issue毎のid)をqueryに含めるとshortIdで検索が可能になります |
| query | `"is:unresolved"`や `event.timestamp:`など | その他の検索条件 |

※queryに指定できるパラメータは以下を参照してください。
https://docs.sentry.io/product/sentry-basics/search/#issue-properties

API Reference
https://docs.sentry.io/api/events/get-project-group-index/


# issues一覧をcsv形式でエクスポートする
指定期間内のissue一覧の指定項目をcsv形式で./data/ディレクトリにエクスポートします。

## 手順

以下の手順に沿って実行してください。
1. 事前にAuth Tokenを作成します
　https://sentry.io/settings/account/api/auth-tokens/
2. 以下のpythonプログラムと同階層に `data` ディレクトリを作成してください
3. paramsのパラメータを必要に応じて修正してください
4. 以下のコマンドでプログラムを実行します
　`$ python download_sentry_data.py <org>/<project> <auth_token>`
5. csvファイルがdataディレクトリに生成されます

## pythonサンプルプログラム
```python:download_sentry_data.py

"""Download sentry data.
usage:
 1. create auth token (https://sentry.io/settings/account/api/auth-tokens/).
 2. make a directory for export if not exists.
    $ mkdir data
 3. fix event.timestamp (L27).
 4. execute
    $ python download_sentry_data.py <org>/<project> <auth_token>
 5. a CSV file with a name formatted as "./data/issues_YYYYmmDDHHMMSS.csv" is created.
"""

import requests
import csv
import sys
import datetime


if __name__ == '__main__':
    dt_now = datetime.datetime.now()
    now = dt_now.strftime('%Y%m%d%H%M%S')
    with open('./data/issues_{0}.csv'.format(now), 'w', encoding='utf-8') as csvfile:
        fieldnames = ['count', 'title', 'status', 'lastSeen', 'firstSeen', 'culprit', 'permalink']
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames, extrasaction='ignore')
        writer.writeheader()
        url = f'https://app.getsentry.com/api/0/projects/{sys.argv[1]}/issues/'
        # time-range absolute date
        params = {'query': 'event.timestamp:>=2020-08-01T00:00:00 event.timestamp:<2020-09-01T00:00:00'}
        while True:
            response = requests.get(
                url,
                params=params,
                headers={'Authorization': 'Bearer {TOKEN}'.format(TOKEN=sys.argv[2])}
                )
            data = response.json()
            for event in data:
                # tags = {item['key']: item['value'] for item in event['tags']}
                writer.writerow(dict(event))
            link = response.headers.get('Link')
            print(f"Last event date: {data[-1]['lastSeen']}")
            if link and 'rel="next"; results="true"' in link:
                print("Getting next page...")
                url = link.split()[4][1:-2]
            else:
                break
```
https://gist.github.com/siiramone/0d2ed5fe9a78b4f34f70d60d6a9f80b2
forthでzundoko

#概要

forthでzundokoやってみた。

#サンプルコード


```
: zundoko 0 begin 2 random if ." zun " 1 + else ." doko " drop 0 then dup 4 = until ." doko kiyoshi!" ;

```

#実行結果


```
zundoko zun doko zun zun zun doko doko zun zun doko zun doko doko doko doko doko zun zun zun doko zun zun doko zun doko doko doko doko doko zun doko zun zun zun zun doko kiyoshi! ok
```

以上。
[MySQL]DBとテーブルのディスク容量を確認する

# はじめに
mysqldumpを利用してデータをコピーする前に、予めデータの容量を確認したく、方法を調べました。

(mysqldumを利用したデータの移行方法は[こちらの記事](https://qiita.com/ryoishizawa/items/2d8eb898b848a501f91c)に記載しました。)

環境は以下の通りです。

* OS: Ubuntu
* MySQL version: 5.6

# 方法

以下のSQLを実行することで、各DBのデータ容量を確認できます。

```confirm-data-size.sql
## GB単位で取得
SELECT 
    SUM(ROUND(((data_length + index_length) / 1024 / 1024 / 1024),
            2)) `Total Size in GB`
FROM
    information_schema.TABLES
GROUP BY table_schema;
```

WHERE句で対象テーブルや対象スキーマを取得することも可能です。以下のSQLは、あるDBを指定した上で前方一致でデータ容量を取得します。

```confirm-data-size-2.sql
## MB単位で取得
SELECT 
    SUM(ROUND(((data_length + index_length) / 1024 / 1024),
            2)) `Total Size in MB`
FROM
    information_schema.TABLES
WHERE
    table_schema = 'db_name'
        AND table_name LIKE 'table_prefix_%';
```

# 容量が正しく取得されているのか検証する

ここからは蛇足ですが、SQLで取得した結果がディスクの容量と一致しているのかが気になり、検証してみました。

## 前提
前提として、Dockerを利用してMySQLを動かしており、`/var/lib/mysql`がローカルの `~/mount_dir`にマウントされているものとします。

このマウントされているディレクトリの容量を確認しました。

## SQL実行

上記のSQLを利用して、「test」というDBのサイズを確認します。

```
mysql> SELECT table_schema AS 'DB Name', ROUND(SUM(data_length + index_length) / 1024 / 1024 / 1024, 1) AS 'DB Size in GB' FROM information_schema.tables WHERE table_schema = 'test';
+---------+---------------+
| DB Name | DB Size in GB |
+---------+---------------+
| test    |         122.0 |
+---------+---------------+
```

## マウント先の容量確認

次に、マウントしている先のディレクトリでDB名ごとにフォルダがあるのを見つけたので、そちらの容量を確認します。

```
$ sudo du -sh ~/mount_dir/test
139G	/home/ubuntu/mount_dir/test
（以下略)
```
サイズが合わない…。

## なぜサイズが異なるのか？

以下の記事を見つけました。

[ubuntu - Substantial difference between database size under MySQL and actual size on disk - Database Administrators Stack Exchange](https://dba.stackexchange.com/questions/11567/substantial-difference-between-database-size-under-mysql-and-actual-size-on-disk)


> If you are using InnoDB tables, the size of your ibdata files will grow over time. So, if you issue DELETE statement, your database size will reduce, but the ibdata file will remain the same (not reduce).


つまり、ibdata（共有テーブルスペース）のサイズは時間を経過すると増加することが原因です。例えば、DELETE文を発行してもibdataは削除されない（ので、容量が増えていく）、とのことでした。

また、他にもログがあるはずなので、これもサイズ増大の原因になり得るかと思います。（違ったら、コメントで教えてください。）

## 結論

SQLでデータ容量は正しく確認可能ですが、ibdata等他にもMySQL上で増大するデータがあり、そちらもある程度考慮した上で十分なディスク容量を確保することが必要です。

# 参考
* [MySQL - How to get the database size in MySQL? | TablePlus](https://tableplus.com/blog/2018/08/mysql-how-to-get-the-size-of-mysql-database.html)
* [ケーワン・エンタープライズのエンジニアメモ(｀･ω･´)ゞﾋﾞｼｯ!!: テーブルスペースとログファイルについて（ibdata*、ib_logfile*)](http://k-1-ne-jp.blogspot.com/2012/11/ibdataiblogfile.html)
rails6 + docker + postgreSQL + Materializeで開発環境を作ってみた。


##railsの環境構築

Docker3
Rails6.0.3
Ruby2.7.0
DB:PostgeSQL
こちらの環境で作成していきます。

##1.dockerを立ち上げる
@shungo_m様の[「DockerでRails6の環境構築を行う方法」](URL "https://qiita.com/shungo_m/items/fd1ab99fbe76d39e456c")を参考にしました。

docker立ち上げに必要なファイルの作成

```
$ mkdir myapp
$ cd myapp
$ touch Dockerfile
$ touch docker-compose.yml
$ touch entrypoint.sh
$ touch Gemfile
$ touch Gemfile.lock

```

```php:Dokerfile
FROM ruby:2.7.0
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client

RUN apt-get update && apt-get install -y curl apt-transport-https wget && \
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
apt-get update && apt-get install -y yarn

RUN curl -sL https://deb.nodesource.com/setup_7.x | bash - && \
apt-get install nodejs

RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

CMD ["rails", "server", "-b", "0.0.0.0"]
```

```PHP:docker-compose.yml
version: '3'
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      POSTGRES_HOST_AUTH_METHOD: 'trust'


  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
```

```PHP:entrypoint.sh
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
```

```PHP:Gemfile
source 'https://rubygems.org'
gem 'rails', '~>6'
```

```PHP:Gemfile.lock

```

必要なファイルの作成が出来たので、`rails new`でプロジェクトの作成。

```
$ docker-compose run web rails new . --force --no-deps --database=postgresql --skip-bundle
```

そのままdocker build、upと進めるとwebpackerをインストールしてねと言われるので、インストールをする。

```
$ docker-compose run web bundle exec rails webpacker:install
```
その後はDBの設定をして、docker環境が完成。

##2.Materiarizeの導入
こちらのサイトを参考にしました。https://monaga.site/use-materialize-in-rails6/

```
$ docker-compose run web yarn add materialize-css
```

`app/javascript/packs` に`application_style.js`というファイルを作成・記述します。

```PHP:application_style.js
import "../stylesheets/application.scss";;
```

`app/javascript/stylesheets` ディレクトリの中に `application.scss`ファイルを作成・記述します。。

```PHP:application.scss
@import "materialize-css/dist/css/materialize.min.css";
```

最後にjavascriptの読み込みに必要なコードを `app/javascript/packs/application.js`に追記します。

```PHP:application.js
import "materialize-css/dist/js/materialize.min.js";
M.AutoInit();
```

これで環境構築完了です。

materializeの公式ページにはサンプルが多くあるので、参考にしてください。
https://materializecss.com/

####参考
https://materializecss.com/
https://monaga.site/use-materialize-in-rails6/
https://qiita.com/shungo_m/items/fd1ab99fbe76d39e456c
Goのテストでset-upとtear-down

# 概要
go 1.14 からであれば「`TestMain`」を使うことができる

https://golang.org/pkg/testing/#hdr-Main

# サンプル

```golang

package main

import (
	"log"
	"os"
	"testing"
)

func TestMain(m *testing.M) {
	log.Println("Do stuff BEFORE the tests!")
	exitVal := m.Run()
	log.Println("Do stuff AFTER the tests!")

	os.Exit(exitVal)
}

func TestA(t *testing.T) {
	log.Println("TestA running")
}

func TestB(t *testing.T) {
	log.Println("TestB running")
}
```

```
2020/08/31 20:04:45 Do stuff BEFORE the tests!
2020/08/31 20:04:45 TestA running
2020/08/31 20:04:45 TestB running
PASS
2020/08/31 20:04:45 Do stuff AFTER the tests!
ok      github.com/fan-ADN/test-sample  0.009s
```

* 名前から`main`をテストする用のものと勘違いしたが、そうではないらしい
* `TestMain`を書いていれば、`TestXXX`が直接実行されずに`TestMain`内`m.Run()`で実行するので、前後に処理を挟めると言うことらしい
* 同一パッケージ内に1回しか定義できない

なるほどねー

# 参考
https://medium.com/goingogo/why-use-testmain-for-testing-in-go-dafb52b406bc
Dialogflowで一部の事前定義のシステム エンティティが使用できない。


# 問題点
Dialogflowで事前定義のシステム エンティティ@sys.unit-weightを使用しようとするとエラーが出て、使用できない。

# Dialogflowのエラー
>Entity type mismatch
Unable to add 329 to @sys.unit-weight system entity. 
Please create a custom entity instead. For more info about entity extension click here.

> Some entities haven't been created yet: @sys.unit-weight. Create entities before using them in intents.

# 結論
今のところ、ja（日本語）だと @sys.unit-weight は使用できない。en （英語）なら @sys.unit-weight が使用できる。Languages（言語）によって、事前定義のシステム エンティティの種類が異なる様子。

# 参考
- [System entities reference](https://cloud.google.com/dialogflow/es/docs/reference/system-entities)
セマフォ(semaphore)、スラッシング(Thrashing)、セグメンテーション(segmentation)、スワップアウト (swap out)

応用情報技術者平成30年春期 午前問18

セマフォを用いる目的として，適切なものはどれか。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/2fef444a-c238-d50f-b608-527e9fb9932c.png)


１、セマフォ(semaphore)とは、
信号機の意味で並行動作している複数のタスク間で共通して使用する資源へのアクセスを制御するメカニズムです。整数型の共有変数である「セマフォ変数」と、それを操作する「P操作」「V操作」で同時更新によってエラーを引き起こす処理部分の排他制御を行います。

２、スラッシングを回避するには　(Thrashing)
メモリを増やしたり、メモリを多く使うアプリケーションを終了させたりする。

・スラッシング (英: Thrashing) とは、仮想記憶環境下において、物理メモリが不足気味で、かつ動作しているプロセスのアクセスパターンのために、ページアウトしたデータをすぐにページインするというようなことを頻繁に繰返す必要が発生していて、仮想記憶を管理しているシステム（一般にはオペレーティングシステム）のそのような動作の結果、システムの動作が極端に遅くなっている、というような状態のことである。

３、セグメンテーションとは、（segmentation）
区分け、区分、分割などの意味を持つ英単語。全体を何らかの基準や規則に基づいて、いくつかの部分・断片（segment：セグメント）に分割すること。

・メモリのセグメンテーション
ソフトウェアやプログラミングの分野では、オペレーティングシステム（OS）コンピュータのメインメモリを用途などに応じて可変長の領域に分割して管理することをメモリセグメンテーションという。

・ネットワークのセグメンテーション
ネットワークの分野では、大規模なネットワークを小規模なネットワークに分割して管理することをセグメンテーション（ネットワークセグメンテーション）という。


ーーーーーーーーーーーーーーーーーーーーーーーーーー
補足
ページング方式の仮想記憶において，ページ置換えの発生頻度が高くなり，システムの処理能力が急激に低下することがある。このような現象を何と呼ぶか。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/609cdf3c-4922-71b3-c92e-91a5ba4ecd12.png)


１、スラッシング(Thrashing)
仮想記憶システムにおいて主記憶の容量が十分でない場合にプログラムの多重度が増加すると、ページング処理が多発します。このようにシステムのオーバヘッドが増加したことによりアプリケーションのCPU使用率が減少し、処理速度が遅くなる状態をスラッシング(Thrashing)といいます。


２、スワップアウトは、
主記憶を効率的に利用するために、主記憶上で長い間待ち状態となっているプログラムを実行状態のまま補助記憶上の領域に退避させることです。


参照
スラッシング
https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%A9%E3%83%83%E3%82%B7%E3%83%B3%E3%82%B0#:~:text=%E3%82%B9%E3%83%A9%E3%83%83%E3%82%B7%E3%83%B3%E3%82%B0%20(%E8%8B%B1%3A%20Thrashing)%20%E3%81%A8,%E3%82%AA%E3%83%9A%E3%83%AC%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%EF%BC%89%E3%81%AE%E3%81%9D%E3%81%AE%E3%82%88%E3%81%86

http://fast-macro.com/Johosyori/h30HaruOuyou/h30HaruOuyou-18.html

https://www.fe-siken.com/kakomon/19_haru/q29.html

排他制御に関する用語を大雑把に理解しよう「ロックとセマフォ」「共有ロックと排他ロック」「楽観的ロックと悲観的ロック」
https://qiita.com/momotaro98/items/5e37eefc62d726a30aee

セグメンテーション  【 segmentation 】  
http://e-words.jp/w/%E3%82%BB%E3%82%B0%E3%83%A1%E3%83%B3%E3%83%86%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3.html
AtCoderにてPythonで再帰関数を使う時の注意点

AtCoderにて深さ優先の問題（https://atcoder.jp/contests/atc001/tasks/dfs_a）
について、以下の再帰関数を使ったプログラムを提出したところ、どうしてもREとなってしまうテストケースが存在した。


```Python

def main():
    h, w = map(int, input().split())

    whole_map =[]
    for i in range(h):
        whole_map.append(list(input()))
    s_h = -1
    s_w = -1
    g_h = -1
    g_w = -1
    seek = [[False for _ in range(w)] for _ in range(h)]

    for i in range(h):
        for j in range(w):
            if whole_map[i][j] == "s":
                s_h = i
                s_w = j
            if whole_map[i][j] == "g":
                g_h = i
                g_w = j

    dfs( whole_map, seek, s_h, s_w)

    if seek[g_h][g_w] == True:
        print("Yes")
    else:
        print("No")

def dfs(whole_map, seek, h_idx, w_idx):
    if h_idx < 0 or h_idx >= len(whole_map) or w_idx < 0 or w_idx >= len(whole_map[0]) or whole_map[h_idx][w_idx] == "#":
        return

    if seek[h_idx][w_idx] == True:
        return

    seek[h_idx][w_idx] = True

    dfs(whole_map, seek, h_idx+1, w_idx)
    dfs(whole_map, seek, h_idx-1, w_idx)
    dfs(whole_map, seek, h_idx, w_idx+1)
    dfs(whole_map, seek, h_idx, w_idx-1)
main()

```

pythonはデフォルトで再帰回数の上限が1000とのことで、それに引っかかっていた模様。
def main()前に再帰上限をセットする、以下を記載してACとなった。
※今回はMAX 500*500の深さのため250000をセット

```Python
import sys
sys.setrecursionlimit(250000)
```
【Django】herokuデプロイ時に遭遇したエラー その①

# 何があったか？
Djangoで作成したWebアプリをherokuでデプロイするため

```terminal
$ git push heroku master
```
を実行したところ、以下のエラーが発生した。

```terminal
"""中略"""

remote: 
To https://git.heroku.com/hogehoge.git
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://git.heroku.com/hogehoge.git'
```


# 原因は？
急いでいる人向けに結論から書きます。

**Procfile、runtime.txt、requirements.txtを作成していませんでした。**

慣れている人からすれば「そんな事ある？」って話でしょうが、あります(泣)
なんなら設置場所を間違えて二重に詰まっていました。

# なぜエラーになるのか
それぞれのファイルの役割と作成方法を説明します。

### Procfile
役割 ： **使用するサーバー**をherokuに知らせる
場所 ： **プロジェクトルート**(manage.pyがあるところ)に設置する
内容 ： 以下のように記述

```Procfile
web: gunicorn プロジェクト名.wsgi --log-file -
```
gunicornを使いますよ、という意味
Procfileには**拡張子がない**ので注意！

### runtime.txt
役割 ： **Pythonのバージョン**をherokuに知らせる
場所 ： **プロジェクトルート**(manage.pyがあるところ)に設置する
内容 ： 以下のように記述

```runtime.txt
python-3.8.5 (3.8.5には自分が使用しているpythonバージョンを記述する)
```


### requirements.txt
役割 ： **使用しているライブラリ**をherokuに知らせる
場所 ： **プロジェクトルート**(manage.pyがあるところ)に設置する
内容 ： Procfileとruntime.txtは手動で作成する必要がありますが、requirements.txtはターミナルで以下を実行します。

```terminal
$ cd プロジェクトルートディレクトリ    # プロジェクトルートディレクトリ内で実行すること

$ pip freeze > requirements.txt
```
これだけでOK。以下の例のようにライブラリ一覧が書かれたテキストファイルができていることを確認する。

```requirements.txt
"""
これは例なので実際は自分が使用しているライブラリが一覧で書かれます。
"""

appnope==0.1.0
asgiref==3.2.10
backcall==0.2.0
beautifulsoup4==4.9.1
certifi==2020.6.20
chardet==3.0.4
click==7.1.2
coverage==5.2.1
cssselect==1.1.0
decorator==4.4.2
dj-database-url==0.5.0
Django==3.1
.
.
.

"""以下略"""
```

### 注意点
上記3ファイルは設置していないのはもちろん、ファイル名や内容にミスがあってもエラーとなるのでよく確認しましょう。


# 参考
参考にさせていただいたサイト
[Djangoで作る初めてのウェブアプリケーション（番外編）herokuデプロイ](https://note.com/takuya814/n/n209dd3c95496)

同じ状況の人に参考になるかもしれないサイト
[【git】git pushがrejectされたときの対応方法](https://www.softel.co.jp/blogs/tech/archives/3569)
ActiveHashで複数のプルダウンメニューを作る方法

【概要】
----------------------------------------
<b>1.結論</b>

<b>2.ActiveHashとは何か</b>

<b>3.どのように使用するのか</b>

<b>4.補足</b>



1.結論
----------------------------------------
モデルを複数作って、db/migrateに全て記載する！

<br>
2.ActiveHashとは何か
----------------------------------------
ActiveHashとは<b>変更されないデータをモデルファイルに書き込むことでDBに逐一保存せずにデータを扱えるgem</b>です！

<br>
3.どのように使用するのか
---------------------------------------
ActiveHashの導入方法は他のgemと一緒なので省きます！
また自分が反映させたいテーブルも用意しておきます。

```ruby:コンソール
%rails g model abcdefghi --skip-migration
```
と記載します！
スキップするのはDBにマイグレーションする必要（テーブルを作成）がないからです！

そうすると

```ruby:model
 class Abcdefghi <ApplicationRecord

```
となっているので、
ApplicationRecord を <b>ActiveHash::Base</b>　に書き換えましょう！ActiveHash::Baseに継承することでApplicationRecordのメソッドも使用できます！（ActiveHash::BaseはApplicationRecordの同様のメソッドが使用できます）


```ruby:model
 class Abcdefghi <ActiveHash::Base
self.data = [
   { id: 1, name: '--' },
   { id: 2, name: 'A' },
   { id: 3, name: 'B' },
   { id: 4, name: 'C' },
   { id: 5, name: 'D' },
   { id: 6, name: 'E' },
   { id: 7, name: 'F' },
   { id: 8, name: 'G' },
   { id: 9, name: 'H' },
   { id: 10, name: 'I' }
 ]

```
self.dataでテーブルを作成している感覚で、配列型式でハッシュの使い記載します。データーベースからモデルに引っ張ってくる中身がまさにこのような形ですね。

 ” { id: 1, name: '--' }”は表示の際によく見るものですね。

これをプルダウンメニューを作りたい分だけ3.の最初から繰り返します！


```ruby:db/migrate/20******
 class Create****(該当のテーブル名) <ActiveRecord::Migration[6.0]
 def change
   create_table :*****(該当のテーブル名)  do |t|
     t.integer    :abcdeghi_id     , null: false
     t.timestamps
    end
  end
 end
```
とします！

_idとするのはモデルのidを自分の保存したいテーブル持っていくためです。

あとはいつもどおり

```ruby:コンソール
% rails db:migrate
```
すればOKです！


ただここで気をつけておきたいのが、
アソシエーションです。一応 class Abcdefghi <ActiveHash::Baseの部分でDBのテーブルのような構造になっているのでアソシエーションの記載が必要です。

```ruby:models/****.rb
class (該当のテーブル名)  < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to_active_hash :abcdeghi
end
```
としてください！


<br>
4.補足
----------------------------------------

```ruby:model/****.rb
class ****(該当のテーブル名）< ApplicationRecord
validates :abcdefghi_id, numericality: { other_than: 1 }
```
と記載することで、 ” { id: 1, name: '--' }”
<b>”--”以外は保存できます</b>というバリデーションが記載できます！
id:1よりも上の数字は反映されるという意味だからですね！

<br>
最新のgitをインストール

## gitのinstall方法

- 依存関係のあるライブラリのインストール

```sh
yum install openssl-devel curl-devel expat-devel wget gcc
```

- 最新のgitのURL確認

 [こちら](https://mirrors.edge.kernel.org/pub/software/scm/git/) にアクセス。
`git-X.XX.X.tar.gz` の最新バージョンのリンクをコピー
→ `https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.28.0.tar.gz`

![無題 - ペイント 2020-08-31 19.18.53 - ペイント 2020-08-31 19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/9b3ffddd-1eec-9445-7a00-5b7c363a9b7a.png)

- gitパッケージのダウンロード

```sh

# 適切な場所に移動
cd /var/tmp

# gitのファイルをダウンロード
wget https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.28.0.tar.gz

# ファイルを解答
tar xvzf git-2.28.0.tar.gz

# 移動 
cd git-2.28.0

# インストール
make prefix=/usr/local all
make prefix=/usr/local install
```

- バージョン確認

```sh
# バージョン確認
$ git --version
git version 2.28.0
```
システムの稼働率

応用情報技術者平成30年春期 午前問16


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/d57da941-b476-a8a7-797c-a763ba5d1517.png)

１、稼働率
・直列
　Ra　×　Rb

・並列
　１－（１－Ra)　×　（１－Rb)

２、当該問には、下記のように変形すれば、分かりやすくなりますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/ca7ac00d-34ac-03bf-b737-b99ee6ffebbb.png)

こういう変形できる理由としては、
１、APサーバのいずれか稼働できる場合、システムは稼働できるので、両APサーバは並列ですね。
２、APサーバ両方が稼働できない場合、システムは稼働できないので、両APサーバとDBサーバの間は、直列ですね。

DBサーバも同じ理由です。

計算すると：
　1－(1－0.8)2　＝1－0.04＝0.96
　0.96×0.96＝0.9216≒0.92


参照：

https://qiita.com/lymansouka2017/items/8001aacd4af86e483613

https://www.ap-siken.com/kakomon/30_haru/q16.html
Dialogflowで使用したプロジェクトの削除方法

# 問題点
Dialogflowで使用したプロジェクトが削除できない。シャットダウンしようとすると、以下のエラーが出て、Dialogflowにリンクされるものの、該当プロジェクトのDialogflowのAgentは既に削除済。

# Google Cloud consoleのエラー
>プロジェクト「xxxxxxxxxxx」を削除できません
>プロジェクト「xxxxxxxxxxx」には、誤って削除されるのを防ぐために 1 つ以上リーエンが含まれています。プロジェクトを削除するには、リーエンを削除してから、もう一度お試しください。 詳細
>
>リーエンの原点
>You cannot delete this project because it is linked with a Dialogflow agent. >Please follow the link to Dialogflow and delete the agent: >https://console.dialogflow.com/api-client/#/agent/xxxxxxxxxxx
>
>説明
>Deletion blocked by Dialogflow. リーエンを削除 

# リンク先のDialogfliowのエラー
>- Agent not found.
>- IAM permission 'dialogflow.agents.get' on 'projects/xxxxxxxxxxx' denied.

# 解決策
プロジェクトに適用されているリーエンを一覧表示する。

```
gcloud alpha resource-manager liens list
```

リーエンをプロジェクトから削除する。

```
gcloud alpha resource-manager liens delete xxxxxx
```

もう一度、Google Cloud consoleでシャットダウンを実施すると、無事削除（1ヵ月後に削除）になった。

# 参考
- [リーエンによるプロジェクトの偶発的削除からの保護](https://cloud.google.com/resource-manager/docs/project-liens?hl=ja)
【WordPress】Google Map 埋め込みで発生するエラー【改修作業】

#【経緯】
保守・改修を行っているウェブサイトで、以前は表示されていた Google Map の埋め込みにエラーが起きていました。

経験がなくゼロから色々と調べた所、[「ACF」](https://www.advancedcustomfields.com/resources/google-map/"「ACF」")というプラグインを使って実装されている事や、過去に Google 側の手違い（修正済み）があった事、仕様変更で API の利用が有料化された事などが分かりました。

丁寧に ACF やファイルのコードを確認した所、（APIを使わずに無料で）**「iframe」**タグを使った共有機能を応用していた事が分かりました。

#【結果】

以下の記事を参考にさせて頂き、**地図を埋め込むリンクのURLを修正**した所、正常に表示されました。

[***Google Mapをiframeで利用する際のオプションとレスポンシブ対応させるためのHTMLとCSSを紹介（住所指定で表示もできるよ！）***](https://olein-design.com/blog/google-map-iframe-for-responsive)

エラーは、元々のURLが**「http~」**になっていた事が原因だと思われます。最近ウェブサイトの URL を **「TSL/SSL 対応」**で、**「https〜」**に変更した事が影響していたかも知れません。

また、作業の過程で、**php で住所データを呼び込む為の（<?php the_field('xxxxxxx', $yyyyyy->ID); ?>のような）コードが誤っていた**ようで、確認に苦戦しました。WordPressの管理画面から分かりにくい所もあるので、いずれ、作業しやすい開発環境を用意したいと思いました。
#3 AWSのEC2インスタンス(ubuntu18.04)でPython(Django)環境を構築する part2

#はじめに
私はプログラミング言語の初学者です。
その為、読み間違いや理解不足の部分があると思います。
その場合はコメントで教えて頂けると幸いです。

「ゴール」は事前に作成したPythonのwebアプリケーションをデプロイする所まで行きたいと思います。出来るだけ初学者向けに書くつもりです。

作成手順

* AWSのEC2でインスタンスを構築後に、SSH通信をする　
* 構築したインスタンスの中にPythonの環境を構築する
* インスタンスの中に仮想環境を構築し、Django等をインストール（フレームワーク）　←**現在はここです。**
* PostgreSQLを設定する（データベース）
* インターネット上にアプリケーションが接続出来るように設定する（デプロイ前半）
* NginxとGunicornの設定する（デプロイ後半）

##仮想環境を構築し、Djangoをインストールします。

* Django等をインストールします。
* Git Hubからファイルをクローンします。

###ステップ１（インストール編）

```
pip3をアップデート
$ sudo -H pip3 install --upgrade pip

pip3でvirtualenvをインストール
$ sudo -H pip3 install virtualenv

apt-getでgitをインストール
$ sudo apt-get install git
$ git --version
```

###ステップ２（仮想環境を構築して、Django等をインストール）

```
仮想環境を作成する’仮想環境名’はなんでもいい、決まってないならpython3にでもするべし
$ virtualenv ’仮想環境名’

仮想環境をアクティベートする
$ source ’仮想環境名’/bin/activate

#仮想環境がアクティベートされると、仮想環境の名前がプロンプト($や#のマーク)の左側に表示されます。
(’仮想環境名’) $ 
例.仮想環境名をpython3にした場合
python3$ 
```

###ステップ３（仮想環境内でインストールして行きます。）
前提として感想環境名は（python３）にしていたとして進めて行きます。

```
諸々インストールします
(python3) $ pip install django gunicorn psycopg2 psycopg2-binary Pillow
```
###ステップ４（git hubにプッシュしてあるアプリをクローンします。）

```
鍵を入れるフォルダに移動
$cd ~/.ssh

鍵を生成(全部気にせずEnterして、進んでください）
すると、id_rsaとid_rsa.pubの2つの鍵が生成されます。
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/(username)/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:

lsコマンドでid_rsa id_rsa.pub が出来てるのが確認
$ ls

catコマンドでid_rsa.pubの中身のものを全てコピー
$ cat id_rsa.pub
```
次にこのURLに飛びます。
https://github.com/settings/ssh
バージョンによって表示は違うが2020/8/28時点では、New SSH keyというボタンがあるので、クリックする
Titleは被らないものを入力（なんでもいいかも）
先ほどコピーしたものをkeyの中にペーストする。
そしてもう一度ターミナルに戻ります。

```
接続を確認する。
$ ssh -T git@github.com
Hi ‘git hubのuser name’! You've successfully authenticated, but GitHub does not provide shell access.
この返しが来たら、接続成功
```

git hubのサイトのクローンしたいリポジトリに移動します。
↓code▼みたいなボタンがあるので（多分）これをクリック
use sshをクリックして、urlをコピーする
ターミナルに移動します。

```
$ git clone “コピーしたurl”
```

これでアプリケーションをクローンできたと思います。

次回はアプリケーションとPostgreSQLを連携して行きます。
シンクライアント、リッチクライアント、ファットクライアント端末

応用情報技術者平成30年春期 午前問13

PCをシンクライアント端末として利用する際の特徴として，適切なものはどれか。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/4902d2a0-11bc-3461-da34-6c032c85dc1c.png)

１、シンクライアントは、ユーザが使用する端末にデータやアプリケーションを持たせず、サーバに接続するための必要最小限のネットワーク機能や入出力用のGUIだけを装備させ、サーバ側で必要なデータ処理をするものを指します。シン（Thin）とは「薄い、少ない」の意味です。

シンクライアントシステムには、リモートアクセス型、ネットワーク型、画面転送型など様々な方式がありますが、いずれも端末にデータやアプリケーションを持たせないため、情報漏えいに対するセキュリティ対策になるほか、ファイルのバックアップ、OSやアプリケーションプログラムのアップデート（セキュリティホール対策版への更新）、ウィルススキャン、暗号化など、日常の運用をサーバ側で集中管理できる利点があります。

２、リッチクライアントとは、
クライアント環境の中で、アプリケーションの実行環境のみを搭載したものです。

リッチクライアントは従来の「ファットクライアント」と、アプリケーションをWeb化してクライアントにWebブラウザを持つ「Webクライアント」の中間に位置するクライアントです。リッチクライアントでは、必要に応じてアプリケーションをダウンロードして使用するため、クライアントにかかる負担が少なく、導入に手間がかからない特徴があります。


３、ファットクライアントは
クライアントで実行する状態や環境を全てクライアント側で備えたものであり、一般的な「パソコン」や「クライアント」のことです。「シンクライアント」という仕組みが登場したことにより、区別するために、「Thin」の対義語である「Fat」を用いて使われます。

ファットクライアントは、クライアントで実行する環境を全て備えているため、機能が充実しています。ブラウザやオフィスツール、メールなど、さまざまなアプリや機能を実装しているため、端末の価格は高価になる特徴があります。


参照：
https://www.ap-siken.com/kakomon/30_haru/q13.html

シンクライアントの種類
https://it-trend.jp/thin_client/article/type#chapter-2
【Rails】フォームのエラーメッセージを非同期で表示する

`form_with`を`local: true`なしで使っても、通常エラーメッセージ部分は非同期処理になりません。
非同期で表示してみたので方法をまとめます。

## FormのView
`form_with`に`local: true`を付けないと、非同期で通信が行われます。

```erb:app/views/tests/new.html.erb
<%= form_with model: @test do |f| %>      
  <%= f.text_field :name %>
  <%= render 'shared/err_msg' %>
  <%= f.submit %>
<% end %>
```
```erb:app/views/shared/err_msg.html.erb
<div id='err_container' style='display: none'>
  <ul id='err_ul'>
    <!-- ここにエラーメッセージが入る -->
  </ul>
</div>
```

## Controller
`@test.save`が失敗した時、普通なら`render :new`でnewアクション用のviewファイルを表示するところですが、ここでは`app/views/shared/err_msg.js.erb`に記述したJavaScriptを実行するようにしています。

```rb:app/controller/tests_controller.rb
def index
  @test = Test.new
end

def create
  @test = Test.new(test_params)
  respond_to do |format|
    if @test.save
      format.js { redirect_to tests_url, notice: '作成しました' }
    else
      @object  = @test
      format.js { render 'shared/error', status: :unprocessable_entity } # ブラウザにstatus_code 422を返す
    end
  end
end

private
def test_params
  params.require(:test).permit(:name)
end
```

## エラーメッセージを表示するjs
エラーメッセージ全体のスタイルを`display: none`→`display: block`に変更し、エラーメッセージを`li`でラップして表示しています。

```js:app/views/shared/err_msg.js.erb
let err_container = document.getElementById('err_container');
err_container.style.display = 'block';

let err_ul = document.getElementById('err_ul');
<% @object.errors.full_messages.each do |msg| %>
  err_ul.insertAdjacentHTML('afterbegin', '<li><%= msg %></li>');
<% end %>
```
forthでfizzbuzz

#概要

forthでfizzbuzzやってみた。

#forthの定義済みワード

|||
|:--|:--|
|.	|スタックトップを取り出し表示|
|emit	|スタックトップを取り出し文字表示|
|.s|デバッグプリント|
|cr	|改行表示|
|space	|空白表示|
|+	|スタックトップと２番の加算|
|-	|スタックトップと２番の減算|
|*	|スタックトップと２番の乗算|
|/	|スタックトップと２番の除算|
|mod	|スタックトップと２番の剰余|
|=	|スタックトップと２番の同値|
|<	|スタックトップと２番より小さい|
|>	|スタックトップと２番より大きい|
|max	|スタックトップと２番の最大|
|min	|スタックトップと２番の最小|
|dup	|スタックトップの複製|
|swap	|スタックトップと2番の交換|
|drop	|スタックトップの除去|
|over	|スタックの２番目の複製|
|rot	|スタックの上位３つを回転し，３番目をトップへ|
|and	|スタックトップと２番のBit AND|
|or	|スタックトップと２番のBit OR|
|invert	|スタックトップと２番のBit 反転|
|random |乱数（スタックトップ） |

#サンプルコード


```
: fizzbuzz 100 1 do i 3 mod 0 = i 5 mod 0 = or if i 3 mod 0 = if ." fizz" then i 5 mod 0 = if ." buzz" then else i . then cr loop ;
```

#成果物

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


以上。
ModalBottomSheetのChildでScrollableなViewを使う

`showModalBottomSheet`がお手軽便利だったのでメモ。

# ソースコード

```dart

showModalBottomSheet<void>(
  context: context,
  isScrollControlled: true,
  shape: RoundedRectangleBorder(
    borderRadius: BorderRadius.vertical(top: Radius.circular(16.0)),
  ),
  builder: (context) => DraggableScrollableSheet(
    expand: false,
    builder: (context, scrollController) {
      return ListView.builder(
        controller: scrollController,
        itemCount: 20,
        itemBuilder: (context, position) {
          return ListTile(title: Text('${position.toString()}'),);
        },
      );
    },
  ),
);
```

こんな感じのコードで、ModalBottomSheetを表示しつつスクロール可能な場合はスクロールさせつつ、スクロールがTopの場合はドラッグでBottomSheetが閉じていくUIを表現できる。

- `ModalBottomSheen.isScrollControlled = true`にする
- `DraggableScrollableSheet.expand = false`にする
- DraggableScrollableSheetのbuilderから渡される`scrollController`を、ScrollViewの`controller`に渡す

この辺りがポイント。
また、DraggableScrollableSheetの`initialChildSize`や`maxChildSize`、`minChildSize`の値を調整することでBottomSheetの位置を調整できる。

##### 余談

ちょっと残念な点として、このコードだといわゆるsnapping的な動きは表現できないので、maxChildSizeとminChildSizeの間みたいな中途半端な位置でも、BottomSheetがその高さで止まってしまい、どっちかに吸い付くみたいにはならない。

snappingな動作を表現したい場合は、素直に[sliding_up_panel](https://pub.dev/packages/sliding_up_panel)などのパッケージを使うか、DraggableScrollableNotificationを監視して頑張る([draggable_snappable](https://github.com/JediPixels/draggable_snappable))など、工夫する必要がある。
自分の場合は、手の込んだ変なパッケージ作ったりもした([scrollable_panel](https://github.com/renoinn/scrollable_panel))

「GoogleMapのみたいに動いてほしい！」みたいな要件が無い限りはModalBottomSheetで済ませて、どうしてもって時は各種パッケージを導入するのが楽そう。
mac で 踏み台経由のサーバーに FileZilla で接続

#やること
踏み台先のサーバーに FileZilla で接続する
・ターミナルからポートフォワード
・FileZilla で接続

#ターミナルからポートフォワード
```java:コマンド
ssh -L 接続先ポート（任意）:接続先IP:22(ssh のポート) ユーザー名@踏み台IP -p 踏み台ポート -i ~/.ssh/認証キー
```

#FileZilla で接続
FileZilla のメニュー `ファイル(F)` の サイトマネージャー を開いて設定します

![スクリーンショット 2020-08-31 18.41.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681491/ec203727-31eb-b828-1cc1-e63f00b6ce78.png)


![スクリーンショット 2020-08-31 18.43.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681491/780eaa1f-b619-7bad-acaf-7c64d737e8ce.png)

フォルダを作成して新しいサイトをそこに作成します。
プロトコル（T）:SFTP
ホスト：localhost
ポート：接続先ポート（ターミナルのコマンドで設定した番号）
ログオンタイプ：鍵ファイル
ユーザー：ユーザー名
鍵ファイル：認証キーのディレクトリ

これで設定完了
【Nuxt × Rails】CORSエラーによるプロキシ設定



フロント側から、Railsにユーザー情報をフォーム送信すると、こんなエラーが。

```console
Access to XMLHttpRequest at 'http://localhost:3000' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
```

通常、フロントもバックもドメインは同じURLだが、異なる場合もある。
そんな時発生するのが、`クロスドメイン通信を許可しない`というエラー。

そこで、プロキシ設定をNuxt側にもRails側にもすることで、CORSエラーを解消する必要がある。

[CORSについて](https://dev.classmethod.jp/articles/cors-cross-origin-resource-sharing-cross-domain/)は、リンクを参照にしていただければ。

#フロントエンド proxyの設定をする

バック側のローカルサーバは、`http://localhost:3000`とする。

```shell

$ yarn add @nuxtjs/proxy
```

```nuxt.config.js
  modules: [
    '@nuxtjs/proxy',
  ],
  proxy: {
    '/api': {
      target: 'http://localhost:3000',
      pathRewrite: {
        '^/api': '/api'
      }
    },
  },
```


#バックエンド CORSの設定をする

フロント側のローカルサーバは、`http://localhost:8080`とする。

```ruby:Gemfile
gem 'rack-cors'
```

```shell

$ bundle install
```

```config/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    # 許可するドメイン
    origins 'localhost:8080'
    # 許可するヘッダーとメソッド
    resource '*',
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end
```

#番外編　サーバ側で、セッション管理する時


```config/application.rb
config.api_only = false
```

APIモードを使っていたら、trueになっているので、要確認
gem FriendlyIdの紹介と注意点

##gem FriendlyIdについて
[FriendlyId Guide](https://norman.github.io/friendly_id/file.Guide.html)があるので一部抜粋したものを翻訳します。

> FriendlyIdはRubyのActive Recordのアドオンで、URLのidを文字列に置き換えることができます。

> **FriendlyIdを使用しない場合**
> http://example.com/states/4323454
> **with FriendlyId**
> http://example.com/states/washington
> 人間が読めるキーワードを使ってページを識別するURLの部分を作成します。
> これにより、ユーザーにとっても検索エンジンにとっても、アプリケーションをよりフレンドリーなものにすることができます。

gemの名前のFriendlyIdの由来はここから付けられたものだと言うことがわかりますね。

## 実装の例

弊社のサービスCarelyでも実際にfriendly_idを使用しているので紹介したいと思います。

```ruby
class Customer < ApplicationRecord
  include FriendlyId ---- ①

  friendly_id :uuid, use: :finders ---- ②
```

①modelで FriendlyId を使用するには、まず FriendlyId moduleをincludeする必要があります。

②これはuuidでactiverecordのfind methodを使えるようにする記述です。

```json
customer: {
  id: 10,
  uuid: "28d0d2b8-3f2c-49d0-bf11-3b01ec164311"
  firstName: "hogehoge",
  lastName: "fugafuga", 
  mailAddress: "hogehoge@example.com",
  age": "30"
  ・
  ・
  ・
}
```

上記のようなcsutomerのデータがあったとします。

本来findは主キー(id)しか対応していないため
`customer = Customer.find(10)`
のような記述になりますが、
`friendly_id :uuid, use: :finders`
を記述することで
`customer = Customer.find("28d0d2b8-3f2c-49d0-bf11-3b01ec164311")`
とuuidでもfind methodを使用することができます。
また、URLについても該当のcustomerの情報を表示する場合に
http://example.com/customer/10
となっていましたがFriendlyIdを使用することで
http://example.com/customer/28d0d2b8-3f2c-49d0-bf11-3b01ec164311
となります。
FriendlyIdを使うメリットではFriendlyId Guideに記載されているように
**FriendlyIdを使用しない場合**
http://example.com/states/4323454
**with FriendlyId**
http://example.com/states/washington
と名前をURLに含ませることで識別しやすくなる点もあるのですが弊社のようにuuidを使うことで何番目のデータだと推測できなくなり、テーブルのサイズを推測することもできなくなるというメリットもあります。

またsluggedという機能を使うとURLをフォーマットすることもできます。
FriendlyId Guideに記載されていた例では以下のようにtitleへスペース入りの文字列を入れた場合、本来はURLは`/posts/this%20is%20the%20first%20post` のようになっているはずですがSluggedを使用することで `/posts/this-is-the-first-post`と見やすくなります。

```ruby
# a migration
class CreatePosts < ActiveRecord::Migration
  def self.up
    create_table :posts do |t|
      t.string :title, :null => false
      t.string :slug, :null => false
      t.text :body
    end

    add_index :posts, :slug, :unique => true
  end

  def self.down
    drop_table :posts
  end
end

# model
class Post < ActiveRecord::Base
  extend FriendlyId
  friendly_id :title, :use => :slugged
end
```

```ruby
# Sluggedを使うことで整形され見やすくなる
@post = Post.create(:title => "This is the first post!)
@post.friendly_id # "this-is-the-first-post "を返します。
redirect_to @post # URLは/posts/this-is-the-first-postになります。
```

# 注意点
model内でFriendlyIdを使っているかどうかはちゃんと記述を見て判断しましょう。
大体のmodelでFriendlyIdを使ってるからこのmodelでも使ってるだろうという先入観で使うと???となる(なった)というお話です。

例えばcompanyというmodelではuuidというカラムがあるがFriendlyIdとして使っていなかった場合
`company = Company.find("16d28548-2e57-4e67-a041-1f05acfdabba")`
みたいに記述すると
`company = Company.find(16)`
の結果が表示されます。
これはfind methodが引数に文字列を渡した場合に`.to_i`で整数に変換しているからだと思われます。
エラーになればFriendlyIdを使っていないんだなと分かるのですが
データが返ってきたので正常に`uuid = "16d28548-2e57-4e67-a041-1f05acfdabba"`のデータが取れたのだと一瞬間違ってしまいますね。
form要素、input要素、textarea要素

#form要素
フォーム関連要素の集まりを表す要素のこと。

#input要素
フォームの入力欄や実行ボタンなど作成することができる要素のこと。
input要素にはtype属性という設定があり、それを指定することによって様々な種類のフォーム部品を作り出すことができる。


#textarea要素
複数行のテキスト入力欄を作成する要素のこと。

#text
1行のテキスト入力欄を作成

#textarea
複数行の入力欄を作成

#checkbox
チェックボックスを複数作成

#radio
複数の中から１つしか選択できない、ラジオボタンを作成

#submit
送信ボタンの作成