OmniAICreator/Qiita-1.07M huggingface dataset:
Ruby on Rails 　フォーム画面で編集したら前の投稿が消えてしまった。

## ブログ投稿機能で編集機能を作成したら上手く反映されない。。。
### ※とても初歩的なミスです:sweat:

フォーム画面を作成して、タイトル、カテゴリー、コンテンツを入力してブログと投稿できる機能を作りました。

編集画面を作成し、一見updateできたかと思いきや、、

タイトルを編集しなかったらタイトルが消えてしまう、、、


```
<div class="form-group">
<label for="title" class="form-control-label">Title</label>
<input type="text" name="title" id="addpost" class="form-control" placeholder="<%= @post.title%>">
</div>

```
placeholderだから、paramsに修正前のデータが入らず空で上書きしてしまっていたようです。

```
<div class="form-group">
<label for="title" class="form-control-label">Title</label>
<input type="text" name="title" id="addpost" class="form-control" value="<%= @post.title%>">
</div>

```
placeholderをvalueに修正したらタイトルを修正しなくても前回の投稿が反映されていました！！


初心者ゆえに間違いがあればご指摘ください:bow_tone1:
Ruby で StringIO を CSV  として読み込む例

多分こんな感じ。

```ruby
[27] pry(main)> csv = CSV.new(StringIO.new("A,B,C\nX,Y,Z"))
=> <#CSV io_type:StringIO encoding:UTF-8 lineno:0 col_sep:"," row_sep:"\n" quote_char:"\"">
[28] pry(main)> csv.readlines
=> [["A", "B", "C"], ["X", "Y", "Z"]]

```








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Pythonで高速素因数分解〜競プロ用〜

