OmniAICreator/Qiita-1.07M huggingface dataset:
Expoのエラー「Invariant Violation: Tried to register two views with the same name RNCSafeAreaProvider」



React Native (Expo)のアプリを開発していたら急に以下のエラーがiOSのみで発生．どうにか解決できたのでその方法を残しておきます．

### 現象

- iOSのみで発生するエラー，起動時にクラッシュ

- Androidはなぜか動く

### エラー内容

#### Invariant Violation: Tried to register two views with the same name RNCSafeAreaProvider

```
invariant
    browser.js:38:14
exports.register
    ReactNativeViewConfigRegistry.js:86:11
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:141749:57
loadModuleImplementation
    require.js:321:11
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:141605:66
loadModuleImplementation
    require.js:321:11
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:141534:36
loadModuleImplementation
    require.js:321:11
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:141093:47
loadModuleImplementation
    require.js:321:11
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:141004:53
loadModuleImplementation
    require.js:321:11
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:140287:64
loadModuleImplementation
    require.js:321:11
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:133988:26
loadModuleImplementation
    require.js:321:11
<global>
    AppEntry.js:3
loadModuleImplementation
    require.js:321:11
guardedLoadModule
    require.js:201:44
global code
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:202577:3
```

## 解決

### 手段
- 普通に動作する部分までcommitを遡り，package-lock.jsonを比較

### 原因

- "react-native-safe-area-context"がv3.1.1でインストールされていた

- expoがv38.0.8のとき，react-native-safe-area-contextはv3.0.7に互換性がある．しかし，package.jsonで^3.0.7もしくは~3.0.7と指定していると，v3.1.1がインストールされてしまいエラーが発生していた．

### 解決方法

- packageをクリーンアップ

```sh
rm -rf node_modules package-loc.json
```

- バージョンを指定


package.json

```
"react-native-safe-area-context": "3.0.7"
```

### バージョン指定

- yarnを使っているならresolutionsで指定

- ちゃんとバージョンを指定したければ以下のサイトを参照

