OmniAICreator/Qiita-1.07M huggingface dataset:
docker-composeで立ち上げて、nginxでリバースプロキシしてHTMLを書き換えてHello WorldをCrazy Worldにする

# はじめに
[VirtualBoxでUbunts上のnginxでリバースプロキシしてHTMLを書き換えてHello WorldをCrazy Worldにする](https://qiita.com/the1031hiroto/items/33a68f28e80f72c9091b)のDockerバージョンです。

ソースコードは Github に置いておきます。
[ソースコード](https://github.com/the1031hiroto/nginx)
# やったこと
nginxで立ち上げた[http://localhost:3000](http://localhost:3000)にnodeで立ち上げた[http://localhost:8080/](http://localhost:8080/)のHTMLを書き換えて表示させる
# node.jsの公式を参考にDockerでnodeを立ち上げ
cf.[Node.js Web アプリケーションを Docker 化する](https://nodejs.org/ja/docs/guides/nodejs-docker-webapp/)

```
.
├── Dockerfile
├── docker-compose.yml
├── conf.d
│   └── nodejs.conf
└── src
    ├── hello.html
    ├── node_modules
    ├── package-lock.json
    ├── package.json
    └── server.js
```

```Dockerfile:Dockerfile
FROM node
ADD  src/ /usr/src
WORKDIR /usr/src
RUN npm install
EXPOSE 8080
ENTRYPOINT ["npm","start"]
```
# とりあえずdocker-composeで立ち上げてみる
```docker-compose.yml
version: '3'
services:
  node:
    build: .
    ports:
      - "8080:8080"
```
## [http://localhost:8080/](http://localhost:8080/)
<img width="576" alt="スクリーンショット 2019-10-19 14.04.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268079/c3d35345-4ec3-eb2d-3a2d-3668217a2687.png">

# docker-composeにまとめる
```docker-compose.yml
version: '3'
services:
  node:
    image: node
    volumes:
      - ./src/:/src
    working_dir: /src
    ports:
      - "8080:8080"
    command: [sh, -c, npm install && npm start]
```
# とりあえずNginx立ち上げ
```docker-compose.yml
version: '3'
services:
  nginx:
    image: nginx
    # build: .
    ports:
      - "3000:80"
```
## [http://localhost:3000/](http://localhost:3000/)にアクセス
<img width="1055" alt="スクリーンショット 2019-10-19 14.04.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268079/7daaa6cc-2be1-606b-debb-2b765e553250.png">
# リバースプロキシ設定
## docker-compose.yml
/etc/nginx/conf.d 以下に設定ファイルを置くと読み込んでくれるのでマウントする
Nginxで設定するためにhostnameを指定する

```docker-compose.yml
version: '3'
services:
  nginx:
    image: nginx
    # build: .
    ports:
      - "3000:80"
    volumes:
      - "./conf.d/:/etc/nginx/conf.d"
    links:
      - node
  node:
    image: node
    # build: .
    volumes:
      - ./src/:/src
    working_dir: /src
    # Nginxで設定するためにhostnameを指定する
    hostname: node
    ports:
      - "8080:8080"
    command: [sh, -c, npm install && npm start]

```
## Nginx設定
sub_filter '置き換え元文字' "置き換え後文字" ;

```conf.d/nodejs.conf
server {
    listen 80;
    server_name _;
    client_max_body_size 10M;
    location / {
        sub_filter_once off;
        sub_filter 'Hello' 'Crazy' ;
        sub_filter '</head>' "<script>alert('Crazy World')</script></head>" ;
        sub_filter 'nginx' 'Crazy' ;
        # docker-compose.ymlで指定したhostnameを使う
        proxy_pass   http://node:8080;
    }
}
```
# 再び[http://localhost:3000/](http://localhost:3000/)にアクセス
"Hello World"が"Crazy World"に書き換えられて表示される
<img width="614" alt="スクリーンショット 2019-10-19 16.02.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268079/038d2d2b-dfc0-cc85-c552-4068d5d0915c.png">
仙台CTF 2017 [Lab03] タイムライン解析 100

#問題

http://ctf.sectanlab.jp/2017/challenges

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/e1134346-77fe-7edf-58ab-848329965f5f.png)

#解いてみた

問題をダウンロードすると、ddファイルでした。
問題文的にplasoを使ってタイムラインを見る流れなので、plasoを使ってみます。

初めて使います。
まずはイメージファイルを解析するために以下のコマンドを実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/5aa83e28-82c4-477d-5e88-46999d507ec1.png)

ちょっと待ちます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/a8fd2a20-6389-b67a-4b57-f9239fb921a3.png)

うまくいったようです。
これをやるとdiskimage.ddをdb.plasoに変換する処理を行っているようです。
db.plasoはplasoで読み込める形式です。

変換が終わったら、タイムラインを作ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/a6f6608b-1095-2cfd-73ab-c19aaf3f15ce.png)

ちょっと待ちます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/80bd9866-910a-e0bd-3f1e-9b7c644f50f8.png)

成功したようです。

問題文を見ると

```
どうやら、最初に実行されたダウンローダが、マルウェア本体をダウンロードし実行したことで、不審ホストとの通信が開始されたようです。
```

と書かれているので

1 何かのexeが実行
2 どこかに通信（exe？をダウンロード）
3 ダウンロードしたものを実行
4 不正通信先に通信開始

という流れだと思います。
上記を満たすようなところを見つければよいということになります。

と思ったらログの数が多すぎてどうにもならないので、ちょっと方針を変えます。
せめて時期が分かればログを減らせるんですが。

WEBSITEの通信ログに絞ってURLの最後が.exeになってるものを探してみましたが、なし。

通信のログだけ見てみると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/37ea8942-b574-f5c4-b6c8-e0195f027e57.png)

という怪し目な通信を確認することができました。ただほんとに怪しいかどうかは不明です。
エスパーでやるしかないので、ここでは不正な通信としておきます。

「giwiz-newstop.c.yimg.jp」の最初の通信が知りたいので検索します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/a6644c0d-160d-029c-0daa-e9700d4067d0.png)

最初は分かりましたが、その直前に何か実行されているわけではなかったので、不正ではなさそうです。

ちょっとラチがあかないので、普通にイメージを見た方が早そうです。
FTK Imagerを使ってimageを読み込みます。

デスクトップに請求書.exeがありましたが、これは問題文に書いてある通り、マルウェアだけどこの問題とは無関係。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/b7da0bb4-2eb6-4bf6-aff6-2dbd457ef898.png)

デスクトップにもう一つ怪しいフォルダがあるので中身を見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/81d4fac3-aad5-0ce7-d84a-344820e3d2f8.png)

タイムラインで検索していくつかヒットしましたが、なんだか判然としませんでした。
が答えに入れてみると正解でした。。。

これは不完全燃焼です。。。
Qiita開設

# ★Qiita開設★

## Qiita開設の目的
インプットばかりの日々とさよならするため、本ブログを開設することを決意。インプットした情報をまとめて、アウトプットしていきたいと思います。例えば↓

- 技術書のまとめ
- 自己啓発本のまとめ
- IT勉強会のまとめ
- 資格取得までの道のり