#１. はじめに
　どうも〜、AtCoder修行中のsnowです。[ABC110:D-Factorization](https://atcoder.jp/contests/abc110/tasks/abc110_d)という問題の中で、素因数分解を行う場面があったので、その際に書いたコードをちょっとばかり改変して共有します。

「整数 $N$ の素因数の最大値は高々$\sqrt{N}$以下になる」という性質を利用して、$O(\sqrt{N})$で計算できるように実装していますので、大体の問題には対応できるはずです（多分、、、）。

詳細については、Wikipedia ([試し割り方](https://ja.wikipedia.org/wiki/%E8%A9%A6%E3%81%97%E5%89%B2%E3%82%8A%E6%B3%95))を確認してください。


#2. コード
```python
"""nを素因数分解"""
"""2以上の整数n => [[素因数, 指数], ...]の2次元リスト"""

def factorization(n):
    arr = []
    temp = n
    for i in range(2, int(-(-n**0.5//1))+1):
        if temp%i==0:
            cnt=0
            while temp%i==0:
                cnt+=1
                temp //= i
            arr.append([i, cnt])

    if temp!=1:
        arr.append([temp, 1])
    
    if arr==[]:
        arr.append([n, 1])
        
    return arr
    
factorization(24) 

## [[2, 3], [3, 1]] 
##  24 = 2^3 * 3^1
```

#3. おまけ 更なる高速化
　[エラトステネスの篩](https://ja.wikipedia.org/wiki/%E3%82%A8%E3%83%A9%E3%83%88%E3%82%B9%E3%83%86%E3%83%8D%E3%82%B9%E3%81%AE%E7%AF%A9)などの素数列挙アルゴリズムを用いて、事前に素数テーブルを作成しておけば、$\sqrt{N}$以下素数だけの探索で済むので、さらなる高速化が期待できます。

素数列挙には、$O(N\log \log N)$の計算量が掛かりますが、素因数分解を複数回行う必要がある際には検討してみても良いでしょう。
リアクティブプログラミングとは(ほぼリアクティブ宣言の箇条書き)

Reactiveもくもく会に参加して、はじめて「リアクティブプログラミング」を知ったので自分用にまとめてみた。
リアクティブ宣言読み直さなくても思い出すための文章になればいいかな。

# まずはざっくり Reactive Programming

[リアクティブ宣言](https://www.reactivemanifesto.org/ja)によるシステム開発におけるアーキテクチャのアプローチの一つだそうだ。

* より柔軟に
* 疎結合で
* スケーラビリティがあり
* 開発が容易になる
* 変更を受け入れやすくし
* 障害耐性を持ち、障害が起きても素早く対処できる

このようなことを実現ために、
システムアーキテクチャで以下を備えたものをリアクティブシステム(Reactive Systems)と呼ぶ。

* 即応性
* 耐障害性
* 弾力性
* メッセージ駆動

# 即応性 (Responsive)

* 迅速な応答時間を提供
* 一貫した品質
* 問題が素早く検出され対処しやすい

# 耐障害性 (Resilient)

* コンポーネントをお互いに隔離し故障が全体に影響しない
* 各々のコンポーネントの回復処理は（外部の）他のコンポーネントに委譲される
* 必要に応じてレプリケーション

# 弾力性 (Elastic)

* システムの中に競合する場所や中心的なボトルネックが存在しないように設計する
* [シャーディング](https://qiita.com/hharu/items/15627d2058bffe1fadf0)やレプリケーションしたコンポーネントで入力を分散化

# メッセージ駆動 (Message Driven)

* 非同期なメッセージをコンポーネント間でやり取りする
    * 疎結合性
    * 隔離性
    * 位置透過性
* 必要に応じてバック・プレッシャーを適用
    * 特定のコンポーネントが高負荷なので負荷を下げるように管理
* ノンブロッキング通信
    * 受信側のコンポーネントはアクティブ時のみリソースを消費

# 実現するための技術

* [ReactiveX](http://reactivex.io/)
* [RxPy(Reactive Extensions for Python)](https://github.com/ReactiveX/RxPY)

# RxPyのHello Worldやってみた

## RxPy インストール

```
> pip install --pre rx
Collecting rx
  Downloading https://files.pythonhosted.org/packages/0b/f2/15d136bfe8314ce9c6829a6658f82a0c1a1661824ca2d8d060a695a4aa61/Rx-3.0.0b4-py3-none-any.whl (187kB)
     |████████████████████████████████| 194kB 344kB/s
Installing collected packages: rx
Successfully installed rx-3.0.0b4
```

## RxPyのHello World実行

以下にあったものそのまま貼って動かしてみた。
https://github.com/ReactiveX/RxPY

test.py

```python
import rx
from rx import operators as ops

source = rx.of("Alpha", "Beta", "Gamma", "Delta", "Epsilon")

composed = source.pipe(
    ops.map(lambda s: len(s)),
    ops.filter(lambda i: i >= 5)
)
composed.subscribe(lambda value: print("Received {0}".format(value)))

```

実行結果

```
$ python test.py
Received 5
Received 5
Received 5
Received 7
```

# 用語

* FRP = 関数型リアクティブプログラミング

# 大雑把な理解

マイクロサービスを実現するためのアプローチかな。大規模なシステムを作るとき有効になりそう。
各コンポーネント間でメッセージやり取りすることで疎結合にしスケーラビリティを高くする仕組み。
Reactivexなどでよく出てくるObservableはアーキテクトが憧れる[Observerパターン](https://ja.wikipedia.org/wiki/Observer_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3)をもとにしている模様。
まだ仕組みの動きについては理解が届いていないので、もうちょっと凝ったものを作ってみて理解を深める必要がありそう。

# 参考

* [【翻訳】あなたが求めていたリアクティブプログラミング入門](https://ninjinkun.hatenablog.com/entry/introrxja)
* [リアクティブプログラミングとは何だったのか](https://qiita.com/hiruberuto/items/39e4126f470d8b84b291)
* [RxPYをひたすら素振りする](https://qiita.com/mmm_hiro/items/7c2e0b4e77a997534358)
【Rails 備忘録】staging環境にデプロイした時につまずいた箇所をまとめ

# はじめに
**AWS EC2**の**staging環境**にデプロイした際につまずいたところを備忘録として記録しておく。
後日行われるのproduction環境デプロイのために・・・

↓`つまずいた箇所`
・mini_racer
・config/master.keyをコピペ
・.envにdbに関するattrを代入
・yarnをインストール
・config/environments/staging.rb 作成(production.rbをコピペ)
・config.action_controller.forgery_protection_origin_check = false 
・config.assets.compile = true
・mailer設定

なお、Rails version: **5.2.3**

## mini_racer
`rails assets:precompile`しようとしたら怒られたので、
`Gemfile`の**`mini_racer`**のコメントアウトを削除し、bundle install。


## config/master.keyをコピペ
**mini_racer**インストール後、再度`rails assets:precompile`を実行しようとした時に、以下のエラーメッセージが表示された。

```
Missing encryption key to decrypt file with. Ask your team for your master key and write it to /var/www/app/xxxxxxxxxxxxxxx/config/master.key or put it in the ENV['RAILS_MASTER_KEY'].
```

どうやら`master.key`は **gitignore**されているため、config配下に存在していない。(`ls config`してみると確かに無い)
そのため、master.keyを作成し、**`master key`**の値をコピペする必要がある。

なお、**master key**については以下を参照。
https://qiita.com/NaokiIshimura/items/2a179f2ab910992c4d39

##.envにdbに関するattrを代入
keyやpasswordなどを`.env`で管理していたので、そこに値を代入した（というだけ）。

```.env
DATABASE_USER=''
DATABASE_PASSWORD=''
DATABASE_HOST=''
```

##config/environments/staging.rb 作成
staging.rbはデフォルトでは用意されていないため、**production.rb**をコピペして用意した。

##config.action_controller.forgery_protection_origin_check = false 
ログインページからのログインを試みたらエラーページになってしまった。
logを見ると

```
HTTP Origin header (https://stg.xxxxxxxxxx.jp) didn't match request.base_url (http://localhost:3000
```

https://qiita.com/munaita_/items/e1d36fac9515654a76de
を参考に、以下を追記。

```config/staging.rb
config.action_controller.forgery_protection_origin_check = false
```


[Railsガイド](https://railsguides.jp/configuring.html)を参照すると
**`config.action_controller.forgery_protection_origin_check`**: CSRFの追加対策としてHTTPのOriginヘッダーがサイトのoriginと合っていることをチェックすべきかどうかを設定します。

## config.assets.compile = true
アセットパイプラインはうまく行ったはずなのに、styleが反映されていなかった。

`config.assets.compile`はデフォルトでtrueだと思っていたが、実は**false**だった。
**true**に変更することによって、無事にstyleが反映された。

## mailer設定

staging.rbにmailerの設定を投入する。今回はSendGridを使用している。

```staging.rb
  # setting mailer host
  config.action_mailer.default_url_options = { host: "https://xxxxxx.jp" }
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    :user_name => 'xxxxxx',
    :password => ENV['SENDGRID_PASSWORD'],
    :domain => 'xxxxxxxx.jp/',
    :address => 'smtp.sendgrid.net',
    :port => 587,
    :authentication => :plain,
    :enable_starttls_auto => true
```

.envで`ENV['SENDGRID_PASSWORD']` を記述。
【snippets】 React Todoアプリ 

# Reactを使ったTodoアプリ開発時のSnippets

※　[Material CSS](https://materializecss.com/getting-started.html) (CDN) 使用

### App.js

```react:app.js
import React, { Component } from 'react';
import Todos from './components/Todos';

class App extends Component {
  state = {
    todos: [{ id: 1, content: 'Buy milk' }, { id: 2, content: 'Play with dog' }]
  };

  deleteTodo = id => {
    const todos = this.state.todos.filter(todo => {
      return todo.id !== id;
    });
    console.log(todos);
    this.setState({
      todos: todos
    });
  };

  render() {
    return (
      <div className="todo-app container">
        <h1 className="center blue-text">Todo's</h1>
        <Todos todos={this.state.todos} deleteTodo={this.deleteTodo} />
      </div>
    );
  }
}

export default App;

```
### Todo.js

```react:Todo.js
import React from 'react';

const Todos = ({ todos, deleteTodo }) => {
  const todoList = todos.length ? (
    todos.map(todo => {
      return (
        <div
          onClick={() => deleteTodo(todo.id)}
          className="collection-item"
          key={todo.id}
        >
          <span>{todo.content}</span>
        </div>
      );
    })
  ) : (
    <p className="center">You have no toods</p>
  );

  return <div className="todos collection">{todoList}</div>;
};

export default Todos;

```

--- 

### メモ事項

#### filterメソッドの使い方（どの様にTodoアイテムをdeleteしているか）

```javascript

console.log(1 === 1) // １と１は同じである　=> true。その通り。
console.log(1 !== 1) // １と１は同じではない　=> false。同じです！
```

つまり、

```react
  const todos = this.state.todos.filter(todo => {
      return todo.id !== id; 
      // これはfalseである。だからfilterメソッドによって取り除かれる。
    });
```

#### どの様にidを取得しているか

```javascript
onClick={() => deleteTodo(todo.id)}
// こちらでクリックした要素のidを取得する
```
[質問] デプロイや環境移行が面倒という理由でWebフレームワークを積極的に使いたくない。対策ないですか

私は（趣味レベルで）Webブラウザで動くツールを作ることがあるのだが、そのときにWebフレームワークを使うことがあまりなく、基本的にはCGIで書いてしまう[^1]。

その理由は**デプロイや環境移行が楽**である、ということに尽きる。（一度サーバソフトウェアの設定を書いておけば）あとはCGIファイルを置くだけで動くし、環境を移行したい場合もファイルを丸ごと持っていくだけで移行できるし（DBを使っていたらそれも移行する必要はありますが）。

裏を返せば、そのような障壁がなければWebフレームワークを使ってもよいのである。ただ実際には、Webフレームワークを使って書かれたアプリのデプロイは、ファイルを置くことに加え、**Webサーバソフトの設定ファイルを書き換えないとならない**というのが極めて面倒に感じるのである[^2]。「[DRY](https://codezine.jp/article/detail/11574)」という、Ruby on Railsとかが重視している考え方があるけど、この点ってDRYに反しているんですよね。

Herokuとか使えばいいんじゃないかという考えもあるかもしれないけど、できれば自前のサーバ（VPS）でこの点を解決したいと思っているのです。何かいい方法ないでしょうか。例えば「Webサーバソフトの設定ファイルを、アプリの設定ファイル側で管理することができる」（サーバにアップしたら設定ファイルを更新してくれる）というものがあるとありがたいのですが。

※あと希望としては「1サーバに1つだけアプリを置く」という想定*ではない*解決策でお願いしたいです。

[^1]: ちなみに私はRubyが好きなのでRubyで書くことが多いです。
[^2]: フレームワークによっては、CGIとして動かすモードを備えていることもあったりします。例えば[Sinatra](http://sinatrarb.com/)のCGIモードは実際に使ったことあります。
【備忘録】PHPで複数検索条件があるSQLを投げるときのクエリ作成方法

# 概要
* PHPからDBに複数条件のあるクエリを投げるときを想定
* PHPではWEB画面があり、ユーザーからデータの期間と検索対象となるファイルがアップロードされる
* ファイルに書かれた行数によってSQLクエリが変動するのでそれを補う方法を書く

# PHP
* 既にDBには接続されているものとする
* テーブルは

|    ID    |   URL    |  DATE    |
|:-----------------:|:-----------------:|:-----------------:|
| id   | url   | date  |

* アップロードしたファイルの中身(URL)は別途配列として`$uploadUrlList`に格納

```PHP
$countUrlList = count($uploadUrlList);

function createSQL($countUrlList)
{
    if (!is_int($countUrlList)) {
        trigger_error("Only Integer", E_USER_ERROR);
    }
    $sql = <<<EOM1
    SELECT
        ID,
        URL
    FROM
        TABLE_NAME
    WHERE
EOM1;
    for ($i = 0; $i < $countUrlList; $i++) {
        if ($i == 0) {
            $sql .= "(URL LIKE :sqlUrlList{$i} OR ";
        } elseif ($i == $countUrlList-1) {
            $sql .= "URL LIKE :sqlUrlList{$i});";
        } else {
            $sql .= "URL LIKE :sqlUrlList{$i} OR ";
        }
    }
    $sql .= <<<EOM2
    AND
        DATE
        BETWEEN :sqlPeriodFrom
        AND :sqlPeriodTo
EOM2;
    return $sql;
}

$conn->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
$sql = $sql_func->createSQL($countUrlList);
$prepareSqlStatement = $conn->prepare($sql);
$prepareSqlStatement->bindValue(':sqlPeriodFrom', $periodFrom, PDO::PARAM_STR);
$prepareSqlStatement->bindValue(':sqlPeriodTo', $periodTo, PDO::PARAM_STR);
for ($i = 0; $i < $countUrlList; $i++) {
    $prepareSqlStatement->bindValue(":sqlUrlList{$i}", $uploadUrlList[$i], PDO::PARAM_STR);
}
```

ちなみに対象のテーブルは当時500万行くらいあったのですが、URLとDATEにインデックスがありませんでした。
当時は、期間指定で抽出したデータをCSVに吐き出し、URLリスト（アップロードしたファイル）とで`grep -E`で抽出していました。
これでは1時間くらいかかってしまいます。
そこでURLとDATEにマルチカラムインデックス貼ることにし上記のようなクエリにした結果30秒くらいで返ってくるようになりました。
今日の学習内容


## validationのクラス化
今回はvalidationのクラス化を行いました。現在作っているプログラムは単純なものですので、あまりメリットを教授できません。ですが、これから複雑なプログラミングをするようになってくると必要になるとのことなので練習としてやってみました。

```php

<?php
//「Test」はクラス名
class Test{
// メソッドの宣言　public function メソッド名
  public function validation(){
    $err_msg1 ="";
    $err_msg2 ="";
   if(isset( $_POST["name"]) === true ){
     $_SESSION["name"] = $_POST["name"];
   }
   if(isset($_POST["email"]) === true ){
     $_SESSION["email"] = $_POST["email"];
   }
   if(isset($_POST["submit"]) === true) {
     if (empty($_SESSION["name"]) ){
       $err_msg1 = "氏名を入力してください";
     }
     if (empty($_SESSION["email"]) ){
       $err_msg2 = "メールアドレスを入力してください";
     }
     if ($err_msg1 ==="" && $err_msg2 ===""){
     header('Location:http://localhost/form/contact_form/confirm.php');
     }
   }
     return [$err_msg1,$err_msg2];
   }

}
?>
```

関数をclass{}で囲って、functionの前にpublicをつけるだけで終了。とても簡単だなと思いましたが、classには色々な使用法があるらしく今後沢山勉強することが必要そうです（汗）。

実際にクラスを使用するときにはクラスのオブジェクトを生成する必要があるため「$変数名 = new クラス名();」でインスタンスを生成してからクラスを使用します。

そのクラスのプロパティを使用するには作成したオブジェクト変数に矢印演算子(->)でクラスのプロパティを指定します。「＄作成した変数名->作成したプロパティ名（＄はいりません）」
次回は、SQLに保存したデータを編集するプログラミングを行う予定です！
アンドロイドJavaでのIllegalArgumentException: No view found for id in fragmentsの対応

<h2>いきなりでてきたIllegalArgumentException</h2>
初めて投稿してみます。
いつもは個人開発でアンドロイドアプリ作ってます。

最近エンジニアとして仕事を手に入れたので、来月７月から渋谷らへんで
働く予定です。どうぞよろしくお願いします。

さて、ちょっとこのエラーで１時間ほど潰してしまったのでシェア。

<h3>onCreate(savedInstanceState)が原因だったくさい</h3>
僕のコードだと、


super.onCreate(savedInstanceState);から
super.onCreate(null);へ変更

することで解決しました。

起動時のログイン画面部分だったのですが、バンドルのローディングがうまくいっていなかったよう。

こちらの変更でしっかりとコードが通っていたら、
savedInstanceStateが不要でしっかりとactivityが再生成されてるから問題なさげです。

<h3>参考</h3>
Understand the Activity Lifecycle
https://developer.android.com/guide/components/activities/activity-lifecycle

stackoverflow:"IllegalArgumentException: No view found for id in fragments"
https://stackoverflow.com/questions/28637046/illegalargumentexception-no-view-found-for-id-in-fragments
リスト中の要素ごとの出現回数を取得する

「リスト中の要素ごとの出現回数を取得する」というのは、
具体的には、

```python
["a", "b", "c", "c", "b", "c",]
```
から

```python
{"a": 1, "b": 2, "c": 3,}
```
を得る操作を指すこととします。

これををいくつかの言語でやってみます。

--------------------

```python:Pythonの場合
import collections

list = ["a", "b", "c", "c", "b", "c",]

counter = collections.Counter(list)
print(dict(counter))
# -> {'a': 1, 'b': 2, 'c': 3}
```

参考：[python - How to count the frequency of the elements in a list? - Stack Overflow](https://stackoverflow.com/questions/2161752/how-to-count-the-frequency-of-the-elements-in-a-list)

```php:PHPの場合
$list = ["a", "b", "c", "c", "b", "c",];

$counts = array_count_values($list);
echo json_encode($counts) . PHP_EOL;
// -> {"a":1,"b":2,"c":3}
```
参考：[PHP: array_count_values - Manual](https://www.php.net/manual/ja/function.array-count-values.php)

```java:Javaの場合
// import java.util.*;
// import java.util.stream.Collectors;
// import java.util.function.Function;

List<String> list = Arrays.asList("a", "b", "c", "c", "b", "c");
Map<String, Long> counts = list.stream()
    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
System.out.println(counts);
// -> {a=1, b=2, c=3}
```
参考：[java - How to count the number of occurrences of an element in a List - Stack Overflow](https://stackoverflow.com/questions/505928/how-to-count-the-number-of-occurrences-of-an-element-in-a-list)

--------------------

# おまけ

最初Laravelで以下のようにやってみたのですが、[PHPはそのものズバリの標準関数](https://www.php.net/manual/ja/function.array-count-values.php)がありましたね………
さすがPHP……

```PHP:LaravelのCollectionを使う場合

$list = ["a", "b", "c", "c", "b", "c",];

$counts = collect($list)
    ->groupBy(null)
    ->map->count()
;

echo json_encode($counts) . PHP_EOL;
// -> {"a":1,"b":2,"c":3}
```
ログイン保持機能

ECサイトを作成するにあたって、ログイン保持機能が必要です。ログインせずにページにアクセスするとログインを要求するように設計する必要があったのでメモを残します。

## 作りたいもの
- ログイン保持機能
- ログイン中は常にユーザの名前がサイドメニューに表示される
- ログインしないでサイトにアクセスしようとするとログインページでログインを要求する

## ログイン時の処理
`login.php`でログインに成功したとき、以下の処理を行います。

```php
<?php
session_start();
//ログインボタンが押されたときの処理
if($_SERVER["REQUEST_METHOD"]==="POST" &&  $_SERVER['HTTP_REFERER']=="http://localhost/EC/login.php"){

    $_SESSION = $_POST;
    if(isset($_SESSION['email']) && isset($_SESSION['pass'])){
      $val= new Validation();

      $email=$_SESSION['email'];
      $error=$val->login_check($email,$_SESSION['pass']);

    }
  }

 ?>
```
`login_check()`関数はユーザの有無を判定する関数で、以下のように定義しています

```php
<?php
public function login_check($email,$pass){
  $hostname = "localhost";    //ホスト名
  $userid = "iimori";    //データベースユーザ名
  $passwd = "password";    //接続パスワード
  $dbname = "databasename";    //データベース名
  $con=mysqli_connect($hostname,$userid,$passwd,$dbname);   //db接続に必要な情報を変数に入れる

          // 接続状況をチェックします
  if (mysqli_connect_errno()) {
      die("データベースに接続できません:" . mysqli_connect_error() . "\n");
  }
  $isUserExist=0;
  $isCorrectPass=0;
  $error="";

  $con->set_charset('utf8');
  $query = 'SELECT id,name,email,password FROM user';
  $result = $con->query($query);
  // クエリを実行します。
  if (!$result) {
      echo $con->error;
      exit();
  }
  while($row=$result->fetch_array(MYSQLI_ASSOC)){
    $rows[] = $row;
  }
  foreach($rows as $row){

    if($row['email']==$email){

      $isUserExist=1;

      if($row['password']==$pass){

        $isCorrectPass=1;
        $_SESSION['name']=$row['name'];
        $_SESSION['id']=$row['id'];
      }
    }

  }
  if($isUserExist==0){
    $error="入力されたメールアドレスは登録されていません。";
  }else{
    if($isCorrectPass==0){
      $error="パスワードが違います。";

    }else{

      header('Location:product_list.php');
      exit;
    }
  }
  return $error;
  // 接続を閉じます
  mysqli_close($con);
}
 ?>
```
この関数内で、ログインに成功したときにユーザ情報が入っているデータベースからユーザIDとユーザの名前を`$_SESSION['id']`と`$_SESSION['name']`に格納しています。
この変数を利用してログイン状態の判定をします。

## ログイン状態の判定
ログイン後に遷移するページには以下の処理を記述します。

```php
<?php
if(isset($_SESSION['name'])){
          echo "ようこそ、".$_SESSION['name']."さん！";
        }else{
          header('Location:login.php');
          exit;

        }
 ?>
```
ログインしていなければ`$_SESSION['name']`には値が入っていないので、ログインページに遷移してくれます。
ログイン後のページ全てにこれを記述することで、ログインなしではアクセスできなくなります。
任意の場所に図のcaptionを入れたり，labelを追加したりする

# 新規コマンドの追加

```TeX
\makeatletter
\newcommand*{\myCaption}[1]{{\def\@captype{figure}\caption{#1}}}
\newcommand*{\myLabel}[1]{{\def\@captype{figure}\label{#1}}}
\makeatother
```
上記のコマンドをプリアンブルに加えます．
図のキャプションを使いたいときは`\myCaption{キャプション名}`とします．
図のラベルを入れたいときは`\myLabel{ラベル名}`とします．

# コマンドの解説

安易にコマンドを追加したくない人のために，コマンドの解説を書きました．

## `makeatletter`と`makeatother`
`makeatletter`は，新規にコマンドを追加するときの**最初**に記述するものです．
`makeatother`は，新規にコマンドを追加するときの**最後**に記述するものです．

## `\newcommand*{}[]{{}}`
このコマンドによって新規にコマンドを追加することができます．内容は以下の通りです．

```TeX
\newcommand*{\新規の命令名}[引数の個数]{{命令の内容}}
```

### 新規の命令名について
ここにはユーザが指定する新規の命令名を記述します．
:warning:すでに登録されている命令と同じ名前を記述するとエラーになります．

### 引数について
引数とは，コマンドと一緒に`{}`で入力するもののことです．

`figure`内の`caption`コマンドの場合，

```TeX
\caption{1次関数のグラフ}
```
と記述しますが，この「1次関数のグラフ」というのが引数になります．
`\newcommand*`内の`[]`の中には，その**引数の数**を記述します．

引数には入力順序があり，`#数字`で`数字`番目の引数を扱うことができます．

引数が2つの場合を考えてみます．
例えば，以下のように新規にコマンドを登録した場合，

```TeX
\newcommand*{\myString}[2]{{\color{#2}\Large #1}}}
```
引数は2つ指定しているため，コマンドを使用するときは，

```TeX
\myString{あいうえお}{blue}
```
というように，引数に応じて`{}`を右に追加します．

### 命令内容について
ここにはユーザが指定する新規の命令の内容を記述します．

今回は図のキャプションやラベルを好きな場所で使えるようにするために，`\def@captype{figure}`コマンドを使います．
このコマンドは，その行に対して`figure`コマンド内のコマンドを使えるようにするために記述します．他にも，`table`コマンド内のコマンドを使いたいときは`\def@captype{table}`と記述します．

ここまでで，以下の通りに記述することもできます．

```TeX
% 引数なし
\makeatletter
\newcommand*{\myCaption}{{\def\@captype{figure}}}
\newcommand*{\myLabel}{{\def\@captype{figure}}}
\makeatother
```
図のキャプションを使いたいときは`\myCaption\caption{キャプション名}`とします．
図のラベルを入れたいときは`\myLabel\label{ラベル名}`とします．

しかし，新規にコマンドを登録したのにも関わらず，さらに`\caption{}`や`\label{}`として追記するのでは効率がよくないため，新規のコマンドの登録時に`\caption{}`や`\label{}`まで含めておいた方がいいと思われます．

### `\newcommand*`について
今回紹介したコマンドでは`\newcommand*`と記述していますが，`\newcommand`と記述しても大丈夫です．
違いは，**引数に改行を許可するかどうか**です．
`\newcommand`の場合は引数に改行があってもコンパイルは通りますが，`\newcommand*`の場合は引数に改行があるとコンパイルが通りません．ユーザの意図しない改行によって文書がおかしくならないように，予め`\newcommand*`にしておくことをおすすめします．

```TeX
\newcommand{\myString}[1]{{#1}}
...
これは\myString{あいう
えお}です．

% OK
```
```TeX
\newcommand*{\myString}[1]{{#1}}
...
これは\myString{あいう
えお}です．

% エラー
```


### `\newcommand*`内の`{{}}`について
命令は外側の`{}`に加えて，内部にも`{}`を加えることをおすすめします．

例えば，以下のようにコマンドを登録した場合，

```TeX
\newcommand*{\myString}[1]{\Large #1} % {}がない
```
これを実際の文書で書くと，命令内容は以下の通りに解釈されていることになります．

```TeX
この\myString{関数}は一次関数である．
↑
↓
この\Large 関数は一次関数である．
```
つまり，**コマンド以降の文字すべてが`\Large`コマンドによって大きくなってしまう**ということです．
ここで，命令内容を`{}`でさらに囲んで登録すると，

```TeX
\newcommand*{\myString}[1]{{\Large #1}} % {}を追加した
```
これを実際の文書で書くと，命令内容は以下の通りに解釈されていることになります．

```TeX
この\myString{関数}は一次関数である．
↑
↓
この{\Large 関数}は一次関数である．
```
となり，「関数」という文字のみに`\Large`コマンドが適用されていることが分かります．

# 参考文献
[完全攻略！ LaTeX のマクロ定義](https://qiita.com/zr_tex8r/items/5067307890d36c0e4882)
24時間ごとにhttp→httpsへのリンク変更を促すサイトの設定

www.e-Gov.go.jp のhttps化が話題となっていますが、

- http→httpsの変更だけでパスが同じならリダイレクトして欲しい
- リダイレクトするといつまで経ってもリンクやブックマークが修正されない

といったあたりで平行線になっているように感じられます。

そこで「24時間おきにhttp→httpsへのリンク変更を促す」という（ちょっとうざい）設定ができないか試してみました。

## 設定と解説

```
<VirtualHost *:80>
    :
   RewriteEngine on
   RewriteRule ^(.*)$ https://%{HTTP_HOST}/sorry.html [R=303,L]
</VirtualHost>

<VirtualHost *:443>
    :
   <Location "/sorry.html">
      Header set Strict-Transport-Security "max-age=86400;"
      FileEtag None
      RequestHeader unset If-Modified-Since
      Header set Cache-Control no-store
   </Location>
</VirtualHost>
```

- httpへのアクセスでは常にhttps://.../sorry.htmlにリダイレクトする（303は妥当？）
- https://.../sorry.htmlへのアクセスに対して、
 - Strict-Transport-Securityを86400秒（24時間）で返す
 - ['304 Not modified'応答にはHSTSヘッダが付かない](https://www.ibm.com/support/knowledgecenter/en/SSEQTJ_9.0.0/com.ibm.websphere.ihs.doc/ihs/tihs_hsts.html)ので対策する

以上。なんですが、検証していて、

- MaxOS MojaveのSafari(12.1.1)だとページ毎にしかHSTSが効かないっぽい
- Windows 10のEdgeだとブラウザを閉じるまでHSTSが効き続ける
- Chrome, Firefoxは両OSで期待通りの動きになる

というなかなか興味深い挙動が確認できました。 

採用したら500円ください（懐かしいお名前を拝見しました）
バリデーションにwith_options onを設定している時のテスト方法

過去のプロジェクトに後追いでテスト書いてたら`with_options on:` にURIの名前空間渡して条件分岐させているクラスがあったので調べてみた。

ググれば下記の記事がすぐ出てくるからなんてことないんだけど、日本語の記事がなさそうだったので備忘録兼ねて書くことにした。

[rails rspec model validation with with_options statement](https://stackoverflow.com/questions/37673698/rails-rspec-model-validation-with-with-options-statement)

### RSpecの場合

```ruby:sample_spec.rb
expect(sample_instance).be_valid(:condition)
```

be_validの引数に`with_options on:`で設定した条件を渡してあげるだけ

### valid?メソッドの場合

`valid?`メソッドの場合も引数に渡せばいいのかな？と思ってやってみたらそれでOKだった。

```ruby:console.rb
> sample_instance.valid?(:condition)
=> true
```
JAVAでn営業日後を求める

# JAVAでn営業日後を求める
業務ロジックを書いていると、n営業日後の日付が必要になることがあります。
(n営業日以内に処理を行わない場合アラートなど)
が、これを求めるのは結構面倒です。
休日が土日だけなら簡単に計算できますが、祝日には決まった法則がありません。
自システム上にマスタを作成して管理するか、外部から情報を取得する必要があります。

前者は自分でマスタを管理する必要があり面倒なので、今回は後者の手段で営業日を確認するクラスを作ってみました。

## できたもの

``` java

@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class BusinessDayApiAccessorServiceImpl implements BusinessDayApiAccessor {

	private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("uuuuMMdd");

	private final OkHttpClient client;

	@Override
	public LocalDate getBusinessDayAfter(LocalDate baseDate, int days) {
		return getBusinessDay(true, baseDate, days);
	}

	@Override
	public LocalDate getBusinessDayBefore(LocalDate baseDate, int days) {
		return getBusinessDay(false, baseDate, days);
	}

	private LocalDate getBusinessDay(boolean isNext, LocalDate baseDate, int days) {
		if (days == 0) {
			return baseDate;
		}
		return getBusinessDay(isNext, sendRequest(isNext, isNext ? baseDate.plusDays(1) : baseDate.minusDays(1)),
				days - 1);
	}

	private LocalDate sendRequest(boolean isNext, LocalDate baseDate) {
		HttpUrl httpUrl = new HttpUrl.Builder().scheme("http").host("s-proj.com").addPathSegment("utils")
				.addPathSegment("getBusinessDay.php").addQueryParameter("kind", isNext ? "next" : "prev")
				.addQueryParameter("date", baseDate.format(DATE_FORMATTER)).build();
		Request request = new Request.Builder().url(httpUrl).get().build();
		try (Response response = client.newCall(request).execute()) {
			String resultBody = response.body().string();
			return LocalDate.parse(resultBody, DATE_FORMATTER);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public boolean isBusinessDay(LocalDate date) {
		return sendRequest(true, date).isEqual(date);
	}
}

```

## 解説
[国民の祝日チェック](http://s-proj.com/utils/holiday.html)さんの公開されている国民の祝日APIを営業日判定の元ネタとして利用します。
このAPIは対象の日付が営業日だったらその日付を、営業日ではなかった場合は次または前の営業日を返してくれます。
よって、nに達するまで1日ずつ日付をずらしながら、APIを叩くメソッドを実行すればn営業日後(あるいは前)の日付を求めることが出来ます。
なお、APIを叩くのにOkHttpを利用しています。

### 注意点
外部へのAPIアクセスを挟む上に再帰ロジックなのでnの値は多くても10前後までが現実的です。
100営業日後とかを求めようとすると大変なことになります。(業務上あまりないとは思いますが)
万が一必要な場合は別な手段を使ったほうが無難です。
空のリストのTypeHint

Pythonで空のリストを作成する時に、Typeをどのように書くか考えていました。例えば、

```python 
from typing import List, Any

x: list = []
x: List[Any] = []
x: List[str] = []
x: List[int] = []
```

といくつかのパターンがありそうです。そこで、[PEP8 484 Type Comment](https://www.python.org/dev/peps/pep-0484/#type-comments)を見ると、

```python 
x = []                # type: List[Employee]
x, y, z = [], [], []  # type: List[int], List[int], List[str]
x, y, z = [], [], []  # type: (List[int], List[int], List[str])
a, b, *c = range(5)   # type: float, float, List[float]
x = [1, 2]            # type: List[int]
```

と記載がありました。空のリストは、`List[str]`や`List[int]`と明示的に表現するのが適切なようです。配列に何を入れる想定で作成しているかを明示的に宣言するようなイメージみたいです。
systemd で symboliclink の service を enable する

現在、 /etc/systemd/system へ手動で symlink を張ってしまうと `too many levels of symbolic links` のエラーが出るのでその解決方法です。

ここに回答があります。
https://github.com/systemd/systemd/issues/3010#issuecomment-282502364

```
# systemctl enable /path/to/git/foo/foo.service
```

手動で symblink を貼らずに上のコマンドを叩くと下のように symlink を作ってくれます。

```
/etc/systemd/system/multi-user.target.wants/foo.service -> /path/to/git/foo/foo.service                                                                                                                                                                                                       
/etc/systemd/system/foo.service -> /path/to/git/foo/foo.service.     
```

ただし、2019-07時点では、こうして設置した service はサーバの reboot 時に
Cannot add dependency job for unit foo.service, ignoring: Unit not found
のエラーが出て自動で立ち上がらないことが分かりました。
（systemctl daemon-reload したあとで start すれば立ち上がる）

解決策は色々探しましたが、以下の2つのいずれかにするしかないようです。

- symlinc は諦め unit ファイルを直接 /etc/systemd/system に copy しておく
- 再起動時に systemctl daemon-reload と systemctl start foo を実行する unit ファイルを置く

参考

- https://unix.stackexchange.com/questions/291085/systemd-linked-unit-files-on-mounted-disk-fail-to-load
- https://github.com/systemd/systemd/issues/8307
clearfixについて

# はじめに

htmlの記述を見てると時々見かけるclearfixという記述。
あまり理解できていなかったためわかったことをまとめる。

# clearfixの特徴

floatを解除できる！
自分でビューを作成していてこの特徴がとても便利に感じた。

# 1. 自分が陥った状況

```index.html.erb

<div class= contents>
  <div class= left-box>
  </div>
  <div class= right-box>
  </div>
  <div class= bottom-box>
  </div>
</div>

```

```
.left-box{
  float: left;
}
.right-box{
  float: right;
}

```

分かりやすいように必要な記述のみを記載しています。
自分の意識ではこの記述のみでleft-boxとright-boxがcontentsの中で左右に別れてくれると考えていたが実際にビューを確認するとbottom-boxがleft-boxとright-boxと重なるように上部に移動していた。
これはfloatによって浮いた2つの要素の下にbottom-boxが周り込んだためこのようなビューとなったらしい。

#clearfixを使用

```index.html.erb
<div class= contents clearfix>
  <div class= left-box>
  </div>
  <div class= right-box>
  </div>
　<div class= bottom-box>
  </div>
</div>
```

```
.left-box{
  float: left;
}
.right-box{
  float: right;
}

clearfix:after{
 　　content: "";
    clear: both;
 display: block;
}
```

この記述でfloatを解除することができcontentsの中にleft-boxsとright-boxを左右に並べ、その下にbottom-boxを配置することができる。
Gitのコンフリクトの解消法

# Gitのコンフリクトの解消法

**チーム開発時にコンフリクトが発生したのでその時の解消法になります**

コンフリクト時に、Gitのプルリクエストで右上にresolveボタンがありますが押すことができませんでした。

その時にGitHub Desktop上でHistoryのボタンを押して、ブランチの検索フォームでmasterと入力してmasterブランチを検索して選択します。

その後、下のcommitボタン(青色のボタン)を押すとコンフリクト一覧が表示され、選択するとテキストエディタ上に飛ぶと青色で表示されている部分と緑色で表示されている部分があります。

緑色ぼ部分が現在編集している部分、青色がmasterブランチの内容となっています。
色がかかっている部分で現在編集している部分で上書きするか、masterブランチの内容で上書きするか、両方を合わせて上書きするか選択できるボタンがあります。

選択するとその押したボタンに合わせて上書きされ、簡単にコンフリクトを解消することができます。
Git上でやるよりもわかりやすく簡単なのでこの方法はおすすめです

## さいごに

コンフリクトは恐れなくても大丈夫だけど、消してはいけないものは消さないようにしよう
iPhoneでAtCoderに参加する。

#1.対象 

  この記事は、以下の人を対象としています。

 - 諸事情あってパソコンは使えないけどAtCoder には参加したい人。
 - iPhoneユーザー
 - 言語はPython
 - 開発環境に1200円払える人

#2.開発環境 

  課金できる場合はPythonista というアプリが便利です。価格は1200円です。

[Pythonista3](https://apps.apple.com/jp/app/pythonista-3/id1085978097)

いいところ
- 入力補完が充実している。
- タブで複数のファイルを切り替えながらの開発が可能
- 記号入力用のボタンが使いやすい

iPhoneでプログラミングをする場合、キーを打つのが不便なために変数名を省略しがちです。しかし、Pythonista の入力補完は変数や関数にも適用されるので入力の手間を気にせずに意味のある変数名をつけることができます。

また、タブでのファイルの切り替えや、記号ボタンなど、イライラを減らす工夫があり、たいへん便利です。

#3.競プロ中のタブ配置 

iPhoneではアプリの外でのソースコードの改造の操作性が非常に悪いです。そのため、アプリ上で動作確認を終わらせ、AtCoderのサイトへはコピぺして提出するだけにする必要があります。

私は競プロ中、以下の３つのタブを開いています。

 - 問題名.py:提出するソースコードを記述します。
 - input_file.txt:入力データをコピーしておきます。
 - welcome.py:テンプレートのコピーと、入力用の関数の確認用に、practice contestのA - Welcome to AtCoderコードを開いておきます。

welcome.pyは以下の通りです。

```python:welcome.py

import sys

if sys.platform =='ios':
	sys.stdin=open('input_file.txt')
		
#+++++
	
a = int(input())
b , c = map(int, input().split())
s = input()
print(str(a+b+c) + ' ' + s)

```

if文で、iPhoneで実行した場合の標準入力をinput_file.txtで置き換えます。それにより、input関数を実行すると、input_file.txtから一行読んで出力されるようになります。
あらかじめサンプルの入力をinput_file.txtにコピーしておくことにより、実行ボタン１つでプログラムの動作確認ができるようになります。

また、AtCoderのテストサーバーはiosを使っていないので（2019年5月）、ソースコードをそのままコピペして提出することができます。
【AppStoreConnect】 ユーザ権限の変更で焦った話。

あんまり技術的な話じゃないです。

仕事とはいえ、会社で初めてのiOS専用アプリを自分が作ってしまったばっかりに、
「お前が全部把握してるんでしょ？あとのことは、お前がお前の責任でやれ」
みたいになっててツライ。
（そんなこんなで仕事に対する温度が氷点下に落ちたトコから帰ってこない・・・
　私、アプリの製造はしたけど、公開の手続きでいろいろやってる時期は病欠でいなかったんですけどね！）


さておき、会社のAppleIDの下に自分のIDがdeveloper権限で紐付いてるんですが、
どうも作業する上で権限が足りず、結局会社のID(Admin+AccountHolder)で作業することが多い。
Admin権限を付けようと設定変更(Adminにチェックを入れて保存)しようとしたところ、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126315/2b994600-b0de-f21e-acad-649a1ad6b91d.png)
「ご利用のアカウントには他のユーザを編集する権限がありません。詳細については～」
<font color="lightgray">（※このエラーメッセージで検索ひっかかるように前段だけ文字でも打っておきます。）</font>

というエラーが出て変更できない。
(ちなみに、ちゃんと会社のID(AccountHolder)でやってました)

「え、何で・・・？」と思ったんですが、
↓↓のチェックボックスにもチェックを入れたところ、無事保存できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126315/920d0cd9-2b63-b9f7-022b-32a40f30b21c.png)


iPhoneやら何やらハードをいろいろ作ったり、アプリ配信するインフラ作ったり、
Appleスゴいな～、と日々思うわけですが、
アプリ開発やってると時々こういう不親切なエラーメッセージを見つけてモヤモヤしたりもします。

ともかく、割とすぐに解決できてよかったです。
Hyperledger Fabric2.0 アルファ版をまとめてみた

###Hyperledger Fabric alpha
現在v1.4まで製品版としてリリースされているHyperledger Fabricですが
v2.0アルファ版も公開されています。
未だ開発中みたいですが、いくつか大きな変更点があるみたいなのでまとめてみました。

[公式ドキュメントをみたい方はこちら](https://hyperledger-fabric.readthedocs.io/en/latest/whatsnew.html)


####変更点１：チェーンコードのライフサイクル
従来のチェーンコードのインストールやアップグレードに関して変更が加えられています。

今までの「中央集権的な」モデルに加えて、新しく「分散型」モデルを選択することができるそうです。
以下詳細

#####その１：チェーンコードの設定に関しての合意を取れるようになった
今まではチャネル内でチェーンコードを初期化するのに際して、エンドースメントポリシーを一つの組織が決めてしまえるような状態だったが、初期化する際に設定されるパラメータに関しても組織間で合意を取ることができるようになった。

######その２：チェーンコードのアップグレードが安全に行えるようになった。
チェーンコードのアップグレードに関しても、以前は一つの組織がアップグレードのトランザクションを発行してしまうようなことが可能だった。
そうすると同じチャネル内でまだ最新版のチェーンコードをピアにインストールしていない組織があるのにアップグレードが行われてしまうことも考えられた。
アップグレードにも一定数以上組織の合意が必要という設定もできるようになった。

#####その３：エンドースメントポリシーのアップデートできるようになった。
今までは初期化かアップグレードの時にそのチェーンコードのエンドースメントポリシーが決められていたが、ポリシーの変更を行うことができるようになった。
またチャネル内の構成が変わった時にも自動で変更が行われる。

#####その４：チェーンコードの中身が簡単に確認できるようになった
チェーンコードはインストールされるときにパッケージ化されてインストールされるが、インストール後のパッケージの中身を確認するのが難しかった。そのため組織間で今どのチェーンコードのバージョンがインストールされているのかなどの確認が煩雑だった。
しかしチェーンコードをtarファイルの形でパッケージ化することにより簡単に中身の確認が行えるようになった。

#####その５：複数のバージョンのチェーンコードを一つのパッケージで扱えるようになった。

個人的にはこれが一番嬉しい

今までチェーンコードは名前とバージョンで決まった一つのパッケージとしてデプロイすることしかできなかった。
つまり別のバージョンをインストールする時にもまた新しくパッケージとしてインストールするしかなかった。
v2.0では一つのパッケージでバージョン管理ができたり名前を変えたりできる模様。


####Fab Token

UTXOモデルを使用したトークンを発行できるようになった。
もともとHyperledger Fabric内の使用されていたCA、MSPなどのアイデンティティ、メンバーシップサービスと連携しているとのこと。

ちょっと気になるので今後調べます。


####Alpine Linux
２．０以降のバージョンでは、ネットワークのDockerイメージにAlpine Linuxが使用されるようになるらしい。
Alpine Linuxはかなり軽量かつセキュリティを第一に考えて作られたLinuxのディストリビューション。
そのためイメージの軽量化とセキュリティの向上を見込めるとのこと。

参考

[超軽量なAlpine Linuxについて調べた](https://qiita.com/ryuichi1208/items/6020cfabc92bd8153654)


####オーダラーにRaftプロトコルを選択できるようになった
Raft自体はv1.4.1から選択できるようですが、２．０以降もサポートされる模様。
現在はSolo（単一障害点あり）とRaft、Kafkaが選択できます。
現在はHyperledger FabricではKafkaが使われることが多いようですが、Kafkaは管理コストが高く、今後はセットアップも管理も簡単なRaftが主流になるのかも。

こちらも気になるので今後調べます。

####まとめ
Hyperledger Fabric 2.0　アルファについてまとめてみました。
Hyperledger Fabricを触っていると、痒いところに手が届かない・・・と思うことが多いのでどんどん改良されて新機能がついたりすると嬉しいです！

参考

[公式ドキュメント](https://hyperledger-fabric.readthedocs.io/en/latest/whatsnew.html)
[勉強用] React hooksで非同期処理を書く (ステップ4)

## はじめに

[前ステップ](https://qiita.com/daishi/items/cdd1109ffa12826db44a)から続き、勉強用のuseFetchを書いていきます。今回のテーマはエラー処理です。

## 課題

これまではURLが固定でしたが、URLを変えた場合エラーになる可能性があります。また、URLを変えなくてもネットワークエラーは起こり得ます。エラー処理を追加して、エラー時にその旨を表示するなどできるようにします。

## ステップ4: error処理

```javascript
const useFetch = url => {
  const [result, setResult] = useState({});
  useEffect(() => {
    let cleanedUp = false;
    const fetchData = async () => {
      try {
        const response = await fetch(url);
        if (!response.ok) throw new Error(`status: ${response.status}`);
        const data = await response.json();
        if (!cleanedUp) {
          setResult({ data });
        }
      } catch (error) {
        if (!cleanedUp) {
          setResult({ error });
        }
      }
    };
    setResult({ loading: true });
    fetchData();
    const cleanup = () => {
      cleanedUp = true;
    };
    return cleanup;
  }, [url]);
  return result;
};
```

少し複雑になってきました。try-catchでエラーを取得するとともに `response.ok` もチェックしてエラー扱いにしています。

## 動作確認

実際に動くコードはこちらです。[codesandbox](https://codesandbox.io/s/objective-bhaskara-xlmws)

## おわりに

本コードは勉強用ですので、そのままでは使わないでください。(ちゃんとした実装は[こちら](https://qiita.com/daishi/items/f12f524e9d1df0b52d2b))
さらなる課題と解決は[次のステップ](https://qiita.com/daishi/items/a6a1caeb28f599b10517)へ。
【Rails】Herokuにデプロイする方法


##初回にやるべきこと

### git 登録
アプリケーションのディレクトリで

```
$git int
```
[~/environment/app_name (master) $] とmasterと表示されればOK



###Herokuにアカウントを作成する

Heroku：https://jp.heroku.com/home

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/85591e52-a08c-94af-c5d9-98258712cf79.png)


###Herokuにログイン

```ターミナル.
$heroku login --interactive 
```

###Herokuにアプリケーションを作成する（初回のみ）

```ターミナル.
$heroku create 好きなアプリ名
```

##変更の都度やること

###Gitを操作

####Gitで保存するファイルの選択。-Aは全部

```ターミナル.
$git add -A 
```


####git addしたファイルの保存の確定

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

###Herokuにデプロイ

####Herokuにログイン

```ターミナル.
$heroku login --interactive 
```

####Herokuにデプロイ

```ターミナル.
$git push heroku master
```

####マイグレーションの実行

```ターミナル.
$ heroku run rake db:migrate
```

###GitHub

####ソースコードをプッシュ

```
$ git push origin master
Username for 'https://github.com':accountname 
Password for 'https://accountname@github.com':password 
```


##sqliteからデータをcsvファイルに書き出す
https://qiita.com/kumakichiwel/items/5ad175111fcd841c6606

###postgresqlのインストール(初回のみ）

```
$ sudo yum install postgresql postgresql-server postgresql-devel postgresql-contrib
```

##ローカルのテーブルからcsvで吐き出しを行う

```
rails dbconsole
.headers on
.mode csv
.output hoge.csv
select * from shops;
```

##Herokuのpostgresqlに接続してcsvをshopsテーブルにインポート

###Herokuに接続する

####サーバー上のテーブルレコードを削除する場合
アプリケーションのルートに[del_shops.sql]を用意しておく

```del_shops.sql
delete from shops;
```

```ターミナル.
$ heroku login --interactive
$ heroku pg:psql
$ \i del_shops.sql
```

###csvをpostgresqlにインポート

```ターミナル.
\copy shops from 'hoge.csv' CSV header;
```

###切断

```ターミナル.
\q
```
【Swift】伝説のゴリラチャットをiOS版で作りました

##概要
僕がSwift初めて1ヶ月で作成したポートフォリオの進捗をまとめました｡
まだまだ未完成ですがそれっぽく仕上がってきたので公開します｡

![最終課題報告.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416433/c9256c9f-24d9-ee5d-28c2-d40d97881e98.png)


##ゴリラチャットとの出会い
開発経験0の僕はProgateでSwiftに触れたあとに何を作ればいいのかイメージが湧きませんでした｡
とりあえず写経しながら過ごす日々｡そんな毎日に飽きた頃Qiitaにて､この記事に出会いました｡

[ゴリラチャット作りました](https://qiita.com/gorilla0513/items/3828378f92103cba0ab0)

僕はこの記事みたいに､沢山の人を楽しませることができるアプリを作れたらいいなと思い､
SwiftでゴリラチャットのIOS版の制作に挑戦したいとゴリラ氏にDMを送り､快諾して頂きました!!

##生まれて初めて尊敬したゴリラ
こちらが昨年Qiitaを賑わせたゴリラチャットの生みの親､ゴリラ兼エンジニアのゴリラ氏です｡

[ゴリラ氏のTwitter](https://twitter.com/gorilla0513)

きっかけをくれたゴリラ氏ありがとうございました!!

##GitHubに公開
まだ試作品ですが[GitHub](https://github.com/ctbgx797/GorillaChat_DEMO)にて公開させていただきます｡
Xcodeがあればおそらく遊べると思います!!

**コードについては開発未経験の時点で察してください｡**

##SPEC
**言語** Swift 5.0.1

**frontend**
主にXcode
ライブラリは[MessageKit](https://github.com/MessageKit/MessageKit)を使用

**backend**
Firebase

##ICON

左側の顔だけのゴリラをアプリ用アイコンとして､起動時のLanchScreenでゴリラの全体像が映ります｡
![最終課題報告 (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416433/3531731e-750d-7f3e-882f-bbe4b5dad56a.jpeg)

![ダウンロード.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416433/ad2d6985-7237-73d7-c514-c9510bab83b5.gif)


##アプリ全体のイメージ

全体のImageとしてはGoogleSignIn後にゴリラの選択画面へ遷移し､
選択したゴリラがアバターとなりチャットが開始されます｡

**こんな感じ↓**

<img width="416" alt="最終課題報告_-_Google_スライド-3.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416433/39bf9200-6a67-1d9e-7f59-047d3b6c2dd1.jpeg">


##モード

チャット画面の右上のスイッチが､メイン機能のゴリラモードと人間モードの切替スイッチになります｡

<img width="117" alt="iPhone_Xʀ_—_12_2.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416433/bf795024-3bf9-d7c8-685d-8a6a6c3073a7.jpeg">

<img width="121" alt="iPhone_Xʀ_—_12_2-2.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416433/ab6f2ed4-4a18-429b-63fd-3e978ac5c7c0.jpeg">

ゴリラモードと人間モード両方でチャットすることができます｡
基本はゴリラ語でお話して、ちょっとゴリラ語が難しかったら人間の言葉に翻訳してくれます｡

ここは元祖ゴリラチャットと同じです｡

##今の僕の課題
現在付け焼き刃で画像の情報をそのまま渡しているので､画像に番号を割り振ってそれぞれのユーザに反映できるようにしなければチャットアプリとして成立しません｡

ググったところFirebaseStrage機能でなんとかできるのではないかと思ったので着手中です｡

<img width="462" alt="最終課題報告_-_Google_スライド-2.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416433/079267b3-dd2c-8d2a-8b26-95964acb9930.jpeg">

他にもチャットアプリなので､某大手企業のような機能を実装できたらより楽しめるかなぁと思い検討しています｡

##参考にした記事
[ゴリラチャット作りました](https://qiita.com/gorilla0513/items/3828378f92103cba0ab0)
[【iOS12対応】未経験者が有名アプリ開発者になるiOS 12の全て 20個以上アプリをつくりプロになる](https://www.udemy.com/ios12_swift5_iphonex/)
[【Swift】リアルタイムチャットを実現するFirebaseでCRUD(データ作成、読み込み、更新、削除)をやってみる](https://qiita.com/ShinokiRyosei/items/f71c73ab8b0de145c5bc#8-delete%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E5%89%8A%E9%99%A4)
[MessageKitを使用したチャットアプリでのテキスト送信について](https://teratail.com/questions/191932)
brew doctorした時のWarning['Unbrewed header files']解消とNode.jsをインストール

brew doctorしてみるとWarningが出たので解消方法とnodebrewでnode.jsをインストールした議事録です

brew doctorの存在を知り自分のターミナルで実行してみるとまさかの**Warning**が...
[![Image from Gyazo](https://i.gyazo.com/b7a1401104ed473f8f43315d1ec2cb3f.png)](https://gyazo.com/b7a1401104ed473f8f43315d1ec2cb3f)

見てみるとnode関連のファイルがエラーを引き起こしている。
"これらのファイルを故意的に置いていないのならhomebrewする時にエラーを起こすかもしれないから消したほうがいいですよ"みたいな解釈。

記憶にないがnodeをhomebrewなしでインストールしたのかもしれない。

[解決方法はこの記事にあるように1.放置するか2.消してhomebrewから再インストールするか](https://stackoverflow.com/questions/26406484/brew-doctor-warning-unbrewed-header-files-were-found-in-usr-local-include)

自分は今後homebrewでエラーが出てデバッグするのが嫌なので**2.消してhomebrewから再インストールするか**にします。

とりあえずコマンドこれらをremoveしていきます。

##解決方法

`sudo rm -r /usr/local/include/node/`を打ち込んでターミナルで**brew doctor**してみると
[![Image from Gyazo](https://i.gyazo.com/f0ca970e36fc46a72e9b91abb2341c88.png)](https://gyazo.com/f0ca970e36fc46a72e9b91abb2341c88)
..よかった。

##nodebrewをインストール
その前にNode.jsのバージョン管理ツールであるnodebrewをインストールします。

`brew install nodebrew`

***nodebrewはNode.jsのバージョン管理ツールです。***
***複数のバージョンをインストールし切り替えたりすることができます。***
***rubyで言うrbenvみたいな感じです。***

```
You need to manually run setup_dirs to create directories required by nodebrew:
  /usr/local/opt/nodebrew/bin/nodebrew setup_dirs

Add path:
  export PATH=$HOME/.nodebrew/current/bin:$PATH

To use Homebrew's directories rather than ~/.nodebrew add to your profile:
  export NODEBREW_ROOT=/usr/local/var/nodebrew

Bash completion has been installed to:
  /usr/local/etc/bash_completion.d

zsh completions have been installed to:
  /usr/local/share/zsh/site-functions
```
インストール出来ました。

次にパスを追加していきます。
上の通りにすれば良さそうです。
`$ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bash_profile
 $ source ~/.bash_profile
`
##Node.jsをインストール
[![Image from Gyazo](https://i.gyazo.com/91f5274305f9de26e9874ad98017b2fe.png)](https://gyazo.com/91f5274305f9de26e9874ad98017b2fe)
`nodebrew ls-remote`でversionを確認できるみたいですが今回は最新版をインストールします。

`nodebrew install latest`
[![Image from Gyazo](https://i.gyazo.com/230b97b0e9f1ed954d652c5b6eef2319.png)](https://gyazo.com/230b97b0e9f1ed954d652c5b6eef2319)
エラーが出たのでディレクトリとファイルを作成します。
`mkdir -p ~/.nodebrew/src`

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

成功！

以前と比べてコマンド操作の不安もなくなってきて何となくの成長を感じております。
ご覧いただきありがとうございました！
Angular Databinding #memo

#はじめに
AngularはMVCモデルを使って、viewはDOM、controllerはJavascript、Modelはjsにobjectのプロパティが保持されたデータ。

#Data Binding
Angularは{{data}}構文でDOMにデータを表示する。

#Model定義
先ずはModelの生成。```$ ng generate('g') <schematic>```
schematicに応じたファイルを生成する

```
$ ng g class('cl') models/article
```

###Articleモデル
anyにより動的に型を与えることができる。
今回はjsonで扱うので

```typescript:article.ts

export class Article {

    articleId: number;
    articleTitle: string;
    articleContent: string;
    niceCount: number;
    pictureUrl: string;
    createdBy: string;
    createdAt: Date;
    updatedAt: Date;

    constructor(article: any = {}) {
        this.articleId = article.articleId || 0;
        this.articleTitle = article.articleTitle || '';
        this.articleContent = article.articleContent || '';
        this.niceCount = article.niceCount || 0;
        this.pictureUrl = article.pictureUrl || '';
        this.createdBy = article.createdBy || '';
        this.createdAt = article.createdAt || new Date(2000, 1, 1);
        this.updatedAt = article.updatedAt || new Date(2000, 1, 1);
    }
//      constructor() {
//        this.articleId = 0;
//        this.articleTitle = '';
//        this.articleContent = '';
//        this.niceCount = 0;
//        this.pictureUrl = '';
//        this.createdBy = '';
//        this.createdAt = new Date(2000, 1, 1);
//        this.updatedAt = new Date(2000, 1, 1);
//    }
}
```
###Mock Object
mockとはテストに必要な部品の値を擬似的に設定するもの。

```typescript:mock-article.ts
import { Article } from './article';

export const ARTICLES: Article = {
    articleId: 1,
    articleTitle: '記事タイトル',
    articleContent: '記事文章内容',
    niceCount: 2,
    pictureUrl: '',
    createdBy: 'spa.training',
    createdAt: new Date(2019, 1, 1),
    updatedAt: new Date(2019, 1, 1)
};
```
#ModelからViewへ
###Component
```typescript:article-list.component.ts
import { Component, OnInit } from '@angular/core';
import { ARTICLES } from '../../models/mock-articles'; 

@Component({
  selector: 'app-article-list',
  templateUrl: './article-list.component.html',
  styleUrls: ['./article-list.component.scss']
})
export class ArticleListComponent implements OnInit {

  article = ARTICLES; 
  constructor() { }
  ngOnInit() {
  }
}
```

Safe Navigation Operator(?.)によりobjectがnull(or undefined)の場合続くプロパティへアクセスしない

```html:article-list.component.html
<br>
<!-- Article Card List -->
<div class="card">
  <div class="card-body">
    <h5 class="card-title">{{article?.articleTitle}}</h5>
    <p class="card-text">{{article?.articleContent}}</p>
    <div class="card-footer">
      <div class="item">
        <i class="fas fa-heart"></i> {{article?.niceCount}}
      </div>
      <div class="item">
        <img src="{{article?.pictureUrl}}" class="rounded-circle" ngbTooltip="{{article?.createdBy}}" placement="bottom"/>
        {{article?.createdAt}}
      </div>
    </div>
  </div>
</div>
```
Firebase(Web)Tips

## SDKのApiReferenceでググるときはSDKという語句を入れて検索しよう
SDKという語句を入れないとWebAPI(httpのやつ）が出てきて邪魔だぞ
[「firebase sdk reference web」などでググる](https://www.google.com/search?ei=H98VXdqvOtXVmAXC9YqIDA&q=firebase+sdk+reference+web&oq=firebase+sdk+reference+web&gs_l=psy-ab.3..33i21.1165.1748..2015...0.0..0.127.452.4j1......0....1..gws-wiz.......0i30j0i8i30j33i160.TKoj_BpCmac)

## SDKのApiReferenceはすごい重いから片っ端から別のタブで開くと良い
普通に使ってたらストレスでハゲる

## 組織でプロジェクトを作りたいときはまずはGoogleCloudPlatformから
1. GoogleCloudPlatformで組織を作る
2. 自身のアカウントをジョインさせる
3. Firebase上でプロジェクトを作る
4. GoogleCloudPlatform上でも認識されているので、メンバーの追加など必要があればいじる

で私はうまくいった

## (with Nuxt) fuctionsが読み込まれて、nuxtのdev serverを起動すると、functions以下のソースでエラーが出る
functionsがprojectルートに配置されていてnuxtと同居している環境。
functionsはfirebase-toolsのinitで生成された別のnpmプロジェクトなので、topLevelのnuxtからは一切参照したくない。

nuxtはfunctionsというディレクトリはデフォルトで読まないが、typescript関係でなぜか読まれるようだ。
tsconfig.jsonでexludeにfunctionを指定すればOK。

## (with Nuxt) fuctionsが読み込まれて、lintを起動すると、functions以下のソースでエラーが出る
functionsがprojectルートに配置されていてnuxtと同居している環境。
functionsはfirebase-toolsのinitで生成された別のnpmプロジェクトなので、topLevelのnuxtからは一切参照したくない。



```package.json
...
scripts: {
  "lint": "eslint --ignore-paths .gitignore [+ --ignore-pattern: /functions +] ."
}
...
```

ignore-pathsに加えて他のディレクトリを除外する方法はないかググってたら見つけた。
うまく動いてますね。

---

これからどんどん知見を記事に追加していく予定
IE11 で "&not" などのHTMLエンティティがふくまれたURLに location.href しようとすると文字実体の方にジャンプする

# 問題

IE11で次のコードを実行すると、 `&not` がHTMLエンティティと解釈されて `¬`（否定記号) になり、 `/search?q=some_search_word¬_flag=true`にジャンプする。

```javascript
location.href = "/search?q=some_search_word&not_flag=true";
// => /search?q=some_search_word¬_flag=true にアクセスする
```

# 解決(なのか?)

逆に `&` にしたいなら `&amp;` にしちゃえばいいのか？と以下を実行したら意図通り `/search?q=some_search_word&not_flag=true` にジャンプした。


```javascript
location.href = "/search?q=some_search_word&amp;not_flag=true";
// => /search?q=some_search_word&not_flag=true にアクセスする
```

`location` の挙動がHTMLの表示に影響されてる？そもそもセミコロンがなくて `&not;` じゃないから文字参照としても正しくない挙動な気がするが、何か別の仕様があるんだろうか。

# 参考ページ

- [文字参照 - Wikipedia](https://ja.wikipedia.org/wiki/%E6%96%87%E5%AD%97%E5%8F%82%E7%85%A7)
- [Entity (エンティティ) - MDN](https://developer.mozilla.org/ja/docs/Glossary/Entity)
- [特殊エンティティの一覧 - W3C](https://dev.w3.org/html5/html-author/charref)
- [Location - MDN](https://developer.mozilla.org/ja/docs/Web/API/Location)

IEのバグなのかな？同じやり方で直してる方がいた。

- [Internet Explorer: HTML entities in URL - Stack Overflow](https://stackoverflow.com/questions/42893076/internet-explorer-html-entities-in-url)
- [Accidental HTML entities in URLs - Ned Batchelder](https://nedbatchelder.com/blog/200812/accidental_html_entities_in_urls.html)
TECH ~Day6~

六日目の学習を終え、クラスとインスタンスの新たな使い方を学習しました。今までの学習と照らし合わせながらでないと、若干混乱してしまうような内容が出てくるので、毎度冷や汗を掻きます。

学習内容
・インスタンス変数とクラス変数の定義
・クラス変数とインスタンス変数の違い
・initializeメソッド
・クラスの継承
・モデリング


・インスタンス変数とクラス変数の定義
インスタンスメソッドの定義内で行う。
インスタンス変数は、変数の先頭に「＠」を一つつける。

書き方
　class クラス名
　　def sample
　      @test = “ex”
　   end
   end

クラス変数の定義
クラスの範囲内などからでも参照できる変数。
クタスの定義内でおこなう。
クラス変数は、変数名の先頭に@@を二つつける。

（例）
　　class  Review
　　　@@review_count =0
　　　def  ~~~~
          ~~~~
     end
！クラス変数はクラスメソッド、インスタンスメソッドの両方で使える。


・クラス変数とインスタンス変数の違い
クラス変数
　変数名・・・最初に＠＠（アットマーク二つ）
　使えるメソッド・・・クラスメソッドとインスタンスメソッド
　値・・・クラスとインスタンスで共通

インスタンス変数
　変数名・・・最初に＠（アットマーク一つ）
　使えるメソッド・・・インスタンスメソッド
　値・・・インスタンスごとに異なる


・initializeメソッド
他のインスタンスメソッドと同じように定義できる。

（例）
　class Menu
　　def initialize
　　　puts "メニュー生成"
   end
　end

 menu1 = Menu.new
！Menu.newが入力されると自動でinitializeメソッドが呼び出される。

　ターミナル
　　メニュー生成


・クラスの継承
あるクラスに定義されているメソッドを別のクラスで利用できるようにすること。
継承には「親クラス」と「子クラス」の関係がある。
元となるクラスを「親クラス」、親クラスのメソッドを引き継ぎ新しく作成するクラスを「子クラス」と呼ぶ。

書き方
　class 子クラス名　<　親クラス名
！親クラス→クラス的なもの
！子クラス→インスタンス的なもの


・モデリング
やりたいことをプログラムに落とし込むために必要な工程の一つ
iPad OS対応で困っていること。

# 概要

WWDC 2019でiPadのOSがiOSから独自のiPadOSに変わることが発表された。
担当している業務では、ユーザーエージェントによって画面の出し分けを行っているのだが、iPadについてはユーザーエージェントにiPadが含まれることを条件としていた。
しかし、iPadOSのユーザーエージェントが下記の通りであるため、改修が必要になった。

```
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148
```

# 対応

とりあえずの対応として今までユーザーエージェントがiPadであることとしていた箇所に、Macintoshであることという条件を追加した。
これにより、iPadだけでなくMacBook等でも利用できるようになってしまったが、ここは許容した。

# その他

iPhoneでも設定等で「デスクトップ用サイト表示」にするとユーザーエージェントからiPhoneという文言が消え、Macintoshとなった。
ユーザーエージェントの判定にMacintoshを追加したことにより、こちらも対応できるようになったが、iPhoneとiPadの区別が出来なくなってしまった。

同じようなことで困った方、何か対応をした方がいればコメントしていただけると嬉しいです。