[package.json のチルダ(~) とキャレット(^) - Qiita](https://qiita.com/sotarok/items/4ebd4cfedab186355867適切な)
【position:relative, absolute】

今回はposition:relative, position:absoluteについてアウトプットしていきます。

position:relative, position:absoluteというのは特定の親要素の上に子要素を重ねて表示させたい時に使うcssのプロパティです。

今回はテキストフォームの中にアイコンを重ねる方法を説明していきます。


<img width="645" alt="position8.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/673286/84cb9812-2fdf-faa1-aa9b-1b3439a4505c.png">

上の画像はフォーム部分の記述なのですが、親要素が.Form__contentsで、その子要素として
テキスト入力欄とアイコンを配置しています。

cssにpositionを記述しないまま表示するとどうなるかというと

<img width="932" alt="position5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/673286/7a8fd541-be07-27c7-925b-251fcc423a86.png">

アイコンが右端に表示されてしまいます。

今回は右端に表示されているアイコンをテキスト欄の右端に重ねて表示させたいのでそのために
positionの設定をしていきます。


親要素である.Form__contentsの上にアイコンを重ねたいので基準となる.Form__contentsに以下のような記述をします。

<img width="310" alt="position6.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/673286/62562845-fc8f-0ce0-5700-203da50e8b2a.png">

このposition:relativeという記述をすることで重ねたい子要素に対してどこからの位置を基準にして動かすかという基準ができたことになります。

重ねる子要素には以下のように記述します。


<img width="275" alt="position7.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/673286/f0591e50-2b7c-7daa-63ed-89f0ed01e0bb.png">

動かしたい子要素側にはposition:absoluteと記述します。
これでrelativeに指定した要素を基準に位置を指定することができます。
その上でどの一まで動かしたいのかを指定する必要があるので、今回は右端から10px離した位置にアイコンを重ねたいのでright:10px;と記述しています。
もし上からの距離を指定したい場合にはtop:と記述すれば大丈夫です。

以上の記述をすることで


<img width="936" alt="position9.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/673286/a00e1674-01b9-f8b0-7160-829319e71020.png">


このようにテキスト欄の右端にアイコンを重ねることができます。


以上です。
JavaのWebDAVクライアントライブラリのSardine

JavaのシンプルなWebDAVクライアントライブラリ[Sardine](https://github.com/lookfirst/sardine)を使用する。

# gradle

```gradle
implementation 'com.github.lookfirst:sardine:5.10'
```

なお、5.9以前をJava 9以降で使う場合、明示的にjaxb関連の依存性を追加する必要がある。

```gradle
compile group: 'com.github.lookfirst', name: 'sardine', version: '5.9'

// https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api
compile group: 'javax.xml.bind', name: 'jaxb-api'

// https://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-core
compile group: 'com.sun.xml.bind', name: 'jaxb-core', version: '2.3.0.1'

// https://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-impl
compile group: 'com.sun.xml.bind', name: 'jaxb-impl', version: '2.3.0.1'
```

上記のようにしないと以下のような```NoClassDefFoundError```が発生する。これはJava 9でjaxbがデフォルトでは読み込まれなくなったため。

```java
Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
at com.github.sardine.impl.SardineImpl.propfind(SardineImpl.java:459)
```

ちなみに5.10から```org.glassfish.jaxb:jaxb-runtime```の依存性を含むようになっている。

# java

```java
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.List;

import com.github.sardine.DavResource;
import com.github.sardine.Sardine;
import com.github.sardine.SardineFactory;

public class SardineSample {
	public static void main(String[] args) throws IOException {
		Sardine sardine = SardineFactory.begin();

		//リソース一覧の取得
		List<DavResource> resources = sardine.list("http://localhost:81/uploads/");
		for (DavResource r : resources) {
			System.out.println(r);
		}

		//ダウンロード
		try (InputStream inputStream = sardine.get("http://localhost:81/uploads/asd.txt")) {
			Files.copy(inputStream, Paths.get("copy.txt"), StandardCopyOption.REPLACE_EXISTING);
		}

		//アップロード
		sardine.put("http://localhost:81/uploads/asd222.txt", Files.readAllBytes(Paths.get("copy.txt")));
		
		sardine.shutdown();
	}
}

```
ElixirとCloudPub/Subを使ってStackdriverのログを取得してみる

Stackdriverにあるアプリケーションのログを取得してゴニョゴニョしてみたいという気持ちが出てきたので愛するElixirでそれが実現可能か試してみました。
後で見返すときの自分用備忘録です

注意.1)
この記事を読んで得られるものは[ここに書いてる内容（GoogleCloudPlatform/elixir-samples）](https://github.com/GoogleCloudPlatform/elixir-samples/tree/master/pubsub)と同じです！
気になる人はコードも見てみてね！


注意.2)
StackdriverからCloudPubsubへログを流す方法についてはここでは記載しません🙏


## [GoogleCloudPlatform/elixir-samples](https://github.com/GoogleCloudPlatform/elixir-samples/tree/master/pubsub)
Elixir向けのCloudPub/Subのサンプル実装が↑のリポジトリにある。
今回、topicの作成とかはGCPのコンソールからやってるので [elixir-samples/pubsub/lib/pubsub_samples_subscriber.ex](https://github.com/GoogleCloudPlatform/elixir-samples/blob/master/pubsub/lib/pubsub_samples_subscriber.ex)にある実装を ~~パクって~~ 持ってきます。

```elixir
# mix.exsに以下のライブラリを追加
  defp deps do
    [
      {:google_api_pub_sub, "~> 0.23.0"},
      {:goth, "~> 1.1.0"},
    ]
  end
```


```elixir
 def listen(project_id, subscription_name) do
    {:ok, token} = Goth.Token.for_scope("https://www.googleapis.com/auth/cloud-platform")
    conn = GoogleApi.PubSub.V1.Connection.new(token.token)

    # Make a subscription pull
    {:ok, response} = GoogleApi.PubSub.V1.Api.Projects.pubsub_projects_subscriptions_pull(
      conn,
      project_id,
      subscription_name,
      [body: %GoogleApi.PubSub.V1.Model.PullRequest{
        maxMessages: 10
      }]
    )

    if response.receivedMessages != nil do
      Enum.each(response.receivedMessages, fn message ->
        # Acknowledge the message was received
        GoogleApi.PubSub.V1.Api.Projects.pubsub_projects_subscriptions_acknowledge(
          conn,
          project_id,
          subscription_name,
          [body: %GoogleApi.PubSub.V1.Model.AcknowledgeRequest{
            ackIds: [message.ackId]
          }]
        )
        # ここに書きたい処理を書く。今回はIO.putsしてる
        "received and acknowledged message: #{Base.decode64!(message.message.data)}"
        |> (&IO.ANSI.format([:green, :bright, &1])).()
        |> IO.puts
      end)
    end

    listen(project_id, subscription_name)
  end
```
これで動くよ!!

## 今後やりたいこと
ここではログをPullしてくるまでしかしてないですが本番ではPullしたデータを加工してBigQueryに挿入していく処理を書く予定だったりします。
ElixirはLISTを美しく処理できるのでログの中から必要なものを抽出して加工してBulkInsertするとかも綺麗に書けるんじゃないかととても期待している。


## 感想
Elixirいいぞぉ！
ずっとElixir書くお仕事したいっすねぇ...
[VSCode] エクスプローラのディレクトリ階層を色分けするカスタムCSSを作った

VSCode を使っているとディレクトリの階層が深くなって見づらいことがよくあるので、階層ごとに色分けするカスタム CSS を作ってみました。

![](https://raw.githubusercontent.com/yarnaimo/vscode-explorer-colorizer/master/screenshot.png)

色や透明度などを各自でカスタマイズして、Node.js で css をビルドするようになっています。

導入方法はリポジトリの README に書いてあるのでここでは省略します。
https://github.com/yarnaimo/vscode-explorer-colorizer

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">VSCodeのエクスプローラをディレクトリの階層ごとに色分けするカスタムCSS、VSCode Explorer Colorizer をアップデートしました<br>mixins.js の形式が変わったので git pull して Download &amp; Build の 3 以降を再度実行してください！<a href="https://t.co/2mTMmqEsON">https://t.co/2mTMmqEsON</a> <a href="https://t.co/wLTJJ3epEE">pic.twitter.com/wLTJJ3epEE</a></p>&mdash; やまいも (@yarnaimo) <a href="https://twitter.com/yarnaimo/status/1283815641527418880?ref_src=twsrc%5Etfw">July 16, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 実装

VSCode は Electron で作られているので、「Custom CSS and JS」などの拡張機能を使うとカスタム css が適用できます。

エクスプローラはこのように Element がフラットに並んでいて、各 Element は **`aria-level`** 属性で階層の深さ、**`aria-expanded`** 属性で展開されているかどうかがわかるので、それに応じてスタイルを割り当てています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83774/7f224d5b-2dd4-7dd6-108e-cc363ceef90a.png)

各Elementの塗り分けには **`linear-gradient`** を活用しています。 `linear-gradient` は、手前の色とその次の色を同じ位置に指定すると、グラデーションではなく複数色で塗り分けたようにできるので、階層の深さに応じてそれを割り当てています。

例: (フランス国旗ではない)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83774/0542db4a-4f3f-78d7-2291-323722ed48de.png)
【簡単爆速第2弾】Streamlitをherokuにデプロイ


## 前回までのあらすじ
[前回の記事](https://qiita.com/Nate0928/items/566c2073358b4df3ceec)

PythonのオープンソースフレームワークであるStreamlitを使って、爆速でwebアプリを作りました。

## 今回の流れ
Streamlitで作ったwebアプリのディレクトリに必要なファイルを追加して、herokuにデブロイしていこうと思います。
必要なものは

- requrements.txt
- setup.sh
- Procfile
- runtime.txt


## requrements.txt
サーバーがコードを実行するためには、何をダウンロードするか必要があるかを認識させるものです。
`streamlit`や必要に応じて`numpy`や`pandas`を入れてあげましょう。
下は一例です。

```requrements.txt
streamlit==0.60.0
matplotlib==2.2.3 
numpy==1.15.1
```


App not compatible with buildpack
エラー出る
requirement.txt
runtime.txt作る
Procfile

## setup.sh
`setup.sh`も`requirements.txt`と同様にアプリがサーバー上で動作する環境を作るものです。emailは各々で変更してください。

```setup.sh
mkdir -p ~/.streamlit/

echo "\
[general]\n\
email = \"your-email@domain.com\"\n\
" > ~/.streamlit/credentials.toml

echo "\
[server]\n\
headless = true\n\
enableCORS=false\n\
port = $PORT\n\
" > ~/.streamlit/config.toml
```

## Procfile
サーバーがどういったコマンドで実行すればいいかを記述するものです。

```Procfile
web: sh setup.sh && streamlit run {name_of_app}.py
```

## デプロイしていく
まずはログイン

```
$ heroku login
```

herokuはGitを使用してるので、いつもGitレポジトリの初期化を行います。

```
$ git init
$ git add .
$ git commit -m "first commit"
```

そしてherokuに新しいインスタンスを作成します。

```
$ heroku create
```
あとはpushして開くだけです。

```
$ git push heroku master
$ heroku open
```
私も試しにTSPを2-opt法で解けるアプリケーションをデプロイしました。


![TSP_app.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571279/c97c170a-5ecd-38de-ba1b-fcb2428cf1cb.gif)




## 最後に
Pythonだけで気軽に成果物をそれっぽい形にできるStreamlitを、今回はデプロイしてみました。
デプロイまで非常に爆速でしたね。
Streamlit自体の便利さや爆速加減を知りたい方は、ぜひ[前回の記事](https://qiita.com/Nate0928/items/566c2073358b4df3ceec)をご覧ください！!

[次の記事](https://qiita.com/Nate0928/items/4d8b9abef3e520293a4a)
Web-WF Python Tornado その１


# はじめに
webServer APIServerとして、かんたん・すぐれている（と思っている）Tornadoを何回かにわけて紹介したいと思います

Web-WF Python Tornado その１ （この記事
[Web-WF Python Tornado その２](https://qiita.com/sin_hayasi/private/bdc4f45b092ed5433aec)
[Web-WF Python Tornado その３（Openpyexcelの紹介）]
(https://qiita.com/sin_hayasi/private/55b4314f3190cdf2f2ec)
## 対象
フルスタックエンジニア、フロントエンジニア、これから勉強しようと思っている人、Pythonが好きな人

## ゴール
今回はインストール〜簡易的なHTMLとJSONを出力できるまで

# Tornadoとは
Facebookが開発しているPython webフレームワーク＆非同期ネットワークライブラリ
ノンブロッキングネットワークI/Oを使用することにより、Tornadoは数万のオープン接続に拡張できるため、ロングポーリング、WebSocket、および各ユーザーへの長期間の接続を必要とするその他のアプリケーションに最適とのこと（[公式](https://www.tornadoweb.org/en/stable/index.html)


実際に開発に使用していますが、非常に高速で扱いも楽だと思います
[（API ServerとしてならFastAPIもオススメです）](https://qiita.com/sin_hayasi/private/cec8519cc34f7fbfbc75)

# インストール
Tornadoのインストールはpipのみ
(python3.6以上がインストールされていること）

```
$ python -V
Python 3.6.1

$ pip install tornado
```
pipってとても優秀なやつだと、毎回思います

# Hello World
これもまぁ公式なのですが

``` python:mainpy
import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()
```

## 起動＆閲覧
ターミナルで

```
$ python main.py
```

![tornado1-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672217/1c7a13c3-5c1d-fec6-81bb-c0ecae427d4c.png)


# simple HTML/JSON

さらに、ちょっとコードを加えることで簡易的なHTML/JSONを返すようにしてみます
イメージが膨らむし、これだけで開発の補助ツールにもなりますね

## ソース＆閲覧

```python:main.py
import tornado.ioloop
import tornado.web
import json

class htmlHandler(tornado.web.RequestHandler):
    def get(self):
        self.render("simple.html")

class jsonHandler(tornado.web.RequestHandler):
    def get(self):
        data = {"hello": "world"}
        self.write(json.dumps(data))

def make_app():
    return tornado.web.Application([
        (r"/html", htmlHandler),
        (r"/json", jsonHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()
```

```html:simple.html
<!DOCTYPE html>
<html lang="ja">

Hello world.<br />
(This is simple.html)
</html>
```

![tornado1-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672217/010baafc-67ef-1979-92ad-8c788de888eb.png)
![tornado1-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672217/edb6ba9d-c35d-ea4a-9ca6-6c329e574cde.png)
Einstein Analytics で生産性を高める方法の習得

１．システム管理者が Financial Services Cloud を簡単に立ち上げるための機能は何ですか?
２．アドバイザーが Einstein Analytics から得ることができる貴重なインサイトは何ですか?
３．価値が最大の顧客を見つけることができる場所はどこですか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/cd62b117-f02e-26e0-f8fc-8d6f0051cf09.png)
データ集計・分析に役立つExcel関数

データ分析に使うツールと言えばPythonやRを思い浮かべる人も多いかと思いますが、Excelだけでも相関分析や回帰分析などかなりのことができ、容量が大きくないデータなら手軽に集計・分析が可能です。本記事では、データ集計・分析をする場合に便利な関数をいくつかピックアップしてみました。

①CONCATENATE
文字列を結合できます。データの整形ではよく使う関数のひとつです。

```
CONCATENATE(文字列1, 文字列2,…)
```
ダミーデータで試してみましょう（ここではGoogleスプレッドシートを使います）。以下のように、県名や建物名がバラバラのセルに格納されている場合、CONCATENATE関数で結合するセルを指定することで、住所をひとつのセルにまとめることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265091/8cff65b7-d548-78c3-badb-4c6b2843d1cc.png)

②COUNTIF
条件に合致する数値の数を集計します。条件を指定して合計値を出す場合はSUMIF、平均値を出す場合はAVERAGEIF、最大値を出す場合はMAXIFなど、さまざまなバリエーションがありデータ集計で重宝することも多いのではないでしょうか。

```
COUNTIF（範囲, 検索条件）
```
例えばcountif(E2:E11,"男")とすることで、リスト中の男性の数をカウントできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265091/fb02f29b-83a1-4f28-9642-e74c9f115aa0.png)

条件が複数ある場合はCOUNTIFSを使います。以下の例では、性別が男性かつ、住所が福島県の人をカウントしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265091/0638e71d-e998-b227-9212-077aec61fa61.png)

③CORREL
比較したい配列の範囲を指定することで、配列同士の相関係数を算出します。相関の強さは、一般的な相関係数と同様に-1～1で表します。

```
CORREL(配列1の範囲,配列2の範囲)
```
この場合、年齢と購入金額には負の相関がある、つまり年齢が低いほど購入金額が高いということになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265091/cec958af-9972-395e-a460-7b75ef1f1760.png)

④FORECAST
FORECAST関数で、回帰直線を使った数値予測ができます。

```
FORECAST（予測するx列の値, yの範囲, xの範囲）
```

以下の例では、2015～2019年の金額をもとに2020年の見込み値を算出しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265091/7ac67cb4-da77-0146-031b-900f4a89f8e9.png)

ここでは紹介しきれませんが、Excelにはこのほかにもピボットテーブルなど便利な機能は多数あり、データ分析の実務ではぜひ使いこなしたいところです。
競技プログラミング練習記 No.46【ABC116練習】

初回 -> [はじめに](https://qiita.com/easychoco/items/a9ae28aca97cfe47091f)

[ABC116](https://atcoder.jp/contests/abc116)を解きました。
3完です！

|問題|時間|アルゴリズム|実行時間
|:-:|:-:|:-:|:-:|
| A |  1min |-| 7ms|
| B |  4min |-| 7ms|
| C | 13min |-| 8ms|


# まとめ
先にまとめを載せます。これ自体は最後に書いてます。

要素が重複しているかの判定で、`std::set`を使うとメモリ使用量を抑えられます。
配列を使った場合は速度が速いです。

D問題は難しかった。またの機会に解きます。。。



## A - 	Right Triangle

```c++
  int a, b, c;
  cin >> a >> b >> c;
  cout << a * b / 2;
```
直角三角形の面積を求める問題ですね。
直角を挟む2辺の長さがわかれば答えがわかります。
入力の位置が決まっているので、そのまま答えが出せます。

## B - Collatz Problem

``` c++
  int s;
  cin >> s;

  set<int> st;
  st.insert(s);
  int ind = 1;
  while(true)
  {
    ind++;
    s = ((s & 1) ? 3 * s + 1 : s / 2);
    if (st.find(s) != st.end())
    {
      cout << ind;
      return;
    }
    st.insert(s);
  }
```
数列を生成しながら出た数値を保存して、同じものが出た時点で終了しました。
`set`は`bool`型の配列などでも大丈夫です。
`set`だとメモリ使用量を抑えられます。配列を使った場合は速度が速いです。

[コラッツの問題(コラッツ予想)](https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%A9%E3%83%83%E3%83%84%E3%81%AE%E5%95%8F%E9%A1%8C)という問題がベースとなっているそうです。面白いですね。



## C - Grand Garden

``` c++
  int n, h;
  cin >> n;
  int old_h = 0;
  int ans = 0;
  for(int i = 0; i < n; ++i)
  {
    cin >> h;
    ans += max(0, h - old_h);
    old_h = h;
  }
  cout << ans;
```
いもす法の逆演算みたいな問題ですね。

イメージとしては、入力列をヒストグラムのように見て山ごとに分けて考えました。
ただ、使うのはヒストグラムではありません。順番が大事です。
山とは、数値が単調増加して単調減少している集まりです。
単調減少ののちに数値が増えると次の山になります。

例えば、入力例2の`3 1 2 3 1`の場合は、`(0 3 1)`, `(1 2 3 1)` の二つの山ができます。
(※はじめの高さである`0`を入れています)
(※山の境界にある`1`は重複しています)
こうしてみた時、ひとつの山はその「高さ」の回数だけ水やりをすれば作れますね。

つまり、山の高さの和が答えになります。
注意が必要なのは、「高さ」は山の開始時からの高さになります。
`(1 2 3 1)` の山は高さが`3 - 1 = 2`になります。

最初の山の高さが`3`
つぎの山の高さが`2`
なので、答えは`3 + 2 = 5`になります。

もう少し考察を進めると、ひとつ前の入力から大きくなった時にその差を足せば答えになります。
これを実装したものが上のコードになります。





以上です。ありがとうございました。
【誰得？】AWS EC2 autoscaling でスケールアウト時にインスタンスの Tag:Name 値がユニークな値になるようにしたいぞ！！

# 作った背景

ハピタスでは負荷に応じて EC2 インスタンスが自動でスケールアウト・インするように Autoscaling を導入しています。

導入前、システム上の課題で、EC2 インスタンスの Tag:Name がユニークであるという前提で稼働している監視サーバがあり、
単純にスケールアウトすると、Autoscaling Group で設定された Tag:Name が適用されてしまい、ユニークが崩壊するため、
監視サーバが正しく動作しなくなるという課題がありました。

そこでその課題を解決するために EC2 インスタンスの Tag:Name がユニークになるように今回の対応をしました。

まあ、誰得やねんって記事ですが、、
似たようなニッチな状況の人がいるかもしれません、そういう人に役に立てれば幸いですｗ

# 対応読者

- AWS 触っている人
- Autoscaling 導入しようとしている人
- EC2 インスタンスの Tag:Name をユニークにしたいレアな方 もしくは、単に興味でこの記事を見ている方

#　今回の対応

- aws-cli をインスタンスに導入します （古い EC2 インスタンスでなければ、ほとんどはいってますね！）
- User data なるものを使います

細かい手順は割愛します。

## 対応方法

一. AutoScaling を導入したい EC2 インスタンスに aws-cli が導入されているかを調べます

```
$ aws --version
```

これでバージョンが表示されなければ、インストールされていません。
[AWS のドキュメント](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2-linux.html#cliv2-linux-install) に従いインストールします。

二. インストール後 EC2 インスタンスの AMI を作ります
三. 起動設定を作ります。インスタンスタイプやSecurityGroup など、必要な設定をしてください。
　　さらに [追加設定 - 省略可能（Additional configuration - optional）] の [高度な詳細(Advanced details)] の中の [ユーザーデータ(User data)] のテキスト箇所に以下のおまじないを記載します

```
Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0

--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"

#cloud-config
cloud_final_modules:
- [scripts-user, always]

--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"

#!/bin/bash
instance_id=`curl -s 169.254.169.254/latest/meta-data/instance-id`
az=`curl -s 169.254.169.254/latest/meta-data/placement/availability-zone`
region=${az%[a-z]}
instance_name=`aws ec2 describe-instances --output text --region $region --instance-ids $instance_id \
  --query 'Reservations[].Instances[].Tags[?Key==\`Name\`].Value'`

if [[ $instance_name =~ $instance_id ]];
then
  exit 0;
fi

new_instance_name=${instance_name}-${instance_id}
aws ec2 create-tags --region $region --resources $instance_id --tags Key=Name,Value=${new_instance_name}
```

四. 作った起動設定を Autoscaling グループに適用します。そして、EC2 インスタンスに適用されるタグ名を以下のように設定しておきます

![スクリーンショット 2020-07-17 16.28.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218682/97200c45-2ed3-d0f4-0d96-90f64632a5a3.png)

あとは、スケールアウトされると勝手に EC2 インスタンスの Tag:Name が `web-server-i-aabbccddee` のように 設定した Name 値に ユニークな インスタンスID がひっつく形になります
gem install rails を実行時の Gem::FilePermissionError を解決する (Railsチュートリアル 1章)

自分がrailsチュートリアルを進めていく上で、発生したエラーを記録していきます。
ハードはMacBook Air, 開発環境はVScodeを用いています。


railsチュートリアル1章 1.2.2 Railsをインストールする
---

2020.7 現在は、rails6が最新版ですが、railsチュートリアルの無料版はrails5に対応しているので、rails5をインストールします。


**rubyはgemコマンドを用いてインストールします。**

```
$ gem install rails -v 5.1.6
```

gem install を実行する場所に関して、私はホームディレクトリで実行しました。($ cd ~ もしくは cd を実行すると移動できます。)色々調べても、実行場所について記述している記事を見つけることができませんでした:sob:

>**エンジニアは知っていて当然？　
＊豆知識コーナー＊**
ここで、**gemってなんだ？**と感じる人が多いと思います。私もその一人です。
調べてみると、「gemはrubyのパッケージ（ライブラリ）です。」と書いてあります。
私は、railsなどの色々な機能を詰め合わせで入れることができる入れ物のことをgemといい、今回はそこにrailsを入れるのかなあ、とぼんやりイメージしています。
（間違っていたら指摘していただけると助かります）
（参考：https://techplay.jp/column/529 ）


話を戻して、先ほどのコマンドを実行すると、次のようなエラーが発生します。

```
$ gem install rails -v 5.1.6

ERROR:  While executing gem ... (Gem::FilePermissionError)
    You don't have write permissions for the /Library/Ruby/Gems/2.6.0 directory.
```

これは、**権限がありませんよ！**というエラーです。

MacOSには管理者として権限が与えられたユーザー以外に、システム上重大な変更を許さないという機能があります。これによってブロックされてしまっている状態なのでエラーが発生しています。

そこで、**sudoというコマンドを追加します。**

```
$ sudo gem install rails -v 5.1.6
```

**sudoコマンド**によって、Macがコマンドを実行したユーザーが**管理者権限を持っているかどうか（パスワード設定済のアカウントかどうか）を判断**して、管理者権限を持っていた場合、コマンドが実行されます。

その際、パスワードの入力を求められるので、**パソコンにログインする際のパスワードを入力しましょう。**

---
###無事にインストールが完了しました！

役に立ったら是非**LGTMボタンをポチッと押していただけると嬉しいです。**
一緒に Rails学習 頑張りましょう！:raised_hand_tone1:
css 横スクロールメニュー flex box 

横スクロールメニューを作りたい。
画像などを入れると高さがずれるので、それの対策したバージョン。

参考
https://1-notes.com/css-menu-swipe-to-scroll-horizontally/

```hoge.vue

<div class="scroll-nav">
	<ul>
		<li><a href="#">MENU</a></li>
		<li><a href="#">MENU</a></li>
		<li><a href="#">MENU</a></li>
		<li><a href="#">MENU</a></li>
		<li><a href="#">MENU</a></li>
		<li><a href="#">MENU</a></li>
		<li><a href="#">MENU</a></li>
		<li><a href="#">MENU</a></li>
		<li><a href="#">MENU</a></li>
		<li><a href="#">MENU</a></li>
	</ul>
</div>

```

```app.css

.scroll-nav {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
	scrollbar-width: none;
}

.scroll-nav::-webkit-scrollbar {
	display:none;
}

.scroll-nav ul{
	display: flex;
	list-style-type: none;
	padding: 0;
	text-align: center;
}


.scroll-nav li{
	display: flex;
	width:100px;
	padding: 8px;
	margin: 1px;
	background:#FF5252;
}

.scroll-nav li a{
	width: 100%;
	color:#FFF;
	text-decoration:none;
}


```
【JavaScript】Promiseをしっかり理解したい【その3】

## 初めに
Promiseの自学習第3回目の投稿です。

前回の記事は以下となります。
[【JavaScript】Promiseをしっかり理解したい【その2】](https://qiita.com/kum44/items/73c3e993a716ad5812aa)

## Promise.resolveについて
今までPromiseオブジェクトを扱う際は`new`キーワードを使用してインスタンス化していました。

```js:Promiseオブジェクト生成
const promise = new Promise((resolve, reject) => {
    ...
});
```

しかし、上記以外の方法でもPromiseオブジェクトを生成することが可能です。
それは今まで扱ってきた`reslove`を使用することで実現できます。

```js:Promise.resolveによるPromiseオブジェクト生成
Promise.resolve(value)
```
`Promise.resolve`は引数で与えられた値でPromise オブジェクトを返す静的メソッドです。
`new`を使った構文だと以下と同じになります。

```js:Promise.resolveと同じ意味になるもの
new Promise((resolve) => {
    resolve(value);
});
```

`Promise.resolve`で返ってくる値も同様にPromiseオブジェクトなので、 以下のように続けて`then`メソッドを使った処理を書くことができます。
resolveの引数に格納した値は`then`メソッドの引数に渡ります。

```js:Promise.resolveを使った処理
Promise.resolve('こんにちは').then(function(value) {
  console.log(value);
});
```
```console:実行結果
こんにちは
```

今まで学習してきた関数からPromiseオブジェクトを返す書き方は以下になります。

```js:関数からPromiseオブジェクトを返す書き方
function asyncFunc() {
  return new Promise((resolve, reject) => {
    resolve('こんにちは');
  });
}

asyncFunc().then((value) => {
  console.log(value);
});
```
```console:実行結果
こんにちは
```

配列をresolveする例は以下になります。

```js:配列をresolveする
const p = Promise.resolve([1,2,3]);

p.then(function(value) {
  console.log(value[0]);
});
```
```console:実行結果
1
```
また、`Promise.resolve`に与えられた引数の値が`Promise`なら、その`Promise`が返されます。

```js:Promiseをresolveする
const p1 = Promise.resolve('p1でresolve');
const p2 = Promise.resolve(p1);

p2.then(function(value) {
  console.log(value);
});
console.log(p1 === p2);
```

```console:実行結果
true
p1でresolve
```
非同期処理なので最後の行のconsole.logの結果が先に出力されています。`p1`と`p2`は同値となっています。それぞれ`p1でresolve`という値を持ったPromiseオブジェクトになっています。`Promise.resolve`の引数にPromiseオブジェクトが渡された場合、そのPromiseオブジェクトが返されることになります。

## まとめ
理解に時間をかけ過ぎてしまったので、内容が短いのですが今回はここまでにします。処理の流れの中でPromiseオブジェクトが返る、ということを意識するとPromiseの理解が良くなる、逆にここを曖昧にすると混乱してしまうのではないかと思いました。
RDS Aurora を後から暗号化する方法


Aurora の暗号化された DB クラスターには以下の制限事項があります。

> - 暗号化された DB クラスターを変更して暗号化を無効にすることはできません。
> - 暗号化されていない DB クラスターを暗号化された DB クラスターに変換することはできません。ただし、暗号化されていない Aurora DB クラスタースナップショットを暗号化された Aurora DB クラスターに復元することができます。そのためには、暗号化されていない DB クラスタースナップショットから復元する場合は、KMS 暗号化キーを指定します。
> - 暗号化されていない Aurora DB クラスターから、暗号化された Aurora レプリカを作成することはできません。暗号化された Aurora DB クラスターから、暗号化されていない Aurora レプリカを作成することはできません。

> 引用元: [Amazon Aurora の暗号化された DB クラスターの制限事項](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/Overview.Encryption.html#Overview.Encryption.Limitations)


従って、暗号化していない DB クラスターを暗号化したい場合は、以下の手順で行う必要があります。

# 1. 暗号化されていない DB クラスターのスナップショットを取得

1. Amazon RDS コンソールを開き、ナビゲーションペインで [データベース] を選択。
1. 暗号化されていない DB クラスターのインスタンスを選択。
1. [アクション] > [スナップショットの取得]をクリック

# 2. スナップショットを暗号化済み Aurora DB クラスターに復元

1. Amazon RDS コンソールを開き、ナビゲーションペインで [スナップショット] を選択。
1. 作成した暗号化されていないスナップショットを選択。
2. [アクション] > [スナップショットの復元]
3. 暗号化を有効化にチェックする。
3. その他の入力項目に適当な値を入力する。
4. [DBインスタンスの復元]をクリック

暗号化済みのDBクラスターと書き込み用のインスタンスが作成されます。

# [任意] 3. 別リージョンに読み込み用インスタンス(リーダー)を作る

1. Amazon RDS コンソールを開き、ナビゲーションペインで [データベース] を選択。
1. 暗号化されている DBクラスターのインスタンスを選択。
1. [アクション] > [リーダーの追加]をクリック
checkio APIを使ってみた


記事の要約：checkio-clientを使えばブラウザからでなくてもcheckioの問題を解けるようになるよ

## 経緯

<details><summary>checkioって何？</summary><div>

[checkio](https://checkio.org/)はPythonやTypescriptの学習用サービス（というよりはコーディングゲーム？）。
特徴的な点は、実用性重視の問題が出題されるところ。
例えば「正規表現を使って特定の文字列を検出する問題」ではなく「[対応がめんどくさいメールを選別する問題](https://py.checkio.org/en/mission/stressful-subject/)」といった形式で出題される。
一問につき1知識の学習をさせる一般的な教材と違って、1つの基礎問題で様々な知識を要求してくるので総じて難易度は高い（最低難易度のElementaryでも解けない時があって結構凹む）が、学習の質とモチベーション向上には間違いなく貢献してくれている。他人と解答を共有できるのも素晴らしい。

</div></details>

便利なサービスではあるが問題点が一つ。
**解答画面が滅茶苦茶使い辛い。**
スクリプトはWeb上のエディタに打ち込むのだが、コマンド補完機能が用意されていないのでタイポ、カッコ閉じ忘れ、pep8を守っていないコーディングが頻発する。デバッグ作業もやりづらい。
普段vscodeの補完機能に頼りきりなのが悪いのだが、だからと言って一々そんなミスの修正に思考リソースを割きたくない。
結果どうするかというと、
**vscodeでスクリプト書いて、デバッグして、うまくいったらブラウザの解答画面にコピペ**している。

そんな無駄な工程挟むなら、いっそスクリプトファイルごと送信して答え合わせしてくれよ…
↓
APIでpyファイル送れるやん!

という事実を~~checkio2年使ってて初めて~~知ったのでここで紹介することにする。




## 準備するもの

- python3
- pip
- checkioのAPIキー([ユーザープロファイル](https://py.checkio.org/profile/edit/)から確認できる)

## インストール

### 1.checkio_client(API)をインストール

```bash
pip3 install checkio_client
```

### 2.configを設定

```
checkio config
```

```
Which domain you want to use by default? (code required)
[py] - https://py.checkio.org
[js] - https://js.checkio.org
[epy] - https://empireofcode.com
[ejs] - https://empireofcode.com
by default:py
Code for domain[py]:
```
pythonを利用するのでそのままEnter

<br>

```
What is your KEY for https://py.checkio.org ?
You can find one on https://py.checkio.org/profile/edit/
KEY:
```
APIキーを入力

<br>

```
Choose folder for your solutions [/home/user/py_checkio_solutions]:
```

ファイルの保存先とするディレクトリを入力（デフォルトのままでもok）


### 3.進行状況を同期

```
checkio sync ~/py_checkio_solutions
```

指定したディレクトリに解答ファイルが同期される
![dir_tree.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625877/e7c0f056-df54-fdba-0139-d24a88b1c75c.png)

2度目以降は

```
checkio sync
```
だけで同期できる。

## 利用方法

### 1.pyファイルに解答を書き込む

同期されたpyファイルに解答を書き込んでいく。
問題文もファイル内に記述されているのでブラウザで問題文を開く必要もない。

### 2.解答をテスト

assert文が通ったら回答を送信してテスト

[Zigzag Array](https://py.checkio.org/en/mission/zigzag-array/)を解いた場合

```
zigzag_array.py --check
```

```
Start checking...

*** Basics ***
->[3, 5]
<-[[1, 2, 3, 4, 5], [10, 9, 8, 7, 6], [11, 12, 13, 14, 15]]
->[5, 1]
<-[[1], [2], [3], [4], [5]]
->[3, 3, 5]
<-[[5, 6, 7], [10, 9, 8], [11, 12, 13]]
*** Extra ***
->[0, 3]
<-[]
->[3, 0]
<-[[], [], []]
->[0, 0]
<-[]
->[10, 1]
<-[[1], [2], [3], [4], [5], [6], [7], [8], [9], [10]]
->[4, 2]
<-[[1, 2], [4, 3], [5, 6], [8, 7]]

!!! Congratulation !!!

Link for checking solution of other users: https://py.checkio.org/mission/zigzag-array/publications/

Link for sharing solution: https://py.checkio.org/mission/zigzag-array/publications/add/
```

Congratulationが表示されたらテスト合格。

### 3.解答を投稿
Link for sharing solution のリンクにアクセスして解答を提出
ユーザーページのActivityに"Shared Clear solution..."といった通知が表示されていたら投稿完了。 

## おわりに

「問題選ぶ→解く→テスト」までをvscode上で完結できて非常に便利。

checkio-clientについてもっと知りたい場合は公式ブログを参照。
https://py.checkio.org/blog/new-tool-checkio-client/

ブラウザ拡張機能もあるようだが、レビュースコア低い＆最終アップデートが2018年末（2020年6月現在）と散々なのであまり使う気はしない。
http://www.checkio.org/local-editor/chrome/extension/
Python3 Error :No module named '_lzma' の対処方法

# はじめに
今回の記事は題名の通り**lzma** moduleがないと怒られ, エラーが出た時の対処方法について書きます. 
と言っても, 私が試した方法はその場しのぎなので根本的な解決になっていない様な気しかしないですが...
何はともあれ, この方法でエラーは取り消せたので未来の自分と, 同じく困っている人の一助になればと思い記します.

私はこの`No module named '_lzma'`のエラーは**pandas**と**scikit-image**をimportする際にでました. 大学の実験や案件でpythonを取り扱う時にこのエラーに遭遇して初めての時は色々苦しみました...

実行環境は次の通りです
## 実行環境
MacOS Mojave 10.14.6
Python 3.6.5 (**pyenv**)

# (その場しのぎの)対処法
一言で言ってしまえば, importエラーが出ているmoduleの**versionを変更**することで対処します.
(もうこの一文でその場しのぎ感が伝わってくる様な...)
と言っても, どのverでエラーが出てどのverだとエラーが出ないのかわかりませんね.
私はエラーが出ていない友人や先輩のverを調べて, それをinstallすることで対処しました.
この記事ではエラーが出たmoduleのverとエラーが出なくなった際のverについて記載して行こうと思います.

## pandasで遭遇した際の対処
[参考文献1](https://qiita.com/mynkit/items/a6ae2aa73afc06d9f7bd)で示した方法と同じなのですが, エラーが出た際のpandasのversionは`pandas 0.25.0`でした.
そのため, pandasのversionを`pandas 0.25.1`に変更すると`No module named '_lzma'`は出力されなくなりました.

## scikit-imageで遭遇した際の対処
エラーがでた際のscikit-imageのverは`scikit-image 0.17.2`でした.
これを`scikit-image 0.14.0`で再インストールすると, `No module named '_lzma'`は出力されなくなりました.

これで記事の目的は達成しているのですが, 別のエラーが出たため, それの対処方法も記しておこうと思います.
`scikit-image 0.14.0`で実行するとこのエラー`cannot import name '_validate_lengths'`が出力されました.
調べてみると, `scikit-image 0.14.2`では修正されているようです([参考文献3](https://qiita.com/drafts/66762ce8a75ee069ee7f/edit#%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE)より)

## 他の対処方法
[参考文献1](https://qiita.com/mynkit/items/a6ae2aa73afc06d9f7bd)と[参考文献2](https://blog.morihaya.tech/entry/2019/02/10/170104)でも紹介されているように, pyenvでpythonを入れ直したり, versionアップを行うと治ることもあるようです. 詳しくは[参考文献](https://qiita.com/drafts/66762ce8a75ee069ee7f/edit#%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE)を参照してみてください.

## moduleのversion指定 pip install
```:
// pipでのパッケージ(module)のversion指定インストール方法
$ pip install パッケージ名==version

// 例
$ pip install scikit-image==0.14.2
```
他のpipコマンド, 現在installされているversionの確認などは[参考文献4](https://qiita.com/HyunwookPark/items/242a8ceea656416b6da8)を参照してみてください.

# 最後に
python使って2年間しか?も?経ちましたが...version管理難しいですね. 一部のmoduleのversionを変更すると他のmoduleのimportが上手くいかなくなるなどなど.
そもそも, pyenv環境を構築するのも色々苦労した...pythonとっても便利なんですけど.
この記事を読んで少しでも問題解決に役立ったのなら幸いです. 立たなかったらごめんなさい. 

# 参考文献
**1.** [pandasのversion0.25.0でimportエラーが起きる](https://qiita.com/mynkit/items/a6ae2aa73afc06d9f7bd)
**2.** [pyenvのpython環境で'_lzma'が存在しなかった時の対応メモ](https://blog.morihaya.tech/entry/2019/02/10/170104)
**3.** [cannot import name '_validate_lengths'](https://github.com/numpy/numpy/issues/12744)
**4.** [pipでアップデートするときのコマンド pip update](https://qiita.com/HyunwookPark/items/242a8ceea656416b6da8)
(Ubuntu) snapが動かない時のチェック

# 1. 確認手順
Ubuntu 20.04 でsnap (というパッケージ管理ツール) が動かなくなった時の作業メモ

## 1.1. 通信の確認

```bash
sudo snap debug connectivity
```
以下なら問題なし

```bash
Connectivity status:
 * PASS
```

## 1.2. ログの確認

```bash
vi /var/log/syslog
```
snapが動いているなら、以下のメッセージの後HTTPエラー等になるはず

```bash
Jul 17 07:04:33 ip-10-10-174-153 snapd[751]: api.go:990: Installing snap "microk8s" revision unset
```
## 1.3. snapdの動作確認

```bash
systemctl status snapd
```
出力例

```bash
● snapd.service - Snap Daemon
   Loaded: loaded (/lib/systemd/system/snapd.service; enabled; vendor preset: en
   Active: active (running) since Fri 2020-07-17 06:48:13 UTC; 38min ago
 Main PID: 751 (snapd)
    Tasks: 27 (limit: 4915)
   Memory: 256.9M
   CGroup: /system.slice/snapd.service
           mq751 /usr/lib/snapd/snapd
```
また、設定ファイルは、`/etc/environment`にある。

## 1.4. snapレポジトリのリフレッシュ
snapのレポジトリのリフレッシュをしてみる。

```bash
sudo snap refresh
```


# A. 参考資料
- [Unable to contact snap store](https://forum.snapcraft.io/t/unable-to-contact-snap-store/16107)
- [Snap auto-refresh stuck](https://forum.snapcraft.io/t/snap-auto-refresh-stuck/18158)
- [Error: cannot communicate with server: timeout exceeded while waiting for response](https://forum.snapcraft.io/t/error-cannot-communicate-with-server-timeout-exceeded-while-waiting-for-response/15726)
【Rails】【Docker】【Alpine】wicked_pdfを使用してpdfを出力する

# issue

macOSで動作させていたRailsアプリのPDF出力機能がDocker環境で動作しなくなった。

`Error: PDF could not be generated!`
![スクリーンショット 2020-07-17 16.03.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630802/1444392a-3e46-f4fa-4c7a-5838fc330d6b.png)


```ruby:使用したgem

gem 'wicket_pdf'
gem 'wkhtmltopdf_binary'

```

# solutions

`Dockerfileに下記を追記`

```Dockerfile
RUN apk add --no-cache \
    wkhtmltopdf \ 
    ttf-ubuntu-font-family
```

```terminal
/usr/bin/wkhtmltopdf --version
-> wkhtmltopdf 0.12.5
```


`wicket_pdf.rbからalpinelinux上のwkhtmltopdfを見るようにパスを指定する`

```ruby:wicket_pdf.rb
require "wicked_pdf"

WickedPdf.config = {
  exe_path: '/usr/bin/wkhtmltopdf'
}
```


### 日本語が化けた場合

`AlpineLinuxにfont-ipa(日本語)をインストールする`

```terminal:terminal
  $ cd \
    && wget https://ipafont.ipa.go.jp/IPAfont/ipag00303.zip \
    && mkdir .fonts \
    && unzip ipag00303.zip -d .fonts -j \
    && fc-cache -fv ~/.fonts
```

`本番環境ではポチポチインストールできないのでDockerfileに追記`

```dockerfile:Dockerfile
RUN cd \
    && wget https://ipafont.ipa.go.jp/IPAfont/ipag00303.zip \
    && mkdir .fonts \
    && unzip ipag00303.zip -d .fonts -j \
    && fc-cache -fv ~/.fonts
```

[wgetコマンド](https://www.atmarkit.co.jp/ait/articles/1606/20/news024.html)
[fc-cacheコマンド](https://www.atmarkit.co.jp/ait/articles/1812/14/news034.html)
[unzipコマンド](https://www.atmarkit.co.jp/ait/articles/1607/26/news014.html)

# appendix

```ruby:pdf.html.erb
# 最低限なのでcss等適応したい場合は適宜変更する
<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
  </head>
  <body>
      <%= yield %>
  </body>
</html>
```

```ruby:controlloer
respond_to do |format|
      format.html
      format.pdf do
        render pdf: "article_#{params[:id]}",
               layout: 'pdf.html',
               templete: 'articles/show',
               encoding: 'UTF-8',
               page_size: 'A4',
               margin: {
                 top: 10,
                 bottom: 10,
                 left: 20,
                 right: 20
               }
      end
end
```

# reference

[gem wicked_pdf](https://github.com/mileszs/wicked_pdf)
[Does it work with Alpine?](https://github.com/mileszs/wicked_pdf/issues/841)
[Issue with wkhtmltopdf that generates PDF files for this plugin on default Sylius Docker](https://github.com/Sylius/InvoicingPlugin/issues/173)
[wicked_pdf Error: PDF could not be generated](https://www.thetopsites.net/article/58095049.shtml)
[RailsアプリでのPDFファイル生成](https://d4-1977.hatenablog.com/entry/2014/02/28/132540)
[IPAフォントのダウンロード](https://ipafont.ipa.go.jp/old/ipafont/download.html)
【labelの使い方】


ビューにアイコンを表示させて、そのアイコンをクリックするとファイル選択画面が現れるという機能を実装するための方法をアウトプットしていきます。
今回はhaml記法を使っていきます。

<img width="375" alt="icon_label.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/673286/aff06212-8198-3795-7c1a-d8fc5a69f838.png">


上記の画像のようにlabel.クラス名を親要素に指定して、
表示させたいアイコンを親要素に対してネストさせます。

今回はこのicon
に対してクリックするとファイル選択画面が現れるという機能を付与したいので、
iconの下にinput.クラス名{type:"file"}と記述します。

このinput{type: "file"}がファイル選択画面が現れる機能の記述部分です。

このようにlabelに対してネスト→表示させたいアイコンを記述→アイコンに対して実装させたい機能を記述という流れでアイコンをクリックした際にファイル選択画面を出現させることができます。


<img width="915" alt="label.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/673286/b1b3b325-4d7f-a6b0-9b27-d26a4ada3d1e.png">


Sendボタンの左にあるアイコンをクリックすると以下のようになります。


<img width="865" alt="label1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/673286/2d96070d-ac5a-12ec-a054-74257e03883a.png">


ファイル選択画面が出現しています。

追記ですが、input{type: "file"}はファイル選択画面を出現させるための記述ですが、このままだと以下のように

<img width="923" alt="label4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/673286/277116da-981f-2428-1f85-8ab1b3df7281.png">

ファイルを選択という表示が出てしまいますので、この表示を消すためにはcssで以下のように記述してあげる必要があります。


<img width="381" alt="label5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/673286/34d527ca-c293-adb6-badb-7444e8526393.png">

.Hiddenはinput{type: "file"}のクラス名です。
display:none;とすることでファイルを選択を非表示にしてあげることができます。



以上です。
HaskellでMonadを使って簡単な複素数の計算プログラム

[HaskellでFunctorを使って簡単な複素数の足し算プログラム](https://qiita.com/oskats1987/items/4e0216a6e6a7889008f5)
[HaskellでFunctorを使って簡単な複素数の足し算プログラムーその2](https://qiita.com/oskats1987/items/c3e652862001ad002e17)

以前Functorで簡単な計算をするプログラムを作り、今回はMonadで試してみました。

#HaskellでMonadを使って簡単な複素数の計算プログラム

```haskell:Complex.hs
data ComplexNumber n = Z n n

class ComplexFunctor t where
    cfmap :: (a -> b) -> (a -> b) -> t a -> t b

class (ComplexFunctor c) => ComplexApplicative c where
    cpure :: a -> a -> c a
    (<**>) :: c(a -> b) -> c a -> c b

class ComplexMonad c where
    creturn :: a -> a -> c a
    (>>==) :: c a -> (a -> a -> c b) -> c b

instance ComplexFunctor ComplexNumber where
    cfmap func1 func2 (Z a b) = Z (func1 a) (func2 b)

instance ComplexApplicative ComplexNumber where
    cpure a b = Z a b

    (Z func1 func2) <**> c = cfmap func1 func2 c

instance ComplexMonad ComplexNumber where
    creturn a b = Z a b
    Z a b >>== f = f a b

main::IO()
main = do
    let a ans = (\(Z a b) -> (a,b) ) ans

    let ans = cpure (+) (+) <**> Z 1 2 <**> Z 3 4

    print (a ans)

    let add a1 b1 a2 b2 = creturn (a1 + a2) (b1 + b2)
    let sub a1 b1 a2 b2 = creturn (a2 - a1) (b2 - b1)

    let ans2 = creturn 3 4 >>== add 4 5 >>== add 10 20 >>== add 20 30 >>== sub 7 9

    print (a ans2)
```

FunctorとApplicativeの部分は前回と同じです。
`add`関数と`sub`関数は、それぞれ加算、減算する関数で、4引数取ります。
`>>==`関数のところで最初の2引数を部分適用して、実部と虚部を加減算します。

```:実行結果
(4,6)
(30,50)
```
pythonで1つのフォルダの中にあるGoogle Docsをまとめて.txtファイルで落とす方法

# やること

Google Driveの中に`some_folder`というフォルダがあって、
フォルダの中に↓みたいにGoogle Docsファイルが入ってるとします
この `doc1`, `doc2`, ... を全部 `.txt`形式で落とすPythonプログラムを作ります

```
some_folder
└ doc1
└ doc2
└ doc3
└ ...
```

`PyDrive`というGoogle Drive APIのラッパーパッケージを使います

:warning: フォルダ内にGoogle Docs以外のファイル（SpreadSheetとかPDF）とかがあった場合のエラー処理はしてません

# 1. 環境構築

## Drive APIのアクセスキーをダウンロード

[ここ](https://developers.google.com/drive/api/v3/quickstart/python)からアクセスキーのjsonを落としてきます
下の画像の青いボタンを押せばok

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430849/7372e8f9-b98e-dbcf-a77d-c41e33e9dbb8.png)

## アクセスキーのファイル名を変える

ファイル名を
`credentials.json`→`client_secret.json`
に変更します

理由: `PyDrive`パッケージが`client_secret.json`という名前でアクセスキーのファイルを探すから

## `PyDrive`パッケージを入れる

`pip`か`pip3`で入れてください

```python
# pipの人
pip install PyDrive

# pip3の人
pip3 install PyDrive
```

（参考）

- パッケージのサイト: https://pypi.org/project/PyDrive/
- ドキュメンテーション: https://pythonhosted.org/PyDrive/index.html

# 2. Google DriveのフォルダIDをとってくる

フォルダIDは、Google Driveフォルダをブラウザで開くと、URLからわかります

```
https://drive.google.com/drive/folders/xxx
```

URLは↑のような形式になっていて、`xxx`の部分がフォルダのIDです

# 3. コードを書く

これを貼り付けて、2でとってきたフォルダのIDをコードの`FOLDER_ID`のところに入れます

:warning: プログラムは1の`client_secret.json`と同じディレクトリに入れてください

```python:download.py
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive

# OAuthする

gauth = GoogleAuth()
gauth.LocalWebserverAuth()

drive = GoogleDrive(gauth)

# ファイルをダウンロードしてくる

file_list = drive.ListFile(
    {'q': "'FOLDER_ID' in parents and trashed=false"}).GetList()
for file in file_list:
    title = file['title']
    file.GetContentFile(f'{title}.txt', mimetype='text/plain')
    print(f'downloading file: {title}')
```

# 4. 実行

どっちかでプログラムを実行してください

```bash
# pythonコマンドの人
python download.py

# python3コマンドの人
python3 download.py
```

実行すると、ブラウザのタブが開くのでGoogleアカウントで認証してください
ダウンロードしたファイルは、プログラムと同じディレクトリに入ります

おわり :tada:
プログラマがMacを買った時にやること

# 次回買った時のメモでもある

- キーボード設定
- Dockerのインストール
- Pycharmのインストール
- チャットワークのインストール
- Lineのインストール
- マウスの設定最速
- キーボードの設定最速
- クロームのインストール
- クロームマウスジェスチャーのインストール
- Slackのインストール
- xcodeのインストール
- MagicPrefsのインストール
- Atomのインストール
- Officeのインストール
- Gmailの設定
- Homebrewのインストール
- Pycharm 設定
- Qt Designer
- nodebrewをインストール
- nodeのインストール

## キーボード設定
Karabiner-Elementsのインストール
https://creative89.com/2017/05/27/how-to-use-windows-keyboard-on-mac/

## JavaScript デバッグ

```
https://chrome.google.com/webstore/detail/jetbrains-ide-support/hmhgeddbohgjknpmjagkdomcpobmllji/related
```
JavaScript ISO8601形式の日時表記を生成

単純に``Date()``オブジェクトの`toISOString()`メソッドを使えばISO8601形式の日時を返してくれますが、これはどの地域で実行してもZ(UTC)で返ってきますので、地域に合わせたオフセット付きの表記で返すメソッドを書いてみました。

~~~js
Date.prototype.iso8601 = function() {
    if(isNaN(this)) return this;
    const d = new Date(this - this.getTimezoneOffset() * 6e4);
    return d.toISOString().slice(0, -5) +
           d.toString().match(/[-+]..../)[0].replace(/(..)$/, ':$1');
}
~~~

####例####

~~~js:example
// 現在日時
console.log( new Date().iso8601() ); // 2020-07-17T14:31:50+09:00
// 任意日時
console.log( new Date('2020/01/01 00:00:00').iso8601() ); // 2020-01-01T00:00:00+09:00
console.log( new Date(1234567890123).iso8601() ); // 2009-02-14T08:31:30+09:00
console.log( new Date(0).iso8601() ); // 1970-01-01T09:00:00+09:00
~~~

----

他のメソッドとの表記の比較および日時としては同一かの検証

~~~js
const date = new Date('2020/01/01 00:00:00');
const time = date.getTime();
console.log(time);
const a = [];
console.log( a[0] = date.toString() );
console.log( a[1] = date.toISOString() );
console.log( a[2] = date.iso8601() );
console.log( new Date(a[0]).getTime() );
console.log( new Date(a[1]).getTime() );
console.log( new Date(a[2]).getTime() );
~~~

####結果####

![00.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618708/41d2d6b7-7f97-f8f1-0f00-5aca5b12c387.jpeg)

順に、
(1) '2020/01/01 00:00:00' のUNIX時間基準のミリ秒(時差が考慮されますので地域によって変わります)

(2) `.toString()`を追加したもの
(3) `.toISOString()`を追加したもの
(4) `.iso8601()`を追加したもの

(5) (2)を初期値として`.getTime()`を通したもの
(6) (3)を初期値として`.getTime()`を通したもの
(7) (4)を初期値として`.getTime()`を通したもの

(2)～(4)のそれぞれの表記は違っても、(1)と(5)～(7)が同一であればそれぞれ同じ日時ということです。

----

日本以外の地域でもその地域に合わせたタイムゾーンで表示されるか、またそれが日時として正しい結果かを確認してみます。

JavaScriptではPHPの`date_default_timezone_set()`のようなスクリプト内で使用されるデフォルトタイムゾーンを変更する手段は無いようなので、直接OSのタイムゾーン設定を変えて確認。
**OSのタイムゾーン設定を変更すると他の多くのプロセスの動作にも影響が出る可能性がありますので、あまりやらないほうがよいです。**

![01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618708/f2a5198e-fa12-bc94-4b98-3fc47be7285b.jpeg)
![02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618708/75237fcd-42f1-1c5c-7bcd-414537d6da58.jpeg)
![03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618708/c0faf67c-5cf9-5666-ad9b-611abc2741c2.jpeg)
![04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618708/d53caf43-b272-053c-598c-a16f18c96cb4.jpeg)
![05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618708/78e21e3e-549d-00fe-3467-f37d3deadc7d.jpeg)
![06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618708/de1ad7e7-9486-74b1-0159-970b0a6ac727.jpeg)
![07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618708/b1807a59-b1e9-7947-0ee1-a7586ae55ea0.jpeg)

アデレートはUTC+09:30であるのに結果が+10:30となっているのは、サマータイムが反映されているためです。
(1月の日付で検証しているのにサマータイムが反映されているのは南半球にある地域のため)

![08.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618708/ff2251d1-4663-77e4-bd32-cd1ed283b71d.jpeg)
![09.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618708/6feac5c3-70c9-3349-6a32-9e74c7b6bea6.jpeg)

----
【Oracle】INDEXの確認、作成、削除、再有効化

#INDEXの確認、作成、削除、再有効化
##INDEXとは
INDEX(インデックス)とはテーブルにつける索引のことです。
索引をつけることで指定された条件の検索スピードが速くなることを期待できます。
本の目次をイメージしてもらうとよいかと思います。

#INDEXの確認
以下のコードではINDEXがすでに対象のテーブルに張られているかを確認しています。
また、項目が多いため必要な項目のみ出力することをお勧めします。

```sql
-- INDEXの確認
SELECT INDEX_NAME,TABLE_OWNER,TABLE_NAME,STATUS
FROM USER_INDEXES
where table_name = 'USER'
;
```
#INDEXの作成
以下のコードではINDEXを作成しています。
通常、その表に対し行う検索(抽出)条件となるような項目を指定します。
また、ここでは[user_cd]のみ指定していますが、複数項目の指定が可能です。

```sql
-- INDEXの作成
CREATE INDEX user_n1 ON user(user_cd)
;
```

#INDEXの削除
以下のコードでは作成済みの「user_n1」というINDEXを削除しています。

```sql
-- INDEXの削除 
DROP INDEX user_n1
;
```
#INDEXの再有効化
以下のコードではSTATUSがINVALID(無効化)されているINDEXを再有効化しています。

```sql
-- シノニムを定義する 
ALTER INDEX user_n1 REBUILD ONLINE
;
```
PHP 文法エラーと戦ってみた 多分初心者あるある

#PHP 文法エラーと戦ってみた 多分初心者あるある

##
先ほど文法のエラーと戦いましたので、
載せておきます！

エラー前

```php
Route::group(['prefix' => 'admin'], function() {
    Route::get('news/create', 'Admin\NewsController@add');

Route::group(['prefix' => 'admin'], function() {
    Route::get('admin/profile/create', 'Admin\NewsController@add');

Route::group(['prefix' => 'admin'], function() {
    Route::get('admin/profile/edit', 'Admin\NewsController@edit');
```
ここからエラーが発生！
なぜこうなったのか。
まずはエラーのマルポチ●にカーソルを合わせてみてエラー内容をみてみる

#エラー内容
「syntax error, unexpected end of file」

ほう。
直訳すると、
「構文エラー、予期しないファイルの終わり」
と言うことは、、最後のところが何か足りない。。。

あ、カッコが足りないやんけ！！
3つのRoutingに
｝｝｝
が足りない。。。

しかも後々気づいたけど、コードこれまとめられる！
Route::group(['prefix' => 'admin'], function() {
の中に全ての関数を入れちゃえばええんだなと察しました。

まとめてみました。

```php
Route::group(['prefix' => 'admin'], function() {
    Route::get('news/create', 'Admin\NewsController@add');
    Route::get('admin/profile/create', 'Admin\NewsController@add');
    Route::get('admin/profile/edit', 'Admin\NewsController@edit');
}
```

Route::group(['prefix' => 'admin'], function() {
を2つ消したのですっきりしました！
OKと思ったが、またまたエラーです。エラーありがとう経験値溜まります。イライラも笑

##エラー内容
「synatax error, unexpected end of file, expecting ','or'」

ほうほう
直訳すると
「synataxエラー、予期しないファイルの終わり、「、」が必要、または」
あ、さっきと同じようなこと言ってるなぁ
あ、
);
が足りないやんけ！！笑 何回目だよ笑
Route::group(['prefix' => 'admin'], function() {
のRoute::group()←これw
ついでに );←これもw

今度こそは思い、しっかりと付けて直しました！！

```php
Route::group(['prefix' => 'admin'], function() {
    Route::get('news/create', 'Admin\NewsController@add');
    Route::get('admin/profile/create', 'Admin\NewsController@add');
    Route::get('admin/profile/edit', 'Admin\NewsController@edit');
});
```

今度はエラー出ませんでした！！！
よし！次回からは気をつけよう！！
皆さんも([]);気をつけてね٩( ᐛ )و
Swift5を使ってURLスキームで設定画面に遷移する方法

# 初めに
今回はURLスキームを使って設定画面に遷移させる方法を記事にします。
Appleに申請した時あるコードを使うとリジェクトする話もしたいと思います。
## 実装
以下が設定画面の遷移コードです。

```swift:test.swift
guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else {
  return
}
if UIApplication.shared.canOpenURL(settingsUrl)  {
  if #available(iOS 10.0, *) {
    UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
    })
  }
  else  {
    UIApplication.shared.openURL(settingsUrl)
  }
}

```
## リジェクトするコードの実装
以下がリジェクトの対象コードです。
同じく設定画面にこちらからも遷移できますが、リリースする場合はこちらのコードはNGです。

```swift:test.swift
if let url = URL(string:"App-Prefs:root=NOTIFICATIONS_ID&path={ビルドID}") {
    if #available(iOS 10.0, *) {
        UIApplication.shared.open(url, options: [:], completionHandler: nil)
    } else {
        UIApplication.shared.openURL(url)
    }
}
```
## 実際のAPPLEのエラー
ちなみに、リジェクト対象のコードで申請すると下記のエラーで怒られます。。。。。

```
Guideline 2.5.1 - Performance - Software Requirements
  Your app uses the "prefs:root=" non-public URL scheme, 
which is a private entity. 
The use of non-public APIs is not permitted on the App Store because it can lead to a poor user experience should these APIs change.  Specifically, 
your app uses the following non-public URL scheme:  app-prefs:root=notifications_id&path=  Next Steps  To resolve this issue, 
please revise your app to provide the associated functionality using public APIs or remove the functionality using the
 "prefs:root" or "App-Prefs:root" URL scheme. 
```

#終わり
今回は設定画面に遷移する方法を紹介しました。
リジェクトするとリリースまで期間が延びちゃうのでそこら辺は慎重にしたいですね。