##参考
[Qiita Markdown 書き方 まとめ](https://qiita.com/shizuma/items/8616bbe3ebe8ab0b6ca1#%E5%8F%82%E8%80%83)
scalaで開発する環境を整える@AndroidStudio, Mac

めちゃめちゃ苦しんだ…
すでにできているリポジトリをクローンして開発環境を整えるまでのメモ

作業環境⬇︎
MacOS：Mojave 10.14.6（18G95）
android studio：3.0.1

#もろもろインストール
とりあえずandroid studioで該当のPJを開くとno scala sdkみたいなのが上部に出てるので指示通りに入れる。
PJではsbtを使ってたので、ローカルにもインストール

```
$ brew install sbt
Error: An exception occurred within a child process:
  CompilerSelectionError: sbt cannot be built with any available compilers.
Install GNU's GCC:
  brew install gcc
```

言われた通りgccをインストール

```
$ brew install gcc
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun

xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
Error: Xcode alone is not sufficient on Mojave.
Install the Command Line Tools:
  xcode-select --install
```
orz

https://qiita.com/ponsuke0531/items/10bca8aee7534bdefa1f
xcodeのコマンドラインツールがないとだめらしい。そういえばxcodeをzipからインストールしたのでそのときのインストール忘れ？
＞仕方ないので上記サイトの通りインストール
＞https://developer.apple.com/download/more/
の中の`Command_Line_Tools_macOS_10.14_for_Xcode_10.2.1`をDL。

```
$ xcode-select --install
```
を叩くと

```
xcode-select: error: command line tools are already installed, use "Software Update" to install updates
```
が出た。
もうインストールされてるとのことなのだけどどのタイミングで入ったんだろうか…
この後gcc > sbtの順で無事インストールできた

#アプリを実行するまで
https://dev.classmethod.jp/smartphone/scala-androi/
の通りコンソールからsbtを起動してみる

```
$ sbt
[info] Loading project definition from {PJルート}
[error] set ANDROID_HOME or run 'android update project -p {PJルート}'
Project loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore? q
```
起動に失敗してる。。

```
$ export ANDROID_HOME=/Users/hoge/android-sdks/
```
してみる
＞この状態でsbtを起動できた。さらに`android:package-debug`でapkを作成できた。
パスは`./bin/appname.apk`
＞これを`adb install`して実機で確認できた。
yamlに書いた条件でAnaconda仮想環境をつくる

複数マシンにpackageバージョンを合わせてインストールしていくのは結構面倒ですが、幸いなことにconda createコマンドはyamlファイルに条件を書いておいて、まとめてインストールすることが出来ます。

# yamlファイルからconda環境を作る

packageを探すchannel、condaでインストールするdependencies、pipでインストールするpackageをそれぞれ指定できます。

```yaml:hoge.yml
name: hoge
channels:
- anaconda
- pytorch
dependencies:
- python=3.6
- pytorch=0.4
- numpy
- scipy
- pip:
  - torchvision
  - dominate
  - visdom
  - Pillow==5.0.0
```

```terminal:terminal
conda env create -f hoge.yml
```
複数の環境それぞれに同じファイルを持って行けば簡単に同じ環境をつくれます。

# conda環境からyamlファイルを作る

逆に既に作ってあるconda環境をactivateしておいて、そこからyamlファイルを作ることもできます。

```terminal:terminal
conda env export > fuga.yml
```

レッツトライ！
Mixed Content Errorで悩まされたが、URLの記述が厳密にはおかしかった

## Mixed Content Error （混在コンテンツ）とは？

<details><summary>例：Mixed Content Error（押してね）</summary>Mixed Content: The page at 'https://googlesamples.github.io/web-fundamentals/fundamentals/security/prevent-mixed-content/xmlhttprequest-example.html' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://googlesamples.github.io/web-fundamentals/fundamentals/security/prevent-mixed-content/xmlhttprequest-data.js'. This request has been blocked; the content must be served over HTTPS.
</details>

簡単に言うと、ユーザがブラウザからhttpsでURLにアクセスしているが、ページ内部にhttpのリンクがありセキュリティ的によろしくないのでブラウザが警告やエラーを出すというものです（他にも例はあるかもしれません）。基本的にはhttpsで書き直してあげれば解決します。

以下、信頼できる情報です。
[混合コンテンツとは Web Fundamentals](https://developers.google.com/web/fundamentals/security/prevent-mixed-content/what-is-mixed-content?hl=ja
)
[混在（ミックス）コンテンツと CSP]
(https://rms.ne.jp/Introduction_to_https/mixed-content.html)

#### 二種類の混在コンテンツ
理解するために一つ重要なことは、混在コンテンツは二種類あるということです。

- 混合アクティブコンテンツ： JavaScript、CSS、object、XMLHttpRequest (XHR)、iframe、font
- 混合パッシブコンテンツ： img

混合アクティブコンテンツはHTTPSページ全体や一部の機能を書き換えることができるコンテンツで危険なものです。一般的なブラウザではエラーとしてブロックされます。パッシブ混合コンテンツは、HTTPSページ全体の機能を書き換えることはできないコンテンツで、前者よりは危険度が低いので警告が出るのが通例かと思います。ブラウザによって挙動が変わる可能性があるので確認してみてください。

また、実害はなかったとしても画面上のURL近くにも警告マークが出たりするので、ユーザに安心して使ってもらうためには解消するのがよろしいかと思います。

## エラーの原因は直接的なものではないかも

私の例では、ロードバランサ導入後に、それまで問題にならなかったMixed Content Errorが表面化することがありました。相対パス（プロトコルとホスト名などが省略）で書かれていました。Chrome Console で探ると、リクエストURLの末尾にスラッシュがついていたという凡ミスですが、Mixed Content エラーの内容とは直接は関係ないもので調査に少し時間をかけてしまったことがあります。

<b>Example1: リクエストURLの末尾にスラッシュが付いていた</b>

- bad:  `/api/from/js/to/laravel/server/`

- good: `/api/from/js/to/laravel/server`

<b>Example2: クエリパラメータの前に余計なスラッシュが付いていた</b>

- bad: `/api/from/js/to/laravel/server/?param=123`

- good: `/api/from/js/to/laravel/server?param=123` 

相対パスで原因不明のエラーに悩まれている方はURLを見直してみてください！


HTTPで絶対パスを記述している方は、置換などして直す必要があるかと思います。
参考：[みんなのウェディングのウェブサービスを完全HTTPS化した流れを紹介！](https://blog.mwed.info/posts/full-https.html)
#Rails + #rspec で Logger や標準出力を無効にする一番簡単なコード ( rails_helper )

- `rspec supress stdout` とかで標準出力を無効にする系の情報が山ほど出てくるが、どれもうまく効かない。
- binding.pry などでの標準出力も無効になったりしてしまう。
- rails helper の before each を設定するとうまく動いた。
- puts も p も Rails.logger.info とかも無効にしてくれる。
- rspec 的な before で標準出力をモックしているので、インスタンス変数を取り回すなど汚いコードで before after する必要がない。

```
RSpec.configure do |config|
  config.before(:each) do
    allow($stdout).to receive(:write)
  end
end
```

[How to Ignore Ruby Puts in RSpec Tests | The Ruby Railroad](https://rubyrailroad.com/2014/01/23/how-to-ignore-ruby-puts-in-rspec-tests/)

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2606








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools)...エラーの対処法

いつものようにgitにpushしようとしたら

```xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun```

という何やら意味不明なエラーが。
いつものコマンド打っただけなのに何で？と思い調べてみたらOSのアップデートが関係してるっぽい。
昨日MojaveからCatalinaにアップデートしたのでそれがどうやら原因のようだ。

https://qiita.com/nishina555/items/e23d73067a5cac182a63

上記記事を参考に

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

を実行。
これはMacのCommand Line Developer Toolsを手動でインストールするコマンド？
するとCommand Line Developer Toolsのアップデートが始まる。

アップデート終了後もう一度Gitのコマンドを打つと問題なく動作しました。
Catalinaにアップデート後にこのようなエラーが出たら参考にしてみてもらえると良いかと思います。
terraform module内でtemplatefile関数を実行した際に、ファイルが見つけられなくて困った

# バージョン

```
➤ terraform --version
Terraform v0.12.6
```

# ディレクトリ構成

```
.
└── ecs_task_definition
    ├── main.tf
    └── templates
        └── container_definitions.tpl.json
```

# リソース

```
resource "aws_ecs_task_definition" "default" {
  ~~ 省略 ~~
  
  templatefile("./templates/container_definitions.tpl.json", { hoge = "fuga" }
}
```

この時に no file exists になってしまう。

```
➤ terraform plan

Error: Error in function call

  on ./modules/ecs_task_definition/main.tf line 54, in resource "aws_ecs_task_definition" "default":
  54:   container_definitions    = templatefile("./templates/container_definitions.tpl.json", { hoge = fuga })

Call to function "templatefile" failed: no file exists at
templates/container_definitions.tpl.json.
```

# 解決法

相対パスではなく、 `path.module` を使うと解決した。

```
resource "aws_ecs_task_definition" "default" {
  ~~ 省略 ~~
  
  templatefile("${path.module}/templates/container_definitions.tpl.json", { hoge = "fuga" }
}
```

参考： https://www.terraform.io/docs/configuration/functions/templatefile.html

# 余談
軽くしか探していないが、path.moduleに関してのドキュメントは見つけられなかった。
terraform consoleで `path object` が存在することがわかるが、どういったattributeがあるのかはわからない。ソースコード読むべきだろうなあ

```
> path


> Error: Invalid "path" attribute

  on  line 0:
  (source code not available)

The "path" object does not have an attribute named "".


Error: Invalid reference

  on <console-input> line 1:
  (source code not available)

The "path" object cannot be accessed directly. Instead, access one of its
attributes.

```
WorkboxでCacheの更新を検知する為の設定等

#これは何？
ServiceWorkerをサクっと実装するのに使うのがWorkbox。ただ、Cacheが更新されたEventを受け取るためにはいくつかハマりポイントがあり、そのポイントを解決するのに必要な情報を雑にリスト化した記事です。
まとまりはありません＆そこまで参考にはならないかもしれません。

# この辺りを探ろう

## 手順はこれ
何はともあれ本家。実は「注意するように！！！」と明確に記載されてます。
<img width="662" alt="Screen Shot 2019-10-19 at 15.39.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61221/e7d800bd-62ff-639e-ef52-feda8fc54709.png">

[Workbox Broadcast Update  |  Google Developers](https://developers.google.com/web/tools/workbox/modules/workbox-broadcast-update)

(1) Requestに no-corsを追加

- [javascript - What limitations apply to opaque responses? - Stack Overflow](https://stackoverflow.com/questions/39109789/what-limitations-apply-to-opaque-responses)

(2) Serverから出すResponseにHeaderを追加
`Access-Control-Expose-Headers: X-Is-Cacheable`

- [workbox.cacheableResponse.Plugin · Issue #2051 · GoogleChrome/workbox · GitHub](https://github.com/GoogleChrome/workbox/issues/2051)


## アプリ側はこれらを参照するとよい
- [Workbox 4: Implementing refresh-to-update-version flow using the workbox-window module](https://medium.com/@webmaxru/workbox-4-implementing-refresh-to-update-version-flow-using-the-workbox-window-module-41284967e79c)
- [Workbox Broadcast Update  |  Google Developers](https://developers.google.com/web/tools/workbox/modules/workbox-broadcast-update)


## その他
「(1) Requestに no-corsを追加」は、行わなくてもOKだった。
MacでAnacondaを使ったPythonでNo module named 'fastprogress'が出たとき

#概要
Macでfastprogressを使いたいため、https://pypi.org/project/fastprogress/ にしたがって
`conda install -c fastai fastprogress `
をして
`import fastprogress`
としたら
`ModuleNotFoundError: No module named 'fastprogress'`
と出てしまい、少しハマりました。しかししばらくして解決できたので、解決した方法を共有します。

#原因
`conda list`
をしても、
`fastprogress 0.1.21 py_0 fastai`
という結果となっており、「おかしいな。。あるじゃん。。」と思っていました。

結局、Anacondaが2つ入っていて、installした場所とその後読み込んでいる場所が違ったのが原因でした。
なぜこれに気づいたかというと、ターミナルでPythonと打った場合とiPythonと打った場合で読み込んでいるAnacondaの保存場所が違うことに気づいたからです。まずPyhtonの方は、
```python
import numpy
numpy.__file__
```
としたら
`'/Users/kashi1mochi/anaconda3/lib/python3.6/site-packages/numpy/__init__.py'`
と出ます。一方、iPythonだと
```ipython
import numpy
numpy.__file__
```
とすると
`'/anaconda3/lib/python3.6/site-packages/numpy/__init__.py'`
と出ました。
なるほど。。違う場所にあるんだな。。

実際、
`cat ~/.bash_profile`
として確認すると、

`# added by Anaconda3 5.0.1 installer
export PATH="/anaconda3/bin:$PATH"`
`# added by Anaconda3 5.0.1 installer
export PATH="/Users/kashi1mochi/anaconda3/bin:$PATH"`
のように出てしまっています。

#解決策
今回はpython関係のモジュールを全てanacondaで管理することにしました。そのため、簡単に言うと、「全てanacondaでやりましょう」ということです。Dockerとか使えるのかもしれませんが、まだよく理解できていないので。
python、ipython、jupyterは /usr/local/bin を参照していて、でもanacondaでいろいろインストールしていて、、と、参照先がバラバラだと訳がわからなくなってしまいます。
この「全てanacondaでやる」というのは、ググってみてください。
とは言え一応少し参照先の確認方法などを書いておきます。

`which python`
`which ipython`
`which jupyter`
などとすると、
`/Users/kashi1mochi/anaconda3/bin/python`
のように、それぞれのライブラリがどこを参照先としているのかを簡単に確認できます。これで全てanacondaを参照していれば、「conda installしたのになぜかno moduleって出る。。」みたいなことはなくなります。
SQLについて

こんにちは。今日はSQLの基本についての記事を書いていきたいと思います。
#基本の四動作
##SELECT
SELECTは取得を意味します。何かのデータを取得したい場合は

```sql
SELECT *
FROM テーブル名
```

で取得できます。「*」はすべてのデータと言う意味です。

##INSERT INTO
これは何かの情報を追加したいときに使用します。

```sql
INSERT INTO テーブル名
VALUES (　　,  ,  ,  )
```

##UPDATE
UPDATEはもともとあるデータを変更（アップデート）したいときに使います。

```sql
UPDATE テーブル名
  SET カラム名 = 値, カラム名 = 値 
```

UPDATEとWHEREは併用可能。

##DELETE
DELETEはデータの中から何かを削除したいときに使います。
WHEREで条件指定しないと全部消えてしまうことがあるので注意が必要です。

```sql
DELETE FROM テーブル名
WHERE　条件
```



これらがSQLで使われる基本動作です。
これからSQLで大事だと思った項目をアップデートしていきたいと思います。
【Ruby on Rails】rails dbでよく使うコマンド


Ruby on Railsのデフォルト

SQLiteを起動

```ruby:コマンドライン
$ rails db
```
SQLiteを終了

```sql:コマンドライン
sqlite> .quit もしくは .q
```

テーブル一覧を確認

```sql:コマンドライン
sqlite> .tables
```

テーブルの構造（スキーマ）を確認

```sql:コマンドライン
sqlite> .schema テーブル名
```

テーブルの中身を確認する

```sql:コマンドライン
sqlite> select * from テーブル名;
```
ローカル開発環境からレンタルサーバーにデプロイまで

備忘録です。

ローカル開発環境からGitを使ってレンタルサーバーにデプロイする流れ


##大まかな流れ
- GitHubでリポジトリの作成
- ローカル開発環境で作成したファイルをGitHubに公開
- レンタルサーバー側でGitHubに公開したファイルを取得
- レンタルサーバー側のSQL設定

##githubにリモートリポジトリを作成する
1.まずはログイン
https://github.com/login
※アカウントを作成していない方はコチラ

![スクリーンショット 2019-10-19 9.58.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420746/6dbebf6d-99de-2100-cb8c-a6c21f6474af.png)

2.リポジトリを作成するために、NEWボタンを押す
![スクリーンショット 2019-10-19 10.00.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420746/0e0f48f9-f68d-e4f4-fb4c-29518da7b5f4.png)

3.リポジトリを作成する
![スクリーンショット 2019-10-19 10.01.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420746/efa7fe14-875b-d52b-99a6-16686072d85b.png)

4.リモートリポジトリのアドレスをコピー
![スクリーンショット 2019-10-19 10.03.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420746/1fc198b9-5e3b-c2e0-c959-95d03f1f9897.png)



## Gitの初期設定
1.まずはこれ

```command
$ git init
```

2.githubに作成したリモートリポジトリを登録する

```command
$ git remote add origin https://github.com/junichi-matsuo/schedule.git
```

2.githubに登録するファイルをインデックスする
 ※ -Aとすることで全てのファイルをインデックスする

```command
$ git add -A
```

3.インデックスしたファイルをローカルにコミット

```command
$ git commit -m "first comit"
```

4.github上に登録する

```command
$ git push origin master
```

5.リモートリポジトリのurlにアクセスし登録させていることを確認

![スクリーンショット 2019-10-19 10.21.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420746/9f730055-6378-dd7d-5875-9fa38adac2d4.png)

##レンタルサーバーの設定

1.ロリポップにログインhttps://lolipop.jp/

![スクリーンショット 2019-10-19 10.55.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420746/dae2b30e-11dd-1ad9-2b84-13a4d7904c3b.png)

2.SSHの設定
![スクリーンショット 2019-10-19 14.48.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420746/237edd6f-42a9-93a9-3f94-37cf5a8a0975.png)

![スクリーンショット 2019-10-19 14.58.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420746/a5b96334-94ae-dc76-51d6-2dc4bd4207d3.png)

![スクリーンショット 2019-10-19 14.58.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420746/6883ea19-aa71-cb7c-6f63-190741c4e2cc.png)

>ロリポップユーザーマニュアル参照
https://lolipop.jp/manual/user/ssh/



2.レンタルサーバーにコマンドラインで接続

```command
$ ssh お客様のSSHアカウント名@お客様のホスト名 -p 2222
```

3.フォルダを移動

```command
$ cd web
```

4.フォルダを作成する

```command
$ mkdir ファイル名
```

５.フォルダに移動

```command
$ cd ファイル名
```

５.gitの設定、リモートリポジトリの登録、リモートリポジトリよりデータを入手

```command
$ git init
$ git remote add origin https://github.com/junichi-matsuo/schedule.git
$ git pull origin master
```

##レンタルサーバーでのMySQL設定

1.

![スクリーンショット 2019-10-19 15.13.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420746/2533dfb0-e68e-f023-2ce6-f005f53c8767.png)

2.使用するデータベースの情報を確認
![スクリーンショット 2019-10-19 15.17.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420746/a08bb80b-97d5-407b-588e-0b8c90825cbd.png)

3.先ほど確認したデータベースの情報に書き換える

```php5:mysql.php
<?php

define("DB_DATABASE","データベース名");
define("DB_USERNAME","ユーザー名");
define("DB_PASSWORD","パスワード");
define("PDO_DSN","mysql:host=データベースホスト名;dbname=" . DB_DATABASE);

?>
```

とりあえず、終了
Firebase Performance Monitoringをデバッグ以外で導入する

# 概要
Firebase Performance Monitoring、存在は知っていたのですが、測っていないのですがコンパイル時に処理を差し込むので、ビルドに時間がかかりそうなので、あまり入れたくないというのがありました。 
具体的には `app:transformClassesWithFirebasePerformancePluginForDebug` という感じのタスクになってここで織り込まれるようです。
現在はFirebase Performance MonitoringにBuildTypeで無効にする機能があるので、デバッグ時では導入せずに、リリースでだけ入れることができます。

具体的には以下のページで書かれているとおりです。
https://firebase.google.com/docs/perf-mon/get-started-android?hl=en
https://firebase.google.com/docs/perf-mon/disable-sdk?hl=ja&platform=android

# Firebase Performance Monitoringのデバッグ

デバッグのビルドタイプ用のsrc/debugフォルダを作って、AndroidManifest.xmlを作って以下のように入れておきます。
これによって、デバッグ時にログを出すことができ、起動時間やセッションの名前などが表示されるようになります。

```xml
    <meta-data
      android:name="firebase_performance_logcat_enabled"
      android:value="true" />
```

# debug版でビルドが遅い問題を解決する

下記でビルド時にコードが埋め込まれなくなるため、ビルドが遅い問題を解決します。しかし、ネットワークのログと`@AddTrace`を使ったログ以外のログ、例えば、起動時間などのログが送られてしまいます。

app/build.gradle

```groovy
  buildTypes {
    debug {
      FirebasePerformance {
        // Set this flag to 'false' to disable @AddTrace annotation processing and
        // automatic HTTP/S network request monitoring
        // for a specific build variant at compile time.
        instrumentationEnabled false
      }
    }
  }
```

# debug版でデータが送られてしまうのを防ぐ

デバッグ時に同じパッケージ名でやっていると、LeakCanaryなどでデバッグ版アプリのパフォーマンスがかなり悪くなっている場合がるので、そもそもログを送らないということも可能です。
(課金のテストのためにパッケージ名をリリース版と揃えられるようにしている場合などに同じパッケージでデータが汚染されてしまうことを防ぐことが可能です。)

デバッグのビルドタイプ用のsrc/debugフォルダを作って、AndroidManifest.xmlを作って以下のように入れておきます。
これによりデバッグでは完全にFirebase Performance Monitoringのログが送られなくなります。

```xml
  <application>
    <meta-data
      android:name="firebase_performance_collection_enabled"
      android:value="false" />
  </application>
```

# 終わりに
このようなかゆいところに手が届くオプションが追加されており、Firebase Performance Monitoring自体は結構昔からあるもので、結構成熟してきている感じがあります。
pgAdmin4の日本語化

久々にPostgreSQLを使ってみたら、pgAdminがwebアプリになってました。以前はデスクトップアプリだったのに。

ここでは備忘録を兼ねて、日本語化の手順を書いておきます。

1. [File]から[Preferences]を選択
1. [Miscellaneous]の[User language]を選択
1. [User language]で[Japanese]に変更し、[Save]を押下
1. ブラウザをリロード

以上
SQLiteのジャーナルモードに関わる不具合

最近対応した不具合で勉強になったのでメモ

#不具合内容
ActiveAndroidからSQLiteを利用してるアプリのデータ引き継ぎで、dbファイルをやりとりしても正常に引き継がれなかった。

#原因
SQLiteのジャーナルモードがwalになっており、本体dbファイルが更新されていなかったため。

#ジャーナルモードとは？？
http://nave-kazu.hatenablog.com/entry/2015/12/18/140634
SQLiteのデータ更新時の挙動を変えるもの。
トランザクションを貼る=>コミットするまでのデータをどこに保持するかという話。

ジャーナルモードの例を下記に２点挙げる。だいたいこの二つのどっちかを使ってる印象がある。
https://sqlite-r.com/journal_mode
によれば他にもいろいろモードがあるので、状況に合わせて使い分けるべき

####delete（デフォルト）
コミットまでの変更をdbファイル名末尾に`-journal`がつく別ファイルをつくってそこに書き込む。
コミットされたら変更を本体dbファイルに反映して-journalの方を削除する。

####wal
トランザクション開始から終了までの更新内容を`-shm`ファイルに書き込み、コミットした時に`-wal`ファイルへ更新内容を書き込む。
よってdeleteモードと違い、<font color="Red">コミットした段階では本体dbは更新されない</font>。
本体が更新されるタイミングは下記の２通り

- コミット数が設定された定数を超えた場合
- 他にだれも接続していない状態でDBの接続を切った場合

#対応
ということでデータ引き継ぎの際本体dbファイルが更新されていないと、移行先でデータが合わないことになる。
解決策としては移行前に本体dbを更新させればよいので、dbファイルを送信する直前に

```
ActiveAndroid.dispose(); //一旦破棄すれば接続が切れてdbファイルに書き込まれる
```
を追加。その後initializeし直す
これで引き継ぎ成功した

#余談
要するに本体dbファイルを更新すればよいので、上記以外にもいい方法があるような気がする…
そもそも一度disposeしたらinitializeされることを絶対に保証する必要があるのでデバッグは慎重に行う。

それか、shmとwalもいっしょに移行してしまえばいいのだがそっちの方が面倒そう…
laravel 5.7 mysqlチューニング インデックスを貼る

サイト作成後に、テストデータをてんこ盛り入れてすぐにチューニングしてもいいんじゃないかと思う。あとでやろうとすると面倒なので。


>DBクエリ改善は地道な道。楽な道がない。

根気よくやっていきましょう。

use DB;を忘れずに。

```HogeController.php

use DB;

class HogeController extends Controller
{
    public static function test(request $request)
    {
        DB::enableQueryLog();//SQLログ記録開始
        $res = Contactsub::query()
            ->where('voice_flag',0)
            ->where('to_id',26112)
            ->orderBy('created_at', 'DESC')
            ->get();//全て取得
            
      dd(DB::getQueryLog());//SQLログを表示
        die;
    }


```



# 結果

```

[query] => select * from `contactsubs` where `voice_flag` = ? and `to_id` = ? order by `created_at` desc
[bindings] => Array
                (
                    [0] => 0
                    [1] => 26112
                )

[time] => 32.65
            
```

32.65 かかっていますね。
上記の query を EXPLAINをしてみます。

```

//        EXPLAINをつけた query , bindings の データ
$data = DB::select("EXPLAIN select * from `contactsubs` where `voice_flag` = ? and `to_id` = ? order by `created_at` desc",[0]);
dd($data);


```

# 結果


```

    [0] => stdClass Object
        (
            [id] => 1
            [select_type] => SIMPLE
            [table] => contactsubs
            [partitions] => 
            [type] => ALL
            [possible_keys] => 
            [key] => 
            [key_len] => 
            [ref] => 
            [rows] => 27240
            [filtered] => 1.0000001192093
            [Extra] => Using where; Using filesort
        )


```

・[key] が 空
・Extra に filesort がある

ということで、インデックスを貼ります。

今回は
・voice_flag
・to_id
・created

の 3つを使うので、複合インデックスを貼ります。

```

//インデックスを追加
DB::statement('ALTER TABLE contactsubs ADD INDEX voice_to_created(voice_flag,to_id,created_at)');


//インデックスを削除
//DB::statement('ALTER TABLE contactsubs DROP INDEX voice_to_created');

```

インデックス追加後に再度 EXPLAINを 実行。


```

    [0] => stdClass Object
        (
            [id] => 1
            [select_type] => SIMPLE
            [table] => contactsubs
            [partitions] => 
            [type] => ref
            [possible_keys] => voice_to_created
            [key] => voice_to_created
            [key_len] => 12
            [ref] => const,const
            [rows] => 16
            [filtered] => 100
            [Extra] => Using where
        )



```

お。key に voice_to_created が入りましたね。
では速度もチェック。

```

    [0] => Array
        (
            [query] => select * from `contactsubs` where `voice_flag` = ? and `to_id` = ? order by `created_at` desc
            [bindings] => Array
                (
                    [0] => 0
                    [1] => 26112
                )

            [time] => 17.84
        )


```

17.84 まで落ちましたね。

インデックスを貼るコツは、AとBをwhere して C で並び替える。という場合は、全てに複合インデックスを貼るってのがコツです。
Rails チュートリアル　第5章　まとめ

#全体像の把握
home等のstatic_pageのレイアウトを作成。bootstrapでデザインもつける。
headerとfooterのPartial化。
名前付きルートにルーティングを変更。
統合テストの実行。


```application.html.erb
<%= csrf_meta_tags %>　#csrfというクラッキングに対するセキュリティ
<%= stylesheet_link_tag    'application', media: 'all',
                               'data-turbolinks-track': 'reload' %>
#stylesheetを呼ぶ、media: "all"はハッシュのカッコなしでkeyがシンボルvalueが"all"
<%= javascript_include_tag 'application',
                               'data-turbolinks-track': 'reload' %>
```

header部分のレイアウト構造を作る

```
<%= link_to "sample app", '#', id: "logo" %> 
#第一引数には表示したい文字、第二引数にはリンク先、第三引数にオプション引数としてハッシュ
```

```home.html.erb
<%= link_to image_tag("rails.png", alt: "Rails logo"),
            'http://rubyonrails.org/' %>
#link_toの第一引数にimage_tag、第二引数にリンク先を、上のlink_tomと同じ構造
#rails.pngが参照する場所はapp/assets/images、ここに画像を置いておけば良い
```

bundle install をした時には、rails serverをもう一度立ち上げる
bundle installした内容が読み込ませるために

Bootstrap
cssを書き写すだけ
testでエラーになる場合、`gem 'autoprefixer-rails'`をGemfileに加える
それでもErrorなら、Cloud9の再起動
application.cssはグレー文字だが、これを消すとbootstrapが無効になるので注意
Errorでcustom.cssというファイルがなぜか生成されて画面に出現することがあるが、その場合、そのファイルを削除することで対応できる

Partial
目的
レイアウト構造を綺麗にしたい。情報を整理するために、ある場所にまとめて置きたい

例えば、header部分のpartialを作るなら、layoutsまでcdで行った後に

```
touch _header.html.erb #_から始める
```
そして、作った_heade.html.erbに元々の内容を書き写す
書き写したら、元々の内容を消してから以下のコードを書く


```application.html.erb
<%= render "layouts/header" %> # <header></header>をこの一行に書き換えた
```

疑問
renderでapp/viewsを書かなくていい理由

Asset Pipeline 
拡張言語を毎回コンパイルすることなくスムーズに使うための概念
複数のファイルに分けて開発したものをアセットパイプラインが機械が読みやすいように改行や空白をなくすなどして変換する。すると、速く読み込めるようになる

プリプロセッサエンジンが核
foobar.js.erb.coffee
の場合、coffeeが評価され、erbが評価され、それがjsに入る

--------
問題提起
URLを機能的にしたい、stattic_pages/aboutは長いので、/aboutに変えたい


```ruby:route.rb
get  '/help',    to: 'static_pages#help'
get  '/about',   to: 'static_pages#about'
get  '/contact', to: 'static_pages#contact'
```
GETリクエストが /help に送信されたときにStaticPagesコントローラーのhelpアクションを呼び出す
このように変えると、名前付きルート(help_path)が使えるようになる
テスト内容を、help_pathとすると、/helpにgetリクエストを送るという意味になる

ターミナルで固まった時、`control + c`

統合テスト
リンクが正しく動いているか、ブラウザを立ち上げてからの動作をチェックする
`rails g integration_test --`で作成
`rails generate integration_test site_layout`



```ruby:
 test "layout links" do
    get root_path #urlにリクエストを送る
    assert_template 'static_pages/home' #Homeページが正しいビューを表示するか確かめる
    assert_select "a[href=?]", root_path, count: 2 
#<a href="/">...</a>　 = root_pathかどうかチェック、?がroot_pathに置きかわる（第3章）
#転じてroot_pathが二つあるかという意味になる
    assert_select "a[href=?]", help_path
    assert_select "a[href=?]", about_path
    assert_select "a[href=?]", contact_path
  end
```

以上でStaticpagesコントローラの作成が終了

Userコントローラの作成
newアクション -新規登録
Homeからのリンクだけ作った
apt install curl で FATAL -> Failed to fork

GKEをいじっていてとあるdockerコンテナからcurlを叩きたかったのでsshログインしてapt installしたところ`FATAL -> Failed to fork`と言われた。

```bash
root@container-name-8df5b4f7-chmsm:/# apt install curl -y
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
  krb5-locales libcurl3 libgmp10 libgnutls30 libgssapi-krb5-2 libhogweed4 libidn2-0 libk5crypto3 libkeyutils1 libkrb5-3 libkrb5support0 libldap-2.4-2
  libldap-common libnghttp2-14 libp11-kit0 libpsl5 librtmp1 libsasl2-2 libsasl2-modules libsasl2-modules-db libssh2-1 libssl1.0.2 libtasn1-6 libunistring0
  publicsuffix
Suggested packages:
  gnutls-bin krb5-doc krb5-user libsasl2-modules-gssapi-mit | libsasl2-modules-gssapi-heimdal libsasl2-modules-ldap libsasl2-modules-otp
  libsasl2-modules-sql
The following NEW packages will be installed:
  curl krb5-locales libcurl3 libgmp10 libgnutls30 libgssapi-krb5-2 libhogweed4 libidn2-0 libk5crypto3 libkeyutils1 libkrb5-3 libkrb5support0 libldap-2.4-2
  libldap-common libnghttp2-14 libp11-kit0 libpsl5 librtmp1 libsasl2-2 libsasl2-modules libsasl2-modules-db libssh2-1 libssl1.0.2 libtasn1-6 libunistring0
  publicsuffix
0 upgraded, 26 newly installed, 0 to remove and 8 not upgraded.
Need to get 5373 kB of archives.
After this operation, 14.4 MB of additional disk space will be used.
0% [Waiting for headers] [Waiting for headers]FATAL -> Failed to fork.
```

原因はメモリ不足の模様。

特に要件を決めてなかったので`memory: 50Mi`と仮で入れておりとりあえず`200Mi`くらいにあげると無事インストールできた。
【Unity】PUN2でキック実装

#はじめに
キック機能について書いてあるところが少ない気がしたので。
まあ簡単すぎて書くほどのことでもないと判断されているのかもしれないし、私が情弱なだけかもしれないですが。
メモとして残します。
ちなみにキックとは、オンラインゲームでプレイヤーをルームから追い出す機能です。

###作業環境

Unity2019.1.8f1
PUN2.13

##対象プレイヤーをキックする
```C#:kick.cs
PhotonNetwork.CloseConnection(Player kickPlayer);
```
PhotonNetwork.CloseConnection関数の引数に、キックしたいプレイヤーを渡すだけです。
ただし、**MasterClientのみが使用可能**であることに注意。

##自分がキックされたことを知る
キックされたことを知る関数があるかどうかは、正直調べがついてないです。
ご存知の方が居ましたら教えてください。
というわけで、私はコールバック関数**OnLeftRoom()**にて、退室した際に通知を受け取ることで対処しています。
ただし、自分で退室したのか、ホストにキックされたのかはわからないので、自力でフラグ管理することで判断しました。

```C#:PhotonNetworkManager.cs
public class PhotonNetworkManager : MonoBehaviourPunCallbacks
{
	//
	//～接続処理とか。
	//

	//部屋から退室した時
	public override void OnLeftRoom()
	{
		if(PushBackKey)	//退室ボタンを押して自分で退室した
		{
			Debug.Log("退室しました。");
		}
		else
		{
			Debug.Log("キックされました。");	//退室ボタンを押していないが退室した→つまりキックされた
		}
	}
}
```
これで事足りるから準備されてない感じだったりするんですかね？

####参考
[【Unity】僕もPhotonを使いたい #05 ルームからの流れ]
(https://www.urablog.xyz/entry/2016/09/17/234255#ルームにいる状態からの流れ)
[【Unity】2. Photonに接続してロビーに入る【PUN2】]
(https://gamefbb.com/%e3%80%90unity%e3%80%91photon%e3%81%ab%e6%8e%a5%e7%b6%9a%e3%81%97%e3%81%a6%e3%83%ad%e3%83%93%e3%83%bc%e3%81%ab%e5%85%a5%e3%82%8b%e3%80%90pun2%e3%80%91/)

#最後に
いざ書いてみたら、たしかに書くことが少なかったですね。
でもメモしてないと後々また探しそうなので・・・。
AtCoder Regular Contest 080 young maids(segment tree)

# young maids(segment tree)

https://atcoder.jp/contests/arc080/tasks/arc080_c
セグメント木のライブラリ用に。

```python
from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
import math
import bisect
import random
from itertools import permutations, accumulate, combinations, product
import sys
from pprint import pprint
from copy import deepcopy
import string
from bisect import bisect_left, bisect_right
from math import factorial, ceil, floor
from operator import mul
from functools import reduce
from pprint import pprint


sys.setrecursionlimit(2147483647)
INF = 1 << 32
def LI(): return list(map(int, sys.stdin.buffer.readline().split()))
def I(): return int(sys.stdin.buffer.readline())
def LS(): return sys.stdin.buffer.readline().rstrip().decode('utf-8').split()
def S(): return sys.stdin.buffer.readline().rstrip().decode('utf-8')
def IR(n): return [I() for i in range(n)]
def LIR(n): return [LI() for i in range(n)]
def SR(n): return [S() for i in range(n)]
def LSR(n): return [LS() for i in range(n)]
def SRL(n): return [list(S()) for i in range(n)]
def MSRL(n): return [[int(j) for j in list(S())] for i in range(n)]
mod = 1000000007


class Segtree:
    def __init__(self, A, ide_ele, segfunc, initialize=True):
        self.n = len(A)
        self.size = 2 ** (self.n - 1).bit_length()
        self.ide_ele = ide_ele
        self.segfunc = segfunc
        if initialize:
            self.data = [ide_ele] * self.size + A + [ide_ele] * (self.size - self.n)
            for i in range(self.size - 1, 0, -1):
                self.data[i] = self.segfunc(self.data[2 * i], self.data[2 * i + 1])
        else:
            self.data = [ide_ele] * (2 * self.size)

    def update(self, k, x):
        k += self.size
        self.data[k] = x
        while k:
            k = k >> 1
            self.data[k] = self.segfunc(self.data[2 * k], self.data[2 * k + 1])

    def query(self, l, r):
        L, R = l + self.size, r + self.size
        s = self.ide_ele
        while L < R:
            if R & 1:
                R -= 1
                s = self.segfunc(s, self.data[R])
            if L & 1:
                s = self.segfunc(s, self.data[L])
                L += 1
            L >>= 1
            R >>= 1
        return s

n = I()
P = LI()
D = {P[i]: i for i in range(n)}
p_even = [P[i] if not i & 1 else INF for i in range(n)]
p_odd = [P[i] if i & 1 else INF for i in range(n)]
st_even = Segtree(p_even, INF, min)
st_odd = Segtree(p_odd, INF, min)
hq = [(st_even.query(0, n), 0, n)]
ans = []
for _ in range(n // 2):
    v1, l, r = heappop(hq)
    p1 = D[v1]
    if not l & 1:
        st1, st2 = st_odd, st_even
    else:
        st1, st2 = st_even, st_odd
    v2 = st1.query(p1, r)
    p2 = D[v2]
    st2.update(p1, INF)
    st1.update(p2, INF)
    if l != p1:
        heappush(hq, (st2.query(l, p1), l, p1))
    if p1 + 1 != p2:
        heappush(hq, (st1.query(p1 + 1, p2), p1 + 1, p2))
    if p2 + 1 != r:
        heappush(hq, (st2.query(p2 + 1, r), p2 + 1, r))
    ans += [v1, v2]


print(*ans)

```
どういう訳だか、INFを2 ** 32とかにするより、1 << 32とかにする方がだいぶ速くなる。理由はわからない。
自分的に上手くいった仕事の仕方

こんにちは、ぽんぽこです。

本日はいつもと違ったテーマで自分の仕事の仕方について話したいと思います。

最近、効率よく正確に仕事をこなしたい欲が高まっており、
色々試して自分的に一番よかった仕事の仕方を紹介したいと思います。

##出社してまず何してる？
出社したらメールの確認だったり、コーヒーを飲んだり人によって様々だと思います。

自分はまずその日のタスクの確認と終わらせる目標時間を設定しています。

なぜそんなことをするのかと言いますと、

タスクの確認をしなければだらだらと目の前の仕事をするだけになり、

突然、仕事を依頼された場合の対応に困るからです。

併せて、目標時間内で仕事が終わると達成感もありモチベーションを高く維持することが可能です。

##仕事の優先順位を考える。

先ほどの話に共通するものがありますがタスクの確認を行う際に

優先順位をつけるとより効率的にそしてうっかりして忘れてました。みたいなことが無くなります。

優先順位が分かっているだけでも上司やその他関係者からの評価が上がるのでは？

##自分の状況を伝えた上で仕事をもらう

これは仕事を貰う上で非常に大切だと思っております。

というのも優先順位が高い仕事ばかりもってしますと自分が大変だからです（笑）

事前に自分の現状を伝えておくと後からガミガミ注意を受けることを避けれます。


##最後に

自分が若いので少しずつ成長していきたいと思います。

もしかするとみなさん実践されているかもしれませんがこうするともっといいんじゃないか？など

あれば教えてください！

自分はこれらを実践して効率よく仕事を終わらせています。

まだ実践できていない人は実践してみては？
WinSCPでエラーコード4になった

# あらすじ
はじめてのwindows環境、はじめてのWinSCPたらいうツールでファイルをコピー中にいきなりエラーに直面しちゃいました。

# error code 4 is 何
[SFTP Status/Error Codes - Code 4 (Failure)](https://winscp.net/eng/docs/sftp_codes#code_4)

> In this case the server is required to provide meaningful description of the error itself (see above). Unfortunately, OpenSSH SFTP server uses always description “Failure”. Is such case, there is unfortunately no way to tell a reason of the failure. 

環境とかなんやかんやで原因は多岐に渡るみたいで特定は困難みたいです。代表的なもので以下のようなことが考えられるっぽい

>   - Renaming a file to a name of already existing file.
  - Creating a directory that already exists.
  - Moving a remote file to a different filesystem (HDD).
  - Uploading a file to a full filesystem (HDD).
  - Exceeding a user disk quota.


# my case
自分の場合は上記の最後にある、ディスククォータの上限を越えたことが原因だったようです。

適当に作ったCentOS7で雑にrootで作業していて発生したのですが、自動ディスクパーティションで`root`に割り振られたぶんがデフォルトの50GBだけになってました。これは`df`コマンドにて同定しました。

```
df -h
```

なるほどね。


# ぜんぶ/に割り当てる
勝手に作られていた`/home`に450GB割り振られていたのでこれを`/`にもっていきます[^1]。

以下の記事を参考にさせていただきました。以上。ありがとうございます。終了。

[CentOS7で/と/homeを別に作られたので対処する](https://fefcc.net/archives/195)


[^1]: 一応書いとくとrootでなんやかんやするのは非推奨ですが、なんかしらんけど今回アサインしたプロジェクトでそういうことになっていました
abc138 D問題がめちゃくちゃ勉強になった話(python用)

# abc138のD問題KIがよかったよって話
自分用：dfs、再帰、入力でreもしくはTLE吐いたらここに来るのです

とりあえずソースコード

```python:ki.py
import sys
sys.setrecursionlimit(10 ** 6)
import sys
def input():
    return sys.stdin.readline()[:-1]
N , Q = map(int,input().split())
graph = [[] for _ in range(N)]
point = [0] * N
for _ in range(N - 1):
    a , b = map(int,input().split())
    graph[a - 1].append(b - 1)
    graph[b - 1].append(a - 1)
#print(graph)
for _ in range(Q):
    a , b = map(int,input().split())
    a = a - 1
    point[a] += b
# dfsを用いて累積和を計算する
# 初期状態だと前の値がないためデフォルト引数に-1を代入
def dfs(now , prev = -1):
    for next in graph[now]:
        # 次のノードが前に参照した値の時はcontinue
        if next == prev:
            continue
        # 現在の値を次のポイントに加算することで累積和をとる
        point[next] += point[now]
        # 次のノードと現在のノードを引数にdfsを継続する
        dfs(next , now)

dfs(0)
print(*point)
```

## 何がよかったか
1. dfsの書き方を勉強できたこと
    2. デフォルト引数実際に使ったお
2. 配列の参照以外でreの原因探しができたこと
3. 入力の速度意外と大事だねってこと


## やったこと
1.dfsの書き方を勉強できたこと

使ってる人は分かっていると思うが累積和とdfsの複合問題を扱えたこと。
慣れてないうちはforと再帰のループの区別が大変そう


```

# dfsを用いて累積和を計算する
# 初期状態だと前の値がないためデフォルト引数に-1を代入
def dfs(now , prev = -1):
    for next in graph[now]:
        # 次のノードが前に参照した値の時はcontinue
        if next == prev:
            continue
        # 現在の値を次のポイントに加算することで累積和をとる
        point[next] += point[now]
        # 次のノードと現在のノードを引数にdfsを継続する
        dfs(next , now)

dfs(0)
```


2.配列の参照以外でreの原因探しができたこと

噂に聞いていたpythonにおける再帰限界の問題を完全に忘れていた。
実際のコンテストでこれ描き忘れてたら泣きそう


```
import sys
sys.setrecursionlimit(10 ** 6)
```

3.入力の速度意外と大事だねってこと

今回は入力が2 * 10 ** 5だったので入力自体でなかなか時間がかかってTLE吐いていた。
普段気にしてなかったけど10 ** 5くらいになったら意識的にimport sysしないとダメだね

```
import sys
def input():
    return sys.stdin.readline()[:-1]
```


# まとめ
dfsやれ
再帰上限考えろ
入力の速度をバカにできんよ
（困ったらここコピペしてえ）

# PS:こうやったらもっと早くなるよってことあったら教えてください（速さこそ正義）
Pythonを使用したGmailによるコンピューターのリモートコントロールシステム「Pymote PC on Gmail」の開発

#Pythonを使用したGmailによるコンピューターのリモートコントロールシステム「Pymote PC on Gmail」の開発
##概要

「Pymote PC on Gmail」では、Pythonを使用して、Gmailで受信したコマンドを実行します。
筆者は自分の部活の空き時間でこれを作りました。
##使用したもの
開発環境:windows10 home,Anaconda
使用ライブラリ:httplib2, base64,email,time,subprocess, apiclient, oauth2client,
使用した技術: Python, base64, Json, HTTP, Gmail, OAuth, APIs
###言葉の説明

Pythonとは
文法を単純化して、読みやすく、また書きやすくすることで作業性とコードの信頼性を高めることを重視してデザインされた高水準プログラミング言語です。インターネット上に様々なライブラリ(機能を拡張できるツール群)が用意されています。最近は人工知能の開発に用いられています。
 
Anacondaとは
Anaconda はデータサイエンス向けのPythonパッケージなどを提供する統合型開発環境です。（Python以外の言語のプログラミングも使用可能。）
 
httpとは
HTTP(Hyper Text Transfer Protocol)は、WWW(World Wide Web)上でWebサーバとクライアントが、 HTML(Hyper Text Markup Language)で書かれた文書などの情報をやりとりする時に使われる通信手順(プロトコル)を意味しています。

APIとは
APIとはソフトウェアやアプリケーションなどの一部を外部に向けて公開することにより、第三者が開発したソフトウェアと機能を共有できるようにしたものです。これが今回は中心です。

OAuthとは
OAuthとは、SNSやWebサービス間で「アクセス権限の認可」を行うためのプロトコルのことで、現在では2012年に発行されたOAuth 2.0が標準化されています。 

JSONとは
Json(JavaScript Object Notation)は、データフォーマットの一種です。

Base64とは
電子メールにおいて、バイナリーデータを送信するための規約であり、テキストデータにエンコードする方式の一つです。RFC 2045で定義されています。

Gmail APIとは
Gmail APIは、Gmailメールボックスへのアクセスとメールの送信に使用できるAPIです。 大部分のアプリケーションでは、Gmail APIは、ユーザーのGmailデータへの承認されたアクセスに最適といえます。
##仕組み
GmailのAPIと連携し、５秒ごとに最新のメールをプログラムで受信し、コマンドかそうでないかの条件分岐を行い、コマンドの場合はそれをコンピューター内で実行することによって、Gmailとプログラムを仲立ちにして、間接的にコンピューターを遠隔操作できるようにしました。


##やったこと
* GmailのAPIと連携する
 Google Developer ConsoleのAPI ManagerからGmail APIを有効にし、認証データclient_id.json をダウンロードします。
 その後、PythonからAPIと連携させ、client_id.jsonをもとに、credentials-gmail.jsonを生成し ます。これがGmailにアクセスする鍵です。
　　


* Gmailのサービスにアクセスし、メッセージを取得できるようにする。
 プログラムでAPIを使えるように設定をし、ユーザーのメッセージを取得します。
 メールの暗号化(base64)を解析し、本文を取得します。
　　
* コマンドかそうではないかの認識
本文を文字列にし、例えば、「cmd:」で本文が始まるならcmd:を取り除いたほかの部分をコマンドとしてコンピューター内で実行するようにします。

##改善が必要な点
* 一回届いたコマンドを新しいメールが届くまで何回も実行してしまう点
 * そのまま。
* 個人情報の保護
 * このプログラムが作動しているときは、cmd:という認識用の文字列(今はこれをパスワードとするしかない)とメールアドレスが第三者に知られてしまうと、コンピューター上で任意のコードを実行することができてしまうので、送信元のメールアドレスを取得し、そのアドレス以外からの実行は受け付けないようにしたいです。また、Googleアカウントに登録していないデバイスから来たコマンドについては実行はするものの、その詳細をGoogle アカウントに通知できるようにしたいと思います。
* 使いやすさの向上
 * 実行結果を返信で知らせることができるようにしたいです。また、GmailのAPIをさらに活用することによって、自動化できる処理を増やしたいです。
* 理想
 * パスワードで保護されたwebアプリをPythonで作成し、画面を作成して同じことができるようにしたいです。最終的には、他の言語も利用しながらそれをデスクトップアプリケーション化したいです。(Electron×Bottle.pyなど)


##参考文献
退屈なことはPythonにやらせよう　2017/6/3 Al Sweigart  (著), 相川 愛三 (翻訳)

Web API: The Good Parts　2014/11/21 水野 貴明  (著)

Electronではじめるアプリ開発 ~JavaScript/HTML/CSSでデスクトップアプリを作ろう　2017/3/28 野口 将人  (著), 倉見 洋輔 (著)

Web技術の基本　2017/3/16 小林 恭平  (著), 坂本 陽  (著), 佐々木 拓郎  (監修)
仙台CTF 2017 [Lab02] メモリフォレンジック 100

#問題

http://ctf.sectanlab.jp/2017/challenges

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/c9d566eb-0980-67fd-4f5e-d3717d08a87e.png)

#解いてみた

メモリファイルをダウンロードして、volatilityで解析します。
まずはimageinfoします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/e65b9edf-6895-1915-22ac-fcd53659b557.png)

先頭がWin7SP1x86_23418になってますが、問題文から2番目のWin7SP0x86が正しいと思われます。

connectionsかconnscanで通信見れるか確認したもののこのプロファイルには対応してませんでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/6027eba1-b129-2ca2-bf3e-e32bdee67c1b.png)

netscanをしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/fa3b7e90-9912-38e5-7254-22e74688b29d.png)

大量に出てきましたが、いずれにせよグローバルIPへの通信はありませんでした。
が、iexplore.exeが通信している相手が全部192.168.100.50であることを考えると、192.168.100.50はプロキシのようなものなんじゃないかなと思いました。

192.168.100.50に通信しているiexplore.exe以外のプロセスはservices.exeがあったのでこのpidを入力すると正解でした。
2019.10Ver[解決済/時系列] TWITTERアカウントが凍結された　ツイッターがアカウント停止されている場合

TWITTERのアカウントが凍結された時に対応を記載しました。Twitterは結構簡単にアカウントが凍結されますので凍結された方は参考にしてください。


#１ツイッターでツイートできない。　2019月10月19日
急いでいる方もいると思いますので時系列も記載します。2019月10月19日以下のようなメッセージが表示されてツイートできません。

![0001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140071/e2f7b4fe-6323-88d7-6a95-5f80a31df369.jpeg)

```
Your account is suspended and is not permitted to send Tweets.
```

![0001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140071/fe97420a-978e-035d-3b85-7f16934fa229.jpeg)


```
Your account is suspended and is not permitted to perform this action.Learn more
```

訳：アカウントは停止されましたのでツイート投稿は許可していません。

つまりTwitterアカウントが凍結されました。

#２ツイッターに異議申し立ての詳細を送る　同日

ここのフォームから異議申し立てを行いましょう。
https://help.twitter.com/forms/general?subtopic=suspended

Description of problem　の記入は以下を送りましょう。あなたのアカウント名には@abcやDERなどあなたのツイッターアカウントを記入して下さい。英語は通じれば何でもいいです。※設定が日本語の方は日本語でOK

Hi MY ACCOUNT NAME = __@あなたのアカウント名__ I've found my Twitter account, being suddenly suspended!!May I ask your favor could you unlock suspension if there are no problems.Thanks in advance.

私のツイッターアカウント名称は __@あなたのアカウント名__　です。ツイッターアカウントが突然凍結されてしまいました。お手数ですが、問題がなければアカウント凍結を解除する手順を教えてください。

#３　twitterにメールに返信する　同日

以下メールがツイッターから来ます。

```
Hello,

Thanks for your report. It looks like this is connected with your original case # 0123456789, so we’ve added it to that first report. We’ll continue our review with this information. If you have more details you think we should know, please respond to this email to send them our way. We appreciate your help! 

Thanks, 

Twitter
```

上記に記載してあるとおり、自分のメールで以下文面を再度返信します。

Hi MY ACCOUNT NAME = __@あなたのアカウント名__ I've found my Twitter account, being suddenly suspended!!May I ask your favor could you unlock suspension if there are no problems.Thanks in advance.

#４　twitterから解除通知が来ます　2019年10月20日

題名：We’ve unlocked your account 0123456789 [ ref:_000000000._504030201020030:ref ]

Hello,

We’re writing to let you know that your account is now unlocked. We’re sorry for the inconvenience.
 
A little background: We have systems that find and remove automated spam Twitter accounts, and it looks like yours was flagged as spam by mistake. This can happen if an account exhibits automated behavior in violation of our rules.

We apologize for the mixup, and hope to see back on Twitter soon. 

If you need to get in touch with us again, please file a report through your Twitter app or our forms page, as this account isn’t monitored for replies. 

Thanks,

Twitter

ずいぶん丁寧に謝罪してますがtwitterが凍結する理由は人それぞれですが今回は完全にこちら側に瑕疵がないケースです。なぜならこのアカウントは__一度もtweetしたことがないから__です。いずれにせよ早めの対応で楽しいtweetlifeを。以上です。
[Flutter] Firebase Dynamic Links を受信して捌く

## 起動中/未起動中に、Link を受信したら遷移する
[Firebase Dynamic Links](https://firebase.google.com/docs/dynamic-links?hl=en) の Deep Link を、どの Widget にいても捌く方法。
抜粋したものを雑に示すとこんな感じ。[navigatorKey](https://api.flutter.dev/flutter/material/MaterialApp/navigatorKey.html) が肝。

```sample_app.dart
final _navigatorKey = GlobalKey<NavigatorState>();

FirebaseDynamicLinks.instance.onLink(onSuccess: (PendingDynamicLinkData dynamicLink) async {
  await navigatePage(deepLink?.link);
});

Future<void> navigatePage(Uri deepLink) async {
  final routeName = 'foo' // 実際には、dynamicLink の情報から組み立てる
  await _navigatorKey.currentState.pushNamed(routeName);
}

runApp(
  child: MaterialApp(
    title: 'Sample Handling Firebase Dynamic Links',
    navigatorKey: _navigatorKey,
    home: Foo(),
  ),
);
```

```foo.dart
Future<void> hoge() async{
  // アプリが起動してない状態で Link を受信した場合に、ココでハンドリングしたいとする
  final data = await FirebaseDynamicLinks.instance.getInitialLink();
  await navigatePage(data?.link)
}
```

## ちなみに
カスタムドメインを使う場合、[iOS setup](https://firebase.google.com/docs/dynamic-links/custom-domains#manual) の最後の項目を忘れやすい気がするのでご注意。
macOS Catalina で zip の展開に失敗する


### 現象

2019/10/19 現在、macOS 10.15 Catalina で zip ファイル展開時に`（エラー22 引数が無効です。）` というエラーが表示され失敗する現象が発生する。

<img width="490" alt="スクリーンショット 2019-10-19 13.56.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45588/d0f09b41-e72f-8d5d-26f7-0c22885a1e23.png">

zipファイルが展開できなくなりました。 - Apple コミュニティ
https://discussionsjapan.apple.com/thread/250723091

上記などでも報告されており、端末依存ではなく Catalina のアーカイブユーティリティにバグがある模様。
macOS 上で圧縮された zip ファイルでは再現せず、サードパーティ製の App で圧縮されている場合に再現する。

### 解決策

Mac App Store で `Zip File Unarchiver` などサードパーティ製のアーカイブ App をダウンロードし利用する

<img width="1292" alt="スクリーンショット_2019-10-19_13_57_20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45588/debfabcb-d3ec-a5f3-2e65-1ad71e9eff43.png">
zip ファイルをドラック&ドロップし、エキスを選択する
<img width="972" alt="スクリーンショット_2019-10-19_14_13_24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45588/66cbe985-e673-e0aa-554e-4b38f91bb3c8.png">

bugfix までは暫定対応にはなりますが、これで解決することができます。
飽きないローディング画面とかログイン画面とか


クラウドのローディングって一般的にspinnerですけど、時にイラっとしません？なんか待たされてる感が強いんですよねー。一刻を争って焦ってる障害対応時以外でも、いっつも同じってのもな。単にパーセンテージが出てこないのに、くるくるしてるのが退屈なだけなのかもしれない。

<hr>

#### おさらい

この前の

[セコクラウドの立ち上げからいつの間にか見た事のない実装を社内ローンチしちゃった件](https://qiita.com/ykato/items/60a2e6bb1b7bce5b5644)

この謎クラウドでは[1041uuu](https://1041uuu.tumblr.com/)を使わせて頂いて

![anim.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189193/4b0627a5-8b63-8dac-82bf-8bd953dc0d9d.gif)

こんな感じにしました。ランダムでぼーっと見てて楽しいGIFを表示するようにしてます。少しでも待ちって感覚が無くなれば良いなと思って。こっちの方がUXとして楽しくないですか？
（絶対的主観に基づく・・CDN無くても早いローカルだから成り立つわけで。。）

#### ログイン画面

あとログオン画面。SIer標準ではTeraterm一択でMACぽいカラフルでオサレなターミナルは出しようもないので踏み台ログイン時に

[Ubuntuでコンソールに画像を表示するツール](https://qiita.com/f0o0o/items/ad25fe8e2d1603e209fe)

こちらの記事を参考にtimg入れて

```
timg -g60x30 googlelogo_color_272x92dp.png > /home/user/login.logo
```

こんな風に画像をテキストに変換しておきます。それを表示するプログラムをログイン時に出せば、完成！

```
package main

import (
    "os"
    "log"
    "io"
)

func main() {
  fh, err := os.Open("/home/user/login.logo")
  if err != nil {
    log.Fatal(err)
  }

  _, err = io.Copy(os.Stdout, fh)
  if err != nil {
    log.Fatal(err)
  }
}
```

こんなベタコードを.bash_profileに仕込んでで画像を出すようにしました。

![cons.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189193/b39c2187-37bd-f65d-d32d-cfc13d4ccd91.png)

golangなのでエスケープシーケンス画像を1ファイルに組み込みは出来るんですが、バッチ処理で画像差し替えて表示が変わって**お！？**と思えるように別ファイルに分けています。画像ファイルの差し替えでbuffer overflow食らいそうですが出来るか分かんなかったのでそのまま動かしています。笑

良いデザインでも、二度三度使ってくとデザインの良さに慣れて、レスポンスのスピードとか他の部分が気になってしまったりするのでこういう目先をズラすようなアプローチもアリな気がします！という話です
~~そもそも動くのがウザいという意見もありますが~~

ただ元コンテンツ>>>>>見交わしネタだと逆に怒られそうです。
この前フォートナイトがブラックホール化した時の裏技ミニゲームで気がまぎれたりはしなかったんじゃないだろうか・・