OmniAICreator/Qiita-1.07M huggingface dataset:
ReactNativeバージョンアップ作業は新規プロジェクトに移植方式が良い (v0.48.4 -> v0.60.5)

2年ぶりにiOSアプリのReact Nativeのバージョンアップ作業を行いました。v0.48.4 -> v0.60.5。バージョンをひとつ上げるだけでも苦しめられていたのに、これだけ大幅なバージョンアップは気が遠くなる苦行に違いありません。だけど、[Google アナリティクス開発者サービス SDK が終わってしまう](https://support.google.com/analytics/answer/9167112?hl=ja)ため、他のアクセス解析を導入する必要がありました。

## 新規プロジェクト立ち上げ方式

この困難な道のりを出来るだけ平坦にする良い方法はないか模索してみました。そして、既存プロジェクトのReactNativeバージョンを上げてエラーと格闘するよりも、最新のReactNativeで新規プロジェクトを作成し、そこにソースコードを移植する方が簡単ではないかという結論になりました。実際どうなのかは不明ですが、この新規プロジェクト立ち上げ方式に託してみることに。

```
react-native init NewProject
cd NewProject
npm install
react-native run-ios
```

新規プロジェクトはまぁ普通に動いたので、とりあえず使いたいモジュールをpackage.jsonに追加してみました。すると、ReactNative v0.60から追加されたautolinkなるものが非常に便利。package.jsonにモジュールを追加してnpm installした後にpod installすると、Xcodeプロジェクトへの追加やバイナリのinclude設定などを自動的にしてくれます。autolink以前はXcodeのモジュール設定でうまく行かずclean&buildを繰り返していた記憶があるので、この作業時間がなくなるのは素晴らしいです。モジュールを削除してからnpm installすればちゃんとXcodeからも削除もしてくれます。

ただし、autolink未対応のモジュールや古いモジュールについては、対応されるまで待つか、以前のように手動でXcodeに追加する必要があります。手動追加する場合は、プロジェクト直下にreact-native.config.jsというファイルを作って以下の記載をすることで、[指定したモジュールのautolinkを動かなくしておきます](https://github.com/react-native-community/cli/blob/master/docs/autolinking.md#how-can-i-disable-autolinking-for-unsupported-library)。

```
module.exports = {
   dependencies: {
    'realm': {
      platforms: {
      ios: null,
      },
    },
  },
}
```

使っているモジュールのうち、realmのみこの手動追加が必要でした。[realmについてはautolink対応がissuesに上がっていて](https://github.com/realm/realm-js/issues/884)、現時点では対応済みみたいなので、次からはautolinkに切り替える必要があります。

## realm動作確認用の簡易ソース

```
import React from 'react'
import { Text } from 'react-native'
import Realm from 'realm'

const ExampleComponent = (props) => {
    return ( Hello world!)
}

export default class App extends React.Component {

  render() {
    let realm = Common.getRealm()
    return (
    );
  }
}
```

## React Navigationアップデート

というわけで、まずはrealmが動く状態にしてから、既存プロジェクトからappディレクトリ、index.jsなどをコピーして再びrun-ios。そして、React Navigationのバージョンを上げないとダメっぽいので最新版に。更に、いくつかのエラーに対応しました。

エラー「unable to raesolve module reactnative-gesture-handler」-> いくつかのモジュールがスピンアウトしたらしく、[Getting started · React Navigation](https://reactnavigation.org/docs/en/getting-started.html)を参照してインストールしたらOK。

エラー「bundling failed: Error: Unable to resolve module `./navigators/createContainedStackNavigator」-> [キャッシュクリアで解消](https://github.com/react-navigation/react-navigation/issues/4895)

```
npm start --reset-cache
```

エラー「undefined is not a function (evaluating '(0,_reactNavigation.stacknavigator)')」-> StackNavigatorが消滅してCreateStackNavigatorになっていたので修正。更に、同じような感じで以下の関数を修正。
TabNavigator -> createBottomTabNavigator
StackNavigator -> createStackNavigator

[addNavigationHelpersが消滅していた](https://stackoverflow.com/questions/50246457/react-native-reactnavigation-addnavigationhelpers-in-not-a-function)ので修正。

## 無事？アップデート完了

色々修正したりしましたが、事前に想像していたよりも作業がサクサク進んだ気がします。もっと死ぬかと思ってた。すべてをクリアして一からやり直す下記コマンドはそんなに何度も使うことなくエミュレータ動作確認まで漕ぎ着けることができました。

```
rm -r node_modules && npm i && cd ios && pod install && cd .. && react-native run-ios
```
【EV3 x Python】スワップ領域を作成する方法

# 概要
ev3に搭載されているRAMは合計で64MBで，`free`コマンドでメモリーの容量はすでに作られているスワップ領域と合わせメモリー量は152MB．**これでは少なすぎる**（`apt-get install`などで落ちることがしばしば・・・）のでもっと増やしてやりましょう．

# スワップ領域とは
> スワップ領域とは，搭載されている物理メモリがいっぱいになったときに，使っていないデータを退避させるための領域．本記事ではスワップ領域はSDカード上に作成します．

# 実際に作ってみる
今回は512MBのスワップ領域作ってみたいと思います．
## まずはスワップ領域となるファイルを作る
```bash
sudo dd if=/dev/zero of=/var/swap bs=1M count=512
```

# 実行権限をつける
```bash
sudo chmod 644 /var/swap
```
## スワップ領域の作成
```bash
sudo mkswap /var/swap
```

## スワップ領域を有効にする
```bash
sudo swapon /var/swap
```

## Before → After
freeコマンドのTotalに表示されている数値がメモリの容量です．
### Before
```bash
robot@ev3dev:~$ free -h -t
              total        used        free      shared  buff/cache   available
Mem:            56M         15M        1.9M         16K         38M         36M
Swap:           95M        7.7M         88M
Total:         152M         23M         90M
```

### After
```bash
robot@ev3dev:~$ free -h -t
              total        used        free      shared  buff/cache   available
Mem:            56M         16M        1.6M         16K         38M         36M
Swap:          601M        7.7M        594M
Total:         658M         23M        595M
```

# 再起動後にもスワップ領域がマウントされるように・・・（追記：2020/01/17）
スワップ領域を再起動後に自動でマウントされるように`/etc/fstab`を編集します．
まずはev3のターミナルで下のコマンドを入力してテキストエディタを開きます．

```bash:ev3上のターミナル
sudo nano /etc/fstab
```

```bash:/etc/fstab
#<file system>  <mount point>   <type> <options>                           <dump> <pass>
/dev/mmcblk0p1  /boot/flash     vfat   defaults,errors=remount-ro,noatime  0      2
/dev/mmcblk0p2  /               ext4   defaults,errors=remount-ro,noatime  0      1
proc            /proc           proc   defaults                            0      0
tmpfs           /run            tmpfs  nosuid,noexec,size=20M,nr_inodes=4096 0    0
#↓ここから下を追記
/var/swap	swap		swap	defaults			0	0
#↑ここまで
```
`nanoエディタ`はCtrl+oで保存，Ctrl+xで終了することができます．詳しい説明方法はGoogleで調べてください．
Bugsnagで特定のエラーの通知を無効化する

最近の勉強で学んだ事を、ノート代わりにまとめていきます。
主に自分の学習の流れを振り返りで残す形なので色々、省いてます。
Webエンジニアの諸先輩方からアドバイスやご指摘を頂けたらありがたいです！

#BugsnagでRailsの不具合を通知
Railsのエラー監視にBugsnagを利用しています！Slackとの連携をしていてエラーが発生したら通知が飛ぶ様にしております。
今回は、Bugsnagのエラーで通知されるエラーは優先度が高いもののみにしたかったのサービス自体に影響がないエラーの通知を一旦無効化することになりました。
[Bugsnagと黒魔術で、Railsの不具合調査を楽にする仕組み！ | 株式会社スタメン](https://stmn.co.jp/tech/4431/)

#Bugsnagで特定のエラーを無効化する

Bugsnagの公式ドキュメントを確認してみると以下の様な記述がありました！
これによると個々のエラーは破棄できます。 破棄されると、エラーはダッシュボードからすぐに削除され、受信した後続のイベントは保存されなくなる様です！

```
Discard individual errors
#
Individual errors can be discarded. When discarded, errors are immediately deleted from the dashboard and subsequent events that we receive are not stored.
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394657/9d80857e-6a1d-e22c-5bd4-3a94d1ee27fd.png)
[Bugsnag docs › Product › Managing event usage](https://docs.bugsnag.com/product/event-usage//)

#特定のエラーを破棄する
今回、通知を無効化したいので特定のエラーを選択し画像の様に削除しました！
![Screen Shot 2020-01-13 at 10.04.42 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394657/28a86c4c-c1fd-ff60-f4e4-8a174f8cceab.png)

エラーを削除したら、このエラーの今後の発生は保存されず、イベント制限にカウントされません。とのメッセージが表示されました！

```
Discard specific errors via the additional actions (...) menu in the dashboard. Future occurrences of these errors won't be stored or count towards your event limit.
```

この対応で無事、無効化できました！
Goutteで空港情報を取得してみる

# はじめに

友達との作品制作で空港の情報が欲しくなった時にスクレイピングしてみようと思い

下記のサイトさんがたくさんの情報が載っていたのでスクレイピングしようと思いました。
https://www.airlineguide.jp/airport-codes/

PHPやLaravelは初心者でいろんな方の記事を参考にさせていただきました

[Laravel/Goutteで映画タイトルをクローリングする](https://qiita.com/vivid_colors/items/feecf2af1dd646f7395a)

[Goutte(PHP)でスクレイピングしてみる](https://qiita.com/fksk/items/6807d5de07f93114087c)

利用するものとしては友人がLaravelを使用していたのでそれに合わせました

※スクレイピングについては色々あると思うので自己責任でお願いします。

Laravelのバージョンは5.5.45です

## スクレイピングとは

>スクレイピングはサーバサイドのプログラミング言語を使って外部サーバへアクセスし、そのコンテンツから自分たちの欲しい情報を引き出す手法です。多くはHTMLを返す場合に使われ、DOMを解析したり正規表現を使ってデータを抜き出します。 
引用([スクレイピングとAPIの違い](https://developer.ntt.com/ja/blog/e007f5ca-292b-48b6-9fcb-e8051a1f9889))



## 取得した情報
- 空港コード
- 空港名

の三つの情報が欲しいのでサイトをみてみます

<img width="1098" alt="スクリーンショット 2020-01-13 23.59.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519400/be00a296-af6a-e967-564e-352e7e63615d.png">

画像内のテーブルタグに囲まれた
- 1つ目　空港コード
- 3つ目　空港名 OR ３つ目の項目が空なら４つ目の項目を取ろうと思います
## controller

``` AirPortController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Goutte;
use Illuminate\Support\Facades\DB;

class AirPortController extends Controller
{
    //
    public function index(){
        $url = 'https://www.airlineguide.jp/airport-codes/';

        $airCode = array();
        $count = 0;

        $crawler = Goutte::request('GET', $url);
        $crawler->filter('table tr')->each(function($node) use(&$airCode,&$count) {

            if(count($node->filter('td'))){
                //空港コード
                $airCode[$count]['code'] = $node->filter('td')->eq(0)->text();
                //空港名
                if($node->filter('td')->eq(2)->text() === ''){
                    $airCode[$count]['airPort'] = $node->filter('td')->eq(3)->text();
                }else{
                    $airCode[$count]['airPort'] = $node->filter('td')->eq(2)->text();
                }
                $count++;
            }

        });

        //DBに空港情報登録
        foreach ($airCode as  $value){
            DB::table('airports')->insert(['airport_code' => $value['code'],
                'airport_name'=> $value['airPort']]);
        }

    }
}
```

## ルーティング

``` web.php
Route::get('/search','AirPortController@index');
```

## 結果

無事

- 空港コード
- 空港名

が取得できました

一つ空白の項目があるのは後からAPIとかで国コードを挿入するためです

<img width="881" alt="スクリーンショット 2020-01-13 23.57.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519400/ae83b115-d2e8-f8d7-6c0e-61d6fa45cea9.png">
React hooks　機能紹介

Reactを使った開発をし始めたので、機能たちを紹介しようと思います。

<h2>React hooksにはいろんな機能があってとてもロジックを組みやすい</h2>
個人的な見解ではありますが、僕はそう感じました。
前バージョンの段階では、よく目にしたのは複雑だったりなんか難しそうだったり、なんか開発者向きなんでしょ？的なのがあったかと思いますが、React hooksが正式リリースして利用してみるとあれって？ってくらい使いやすいわかりやすいと思いました。


下記が主に使用したHoooksたちになります。
<h3>useState</h3>

```react
  const [state, setState] = useState()
```
<h3>useEffect</h3>

```react
  useEffect(() => {
    
  },[]);
```
<h3>useMemo</h3>

```react
  const メモ名 = useMemo(() => {

  },[]);
```
<h3>useCallback</h3>

```react
 const コールバック名 = useCallback(() => {
     
 },[]);
```

useMemoとuseCallbackについては、なかなかはじめ理解にしにくいかと思いますが、ポイントは<strong>メモされた関数の返却かメモされた値の返却か</strong>なのかなと思います。個人的に腑に落ちたのは返却のタイミング（メモのタイミング）が違うってこと思ったことです。

[ ]←こちらについては、簡単に説明しますと<strong>対象</strong>です。
<strong>対象</strong>が、[a , b]のようにあるとそれぞれのタイミングで何かしらのa , bを処理できます。
くらしくは、<a href="https://ja.reactjs.org/docs/hooks-reference.html">フック API リファレンス</a>を参考にどうぞ。

簡単なまとめではありますが、以上になります。
他にも、様々な機能がありますので、ぜひ利用してみてください。
各種乱数生成器の性能と性質

手元のマシンで乱数生成器の性質を TestU01 で調べてみた。

マシンは MacBook Pro (Retina, 15-inch, Mid 2015)。
OS は普通に macOS の最新。
コンパイラは g++-9 (Homebrew GCC 9.2.0_2) 9.2.0

TestU01 は、 repを10にして SmallCrush を実施。都合 15種類を10回ずつで 150回テスト。
処理時間は、$2^{28} $≒ 2億7千万 回乱数を振った時間。関数呼び出しやループ処理の時間を含む。

# 結果

|名前|エラー率|処理時間|補足|
|:--|--:|--:|:--|
|rand48(libc)|32.7%|825ms| `mrand48` を利用 |
|rand(libc)|60.0%|1686ms|man には「bad random number generator」とある |
|random(libc)|74.0%|943ms|man には「better random number generator」とある |
|std::knuth_b|0.0%|17182ms|KnuthのリオーダーアルゴリズムB|
|std::minstd|21.3%|7837ms|線形合同法|
|std::mt19937|0.0%|1078ms|メルセンヌ・ツイスタ|
|std::ranlux24|0.0%|33509ms|RANLUX法のレベル3|
|std::ranlux48|0.7%|47029ms|RANLUX法のレベル4|
|XorShift128|6.7%|402ms|
|xoroshiro128++|0.0%|327ms|
|xoroshiro128**|0.0%|315ms|

#　まとめ

エラー率 0% の乱数がいくつかあるけど、それらの間の優劣は判断できない。
エラー率を見ると **rand(libc)** よりも **random(libc)** の方が悪い。意外。
速さとエラー率を見る限り、やはり **xoroshiro128++** か **xoroshiro128\*\*** を選ぶのが正解っぽい。
GKEのコンテナネイティブ負荷分散が想像以上に効果的だった話



## 背景

GKEのオートスケールは、便利ですがいくつか不満もありました。例えば、**ノードによってトラフィックの割合が均一化されない**と言う問題です。オートスケーラによってPodが増えた場合、新しいPodへのトラフィックはすぐに均一化される訳ではなく、段階的に上昇していきます。これはk8sのデフォルトでの負荷分散の仕組みに起因するものだと思うのですが、新しく作成されたPodが直ちに有効活用されません。この影響で、急なスパイクには対応しにくいですし、安全に運用するためにはオートスケールの条件を緩める必要がありました。

以下のチャートは、Podごとに負荷の推移を観察したものです。新しく作成されたPodの負荷が、既存のPodと同じ水準の負荷に増えるまで、2~3時間かかってるのがわかると思います。

<img width="577" alt="スクリーンショット 2020-01-12 12.28.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79302/3df84b65-4bf0-7b7f-1a80-aa27302d2400.png">


## コンテナネイティブ負荷分散を使ってみる

去年の10月、GKEでコンテナネイティブ負荷分散が正式リリースされました。
https://cloud.google.com/kubernetes-engine/docs/how-to/container-native-load-balancing?hl=ja

既存の負荷分散だと、`LB -> インスタンスグループ -> ノード -> Pod` と言う流れでトラフィックが送られます。
コンテナネイティブ負荷分散だと、`LB -> Network Endpoint Group -> Pod` と言う流れになり、ノードを介さずに分散されます(Network Endpoint Groupに関しての詳細はドキュメントを見ていただけると)。

## コンテナネイティブ負荷分散を既存のサービスで有効にする

留意点はいくつかありますが、コンテナネイティブ負荷分散を使用するために行うことは非常に簡単です。serviceリソースのmetadataに以下のannotationを追記するだけです。


```yaml
apiVersion: v1
kind: Service
metadata:
  name: service名
  annotations:
    cloud.google.com/neg: '{"ingress": true}' # これを追記する
```

反映されるまでに4~5分かかります。稼働中のサービスで行う場合、一時的にトラフィックが途切れるので注意してください。

## 目に見えてトラフィックが均一化された！

コンテナネイティブ負荷分散を有効にした結果、Podへのトラフィックが均一化され、Podごとの負荷も均一になりました。

以下のチャートは、コンテナネイティブ負荷分散を有効にする前と後で、同じ時間帯(4時〜12時)におけるPodごとの負荷を観察したものです。

### Before
<img width="876" alt="スクリーンショット 2020-01-12 12.44.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79302/8f89641d-1b5f-f034-2193-8bdc714b9966.png">


### After
<img width="885" alt="スクリーンショット 2020-01-12 12.43.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79302/59b9dc7f-5a86-c182-ec9b-5b3c2a75559e.png">


有効にする前と比較すると、明らかにPodごとの負荷が均一になっていますね。またそれだけではなく、オートスケーラーによって新しく作成されたPodの負荷も、直ちに既存のPodと同じ水準まで増加しています。

## まとめ

と言うわけで、コンテナネイティブ負荷分散をGKEで使ってみたわけですが・・・これはGKEでオートスケールを利用する場合はほぼ必須と言ってもいいくらい効果があると感じました。実際にこれを利用することで、安定運用に必要なノードの台数を削減することが出来ました。

今回扱ったコンテナネイティブ負荷分散はGCPのネットワークエンドポイントを利用するものですが、k8s側で同様の機能が提供されればAWS等他のプロバイダでも使えるので、今後はその辺にも期待したいです。
PythonGUI（tkinterコンボボックス）で行列を作成

GUI（tkinterコンボボックス）で行列の要素の値を入力し２次元配列型のデータを取得するソースです。行列のサイズ、コンボボックスのリストも変数により変更可能。

```ruby:qiita.rb
from tkinter import *
from tkinter import ttk
import numpy as np


#入力用のGUI
def GUI_Input(n,m):

    root = Tk()
    root.title('Table Input')

    #入力用フレーム
    frame = ttk.Frame(root)
    frame.grid(row=0, column=0)


    list_Items = [0]*(n*m)
    N = n
    M = m
    k=0
    for i in range(0, n):
        for j in range(0, m):


            valuelist = [1,2,3,4,5,6,7,8,9]
            list_Items[k] = ttk.Combobox(frame,values=valuelist,width = 2)
            list_Items[k].grid(row=i+1, column=j+1)
            k+=1


    #コンボボックスからデータを取得し２次元配列としてpritnt出力
    def ButtonClicked_Run():
        B = [0]*(N*M)

        for i in range(N*M):
            B[i] = list_Items[i].get()

        A= np.reshape(B, (N,M))
        print(A)


    #実行ボタンの設置
    button_Run = ttk.Button(root,
                            text='実行',
                            padding=5,
                            command=ButtonClicked_Run)
    button_Run.grid(row=1, column=0)

    root.mainloop()






#n、mの数を変えて、行列のサイズを指定
m = 9
n = 9
GUI_Input(m,n)

```

結果
<img width="395" alt="スクリーンショット 2020-01-13 23.25.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527324/fc5df9fc-f4c7-e70d-291f-1b58972c882e.png">
　　　　　　　　　　　　　⬇︎
　　　　　　<img width="224" alt="スクリーンショット 2020-01-13 23.26.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527324/0c8abeb1-65e9-cad8-d9b2-8d0cc75dc417.png">
GlideApps Mapまとめ

# はじめに
この記事はGlideAppsのMapについてまとめたものです。
［FEATURES］と［ADD］についてはまとめていません。

地図に必要な情報をスプレッドシートに入力し、Glideの［Address］等の各項目にスプレッドシートの情報を紐付けるだけで地図アプリが作成できますので、興味があれば参考までにどうぞ。

![map01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/fbb336f4-f0c9-d696-9c85-3a3fa5eee35d.png)

今回はglideがTemplateとして提供してくれている「City Guide」アプリをベースにまとめていきます。

データは次の通りです。(データはTemplate用に提供してくれているものなので、念のために画像ファイルが保存されているURLだけ塗りつぶしています)
![map02.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/b5098d07-8adc-a426-1a15-885857f8d5dc.png)

# Mapとは
データの中にある住所データを使用してデータを表示するSTYLE。

親画面として**Map画面**と**List画面**が存在。この２つの画面は右下のフローティングボタンで切り替える。
![map03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/50a8d519-071b-7548-a811-5d7523810b51.png)

子画面として**Detail Screen**が存在。親画面で選択したデータの詳しい情報が表示されます。
![map03b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/11d52172-7605-0016-99e8-ecf72a623d01.png)



## DATA

アプリの画面項目に表示させるスプレッドシートのデータの設定。

画面のどこが、どの設定で、どのスプレッドシートのデータと紐づいているのかを下図に示す。

![map04.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/cff1c768-c151-5a51-f698-e389a1c79ed4.png)

［Address］は住所 or 緯度経度から位置情報を取得して、地図上にマーカーを表示させる。(不正な住所や緯度経度が入力されている場合、マーカーは表示されない)
※［Address］は、住所よりも座標(緯度経度)の方が精度が高く、アプリの速度も速いようです。


## OPTIONS

### Allow user to show current location

ユーザーの現在地を表示させるかどうかの設定。
チェックを付けると下図の様に、おなじみの現在地表示マークが表示され、タップする事で現在地が表示される。
![map06.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/beffe548-348b-71af-fc21-e886572109c0.png)

## DESIGN

### Default View
アプリ起動時に、最初に表示する画面を設定。

**Map画面**と**List画面**のどちらかを選択。

### Action

Map内のデータをタップした時の動作の設定。

- Link Detail Screen: Map内のデータをタップするとDetail Screenに遷移する
![map07a.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/07359390-4570-30d6-16af-a06d534c0964.png)
![map07b.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/48036638-485c-fa81-1552-faffc68a0772.png)

- None: List内のデータをタップしても何もしない

# Detail Screen

Detail Screenは他のStyleでも使用可能なので記事を分けました。
[こちらの記事](https://qiita.com/takahiro-kato/items/e7e0f66c7d8050235dfc)をご覧下さい。

# 最後に
Templateとは別に、自分で地図アプリをゼロから作ってみましたが、簡単に地図アプリが作れるのでビックリしました。

地図に必要な情報をスプレッドシートに入力し、Glideの［Address］等の各項目にスプレッドシートの情報を紐付けるだけです。

この手の簡単にアプリが作成できるサービスには制限が付きものですが、それが要件に引っかからなければ強力なサービスです。

最初はGlideでプロトタイプを作成し、可能であればそのままリリース、改良が必要であれば別途作成という進め方も良いかもしれません。
GlideApps Detail Screenまとめ

# はじめに
この記事はGlideAppsのDetail Screenについてまとめたものです。

STYLEのDetailではなく、ListやMap等のStyleの子画面としてのDetail Screenです。

ただ、Titleの有無等の違いはあるものの、基本的に大きく変わりはなさそうなので、STYLEのDetailの参考にもなると思います。

今回使用したデータは次の通りです。
![image01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/bd123707-2d73-9aca-43ab-0d205ff42429.png)

# Detail Screen

1件のデータに対して詳細な情報を記載するためのSTYLE。

ListやMap等に表示されているデータを選択した時に遷移する**Detail Screen(データ詳細画面)**。

他のSTYLEとは違い、データをある程度自由に表現する事が可能。例えば、項目の数や並べ方等。

他にも「お気に入り」や「Video」機能等も実装可能。

## TITLE
タイトルの設定。

アイコンで`Custom`と`From Data`が選択可能。

`Custom`は自分でタイトルを入力する事が可能で、`From Data`は選択したスプレッドシートのカラムの値がタイトルになる。

TITLEが、どのアプリの画面項目と紐づいているのかを下図に示す。
![layout-list-detailscreen-title01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/06a469d3-05f3-a73b-304b-1f1ae10105da.png)

## COMPONENTS

アプリの画面項目に表示させるスプレッドシートのデータの設定。

画面のどこが、どの設定で、どのスプレッドシートのデータと紐づいているのかを下図に示す。
![layout-list-detailscreen-components01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/a14a940a-e03c-5946-7169-aaea4ead6756.png)

COMPONENTSの設定、例えばラベル名(項目名)やタップ時のアクションを変更する場合は、COMPONENTSのボタンをクリックする。
![layout-list-detailscreen-settings01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/fc416348-0fac-cedf-c2ce-ae268acc5823.png)

すると、次のような設定画面(下図はBasic Textの設定画面)に切り替わるので、自分が希望する設定に変更する。
![layout-list-detailscreen-settings-basictext01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/92931d96-9bdf-eec8-586c-8e874da8e48a.png)

COMPONENTSの詳細は1つの記事が作れるくらいのボリュームがあるので、今回は割愛します。
（いつか記事にするかもしれません...）

# 最後に
Detail Screenは簡単に構成する分には難しくありませんが、マスターするとなると難しそうです。

というのもDetail ScreenのキモとなるCOMPONENTS(FavoriteやVideo等)の種類が多く、全てをマスターするには時間が掛かりそうだからです。

今後、機会があればCOMPONENTSを使ったアプリを作成して、記事にしたいと思います。
頼むからGraphQLのクエリを動的に組み立てるのはやめてくれ

主にapolloの話。

https://github.com/Shopify/graphql-js-client のようなクエリビルダを使ってるんだったら別。

ここでいう「動的に」というのは、下記のように通常の文字列結合で引数とかselection setを突っ込むようなコードを指している。

```js
apolloClient.query(gql`
  query {
    procucts(${variables}) {
      id
    }
  }
`);
```

当たり前なんだけど、`variables` に `"first: 10) { __typename } users(first: 10"` みたいな文字列を突っ込んだら、想定とは全く異なるクエリになって何が起こるかわかったもんじゃない。

変数はGraphQLのvariablesに格納するようにしろ。

```js
apolloClient.query(gql`
  query MyQuery($first: Int!) {
    procucts(first: $first) {
      id
    }
  }
`, { variables: { first } }));
```

要は **クエリは静的に決定された状態にしておけ** というのが言いたいだけなんだけど、実行結果が想定外になる、というだけじゃなく、他にも弊害が色々ある。

例えば冒頭のコード、`gql` というTagged Templateを使ってて、apolloでコード書いたらよく出てくるんだけど、こいつは中身の文字列をparseしてGraphQLのASTに変換する役割を持っている。`gql` は一度parseしたASTは元のクエリ文字列をキーにしたObjectに格納してcacheとして利用するように実装されている。折角cacheを持っているのにそこにhitしなかったらメモリの無駄、というのもあるし、このcacheはただObjectにガンガン値突っ込んでるだけで、LRUとかそういうことは一切していないので、SSRの文脈でこのコードをNode.jsのサーバーで動かしたらメモリリークを引き起こす。

クエリの文字列をメモリ上に持ち続ける、というのは persisted queryの文脈などでも出てくる。この場合はクエリ文字列のhash値をキーに、parseしたASTやクエリ文字列を値にした辞書を中間層に保持することになるが、もしクエリが動的にコロコロ変わるようになっていたら、こういった仕組みだってやはり真当に動作しない。

大概のケースだと、codegenとかその手の静的な解析ツールを書けたときにこういう行儀の悪いコードは見つけられると思っていたけど、 `apollo client:codegen` コマンドだと特にエラーも警告も吐かずにそれっぽい型ファイルを生成してしまうのも質が悪い。
Dockerでnginx等を使う時はまずLinuxの知識をだな......(戒め)

## DockerとかVagrantでnginx等を使う時はまずLinuxの知識をだな......(戒め)

#1. 背景
フロント学んできて、そろそろバックエンドもまなんでみようと思い、せっかくなので流行りのDokcerを使用しPHPでサーバーに画像をアップロードするコードを書いた。
そしてハマった

#2. 環境

・windows10<VirtualBox(vagrant)<CentOS7<Docker

起動構成

```docker-compose.yml
version: '3'
services:
  web:
#ver 1.17.7
    build: ./nginx
    ports:
      - '8080:80'
    links:
      - php-fpm
    volumes:
      - ./data/public:/var/www/html/public
    depends_on:
      - php-fpm
  php-fpm:
#ver 7.3
    build: ./php-fpm
    links:
      - db
    volumes:
      - ./data:/var/www/html
```
#3. ハマったところ
このPHPの一行からなるエラーで無限に悩んだ

```php:upload.php

move_uploaded_file($_FILES['image']['tmp_name'], $savePath);
```
![SnapCrab_NoName_2020-1-13_17-51-41_No-00.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439731/bddedb88-bed6-72ef-c950-4a1318924291.jpeg)

Permisson denied ......

##4.1　まずやったこと
とりあえず浅いLinuxの知識を用いて画像保存フォルダの権限を
`$sudo chmod 777 images`
としてコードが動くのを確認。
もちろんこんなセキュリティガバガバな権限は例えローカルサーバーでも許せなかったので却下

##4.2 解決策
phpinfoでユーザーを確認してみる。
![SnapCrab_NoName_2020-1-13_18-30-53_No-00.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439731/e877c5de-c7bd-c335-4768-be5a481c309e.jpeg)

www-dataがUSERだと判明。
じゃあwww-dataに権限付与してあげればよさそう

vagrant環境下の権限はこう

```
$ls -l
~
drwxrwxr-x. 2 vagrant vagrant 4096 Jan 13 08:32 images
~
$ sudo chown www-data images
chown: invalid user: ‘www-data’
```

有効ではないと告げられたのでユーザー一覧を確認してみます



```
$cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
~
vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
```

これ以外にも色々出てきたけどwww-dataユーザーなんて存在しない。


####どうすればいいのか

コンテナを立ち上げて
```docker exec -it [id] bash```
でphp-fpmコンテナに入ってみる。
その中のファイル権限は

```
drwxrwxr-x. 2 1000 1000 4096 Jan 13 08:32 images
```
__1000 1000__？

調べてみたらvagrantユーザーのuidが1000らしい。

これも`$cat /etc/passwd`でユーザー一覧を確認すると

```
vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash
```
vagrntのuidに1000番が付けられてるのが分かる

VMという仮想環境の中にさらに仮想コンテナがあってそのコンテナ内では1000番uidに名前がついていないという事らしい
つまりコンテナ内では1000番にvagrntユーザーも含めユーザーは存在してないという事
でもuidは共通みたいだ


ならばコンテナ内から確認すればwww-dataがいるはず......

```
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
```
いた

####結局どうすればいいのか

正解なのかは分からないけど思いついたのはコンテナ外で33番UIDでグループがvagrantのユーザーを作ってimagesフォルダの持ち主を33番に変える。
これが自分の中でしっくりきました。
というかこれ以外成功してない

```
$useradd -u 33 www-data -g vagrant
$chown www-data images
```



他にも
https://gtrt7.com/blog/nginx/docker_userid_share#3docker-composeyml
のようにしてvagrant側からではなくdocker側から合わせればいけるらしい。


自分はこんなエラー出てわからんくて投げてしまいましたが

```
web_1      | 2020/01/13 13:52:54 [emerg] 1#1: host not found in upstream "php-fpm" in /etc/nginx/conf.d/default.conf:20
web_1      | nginx: [emerg] host not found in upstream "php-fpm" in /etc/nginx/conf.d/default.conf:20
```

default.conf:20`fastcgi_pass php-fpm:9000;`



##正直分からん


Dockerコンテナ内でファイル関係は完結させた方がいいんだろうなと感じてはいるもののいいやり方が浮かばず今回は断念。

ちょっと深堀するにはLinuxやnginx php-fpm等の知識が足りないので今はphpでファイルアップロードしたフォルダを作るさいは適宜権限変更するこのやり方のまま進んで、強くなったら戻ってこようと思いました。



いいやりかたあったら教えてほしい......
UnityでDUALSHOCK4を対応させる方法

私はチームでUnityを使いゲームを制作していました
ゲームを作っているとそのゲームをコントローラーでしてみたいということになり
私はUnityでコントローラーを使えるようにしました
そのやり方を載せてます

まずは私のUnityのバージョンと使用するコントローラーから説明します
バージョンは**2018,3,9f1**で、コントローラーは**PS4**の**DUALSHOCK4**です

ここからコントローラーを対応させる方法を説明します
まずUnityを開くと左上に
File　Edit　Assets　GameObject
と、10個の項目があります
その中の左から2番目の**Edit**を選択しその中の**Project Settings**を選択します
するとAudio Editorなどの様々な項目が表示されますがその中の**Input**を選択すると更に項目が出てきます
そして下の方にFire1,2,3とあります
今回は**Fire1**を使います
まずはFire1を開き1番上にある**Name**を変えます
ここはその項目の名前を決めるので自分が分かりやすい名前に変えることを推奨します
次に**Positive Button**に**joystick button 0**と入力します
このjoystick button 0とはDUALSHOCK4の**四角ボタン**のことを指しています。他にもjoystick button 3は三角ボタンになります
後は**script**で変更した名前を使い、ゲームに反映させれば完了です
これでUnity内でDUALSHOCK4の四角ボタンを押すと実行されます
例としてはゲーム内で四角ボタンを押すとアイテムを使用するなど

ということで説明はここまでです
今回のこれは**初投稿**なうえに**Unityもそこまで詳しくない**ので間違った事を言っていると思います
更に**説明不足**なところもあるので他のサイトの情報を見ることをお勧めします
分かりにくかったと思いますが温かい目で見てくれると助かります
Unityゲーム開発3Dアプリの解像度とfps

# 以下現職の方に聞いたメモ
- 端末の解像度に応じてカメラの位置を替えたりすることもできる。
- また、３Dのゲームアプリで高品質、低品質といった設定を選択できるものがあるが、これは「[レンダーテクスチャ](https://gametukurikata.com/camera/rendertexture)」を使えば実現できる。
  - レンダーテクスチャを使えば、その他例えばゲームシーン中に監視カメラのオブジェクトを用意してその監視カメラに描画する、といったこともできる。
- 低品質にするには、例えばレンダーテクスチャの解像度を1/2にしてこれをキャンバスに描画するみたいなイメージ。
- レンダーテクスチャの解像度(pixel数)が下がれば負荷も下がる。
- プログラミングなしで実現可能。
- fpsはバッテリーに影響する。60fpsで３Dだとあっという間に減っていく。
- fpsが出ないのはスクリプト側よりもレンダリングの方の影響が大きいケースが多い
- ゲームビュー右上のStatsというところのBatchesという部分が重要。80くらいに抑えられるのがよい。
Unityゲーム開発での実機テスト

# 以下現職の方に聞いたメモ
- 推奨端末はシェアで決めたりする。
- iPhoneはメモリがつらいがCPUは高性能なので動作がカクつくことがあまりない
- Androidは機種によりまちまち。XPeria、Galaxyといった人気機種では熱が上がってしまってCPU性能が制限されることがある。
- クラッシュログを送信してくれるミドルウェアをアプリに仕込んでおくと、リリース後の不具合対応に役に立つ。
- エラーを例外処理で握りつぶしまくると、重要なログがとれなくなってしまうことがあるので要注意。
- 個人開発をする上では、コスト上実機検証をしっかりとすることは難しいかと思う。
- メモリやCPU負荷周りの動作確認をするのであれば自身が持っている端末で十分では。
- ちゃんと画面に映っているか？という解像度周りのチェックはUnityエディタ上ですればよい。
【Python】 PythonでJSONを使う

# はじめに
Pythonでjsonのデータを扱うことがあったのですが、Python標準のdict型と親和性があるので紹介します。

# jsonとは
[こちら](https://qiita.com/chihiro/items/dd1912c1406dbfe16b72)とても参考になります。ありがとうございます。
JavaScript Object Notation
データを表現するための記法です。
JavaScriptの構文に似ていますが、JavaScriptとは独立して扱われます。
JavaScript以外のプログラミング言語でもJSONを扱うことができる機能が準備されています。

この記事はJSONを使っていくことを中心な記事なので細かい説明は省略します。
形式は以下のようなものです。keyに対してvalueが紐づいているという感じです。

```
{
  "key":value,
  "key":value,
  "key":value
}
```

keyとvalueのセットというのはPythonのdictと同じですね。

# Pythonのjsonモジュール
Pythonにjsonモジュールが存在します。dict⇔jsonの変換を主にやってくれます。

dictからjsonへの変換には`json.dumps`を使います。
dictの型はもちろんdictですが、変換後はstr型になります。

```Python
import json

sample_dict = {"Japan":"Tokyo","UK":"London","USA":"Washington, D.C."}

print(type(sample_dict))
print(sample_dict)

# 出力
# <class 'dict'>
# {'Japan': 'Tokyo', 'UK': 'London', 'USA': 'Washington, D.C.'}

# 変換
sample_json = json.dumps(sample_dict)

print(type(sample_json))
print(sample_json)

# 出力
# <class 'str'>
# {"Japan": "Tokyo", "UK": "London", "USA": "Washington, D.C."}

```

# pandasからjsonに変換する
pandas DataFrameやpandas Seriesからもjsonに変換することができます。個人的にpandasはよく使うのでありがたいです。
pandasDataFrame(Series)からjsonへの変換は`to_json()`を使います。

```Python
import pandas as pd

df_sample = pd.DataFrame([[1,1,1],[2,3,4],[8,7,6]],columns=["x","y","z"],index=["A","B","C"])
json_df = df_sample.to_json()

print(df_sample)
print(json_df)

# 出力
   x  y  z
A  1  1  1
B  2  3  4
C  8  7  6

{"x":{"A":1,"B":2,"C":8},"y":{"A":1,"B":3,"C":7},"z":{"A":1,"B":4,"C":6}}

```

# jsonを読み込む
jsonのデータを読み込むには json.loads を使います。
先ほどのsample_jsonを使います。

```Python

dict_json = json.loads(sample_json)

print(type(dict_json))
print(dict_json)

# 出力
# <class 'dict'>
# {'Japan': 'Tokyo', 'UK': 'London', 'USA': 'Washington, D.C.'}
```

もちろんdict_jsonはPythonのdictなので

```Python
print(dict_json['Japan'])

# 出力
# Tokyo
```

このような形でアクセスできます。

# おわりに
jsonはpythonだけでなくほかの言語でも使えるので言語間の通信に便利です。ここでは最低限しか説明してませんがぜひ使ってみてください！

# 思ったこと
自分が使ってみて、とかの視点で書いているのでまったく網羅的に触れることができていない記事ばかりだなと思いました。とりあえず今後も自分が使ってみたものについて書いてみて、見直す必要があった場合は記事を更新していこうかなと思います。
【Python】グラデーションを作る関数を作った

#やりたいこと
![無題のプレゼンテーション.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257157/85236293-9288-48b7-e736-63501283e17d.jpeg)

たくさんデータがあるとき、matplotlibで普通にプロットすると大変見づらいです。
配布資料にするにも、自分でデータから傾向を読み取るにも不便です。
なのでグラデーションにしたくなります。

#やったこと

numpy.linspace みたいにグラデーションを作れる関数を作りました。

使い方
1. gradation 関数をコピペ
2. カラーコード(sRGB)をググって、start, endに入れます。
3. return がsRGBの文字列のリストになっています。

```python
import numpy as np
import matplotlib
import matplotlib.pyplot as plt


def gradation(start="#CCCCCC", end="#00519A", step=5):
    """
        before use it
        import numpy as np

    return like this:
    ['#cccccc', '#bc9aa8', '#b95ba9', '#8b2aa9', '#370e83']
    """
    from colorsys import rgb_to_hls, hls_to_rgb
    if len(start) != 7 or len(end) != 7:
        raise Exception(
            f"argument length must be 7: now{len(start)}, {len(end)}")
    rgb_s = (int(start[i:i + 2], 16) / 256 for i in range(1, 4))
    rgb_e = (int(end[i:i + 2], 16) / 256 for i in range(1, 4))
    hls_s = np.array(rgb_to_hls(*rgb_s))
    hls_e = np.array(rgb_to_hls(*rgb_e))
    diff_hls = hls_e - hls_s
    # color is circle
    diff_hls[0] = (diff_hls[0] + 0.5) - np.floor(diff_hls[0] + 0.5) - 0.5
    hls_list = [hls_s + diff_hls * i / step for i in range(step)]
    rgb_list = [hls_to_rgb(*p) for p in hls_list]
    # Transeform floor rgb to Strings rgb
    str_rgb = []
    for rgb in rgb_list:
        str_rgb.append(
            f"#{int(rgb[0]* 256):02x}{int(rgb[1]* 256):02x}{int(rgb[2]* 256):02x}")
    return str_rgb


def main():
    nsinx = 5
    x = np.linspace(0, np.pi * 4, 100)
    dx = np.pi / (nsinx)
    sinxes = [np.sin(x - i * dx) for i in range(nsinx)]
    gra = gradation(start="#CCCCCC", end="#00519A", step=nsinx)
    for i, sinx in enumerate(sinxes):
        plt.plot(x, sinx, label=f"dx*{i}", lw=3, color=gra[i])
    plt.legend()
    plt.show()


if __name__ == "__main__":
    main()
```
追記
関数内でのimportなどPEP8に準拠してません。
コピペで簡単に使えるようにするためです。
コピペコーディングスタイルは保守性がまるでだめです
なんとかしたいが、パッケージングするほどでもないので
なんかいいアイデアあったら教えてもしいです
#参考文献
大変参考になりました。
ありがとうございます。
[Python でグラデーション中の色を求める](https://qiita.com/BlueRayi/items/0709013ee0a7b6cf5096#fn1)
#19 AdMobを使う場合のアプリの申請1例

#はじめに
個人のメモ程度の出来なのであまり参考にしないで下さい．


#環境
Xcode：11.2.1
Swift：5.1.2
2019/11


##part1
全て`はい`を選択する．

<img width="1190" alt="スクリーンショット 2020-01-13 午後11.11.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534708/2a0ac2cb-a4a7-0073-c82a-9549cd448858.png">

<img width="1189" alt="スクリーンショット 2020-01-13 午後11.11.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534708/2ba951ef-4673-1508-0ea1-cae8a7c70bc0.png">
基本のGitコマンド

#はじめに
チーム開発でよく用いれれているGitHubを使用するために必要なコマンドをまとめたいと思います。
前提としてGitHubのアカウントを登録しているという条件で進めていきます。
登録していない方は下記のリンクより行ってください。
[GitHubへの登録/ログインはこちらから](https://github.co.jp/)

#基本的なコマンドについて
**・初期設定を行う**

```コマンド:
$ git config --global user.name "（GitHubのユーザーネーム）"

$ git config --global user.email "（GitHubのアドレス）"
```

**ローカルにリポジトリを作成して、リモートにプッシュする**

```コマンド:
//リポジトリを新規に作成
$ git init

//全てのファイルの場合
$ git add .
//指定したファイルのみ場合
$ git add (ファイル名)

$ git commit -m "（プッシュした時のコメント）"

//プッシュ先のプロジェクトを選択
$ git remote add origin https://github.com/（アカウント名）/（プロジェクト名）.git

//マスターにプッシュする場合
$ git push -u origin master
//ブランチにプッシュする場合
$ git checkout -b （ブランチ名）
☆checkout:移動
☆-bファイル作成
$ git merge （ブランチ名）
```

リポジトリをコピーする

```コマンド:
$ git clone https://github.com/（アカウント名）/（プロジェクト名）.git
```

#最後に
箇条書きになってしまいましたが忘却録としてのこします。
for文のネストをstreamで書いてみる

### 概要
for文をネストすることで、2つのリスト内要素の組み合わせを得られる。
Streamで同じことを行うとしたらどう書けば良いか。


### for文

```java
public static void main(String[] args) {

        List<Integer> numList = List.of(1, 2);
        List<String> strList = List.of("A", "B", "C");

        for (Integer i : numList) {
            for( String j : strList) {
                System.out.println(i + "," + j);
            }
        }
    }
```

#### 出力
```
1,A
1,B
1,C
2,A
2,B
2,C
```

### Stream

flatMapを用いて1,N変換を行い、変換を行った要素をmapで整えてあげれば良い。

```java
public static void main(String[] args) {

        List<Integer> numList = List.of(1, 2);
        List<String> strList = List.of("A", "B", "C");

        numList.stream().flatMap(i -> strList.stream().map(j -> i +","+ j))
                .forEach(System.out::println);
    }

```
【Rails】destroyメソッドを使用しようとしたら"ArgumentError (wrong number of arguments (given 0, expected 1)):"

## はじめに
Railsの`destroy`メソッドを使用しようとしたら以下のように**引数が1つ必要なのに見つかりません**とエラーが発生しました。
凡ミスですが、記録として残します。

```shell
ArgumentError (wrong number of arguments (given 0, expected 1)):
```

## 環境
```yaml
OS: macOS Catalina 10.15.1
Ruby: 2.6.5
Rails: 6.0.2.1
```
## 結論：解決法
今回のコードは以下のようになっていました。

```ruby
def destroy
  posts = Post.where(user_id: 1)
  posts.destroy #ここでエラー発生
end
```
↓

```ruby
def destroy
  post = Post.find_by(user_id: 1)
  post.destroy #これは通る
end
```
このように、`find_by`にすると通ります。

もしくは、該当データが複数ある場合は

```ruby
def destroy
  Post.destroy_by(user_id: 1) #これも通る
end
```
のように`destroy_by`メソッドを使えば該当データをまとめて削除することが出来ます。

## 原因：`destroy`は配列を処理できない
`where`だと該当するデータが1件であっても**配列**で返すようになっています。

そのため、配列を処理できない`destroy`は**引数が見つかりません**とエラーを吐いてしまっていたんですね:sweat_smile:



## おわりに
最後まで読んで頂きありがとうございました:bow_tone1:

どなたかの参考になれば幸いです:relaxed:

## 参考にさせて頂いたサイト（いつもありがとうございます）
- [Active Record の基礎 - Railsガイド](https://railsguides.jp/active_record_basics.html)
ローカルで管理していたgitをGitLabリモートリポジトリにmaster pushする

ローカルでgit管理していたプロジェクトをGitLabに上げる方法の備忘録。

## 前提条件

- ローカルでgit管理していたプロジェクトがある。
- GitLabで予め新規のリポジトリを作成しておく。仮にxxx.gitとする。

## ローカルリポジトリにGitLabリモートリポジトリを設定する

ローカルリポジトリの参照先リモートリポジトリを設定する。

```
git remote add origin git@gitlab.com:XXX/xxx.git
```

設定できたかは下記で確認できる。

```
git remote -v
```

結果は下記になるはず。

```
origin  git@gitlab.com:XXX/xxx.git (fetch)
origin  git@gitlab.com:XXX/xxx.git (push)
```

## GitLabのmasterを上書き可能な状態にする

ここからはGitLab側の設定。
予め作っておいたプロジェクトのBranchを開く。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566525/22e8347f-9d1c-d0c0-ab05-cf958e98f214.png)

project settingsをクリックする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566525/5e5d49f7-f887-ad16-0b4d-9997169b26b5.png)

Protected BranchesをExpandする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566525/0716c36d-a88d-346e-6135-192db75a4c01.png)

masterをUnprotectする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566525/547da984-6bc0-d77c-d777-9a703a253c5e.png)

警告が出るのでOKする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566525/0b1405e2-a9ae-fd0f-9c57-e8c80f7fdbdb.png)

## ローカルリポジトリをGitLabのmasterにpushする

ローカルに戻ってリモートリポジトリに強制pushする。

```
git push -f -u origin master
```

下記のように出力される。

```
Enumerating objects: 142, done.
Counting objects: 100% (142/142), done.
Delta compression using up to 4 threads
Compressing objects: 100% (137/137), done.
Writing objects: 100% (142/142), 4.38 MiB | 59.00 KiB/s, done.
Total 142 (delta 62), reused 0 (delta 0)
remote: Resolving deltas: 100% (62/62), done.
To gitlab.com:XXX/xxx.git
 + XXXXXXX...XXXXXXX master -> master (forced update)
Branch 'master' set up to track remote branch 'master' from 'origin'.
```

## GitLabのmasterをProtecedに戻す

最後にGitLabに戻ってmasterのProtectを設定し直す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566525/f3173d14-f214-2f38-194c-669ea59b6e4f.png)

これでローカルでgit管理していた内容はGitLabに上がった。
【Unity】一定時間ごとに指定した関数を実行する方法

#1. Google検索にて一定時間で実行する方法を検索すると
検索上位の情報では以下の様なヒントが出てくると思います。
- Time.deltaTime
- Time.time

#2. Time.deltaTimeなどを使った時のデメリット
- **時間管理をミスる可能性が高い**
- **バグの原因になる可能性がある**
 
この２種類の関数を用いた時の特徴としてはIF文を書く必要がありますが、沢山の処理があった場合は可読性を落とす事なります。

#3. 何を使えばいいの？
**InvokeRepeating()**を使用すればキレイに解決します。

簡単な説明は以下の通りです

``` C#
InvokeRepeating("使用したいメソッド名", 開始時間, 何秒後に再実行);
```

<br>
サンプルコードは以下の通りです。(スマホの位置情報を一定時間毎に更新したい)

``` C#:sample.cs
/// <summary>  起動時間(秒)　</summary>
private const float START_SECONDS = 0.0f;
/// <summary>  更新間隔時間(秒)　</summary>
private const float INTERVA_SECONDS = 1.0f;

// Start is called before the first frame update
void Start()
{
  InvokeRepeating("UpdateMyPhoneLocation", START_SECONDS, INTERVA_SECONDS);
}

private void UpdateMyPhoneLocation(){
  //GPSデータを取得
}
```

#4. InvokeRepeatingのメリットは？
読んだ人は思うでしょう。。。
Time.deltaTime等と違って**可読性が高い**が最大のメリットだと思います。

#<br>
もっといい方法(アドバイス)や感想があったらコメントしてください以上。

[参考]https://docs.unity3d.com/ja/current/ScriptReference/MonoBehaviour.InvokeRepeating.html
ジェネレーター

```py:forループで
l = ['おはよう', 'こんにちは', 'こんばんは']

for i in l:
    print(i)
```

```:forループでの実行結果
おはよう
こんにちは
こんばんは
```
これをジェネレーターを使って書くと、

```py:ジェネレーター1
def greeting():
    yield 'おはよう'
    yield 'こんにちは'
    yield 'こんばんは'

g = greeting()

print(next(g))
print(next(g))
print(next(g))
```

```:ジェネレーター1の実行結果
おはよう
こんにちは
こんばんは
```
ジェネレーターを2つにすると、

```py:ジェネレーター2つ
def greeting():
    yield 'おはよう'
    yield 'こんにちは'
    yield 'こんばんは'
g = greeting()

def counter(num=10):
    for i in range(num):
        yield 'ががががががー!!!'
c = counter()

print(next(g))

print(next(c))
print(next(c))
print(next(c))
print(next(c))
print(next(c))

print(next(g))

print(next(c))
print(next(c))
print(next(c))
print(next(c))
print(next(c))

print(next(g))
```

```:ジェネレーター2つの実行結果
おはよう
ががががががー!!!
ががががががー!!!
ががががががー!!!
ががががががー!!!
ががががががー!!!
こんにちは
ががががががー!!!
ががががががー!!!
ががががががー!!!
ががががががー!!!
ががががががー!!!
こんばんは
```

forループの様に一気に処理するのではなく、
要素の生成を保持したまま、
他の処理をする事ができる。

なので、
例えば下記のコードの様に、
重たい処理が途中に入っていた場合、
一気に全ての処理をするよりも、
小分けにして実装する事ができる。

```py:ジェネレーター重い
def greeting():
    yield 'おはよう'
    for i in range(1000000):
        print(i)
    yield 'こんにちは'
    for i in range(1000000):
        print(i)
    yield 'こんばんは'
```
yield 'おはよう' を処理。
for i in range(1000000):
        print(i)　を処理しなくもよい。

次に
for i in range(1000000):
        print(i)
    yield 'こんにちは'　を処理。

という具合に小分けに処理できる。


```py:ジェネレーターエラー
def greeting():
    yield 'おはよう'
    yield 'こんにちは'
    yield 'こんばんは'

g = greeting()

for i in range(4):
    print(next(g))
```

```:ジェネレーターエラーの実行時エラー
Traceback (most recent call last):
  File "Main.py", line 9, in <module>
    print(next(g))
StopIteration
```
おはよう、こんにちは、こんばんは の3つなのに、
4つprint(next(g))をしたので、
StopIteration でエラーが返ってくる。
TypeScriptでユーザー定義のエラーを実装する

例外周りにあまり知見がなかったのでJavaScriptの標準のエラーから、TypeScriptでユーザー定義の例外を実装する方法までを調べました。

## JavaScriptの標準のエラーオブジェクトについて

JavaScriptの[標準のエラーオブジェクト](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects#Fundamental_objects)は以下の表の通り7つあります。

|エラーオブジェクト  |説明  |
|---|---|
|Error  |ランタイムエラーが発生した時に投げられます。ユーザー定義の例外の基底オブジェクトとして使用することもできます。  |
|EvalError  |グローバルな eval() 関数に関連するエラーを示します。この例外はもう JavaScript から投げられませんが、EvalError オブジェクトは互換性のために残っています。  |
|RangeError  |値が配列内に存在しない、または値が許容範囲にない場合のエラーを表します。  |
|ReferenceError  |存在しない変数が参照された場合のエラーを表します。  |
|SyntaxError  |構文的に不正なコードを解釈しようとした場合のエラーを表します。  |
|TypeError  |値が期待される型でない場合のエラーを表します。  |
|URIError  |グローバル URI 処理関数が誤った使い方をされたことを示すエラーです。  |

こんなに定義されていたのですね。恥ずかしながらRangeErrorしか知りませんでした:scream_cat:

## TypeScriptでユーザー定義の例外を実装

先ほどの表ではAPIの通信エラーがあった場合、適切なエラーが見つからないのでErrorオブジェクトを使うことになります。

> Errorオブジェクトは、ユーザー定義の例外の基底オブジェクトとして使用することもできます。

とのことなので、より適切な`HttpRequestError`というエラーを作ってみましょう。
まずErrorオブジェクトを継承し`ApplicationError`をユーザー定義の基底オブジェクトを作成します。

``` ApplicationError.ts
export default class ApplicationError extends Error {

  constructor(public message: string) {
    super(message);
    this.name = "ApplicationError";
  }
}
// 最初はErrorインタフェースを実装していたのですが、
// 後ほど使うSentry.captureExceptionでErrorを継承する必要があった
// export default class ApplicationError implements Error {
```

`ApplicationError`を継承した`HttpRequestError`を作成。

``` HttpRequestError.ts
import ApplicationError from "./ApplicationError";

export default class HttpRequestError extends ApplicationError {

  constructor(public message: string, public status: number) {
    super(message);
    this.name = "HttpRequestError";
    this.message = `${status}: ${message}`
  }
}

throw new HttpRequestError("管理者に連絡してください", 500)
```

## 標準エラーとユーザー定義エラーにより異なるアクションを実行

標準エラーとユーザー定義のエラーに基づいて、エラーハンドラー内で異なるアクションを実行します。（[Vueのエラーハンドラーについてはコチラ](https://qiita.com/kitanote/items/fd345d497f99a8decd30)）

``` errorHandler.ts
Vue.config.errorHandler = (error, vm, info) => {
  // ApplicationErrorの場合はユーザーにアラートを表示し
  if (error instanceof ApplicationError) {
    alert(error.message);
    if (error.stack) {
      Sentry.captureException(error);
    }
  }
  // ビルトインのエラーについてはユーザーに表示せず、Sentryなどで開発者に通知する
  if (error instanceof Error) {
    if (error.stack) {
      Sentry.captureException(error);
    }
  }
};
```

## さいごに

JavaScriptの例外のベストプラクティスを探して見つけることができませんでした。
自分で調べた結果このような形に落ち着いたのでしばらくはこの形を使用していく予定です。

間違いやアドバイスがあれば教えていただけると嬉しいです！
[macOS][Kotlin]null安全

<p>Cocoa + Objective-C では、nilは許容されるものでnilに対してメソッド呼び出しを行なってもアボートしないが、Javaだとnullアクセスは例外が投げられてしまう。そのような考えの違いが、null安全についても、SwiftとKotlinで差となっているのかな？</p>

<p>JavaではC言語の基本的データ型に相当するのが基本型（プリミティブ型）で、C言語の構造体に相当するクラスはC言語のポインタ型に相当する参照型（リファレンス型）となる。そして、C言語と同様に値渡しのみとなる。</p>

<p>Kotlinでは全ての型はオブジェクトで、それは参照型（リファレンス型）となる。参照型だとJavaではnullを代入できるが、Kotlinではnullが代入できるnull許容（nullable）と、null非許容（non-nullable）がある。</p>

<p>null許容は型名に?を付ける。</p>
<pre><code>var a: String? = null
</code></pre>

<p>null非許容は型名に?を付けない。以下はコンパイルでエラーとなる。</p>
<pre><code>var a: String = null
</code></pre>

<p>null許容の変数は、nullの可能性があるので、そのまま利用するとコンパイルでエラーとなる。</p>

<pre><code>fun main(args: Array<String>) {
    var s: String? = "demo"
    var n = s.length
    print(n)
}
</code></pre>

<pre><code>Error:(3, 14) Kotlin: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?
</code></pre>

<p>セーフコール演算子（?.）を使うと、nullでない場合は評価され、nullだと回避される。</p>

<pre><code>var s: String? = "demo"
var n = s?.length
print(n)
</code></pre>

<p>セーフコール演算子を使う場合は、nullでないことの確認を行うことになると思うが、素直に書くと以下のようになる。</p>

<pre><code>var s: String? = "demo"
if (s != null) {
    var n = s?.length
    print(n)
}
</code></pre>

<p>もっとスマートに書くために、セーフコール演算子と一緒に使えるlet関数が用意されている。</p>

<pre><code>var s: String? = null
s?.let {
    var n = it.length
    print(n)
}
</code></pre>

<p>デバッグなので強制的にnullでないものとして使うための非null表明演算子（non-null assertion operator）、または、二重感嘆符演算子（double-bang operator）と呼ばれる演算子（!!.）がある。</p>

<pre><code>var s: String? = "demo"
var n = s!!.length
print(n)
</code></pre>

<p>別のnullチェックのやり方として、null合体演算子（null coalescing operator）、または、エルヴィス演算子と呼ばれる演算子（?:）がある。</p>

<pre><code>var s: String? = null
var t = s ?: ""
var n = t!!.length
print(n)
</code></pre>

<p>let関数とnull合体演算子を組み合わせると、以下のように書ける。</p>

<pre><code>var s: String? = null
s?.let {
    var n = it.length
    print(n)
} ?: print("s is null.")
</code></pre>

<p>Kotlinで特徴的なのは、文法的にnullチェックされているのが分かっている場合は、コンパイラをnullチェック済みとするところだ。</p>

<pre><code>var s: String? = "demo"
if (s == null) {
    print("s is null")
    return
}
var n = s.length
print(n)
</code></pre>

<p>これは開発環境を提供している会社が作ったプログラミング言語だからなせる技か。Kotlinには似たような割り切りを感じる部分が他にもある。機会があれば後で取りあげたい。</p>

【関連情報】
<a href="https://cocoa-kanto.connpass.com/">Cocoa.swift</a><br />
<a href="https://www.facebook.com/groups/cocoa.kanto/">Cocoa勉強会 関東</a><br />
<a href="http://www.bitz.co.jp/weblog/">Cocoa練習帳</a><br />
Docker Toolboxでvolumesでマウントができない場合の対策

# Docker Toolbox とは
Windows環境でDockerを使用する場合、

* Windows 10 Pro あるいは Enterprise -> Docker for Windows
* Windows 10 Home（Docker for Windowsのシステム要件を満たしていないもの）-> Docker Toolbox 

と使い分ける必要があります。
本記事は、後者のDocker Toolbox利用者向けの内容になります。

# docker-compose.xmlのvolumes定義でマウント
Docker for WindowsやDocker for Macの場合は、docker-compose.xmlのvolumesに下記のように記述すると、
ホストのディレクトリをコンテナのディレクトリにマウントすることができます。（`ホストのディレクトリ:コンテナのディレクトリ`）。

```docker-compose.xml
version: '3'
services:
  db:
   ～中略～
   environment:
   ～中略～
   volumes:
     - ./initdb:/docker-entrypoint-initdb.d
     - ./data:/var/lib/data
```

特に、コンテナ側に/docker-entrypoint-initdb.dを指定すると、
ホスト側に格納していおいた.sqlや.iniをコンテナの初回起動時に実行してくれるため、
DB作成直後のテーブル作成やレコード作成に活用することが多いですね。

Docker for WindowsやDocker for Macでは、この記述で期待通りマウントが行われますが、
Docker Toolboxでは、期待通りマウントが行われません。

例えば、/docker-entrypoint-initdb.d宛に初回起動時に実行されてほしいsqlのフォルダを指定しても、
コンテナの初回起動時のログに下記のように出力され、sql実行がignoringされてしまいます。
![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566554/c08d24f2-6a20-2f78-0170-708ebda089ac.png)
正しくマウントが行われていれば、コンテナの/docker-entrypoint-initdb.dディレクトリにsqlなどがコピー・実行されますが、
マウントに失敗するため、/docker-entrypoint-initdb.d配下にファイルが無く、何も実行されないのです。

# マウントするための対策

原因は、Docker Toolboxでは、マウントできるホスト側のフォルダが限られているためです。
docker-compose.xmlでそのフォルダを指定する必要があります。

Docker Toolboxをインストールした際、VirtialBoxもインストールされたと思います。
VirtialBoxで、Default＞右クリック＞設定＞共有フォルダーで、下記の設定が確認できます。
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566554/18cd6fde-5df1-064c-988c-b4f27a13c445.png)
この「`c/Users`」が、マウントできるホストのフォルダです。

なので、docker-compose.xmlを下記のように書き換え、

```docker-compose.xml
   volumes:
     - /c/Users/initdb:/docker-entrypoint-initdb.d
```

コンテナの再起動を行います。
（必要に応じて、コンテナの削除→起動を行ってください。）
すると、コンテナ起動時のログに、下記のように出力され、sqlが実行されたことが確認できます。
![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566554/15263254-74b5-b04a-28fb-c662f2d0397f.png)
もちろん、コンテナに入ってもDBに入っても、期待通りマウントとsql実行が行われていることが確認できます。

# 最後に
解決のために、いろいろな記事を参考にさせて頂きました。ありがとうございました。
railsのデータベースをmysqlにする

#rails アプリ作成時

```
rails new アプリケーション名 -d mysql
```

#データベース設定ファイル config/database.yml

```database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: ****
  password: ****
  host: 127.0.0.1

development:
  <<: *default
  database: データベース名
```

#scaffoldを使ってテストをする

* scaffoldとはCRUD機能を簡単にテストすることのできるrailsの機能

```
rails g scaffold モデル名 カラム名:型
```
http://localhost:3000/モデル名s
でアクセスするとテストページに飛ぶ
#18 ホーム画面に表示するアプリ名を変更する1例

#はじめに
個人のメモ程度の出来なのであまり参考にしないで下さい．


#環境
Xcode：11.2.1
Swift：5.1.2
2019/11


##part1
`Info.pliset`の`Bundle display name`を追加し，任意の文字列に変更する．
<img width="910" alt="スクリーンショット 2020-01-13 午後9.55.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534708/bda37aec-bf3f-0b59-f0c4-b3baf8854c9f.png">
Servletでエラー情報を共通エラーページJSPで表示する方法

### Servletでエラー情報を共通エラーページJSPで表示する方法

##### 以下を追加する

```web.xml
  <error-page>
    <exception-type>javax.servlet.ServletException</exception-type>
    <location>/jsp/error.jsp</location>
  </error-page>
```

```console:exception.jsp（エラー発生JSP）
<%
request.setAttribute("err", "エラーセット1");
throw new ServletException("エラーセット2");
%>
```

```console:error.jsp（エラー表示JSP）
<%@ page isErrorPage="true" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>共通エラーページ</title>
</head>
<body>
<p>${err}</p>
<p><%=exception.getMessage()%></p>
</body>
</html>
```
GlideApps逆引き【都度更新】

# 始めに

この記事はGoogleスプレッドシートのデータから簡単にアプリが作成できる[Glide](https://www.glideapps.com/)の逆引き記事です。

## 言葉の定義
一部、「紛らわしい言葉」や「似て非なるもの」があるので、次に示します。

|言葉|意味|
|:--|:--|
|Details|STYLEのDetails|
|Detail Screen|ListやMap等の詳細画面|

# データソースの切り替え

データソースの設定は［Tabs］の［Source］で設定。

タブが１つしか無い場合、データソースの設定を［Layout］や［Data］で探しがちですが、そうではないので注意。

![tabs01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/6d1f2aa9-e77d-ca08-a87e-e221f14fca9d.png)

# 画像の参照

スプレッドシート上に画像のURLを入力

例えば、Googleドライブに保存された画像を参照する場合は`https://drive.google.com/uc?id=<ファイルID>`を入力する。

![image01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/13b112dc-7646-b5bf-f936-5380dbe9d766.png)

# データ登録画面の実装

## Details & Detail Screenの場合

［COMPONENTS］に［Form Button］を追加する。
![02.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/b32f6a42-a469-c55c-1bbc-65c5767f4925.png)

## Details & Detail Screen以外の場合

［ADD］-［Allow users to add items］にチェックを付け、［COMPONENTS］で入力項目を設定する。

データの登録先は、今の画面のSource。(［Tabs］から確認可)

![01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/99acb4b3-f3b1-9bba-85e5-a56ce35dcaf0.png)

# データ編集画面の実装

※Details & Detail Screenでのみ実装可能。

Details or Detail Screenの画面で［EDIT］メニューを表示。

最初に［Allow users to edit］にチェックを付ける。
![09a.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/a5396f04-2b2a-adb7-5652-809bac4f7b77.png)

すると、次の画面のようになるので、必要な機能(入力項目や削除許可など)を設定していく。
![09b.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/39e1da42-6e67-2350-423f-e9537ac50176.png)


# ハンバーガーメニューの実装

［Tabs］-［ADD（右上の＋ボタン）］でタブを作成し、作成したタブを［MENU］にドラッグ&ドロップ。

![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/395480f9-854d-7d9f-3135-053ff1517970.png)

# お気に入りの実装

Detail Screenで［COMPONENTS］に［Favorite］を追加する。
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/d8ae5680-9d3c-1c64-41a0-fd31765e2e8b.png)


Detailsでも［COMPONENTS］に［Favorite］は追加できるが、Detailsは1データしか表示できない画面なので、お気に入りの実装をしても意味がない。

List等の複数データを扱う画面の、子の関係であるDetail Screenに対して実装する事。

# アプリの公開停止

おそらくアプリの公開停止に該当する機能は無いので、同様の結果をもたらす手順を記載します。

全体の流れとしては次の通りです。

1. 公開停止したいアプリのコピー作成
2. 公開停止したいアプリの削除
3. コピーしたアプリのアプリ名を元のアプリ名に変更

まずはアプリのコピーを作ります。

アプリのコンソール画面に表示されている、公開を停止したいアプリの［︙］クリックし、［Duplicate］をクリック
![05.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/e3b51125-c629-d91e-df55-769a9955f1de.png)

次の画面が出現するので、［Keep same sheet］を選択して、［Duplicate app］をクリック。
![06.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/3e5d7513-f37b-eef5-29d0-05fe0389e49a.png)

ここまでの操作で、同じスプレッドシートのファイルをDBとしたアプリのコピーが作成されます。一度コピーしたアプリの動作確認をしておきましょう。

次に公開中のアプリを削除します。

アプリのコンソール画面に表示されている、公開を停止したいアプリの［︙］クリックし、［Delete］をクリック
![07.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/08fdb400-752c-8292-4723-87dd05f98010.png)

最後にコピーしたアプリのアプリ名を変更します。コピーしたアプリ名は`Copy of <コピー元のアプリ名>`になっているので、次の画面で元の名前に変更します。

メニューは［Settings］-［GENERAL］-［Name］です。

![08.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128060/7f6be6a7-b782-d33c-77e5-b3304ea3bb59.png)