OmniAICreator/Qiita-1.07M huggingface dataset:
yukicoder contest 278 参戦記

# yukicoder contest 278 参戦記

## [A 1335 1337](https://yukicoder.me/problems/no/1335)

書くだけ.

```python
A = input()
S = input()

result = ''
for c in S:
    if c in '0123456789':
        result += A[int(c)]
    else:
        result += c
print(result)
```

## [B 1336 Union on Blackboard](https://yukicoder.me/problems/no/1336)

問題文を見た瞬間に★1.5!?ってなった. 2 3 0 や 2 3 1 を手計算してみたところ、どの順序でも同じ数値になったので、順番に関係ないのかと踏んで前から順に処理するコードを書いて AC.

```python
T = int(input())

m = 1000000007

for _ in range(T):
    N = int(input())
    A = list(map(int, input().split()))
    t = 0
    for a in A:
        t = t * a + (t + a)
        t %= m
    print(t)
```

## [C 1337 Fair Otoshidama](https://yukicoder.me/problems/no/1337)

最初に100円も持っているんだったら数字は自由に変えれそうなので、結局 X + Y + Z を3人で分けて同じ数にできるかだけだよなということでこうなった.

```python
X, Y, Z = map(int, input().split())

if (X + Y + Z) % 3 == 0:
    print('Yes')
else:
    print('No')
```

## [D 1338 Giant Class](https://yukicoder.me/problems/no/1338)

長さ W の配列を初期値 H に初期化して、Y - 1 の最小値を取り、毎回減った数を H * W から引いていけば答えが求まる……と思ったら W≦10<sup>9</sup> で死んだ(爆). 辞書で記録するようにして AC.

```python
from sys import stdin

readline = stdin.readline

H, W, Q = map(int, readline().split())

c = H * W
t = {}
result = []
for _ in range(Q):
    Y, X = map(int, readline().split())
    t.setdefault(X - 1, H)
    p = t[X - 1]
    t[X - 1] = min(t[X - 1], Y - 1)
    c -= p - t[X - 1]
    result.append(c)
print(*result, sep='\n')
```
svelteファイルのscript | style タグにデフォルト lang を設定する方法

# これをするとどうなる？

`Svelte`で`TypeScript`を書くとき、通常は`<script lang="ts">`と`lang`設定を書きますが、これを`<script>`でも`TypeScript`と認識させることができます:yum:

以下は`VSCode`で`lang`のデフォルト設定をしていない時と、した時の比較です。

|  :-1: デフォルト設定なし   |  :+1: デフォルト設定あり   |
| ---- | ---- |
|  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134221/098d5cb0-aac8-624d-fe22-f408eccd0ef7.png)  |  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134221/e1bf0372-66eb-2f46-3e49-ecaab43847d8.png)  |

## メリット

- コーディング時に`lang`を書かなくていいから楽 :rocket:
- スッキリするので可読性が上がる :dizzy:
  - `<style>`にシンタックスハイライトがされて読みやすい

# 設定方法

## 1. svelte.config.jsファイルを作成

`svelte.config.js`ファイルを作成してください。保存場所は`rollup.config.js`と同じ階層です。

```svelte.config.js
const sveltePreprocess = require('svelte-preprocess');

function createPreprocessors(production) {
  return sveltePreprocess({
    // ここでscriptやstyleタグのデフォルトlangを指定します
    defaults: {
      script: 'typescript',
      style: 'postcss',
    },
    // その他の設定
    postcss: {
      plugins: [
        require('tailwindcss'),
        require('postcss-import'),
        ...(production
          ? [
              require('autoprefixer'),
              require('cssnano')({ preset: 'default' }),
            ]
          : []),
      ],
    }
  });
};

module.exports = {
  preprocess: createPreprocessors(true),
  createPreprocessors,
};
```

## 2. rollup.config.jsの設定

`rollup.config.js`に、先ほど`svelte.config.js`で設定した`preprocess`設定を読み込ませます。

```rollup.config.js
// ...
const createPreprocessors = require('./svelte.config').createPreprocessors;
const production = !process.env.ROLLUP_WATCH;

export default {
    // ...
    plugins: [
        // ...
        svelte({
            // ...
            preprocess: createPreprocessors(production),
        }),
        // ...
    ],
};
// ...
```

## 3. Svelte Language Serverの再起動

これらの設定をしたら`Svelte Language Server`を再起動します。
VSCodeで`cmd-shift-p`でコマンドパレットを開き、`svelte restart`と入力したら、候補に出てくる`Svelte: Restart Language Server`を実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134221/8eea991f-3263-cec4-5d00-d4739ffc84d0.png)
これで、先程まで出ていた警告が消えました:sparkles:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134221/1966a9e1-4a95-119d-0e5c-42842abbb05c.png)
ビルドも正常に動きブラウザに表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134221/03f6e367-c135-e718-d5a9-205bb0ae9588.png)

# まとめ

2020年の初期だったでしょうか、`Svelte`が`TypeScript`に対応するにはどうしたら良いか議論がされていました。そこで、`Vue`で使われている`Vetur`という`Vue Language Server`にヒントを得て、同様の仕組みを`Svelte`も採用することになりました。
詳しくありませんが、どうやら`Language Server`は言語解析をしてくれて`VScode`に合ってるよ/間違ってるよを教えてくれるもののようです。（間違っていたらご指摘ください :bow:）
このおかげで、`Svelte`でも`TypeScript`を`VSCode`で書けるようになりました。

先日、[『State of JavaScript 2020』](https://2020.stateofjs.com/en-US/technologies/front-end-frameworks/)で`React`を抜き満足度・興味で首位になった`Svelte`。今後も使う人が増えるといいですね。

# 参考サイト

- Using Preprocessors
    - https://github.com/sveltejs/language-tools/blob/master/docs/preprocessors/in-general.md
- Svelte <3 TypeScript
    - https://svelte.dev/blog/svelte-and-typescript
Active Storageで動画投稿

### ★Active Storageは画像、動画が投稿できる
Active Storageで動画の投稿している記事が少なかったので
carrier waveは使わず、こっちでチャレンジしました！！

### ❶バリデーションに形式を記述
validates:videoの部分は現状presenseが適用されていない。。
video_type→携帯撮影をする程で作成しているためtypeで指定
video_size→10秒で20MB程の為、一応指定

```ruby
#app/models/post.rb
class Post < ApplicationRecord
#省略
  with_options presence: true do
    validates :title
    validates :price, format: { with: /\A[-]?[0-9]+(\.[0-9]+)?\z/}
    validates_inclusion_of :price, in: 500..5000
    validates :video
  end
  validate :video_type
  validate :video_size

  private

  def video_type
    if !video.blob.content_type.in?(%('video/quicktime video/quicktime'))
        errors.add(:video, '動画は携帯で撮影したmov形式でアップロードしてください')
    end
  end

  def video_size
    if video.blob.byte_size > 20.megabytes
      errors.add(:video, "動画を短く撮影し直してください(20MB以内)")
    end
  end

end
```

### ❷ビューファイルにvideoタグを記述

```ruby
#app/views/posts/index.html.erb
class PostsController < ApplicationController
#省略
<video src=<%= rails_blob_path(post.video) %> type="video/mov", controls></video>

```

## ★Active Storageは便利…

## ★ [今回の教科書はこちら](https://github.com "教科書")
[memo] bash shortcut

key bind check

```
bind -p
```
移動

```
ctrl+a : 行頭
ctrl+e : 行末
ctrl+b : 戻る
ctrl+f : 進む
```
変更

```
ctrl+h : カーソルの左の文字を消す
ctrl+d : カーソルの文字を消す
ctrl+_ : undo
ctrl+m,j,o : enter
```
履歴

```
ctrl+p : history back(↑)
ctrl+n : history forward(↓)
```
Amazon Linux2にAnisbleをインストールする方法

## はじめに
Amazon Linux2でインストールするためには、「Amazon Linux Extras」が必要です。
Amazon Linux Extrasについては、「` 新しいバージョンのアプリケーションソフトウェアを利用可能にする Amazon Linux 2 のメカニズム `」とAWSの公式ページに記載がありました。利用するには、Amazon Linux 2 のシェルで amazon-linux-extras コマンドが必要になります。
https://aws.amazon.com/jp/amazon-linux-2/faqs/ 

## 環境
```
$ cat /etc/os-release
NAME="Amazon Linux"
VERSION="2"
ID="amzn"
ID_LIKE="centos rhel fedora"
VERSION_ID="2"
PRETTY_NAME="Amazon Linux 2"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
HOME_URL="https://amazonlinux.com/"
```

## 手順1. amazon-linux-extras パッケージがインストールされていることを確認します。
```
$ which amazon-linux-extras
/usr/bin/amazon-linux-extras
```

## 手順2. amazon-linux-extras コマンドでAnsibleが使用できることを確認します。
```
$ amazon-linux-extras
  0  ansible2                 available    \
        [ =2.4.2  =2.4.6  =2.8  =stable ]
```

## 手順3. Ansibleを有効にします。
```
$ sudo amazon-linux-extras enable ansible2
  0  ansible2=latest          enabled      \
        [ =2.4.2  =2.4.6  =2.8  =stable ]
```

## 手順4. Ansibleをインストールします。
```
$ sudo yum install -y ansible

$ ansible --version
ansible 2.9.13
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/ec2-user/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.18 (default, Aug 27 2020, 21:22:52) [GCC 7.3.1 20180712 (Red Hat 7.3.1-9)]
```

## 参考
以下の記事が参考になりました。
https://qiita.com/yreckless/items/6446c4f73872c9243c4e
https://aws.amazon.com/jp/amazon-linux-2/faqs/
https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-install-extras-library-software/
https://dev.classmethod.jp/articles/how-to-work-with-amazon-linux2-amazon-linux-extras/
（在宅勤務）IPoEとPPPoEの併用

#はじめに
最近Covid-19の影響で在宅勤務の比率が上がりました。
私は週に１度くらいしか出社しません。
在宅勤務の効率は通信環境の品質が要素としては大きいので改善ネタを残す。

#前提条件
社内LANへの接続：VPN経由（VPNサーバがIPv4）
自宅のインターネット：フレッツ光ネクスト系（BIGLOBE光）


#課題把握
IPv6対応が進んできたとはいえ、まだまだIPv4サービスに頼っている。
しかしながら、旧来からのPPPoEによるインターネット接続では、帯域が逼迫しており十分な速度が出ない。
近年、V6プラス・IPv6オプションと言った名称で、IPv4 over IPv6(IPoE)が使えるので大分マシではあるのだが
事もあろうに会社のVPNサーバはIPoEでは接続できない仕様になっていた。

よって、在宅勤務には遅いPPPoEを使わなければならない。
しかしながら、自宅ルータをPPPoE仕様でコンフィグしてしまうと、全体的な速度低下が否めない。
特に割を食うのが私用のスマホなどである。

業務用通信：PPPoE
それ以外：IPoE
こういう使い方が出来れば素晴らしい。

#対応
###旧手法（人力で切り変え）
ONU--(PPPoE IPoe 排他)--Aterm WS2600HS--(Wifi)--PC

普通の家庭用ブロードバンドルーターではこの手しかないと思われる。
普通はIPoE通信とPPPoeセッションはどっちか片方しか接続できない。
業務開始直前にルータをIPv6オプションモードから、PPPoeモードに切り替えて対応。
ぶっちゃけ面倒くさいので緊急避難措置。

PC1台しかVPNにつながないなら、ルータにPPPoEパススルーさせて
PC側でPPPoEセッションを張っても良い。（これが一番コストがかからない）
ただし、セキュリティなどでパソコン側のネットワーク設定がいじれなかったり、あまり派手にPC側のコンフィグをいじくると
出社したときに会社で使えませんでした・・・はまずいので、あまりお勧めはしない。

###新手法(併用)
ONU--(PPPoE/IPoE combined)-|AT-AR2050V--(Wifi)--PC

IPoE通信とPPPoeセッションを同時に維持出来るルータを投入
ヤマハじゃなくてアライドにしたのは、BIGLOBEのIPv6オプション対応のため。
逸般の誤家庭によくあるNVRやRTXは無理だとわかっていたので・・・

あとはルーティングさえどうにかすれば良い。

####ルーティング
IPoEとPPPoEの2系統の通信経路が出来たとしても、私用通信と業務用通信で振り分けをしないといけない。

＜接続先がIPアドレスがわかっているとき＞
一番簡単なのは、VPNサーバのIPアドレスがわかっていたら、スタティックルートに書けば良い。
社内の情シス部門がIPアドレス教えてくれたらこっち。
0.0.0.0/0向けは tunnel0(IPoE)へ流し
xxx.xxx.xxx.xxx/28向けはppp0(PPPoE)へ流す。

```default.cfg
ip route 0.0.0.0/0 tunnel0 10
ip route xxx.xxx.xxx.xxx/28 ppp0 0
```

＜接続先IPアドレスがわからないとき＞
こうなると通信元を判断してルートを振り向ける必要がある。
通常のルーティングは宛先アドレスしか見ないので、ポリシーベースルーティング機能が必要になる。

自宅内端末をVLANで分割したとして
VLAN11：Private
VLAN100:Working
・VLAN11からインターネット側に出て行くときは tunnel0を通る
・それ以外はppp0を通る

```default.cfg
policy-based-routing
 application-decision continuous
 ip policy-route 10 from ipv4-internal.vlan11 to internet.wan nexthop tunnel0
 policy-based-routing enable
!
ip route 0.0.0.0/0 ppp0
```

こっちのやり方で現在我が家は在宅勤務環境を作っている。

##自宅環境
ONUとルータとL2スイッチ。
写ってないけど、無線用のはんぺんもある。
逸般の誤家庭はヤマハ勢が多いけど、BIGLOBE光の都合もあったのでアライドで固めている。
![IMG_2599.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615272/4d97eeca-7590-d0be-6415-690b18ff8685.jpeg)

やはりカスタマ向けのルータは自由がきく。
Effective Python 学習備忘録 14日目 【14/100】

# はじめに

Twitterで一時期流行していた 100 Days Of Code なるものを先日知りました。本記事は、初学者である私が100日の学習を通してどの程度成長できるか記録を残すこと、アウトプットすることを目的とします。誤っている点、読みにくい点多々あると思います。ご指摘いただけると幸いです！

# 今回学習する教材

- [Effective Python](https://www.amazon.co.jp/Effective-Python-%E2%80%95Python%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%82%92%E6%94%B9%E8%89%AF%E3%81%99%E3%82%8B59%E9%A0%85%E7%9B%AE-Brett-Slatkin/dp/4873117569/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=Effective+python&qid=1609408832&sr=8-3)

    - 8章構成
    - 本章216ページ

# 今日の進捗

- 進行状況：87-91ページ
- 第4章：メタクラスと属性
- 本日学んだことの中で、よく忘れるところ、知らなかったところを書いていきます。

## getやsetメソッドよりも素のままの属性を使う

getやsetメソッドを定義すると、計算をするときにぎこちないコードになってしまいます。

```python
class OldResistor(object):
    def __init__(self, ohms):
        self._ohms = ohms

    def get_ohms(self):
        return self._ohms

    def set_ohms(self, ohms):
        self._ohms = ohms

r0 = OldResistor(100)
r0.set_ohms(r0.get_ohms() + 500)
print(r0.get_ohms())
# 600
```

それよりも素の属性を使ったほうが計算時にすっきりしたコードになります。

```python
class Resistor(object):
    def __init__(self, ohms):
        self.ohms = ohms
        self.voltage = 0
        self.current = 0

r1 = Resistor(50e3)
r1.ohms = 400
r1.ohms += 200
print(r1.ohms)
# 600
```

後に、属性が設定された時に特別な振る舞いが必要になる場合は、@propertyデコレータとそれに対応する、setter属性を付与すれば良いです。
また、正しく動作するためには、**セッターメソッドとゲッターメソッドの両方の名前が、意図しているプロパティ名と一致しないとダメです。**

```python
class VoltageResistance(Resistor):
    def __init__(self, ohms):    # 初期化
        super().__init__(ohms)   # ohmsを引数として、親クラスの__init__を呼び出す
        self._voltage = 0        # インスタンス変数 _voltageを宣言

    @property                    # _voltageに入っている値を返す
    def voltage(self): 
        return self._voltage

    @voltage.setter              # voltageに新たな値を代入するたびにセッターメソッドが実行される
    def voltage(self, voltage):  # プロパティ名と一致
        self._voltage = voltage  
        self.current = self._voltage / self.ohms

r2 = VoltageResistance(100)
print(r2.current)
# 0
r2.voltage = 10                 # voltage.setterが呼ばれ、voltageに10を渡す
print(r2.current)
# 0.1
```

このように、素の属性を使い、@propertyを使うことですっきりしたコードを書きながら機能を拡張することができます。@propertyメソッドを使ってセッターやゲッターを実装する際に、可読性を落とさないために以下のポイントを抑えるべしです。
関連するオブジェクト状態だけを変更し、オブジェクトを超えて、モジュールを動的にインポートする、遅いヘルパー庵数を実行するなどの、呼び出し元が予期しない動作をしないように注意！
また、複雑であったり遅くなるような場合は通常のメソッドを使って実装すべきなようです。
【Vue.js】初めてのコンポーネント。Vueインスタンスを再利用。

```index.html
<div id="app">
  <hello-component></hello-component>
  <hello-component></hello-component>
  <hello-component></hello-component>
  <hello-component></hello-component>
  <hello-component></hello-component>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>

<script>
  Vue.component('hello-component', {
    data: function() {
     return {
      number: 13
     }
    },
    template: '<p>Hello{{ number }}</p>'
  })

  var app = new Vue({
    el: '#app',
  })
</script>
```

コンポーネントの中では、dataは関数である必要があるらしい。

``` 
Hello13

Hello13

Hello13

Hello13

Hello13
```
iPhoneからもNotionにWebクリップを作成したい

#はじめに
以前、NotionにWebページを保存する方法を紹介しました。同じ作業をiPhoneからもできるので紹介します。

↓以前の投稿
[NotionにQiitaのストックをストック、かつ、様々なWebページも一元管理](https://qiita.com/TerToEer_sho/items/a33366b09fdba72fc12e)

##事前準備
iPhoneでは、ブラウザはSafariを使っています。
iPhoneにもNotionのアプリをインストールし、自分のNotionとリンクさせておきます。
らかじめWebページを保存するページをNotion内に作成しておく必要があります。
そのときに、データベースのカラムにURLも一緒に作成しておくことをおすすめします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/741816/3c9761a4-fc61-73fe-63a6-69384b0994ec.png)

##流れ

####1.Safariで下の共有ボタンを押す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/741816/2f9a5c99-060e-d7da-7953-928084184413.png)

####2.Notionアプリを選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/741816/c3796df3-b007-c77e-e022-6698b6e67e5b.png)

#####3.タイトルを変更後（しなくても大丈夫）Saveを押す。


`Add to`から保存先を変更することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/741816/94584f8a-90e9-3296-89f0-dd636137b4c8.png)
firebase deploy --only functions をしたら、エラーになった時にしたこと


#エラー内容
```firebase deploy --only functions```を実行したら
下記のようなエラーが出力されました。

```
i  functions: preparing functions directory for uploading...
i  functions: packaged functions (33.71 KB) for uploading
!  functions: Upload Error: HTTP Error: 403, Unknown Error

Error: HTTP Error: 403, Unknown Error
Waiting for the debugger to disconnect...
```

#対応
こちらのサイト
https://github.com/firebase/firebase-tools/issues/641
を見てみたら、アカウントの権限が足りてない？のかなと思い、
自分も`firebase deploy --debug`を実行して詳細を出力することにしました。

すると、3分ほど時間がかかりましたが、正常にデプロイできてしまいました！（笑）

```
$ firebase deploy --debug
Debugger attached.
[2021-01-15T14:10:57.749Z] > command requires
..........
..........
..........
+  functions[makeUppercase(us-central1)]: Successful create operation.

+  Deploy complete!

Project Console: https://console.firebase.google.com/project/your-project-name/overview
Waiting for the debugger to disconnect...
```

あれれ？何だったんだろ？

料金のアップグレードを実施したばかりでまだ準備が完了できていなかったのかな？

自分は組織の管理者アカウントで実行したから、アクセス権限がないことはないと思うんだけどな。。
不思議なエラーでした。

一応、その後```firebase deploy --only functions```をもう一度実行してみたら、正常に実行できました。（笑）

```
$ firebase deploy --only functions
Debugger attached.

=== Deploying to 'your-project-name'...

i  deploying functions
Running command: npm --prefix "$RESOURCE_DIR" run lint
Debugger attached.
Debugger attached.
............
............
............
+  Deploy complete!

Project Console: https://console.firebase.google.com/project/your-project-name/overview
Waiting for the debugger to disconnect...
```
【React】仮想DOMって何！？コンポーネントのレンダリングと描画について理解しよう！

### ReactにおけるDOM構築について

ReactはDOMを仮に構築する仕組みを備えており、**仮想DOM**を設計してから**リアルDOM**を作成するため、従来のDOMやフレームワークで構築されたDOMに比べて処理のスピードが速く、Webページの表示を高速で切り替えることができます。

#### DOMについて

DOM（Document Object Model）は、HTMLファイルのソースコードのことではなく、画面を表示するまでに解釈したHTML/CSS/JavaScriptによって構築されたDOM（ツリー）を指します。DOMはChromeやFireFox、Safari、IEなどのブラウザ上で、Webページを描画するために構築されます。

Chromeの開発者ツールのElementsタブでDOMツリーを見てみます（イメージ）。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218656/67d2d31b-8c73-ed5b-10dc-607b8b276768.png" alt="Chromeの開発者ツールのElementsタブでDOMツリーの例" width=600px />

ここで表示されているものはHTMLのソースコードそのものではなく、ブラウザ上にwebページを描画するために解釈されたHTML/CSS/JavaScriptよって構築されたDOMになります。

DOMツリーの最上階は「Document」で、DocumentとはHTML全体を表しています。

![pic_htmltree.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218656/9dd7e4e5-11d2-3536-6c9c-5a2ded905080.gif)

出典： [JavaScript HTML DOM](https://www.w3schools.com/js/js_htmldom.asp)

DOMはWebページとスクリプトやプログラミング言語を接続するものであり、JavaScriptなどによって、要素の値をダイレクトに操作することができます。

JavaScriptや従来のフレームワーク（jQueryなど）では、スクリプトのロジックから受け取った情報をもとにHTMLを作成し、それを元にブラウザに表示するための描画を行います。

状態が変わるなど情報に変化があった場合は、改めて情報を受け取り直してからDOMを再構築し、それを元に再描画を行って画面を変化させるので表示が遅くなってしまいます。

#### 仮想DOM（VIRTUAL DOM）について

Reactにおける**仮想DOM**とは、情報を受け取ってもすぐにはブラウザの描画を行わず、まずはバーチャルなDOM（プログラム的に作成された仮のDOM）を構築することを指します。そして、構築された仮想DOMの内容を元にHTMLを作成し、実際のDOM(リアルDOM)に同期されます。このプロセスは差分検出処理 (reconciliation)と呼ばれます。

この仮想DOMはリアルDOMに比べ、ページ表示の高速化を実現します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218656/e1a122a6-4381-5e67-af61-f3b8f862f9f3.jpeg" alt="従来のDOM構築の流れとReactで仮想DOMを利用したDOM再構築の流れ" width=700px />

仮想DOMを利用することで、ページ変更前と変更後を仮想DOMを比較、情報が変化した部分だけを素早く見つけ出し、変更差分だけリアルDOMに反映するので、変更が最小限に抑えられるという仕組みです。

無駄のないDOMの操作処理を行うことで、ページ表示の高速化によるパフォーマンス向上を実現します:heart_eyes:

#### コンポーネントのレンダリングと描画について

##### レンダリングとは

Reactにおけるレンダリングとは、現在のPropsとStateを元に、コンポーネントに対して、それらがどのように画面上に表示されるか、実際にDOMに変更を加える必要があるかどうかを知るために行われるプロセスです。

コンポーネントツリーのルートから開始し、前回との差分を見つけるために下方にループしていき、デフォルトでは子孫コンポーネントのすべてが再帰的にレンダリングします。言い換えると親コンポーネントがレンダリングするとその子コンポーネントもすべてレンダリングされるということです。

関数コンポーネントのレンダリングは以下のタイミングで行われます。

- コンポーネントの初回レンダリング時
- 親コンポーネントがレンダリングされた時**すべての子コンポーネントは無条件にレンダリングされる**
- コンポーネント内で定義された`useState()`の状態変数/現在の値に変化があった時
- カスタムフックからコンポーネントが受け取っている変数が変化した時

Reactがレンダリングを行うのは、変更前と変更後の仮想DOMを構築し変更差分を検出することで、リアルDOMを構築する必要があるかどうかを知るための手段です。変更差分がなければ、DOMの更新は行われません。


##### 描画とは

描画とは、レンダリングによって変更差分が見つかった場合に構築されたリアルDOMをブラウザに反映させることを指します。よってReactがコンポーネントを再レンダリングしても、変更差分がなければ再描画されません。

「レンダリング」の結果、変更差分があった場合「描画」されるので、しっかり区別します。

#### Reactにおけるパフォーマンス・チューニング

Reactコンポーネントで行われるレンダリングの一連の流れは、当然コストがかかってきます。レンダリングに問題があるわけではないのですが、レンダリングには時間やコストがかかり、レンダリングの結果、変更差分がなく、DOMに変更がなかった場合、結果的に「無駄なレンダリング」がおこなわれてしまったことになります。

コンポーネントのPropsとStateが変更されていないことが事前にわかっていれば、レンダリング出力は同じなので、作業をスキップできるはずです！！

↓パフォーマンス・チューニングの記事も参考にしてみてください↓

[【React】もっと速くなる！？React.memo, useCallBack, useMemoでパフォーマンス最適化に挑戦！](https://qiita.com/seira/items/9e38204758030cd5442a)
FizzBuzz問題の解説

# FizzBuzz問題 解説
[FizzBuzz問題に使用されている表現](https://qiita.com/iamu_TECH_CAMP/items/ac97eeb3a839289f6ff5)に関してもまとめてみました。


>**ステップ1** 
1〜100までの数字をターミナルに出力
>>**ステップ２**
「3の倍数」のときは数字の代わりに文字列でFizz
「5の倍数」のときも同様にBuzz
>>>**ステップ３**
3と5の倍数である「15の倍数」のときはFizzBuzzと出力

---
## プログラムのひな形
```ruby:雛形
def fizz_buzz 
# 処理の中身
end

fizz_buzz
```
---
## 1〜100までの数字をターミナルに出力するためのプログラム
**ステップ1**
`1〜100までの数字をターミナルに出力`

```ruby:1〜100までの数字をターミナルに出力する
def fizz_buzz
  num = 1
# num = 1から始まる処理の中身
  while num <= 100 do # 真偽値がtrueである限りは以下の処理が続く
    puts num # 出力される数値

    num = num + 1 # 真偽値に +1
  end
# 処理の中身
end

fizz_buzz
```
---
## 「3の倍数」のときは文字列でFizz、「5の倍数」のときはBuzzと出力する
**ステップ２**
`「3の倍数」のときは数字の代わりに文字列でFizz`
`「5の倍数」のときも同様にBuzz`

```ruby:「3の倍数」のときは文字列でFizz、「5の倍数」のときはBuzzと出力
def fizz_buzz
  num = 1
# num = 1から始まる処理の中身
  while num <= 100 do # 真偽値がtrueである限りは以下の処理が続く
    if num % 3 == 0 # 3で割った余りが０の時
      puts "Fizz"
    elsif num % 5 == 0 # 5で割った余りが０の時
      puts "Buzz"
    else # それ以外のとき
      puts num # 上記の3の倍数・5の倍数に当たらない数値はそのまま出力
    end
    num = num + 1 # 真偽値に +1
  end
# 処理の中身
end

fizz_buzz
```

## 「15の倍数（3と5の倍数）」の時についての条件式を追加する
**ステップ３**
`3と5の倍数である「15の倍数」のときはFizzBuzzと出力`

```ruby:「15の倍数（3と5の倍数）」の時の条件式を追加
def fizz_buzz
  num = 1
# num = 1から始まる処理の中身
  while (num <= 100) do # 真偽値がtrueである限りは以下の処理が続く
    if num % 15 == 0 # 15の倍数のとき
      puts "FizzBuzz"
    elsif (num % 3) == 0 # 3で割った余りが０の時
      puts "Fizz"
    elsif (num % 5) == 0 # 5で割った余りが０の時
      puts "Buzz"
    else # それ以外のとき
      puts num #上記の3・5・15の倍数に当たらない数値はそのまま出力
    end
    num = num + 1 # 真偽値に +1
  end
# 処理の中身
end

fizz_buzz
```

<font color="Red">注意点</font>
下に追加してしまうと上記の「3の倍数であるか」または「5の倍数であるか」という条件式が真になり、FizzまたはBuzzと表示されてしまう。

以上の点からif文の最初に「15の倍数」のときはFizzBuzzと出力する条件を追加。

* 別解 「15の倍数であるとき」の条件式
  * 上記で取り上げたのは`num % 15 == 0`
  * `num % 3 == 0 && num % 5 == 0`のように置き換える事も可能。
JavaScript,PHP,Javaのrandom関数をまとめてみる

今回はrandom関数を各言語ごとにまとめてみます。
なんでrandom関数なのかというとミニゲームなど作成時に使用する頻度が高く、好きな関数の一つだからです。
言語ごとに微妙に違いがあり、備忘録として記事にしておきます。

ちなみにrandom関数にもアルゴリズムがあるので*「擬似乱数」*であって、
*「真乱数」*ではないところに注意。

#JavaScriptのMath.random()
JavaScriptのMath.random()関数は0以上1未満の値を返します。
※0は含むが1は含みません！

```JavaScript
let num = Math.floor(Math.random() * n) + m;
// n = 上限値 , m = 下限値
```

Math.random()は浮動小数点で返ってきますので、Math.floor()で小数点以下を切り捨てます。
「n」は上限値を設定し、「m」で下限値を設定します。

####例 ） １〜１０の乱数を生成する

```JavaScript
let num = Math.floor(Math.random() * 10) + 1;
```

1. Math.random()によって０以上〜１未満の乱数が生成される
2. １０を乗算することによって０以上〜１０未満の乱数となる
3. Math.floor()によって小数点以下を切り捨て（ここで０〜９のいずれかの整数になっている）
4. １を足してあげることで１〜１０のいずれかの整数が生成されます。

注意すべき点は１未満の数字を生成する点です。

#PHPのrandom_int()
PHPで擬似乱数を生成するためにはrandom_int()関数を使用します。

```PHP
$num = random_int(int $min, int $max);
```

第一引数に下限値を渡し、第二引数に上限値を渡します。
min〜maxを含む乱数を整数値で返します。

####例 ) １〜１０の乱数を生成する

```PHP
$num = random_int(1, 10);
```

指定した数値を含むので簡単ですね。

#JavaのRandom()クラス
Javaではjava.utilパッケージにあるRandom()クラスとnextInt()メソッドを使用します。

```Java
int num = new java.util.Random().nextInt(n);
```

int型で返ってくるため変数はint型で宣言します。
nextInt()の引数が上限値となり、０〜上限値未満の値を返します。
JavaScriptと同じく指定した上限値自体は含みません！

####例 ） １〜１０の乱数を生成する
```java
public class Main {
 public static void main(String[] args) {
  int num = new java.util.Random().nextInt(10) + 1;
 }
}
```

上限値を含まない点に注意して値を渡しましょう。

#まとめ
**Javascript**
０以上１未満の浮動小数点を生成。
Math.floor()とセットで覚える。

**PHP**
下限値、上限値指定した値を含む整数値を返す。

**Java**
Random()クラスを使用する。
nextInt()メソッドの引数に上限値を渡す。
０以上「上限値」未満の整数を返す。

##こぼれ話
訓練校で「なぜ1未満なのか？」と先生に質問しました。
先生の答えはこうだった

「なぜでしょうね〜、、、」

何か意図があって１未満なのかなと思ったが、
そんなの言語作った人にしかわからんよな。と思いました。

それ以降、定義済の関数や変数、定数に疑問を抱くのはやめましたw
Jupyternotebookでpandas-profilingの日本語部分が文字化けする件について

# はじめに
データ分析をする際に初めにやることといえば、データがどのような特徴を持っているのか把握することからだと思います。そんなときにpandas-profilingを使うとEDAを一括して行ってくれるのでとても便利です。しかし、Jupyternotebookで試したところデータの日本語のカラムなどが□□□のように文字化け(豆腐)となってしまったので解決策をまとめていきたいと思います。

# 環境
- Python3.8
- Docker
- Jupyter notebook

# 原因
pandas-profilingで文字化けが起きる原因は**matplotlib**と**seaborn**が日本語化対応できていないことに起因します。日本語化対応できれば、matplotlibとseabornを利用したpandas-profilingも日本語対応されます。

この記事では**matplotlib**と**seaborn**の日本語化の手順について説明することになります。

# Matplotlibとseabornの日本語化
この記事ではDockerを利用したJupyternotebook環境の日本語対応について説明します。
さらに効率の良い方法があるかもしれませんので、その際にはコメントを頂けると嬉しいです。
# 1. 日本語のフォントをダウンロードする

[こちらのサイト](https://moji.or.jp/ipafont/ipaex00401/)から**ipaexg00401.zip(4.0MB)**をダウンロードして解凍します。
ipaexg00401フォルダの中にある**ipaexg.ttf**をDockerfileがあるディレクトリに移動します。

# 2. seabornの日本語対応のためコンテナ上のファイルをホストにコピーする
ここで行う作業は、seabornを日本語化させるために必要なrcmod.pyをローカルにダウンロードして内容を書き換え、docker-compose upの度に、コンテナ上のrcmod.pyをホストの書き換え済みのrcmod.pyで上書きするように設定します。このような流れをとることでdocker-compose upの度にrcmod.pyを書き換えずに済みます。

(本当はDockerfileでコンテナ上のを書き換えたいのですがわかりませんでした)

日本語対応していない状態で**docker-compose up**をします。
別のターミナルを開いて、コンテナIDを確認します。

```
# コンテナIDを確認する
$ docker ps
```

次にコンテナ上のrcmod.pyをホスト(ローカル上)に保存します。

```
$ docker cp [コンテナID]:opt/conda/lib/python3.8/site-packages/seaborn/rcmod.py [保存先(C:\Users\....など)]
```

最後に保存したrcmod.pyをDockerfileがあるディレクトリにコピーします。

# 3. rcmod.pyを書き換える
rcmod.pyを開いて以下の内容を変更します。

86-87行目のdef set(context="notebook", ...)のfontの部分を**font="IPAexGothic"**に変更します。

```
def set_theme(context="notebook", style="darkgrid", palette="deep",
              font="IPAexGothic", font_scale=1, color_codes=True, rc=None):
```

次に205行目の**"font.family": ["sans-serif"]**を以下に変更します

```
"font.family": ["IPAexGothic"]
```

これでseabornの日本語対応のための書き換えは終了です。



# 4. Dockerfileに以下を追加する

```
# matplotlibとscipyの日本語化
# 日本語のフォントをコピーする
COPY ipaexg.ttf /opt/conda/lib/python3.8/site-packages/matplotlib/mpl-data/fonts/ttf/ipaexg.ttf
# 書き換えたrcmod.pyでコンテナ上のrcmod.pyを上書きする
COPY ./rcmod.py /opt/conda/lib/python3.8/site-packages/seaborn/rcmod.py
# matplotlibの設定ファイルの最後にfont.family : IPAexGothicを追加する
RUN echo "font.family : IPAexGothic" >>  /opt/conda/lib/python3.8/site-packages/matplotlib/mpl-data/matplotlibrc
# キャッシュを削除する
RUN rm -r ./.cache
```

これでmatplotlibとseabornの日本語対応が行えます。
以下のコードで文字化けしないか確かめることができます。

```
# matplotlibが日本対応できているか確認する
import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4])
plt.xlabel('日本語化')
plt.ylabel('matplotlibの')
plt.show()
```

```
# seabornが日本語対応できているか確認する
import seaborn as sns
sns.set(style="whitegrid")

# Load the example Titanic dataset
titanic = sns.load_dataset("titanic")

# Draw a nested barplot to show survival for class and sex
g = sns.catplot(x="class", y="survived", hue="sex", data=titanic,
                height=6, kind="bar", palette="muted")
g.despine(left=True)
g.set_ylabels("seabornの日本語化")
```

ラベルに日本語が使われているので、ラベルが文字化け(豆腐)してなければ成功です。

matplotlibとseabornの日本語対応が確認出来たら、pandas-profilingでも日本語対応されているはずです。

# 終わりに
EDAを行う前にとりあえずpandas-profilingするのが定番になりそうな気がしています。
Scratch Offline Editor for Linuxを作る

ScratchはOffline Editorを提供しているため，オンラインでなくても使うことができます．
[Scratch - Scratch Offline Editor](https://scratch.mit.edu/download)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601799/aadb94d4-c4c2-cac1-2e15-b406cc1cb529.png)

しかし，上記リンクを見れば分かるとおり，**Linux向けがありません**．残念...

ところが，ScratchはEditorのGUIをオープンソースで公開しています．
[LLK/scratch-gui](https://github.com/LLK/scratch-gui)

これを自分でビルドしてローカルで実行すれば，オフライン版Scratchとして使えそうです．

# 準備
以下を揃えてください．

- Node.js
- npm
- git
- 適当なブラウザ(ChromeとかChromiumとかFirefoxとか)

以下はUbuntuでの例です．

## Ubuntuでの例

パッケージをインストールします．

Gitをインストールします．

```bash
sudo apt install git
```

次に，以下の記事を参考にしてNode.jsの環境を入れてください(引用させていただきます．ありがとうございます)．
[Ubuntuに最新のNode.jsを難なくインストールする](https://qiita.com/seibe/items/36cef7df85fe2cefa3ea)

# いざ

まず，Gitからリポジトリをクローン，依存関係のインストールを行います．結構時間かかるかも．

```bash
git clone --depth=1 https://github.com/LLK/scratch-gui.git
cd scratch-gui
npm install
```
ScratchはReactで作られているので，これで`npm start`とすれば起動できますが，起動するたびにコンパイルされるのは少し時間がかかってしまいます．ということで，先にコンパイルしておきます．
結構時間かかります．

```bash
npm run-script build
```

終わると，`builds/`内に`index.html`が生成されていると思います．これをChrome等で開き，正常に動作すればオフライン版完成．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601799/43092831-3fea-f9f4-3c3f-3db20895cba2.png)
画像の切り抜き

📚画像を切り抜く方法。
https://eezzee.io/blog/images-crop?utm_source=serg
これは、画像を簡単に切り抜くのに役立つガイドです
切り抜く必要のある画像をアップロードします。
すべての設定を行います。長方形または楕円形のテンプレートを使用して画像を切り抜くか、ミラーリングするか、回転させます。 「切り抜き」をクリックします。
「ダウンロード」ボタンをクリックして、トリミングした画像を保存します。
💻ドライブ、Dropbox、OneDrive。
切り抜く画像をコンピューターからアップロードするか、必要な画像をGoogleドライブ、Dropbox、OneDriveなどのクラウドストレージから直接インポートします。

💲無料サービス。
このWebベースのツールを使用して、画像を無料でトリミング、反転、回転、またはまっすぐにします。必要な変更を加えて、何も支払わないでください。トリミングする写真の数に制限はありません。

📧メールはありません。
オンライン画像の切り抜きを開始するために登録は必要ありません。メールアドレスやその他の識別可能なデータを提供するように求められることはありません。数回クリックするだけで写真を変更できます。必要なのは安定したインターネット接続だけです。高品質が維持されます。セキュリティを提供します。アップロード、編集、ダウンロードされたファイルについて、当社はいかなる権利も主張しません。したがって、画像が安全であることを確認できます。

📑画像フォーマット。
画像をトリミングするためのこの無料のオンラインツールは、BMP、EPS、GIF、HDR / EXR、ICO、JPG、PNG、SVG、TGA、TIFF、WBMP、WebPの形式と互換性があります。

🚂すばやく簡単。
このオンラインクロッパーで簡単かつ迅速に画像を変更します。数回のクリックで必要な変更を導入します。トリミングのプロセスはスムーズで高速です。私たちはあなたの時間を節約します！
MahAppsのHamburgerMenuでMaterialDesignのアイコンをViewModelからバインドする

#はじめに
Windows Template StudioからWPFアプリを作成したときに、自動的にMahAppsのHamburgerMenuが作成されるのですが、HamburgerMenuにMaterialDesignのアイコンを利用したいなと思いました。
いろいろ試した結果うまく動作したので覚書も含めて書いておこうと思います。

## DataTemplateの作成
IconDataTemplate を作成します
一緒に最初から書かれているHamburgerMenuGlyphItemも参考に併記しておきます

```C#
    public class MenuItemTemplateSelector : DataTemplateSelector
    {
        public DataTemplate GlyphDataTemplate { get; set; }

        public DataTemplate IconDataTemplate { get; set; }

        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            if (item is HamburgerMenuGlyphItem)
            {
                return GlyphDataTemplate;
            }

             if (item is HamburgerMenuIconItem)
            {
                return IconDataTemplate;
            }


            return base.SelectTemplate(item, container);
        }
    }
```

##Viewのxaml
MenuItemTemplateSelector.IconDataTemplateのみ書いています。
MenuItemTemplateSelector.GlyphDataTemplateはデフォルトのままなので記載していません

```C#
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"

<controls:MetroWindow.Resources>
    <templateSelectors:MenuItemTemplateSelector x:Key="MenuItemTemplateSelector">
        <templateSelectors:MenuItemTemplateSelector.IconDataTemplate>
            <DataTemplate DataType="{x:Type controls:HamburgerMenuIconItem}">
                <Grid Height="48">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="48" />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <materialDesign:PackIcon Grid.Column="0"
                                    Kind="{Binding Icon}"
                                    VerticalAlignment="Center"
                                    HorizontalAlignment="Center"
                                    Width="32"
                                    Height="32"/>
                    <TextBlock
                        Grid.Column="1"
                        VerticalAlignment="Center"
                        FontSize="16"
                        Text="{Binding Label}" />
                </Grid>
            </DataTemplate>
        </templateSelectors:MenuItemTemplateSelector.IconDataTemplate>
    </templateSelectors:MenuItemTemplateSelector>
</controls:MetroWindow.Resources>

```

##ViewModel

```C#
using MahApps.Metro.Controls;
using MaterialDesignThemes.Wpf;

  public ObservableCollection<HamburgerMenuItem> MenuItems { get; } = new ObservableCollection<HamburgerMenuItem>()
  {
      new HamburgerMenuIconItem(){Label = Resources.ShellStartPage,
                                  Icon = PackIconKind.Home,
                                  Tag = PageKeys.Start },
            
      new HamburgerMenuGlyphItem() { Label = Resources.ShellSettingsPage, 
                                     Glyph = "\uE8A5", 
                                     Tag = PageKeys.Settings },
  };

```

##実行
こんな感じでうまく表示できました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956246/3d371db9-b12c-2a9f-7525-b7dd53674c9e.png)
M1 MacでAndroidエミュレータを動かす

先日[M1 Macを購入](https://qiita.com/honeniq/items/c2350c7920f4735ac106)し、 思ったよりもトラブることなく快適に使っています。

Androidの開発環境を作っていたところ、まだ公式にはエミュレータが使えない状態だったので、何とかできないかと試してみました。

※ この記事内の情報はすべて、執筆時点（2021/01/15）のものです。

## Android Studioを入れたての状態だと

M1 Macはまだサポートされていないので……
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2492/7a5b0484-937e-0db5-d037-215f0cce5054.png)
AVDマネージャを開くと、「Your CPU does not support VT-x.」と警告されます。
（そもそもVT-xが使えることは無さそうですが。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2492/56dcb312-f9fd-113e-867c-44c95d09785f.png)
x86用のイメージでエミュレータを開こうとしても、エラーが出て起動できません。

## ARM用イメージを試してみる

AVDマネージャからARM用イメージを追加して試してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2492/9bd4f145-0cfa-c574-15c0-1da27209a620.png)
「Other Images」に、arm64-v8a用のイメージがありました。
とりあえずこれを使おうとしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2492/314da233-7008-80c8-20b1-4affd4fa16c1.png)
x86用イメージと同様、エラーが出て起動できませんでした。
arm64版のイメージだからって、そのまま使えるわけではないみたいです。

## Android Emulator M1 Previewを試す

[google/android-emulator-m1-preview](https://github.com/google/android-emulator-m1-preview)を試してみます。
８
https://github.com/google/android-emulator-m1-preview

1. [releases](https://github.com/741g/android-emulator-m1-preview/releases)のページから一番新しいのを取得（執筆時点ではInitial Preview 2）
2. dmgを開いて「Android Emulator」をApplicationsにインストールする
3. インストールした「Android Emulator」を右クリックから開く ※普通に開くと「開発元を検証できないため開けません」のエラーが出ます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2492/0d43bc4b-b023-ab16-72f8-b5907fc374a3.png)

開きました。:tada:

### ADBのパスを通す

しかし、別の警告が出ています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2492/382027e2-bb37-7c78-fbc3-61eb5272ac22.png)

警告に書いてある通り、エミュレータの設定画面でADBのパスを指定します。（``adb``コマンドにパスが通ってれば自動検知されるかも？）
私の環境では、「/Users/<ユーザー名>/Library/Android/sdk/platform-tools」の中にありました。

そして、エミュレータを起動した状態でAndroid Studioを見ると・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2492/0b6e5e3f-2a0d-5c18-76bb-c2b66e1aeb30.png)

「Virtual Device」として検出された！
ビルドしたアプリが動いた！（画面は無しです。）
デバッグ機能も使えた！！

というわけで、M1 Mac上でAndroid Studioからエミュレータが使えるところまで持ってこれました。:tada::tada:

## とはいえ……

まだまだプレビュー版で、このエミュレータだけで開発できる状況ではなさそうです。
既知の課題も山盛り。

> - Webview doesn't work in the AOSP version, but works in the Google APIs version preview v3. However, Chrome doesn't work.
- No device skins
- Video codecs not working
- 32 bit ARM apps won't work
- Graphical glitches in some Vulkan apps
- Popup on startup about not being able to find the ADB path (ADB will still notice the emulator if you have it installed though)
- When building, it may be faster to start then cancel the Python triggered build and then reissue ninja -C objs install/strip versus letting the Python triggered build finish.

なんとWebviewも動かない。
正式版が出るまでは、ちゃんと実機も用意して開発するのが良さそうですね。
【Vue 3】vue-composableのuseVModelを利用して複数の値のv-modelの煩雑さを回避する

Vue 3の機能変更の一つとして、コンポーネントに対するv-modelが複数の値に対応するになりました。
機能的には、3.xから削除された[.sync修飾子](https://jp.vuejs.org/v2/guide/components-custom-events.html#sync-%E4%BF%AE%E9%A3%BE%E5%AD%90)と同様のものです。

親コンポーネントでの利用は、次のように直感的に理解できます。

```html:App.vue
<template>
  <app-form v-model.title="title"
    v-model.description="description"
  />
</template>

<script lang="ts">
import { defineComponent } from 'vue'
import AppForm from '@/components/AppForm.vue'

export default defineComponent({
  components: {
    AppForm,
  }  
})
</script>
```

子コンポーネント側の記述は次のようになります。

```html:AppForm.vue
<template>
  <label>タイトル</label>
  <input :value="title"
    @input="$emit('update:title', $event.target.value)"
  />

  <label>概要</label>
  <input :value="description"
    @input="$emit('update:description', $event.target.value)"
  />
</template>

<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
  props: {
    title: {
      type: String,
      required: false,
      default: ''
    },
    description: {
      type: String,
      required: false,
      default: ''
    }
  }
})
</script>
```

# 何が煩雑か

子コンポーネント側から、親コンポーネントに対して値の変更を伝える必要があるのですが、`props`の値は直接変更することができないので子コンポーネントでは便利な`v-model`ディレクディブを使うことができず、`:value`と`@input`に分けて記述する必要があります。

さらに、親に変更を通知する手段として`$emit('update:title', $event.target.value)`のように`update:{v-modelの引数で渡した名前}`というイベント名をemitする必要があります。
似たような記述を何回も書く必要がありますし、`update:{v-modelの引数で渡した名前}`というイベント名を使う構文はなかなか覚えられません・・・
機能として提供されているわけではなく、emitのイベント名での提供なのでインテリヘンスが効かないですし、タイポにも気が付きにくです。

Composition APIでロジックを外だしできるようになったので共通関数にできないのか・・・と思ったらすでにありました。

# vue-composableを使う

[vue-composable](https://pikax.me/vue-composable/)は、Composition APIで使える便利な関数群をまとめらライブラリです。今回利用する`useVModel`以外にも、バリデーション・フォーマット・マウスイベントなど汎用性の高い機能が利用できます。

まずはインストールしましょう。

```sh
# install with yarn
yarn add @vue/composition-api vue-composable

# install with npm
npm install @vue/composition-api vue-composable
```

## useVModel

[useVModel](https://pikax.me/vue-composable/composable/misc/vmodel.html#vmodel)は第一引数にpropsオブジェクト、第二引数にpropsのキーを受け取り、リアクティブなpropsのキーのコピーを返します。

```ts
const _title = useVModel(props, 'title')
```

`useVModel()`で返された値を`v-model`で利用すれば、それだけで親コンポーネントに変更を通知してくれます！

```html:AppFrom.vue
<template>
  <label>タイトル</label>
  <input v-model="_title"/>

  <label>概要</label>
  <input v-model="_description"/>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
import { useVModel } from 'vue-composable'
export default defineComponent({
  props: {
    title: {
      type: String,
      required: false,
      default: ''
    },
    description: {
      type: String,
      required: false,
      default: ''
    }
  },
  setup (props) {
    const _title = useVModel(props, 'title')
    const _description = useVModel(props, 'description')

    return {
      _title,
      _description
    }
  }
})
</script>
```
EclipseにGradleプロジェクトをインポートする

- 環境
    - Windows10 Pro バージョン1909
    - Eclipse IDE for Enterprise Java Developer Version: 2019-09 R (4.13.0)
    - プロジェクトのGradle 4.3
    - プロジェクトのjava version "1.8.0_251"

# Gradleのバージョンを確認して使うEclipseのバージョンを決める
1. インポートするプロジェクトの`wrapper/gradle-wrapper.properties`の`distributionUrl`でGradleのバージョンを確認する
1. Eclipseの起動用JVMが、ななななんと関係することがあるので、「Gradleのバージョンに合ったJavaのバージョン」を**起動用JVMに設定できるEclipseのバージョン**を選択する
    - 例) Gradle 4.3の場合はJava8を使いたいけれどEclipse2020-09は起動用JVMをJava11からしか設定できないので、Eclipse2019-09を使った
        - Gradle 4.3にJava11を使うとエラーになることがある
        - [Could not create an instance of Tooling API implementation using the specified Gradle distribution - Qiita](https://qiita.com/ponsuke0531/items/4158786e2f1b55357c05)

```properties:wrapper/gradle-wrapper.properties
# 今回はGradle4.3
distributionUrl=https\://services.gradle.org/distributions/gradle-4.3-bin.zip
```

# Eclipseを設定する

1. eclipse.iniの`-vm`にプロジェクトのGradleで使いたいJavaのバージョンを指定する(JAVA_HOMEに違うJavaが設定されたとき用)
    - [eclipse.iniに-vmを指定する方法 - Qiita](https://qiita.com/ponsuke0531/items/4e8a2221d712f4779b65)
    - 今回は、Java8を設定
1. Eclipseを新規ワークスペースで起動する
1. [Help] > [Eclipse Marketplace]で以下がインストールされていることを確認する
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159761/e59ec396-7c9d-634d-f84d-52f10c1aa035.png)
    - 注意 : `Gradle IDE Pack`は[廃止予定なのでインストールしなくていい](https://qiita.com/ponsuke0531/items/40fca718c70843ab3ad6)
2. [Preferences]で以下を設定する
    - [Java] > [Installed JREs] > 「Java1.8」
    - [Java] > [Compier] > [Compier compliance level] > 「1.8」
    - [Gradle] > [Java home] > 「Java1.8のディレクトリ」
    - [ついでに文字コードとか改行コードとかエディタの設定とかしておく](https://qiita.com/ponsuke0531/items/f6ede34c1e34a5dd0810#%E6%96%87%E5%AD%97%E3%82%B3%E3%83%BC%E3%83%89%E3%81%A8%E6%94%B9%E8%A1%8C%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%97%E3%81%9F%E3%81%84)

# プロジェクトをインポートする
1. [Project Explorer] > [Import project] > [Gradle] > [Existing Gradle Project] > [Next]ボタン
1. [Project root directory]にプロジェクトのディレクトリを指定
2. [Next] > [Next]ボタン(ここあたりでエラーが出たらなんか設定が違う)
3. [Finish]ボタンでインポートする
デバッグ時はprintではなく、Icecreamを使うと便利

[この記事](https://towardsdatascience.com/stop-using-print-to-debug-in-python-use-icecream-instead-79e17b963fcc)を読んでみて、とても便利だなーと思ったので共有したいと思います。
## モチベーション
以下のコードを想定しましょう。

```python
num1 = 30
num2 = 40

print(num1)
print(num2)
```
出力は

```python
30
40
```
となります。さて、上の出力を見て`30`と`40`が`num1`と`num2`のどちらに対応しているかすぐに判別がつくでしょうか？
出力変数が少ないうちはこれでも問題はなさそうですが5個とかになると少し面倒くさくなりますね。

とりあえずの解決策として次のようにすれば良いでしょう。

```python
num1 = 30
num2 = 40

print('num1', num1)
print('num2', num2)
```
出力は

```python
num1 30
num2 40
```

確かに変数名と変数値の対応は元のコードよりは分かりやすくなりました。しかし、問題はコードの記述が面倒という点です。

### Icecreamとは？
上のような問題への解決策としてpythonライブラリの`Icecream`があります。
インストールは`pip`で行えます。

```python
pip install icecream
```

```python
from icecream import ic

num1 = 30
num2 = 40

ic(num1)
ic(num2)
```

出力は

```python
ic| num1: 30
ic| num2: 40
```
非常にシンプルでいいですね！
Icecreamの便利性はこれだけではありません。関数や条件分岐など使えます。
興味ある人は[こちら](https://github.com/gruns/icecream)から調べてみてください。
プルリクエストテンプレートの作成

#はじめに
ポートフォリオ作成中の初学者です。
忘れないようにまとめます。自分用メモ。

__1. Add file → Create new fie__
![image](https://i.gyazo.com/abbbfa6a646aa21981fe151be04a8813.png)
__2. ファイル名フィールドに[.github/pull_request_template.md]__
![image](https://i.gyazo.com/6a6928b5be2a9e2e307ba88059a68e5f.png)
__3. ファイル本文にプルリクエストテンプレートを追加(以下のような内容)__

- リポジトリ内の関連する Issue への参照。
- プルリクエストで提案された変更の説明。
- 提案された変更のレビューを担当する個人やチームの@メンション。

__4. ファイルに対して行った変更を説明するミットメッセージを入力__

__5. ブランチを選択__
__6. Propose new file__

#完成
これでプルリクのたびにテンプレートが書かれた状態に！
便利！

#参考

 [公式](https://docs.github.com/en/free-pro-team@latest/github/building-a-strong-community/creating-a-pull-request-template-for-your-repository)
Windows10でタスクバーの表示がおかしくなったときの対処法

# ときどきあるのでメモっとく
間違えて電源ボタン押して、シャットダウンしちゃったときとか、タスクバーのアイコンがおかしくなるときがある。アイコンが変わったり、消えたりとか。  
再起動しても治らない。
気持ち悪いままなので、結構困ってた。
対処法を見つけたのでメモっとく。

# 対処法
タスクマネージャーを開き、「エクスプローラー」を選択して「再開」を押す。
すると、あら不思議、アイコンの表示がもとに戻る。
__git_ps1: command not found

# 事象 : `sh`と打ったらなんか言われるようになった。
- 環境 : Windows10 Pro バージョン1909

```bash
# なんか言われた
ponsuke@tarou MINGW64 /c/git/git-repo (develop)
$ sh
sh: __git_ps1: command not found
# 何しても言われるようになった・・・ブランチ名が表示されなくなってしまった・・・
ponsuke@tarou MINGW64 /c/git/git-repo
$ cd .git
sh: __git_ps1: command not found
```

## 原因 : git_ps1コマンドが消失したから?
参考 : [bash_completionで「-bash: __git_ps1: command not found」となった時の対処法 - くりにっき](https://sue445.hatenablog.com/entry/2012/08/30/005627)

### 対応 : Git Bashを再起動する
その画面を閉じてまた起動すれば大丈夫！
【休止】趣味で何か作りたい人のエンジニア仲間の探し方

__追記 2021/10/30__
運営者の事情により、このコミュニティは休止となりました。
関わってくださった皆様、ありがとうございました。

追記 2021/06/26
初回のコミュニティ機能の開発メンバーの募集を終了いたしました:writing_hand:
これから、空き時間でぼちぼちとコミュニティメンバーが使える便利な機能を開発していこうと思います。

githubへもコードを公開可能な部分はしていきたいと思っていますので、
時たまHP等を確認いただけるとありがたいです:thumbsup_tone1:

これからもよろしくお願いいたします:boy_tone1::girl_tone1:

ーーーーーーーーーーーーーーー
追記 2021/06/17
300人以上Slackに登録いただきました。ありがとうございます :thumbsup: 

空き時間にプロダクトの作成をするエンジニアのためのコミュニティ 『off.dev』 の機能開発を進めていますが、現状二人で進めていて進捗があまり出ていません:cry:
お時間がある方がいれば、ぜひ開発に参加してもらえるとありがたいです！
（新しくHPに機能開発用のページを作りました。）

よろしくお願いします🙏
~~https://offdev.bubbleapps.io/offdev_feature_creater~~

ーーーーーーーーーーーーーーー
空き時間にプロダクトの作成をするエンジニアのためのコミュニティ 『off.dev』 を作ろうとしています。
記事を読んで、いいねと思ったら、お気軽にSlackに参加してください🙏
~~http://offdev.bubbleapps.io~~

# このコミュニティを一言でいうと
__時間⏰やお金💰などについて、小さなリスクでも、０からプロダクトを育てていける仲間や経験をしたい人向けのコミュニティ🏫__

# こんな感じのコミュニティにしたい
「主体性を持った開発ができる環境」
「ストーリーがある出会い」
「各々のコミットメントの度合いがわかりやすい」
「コニュニケーションが安全・安心でスムーズ」
「チームに入りやすいし、抜けやすい」
「プログラミング以外のノウハウの共有」

# 作ろうと思った経緯
大手Sierから小さなITベンチャーへ転職し、１からプロダクトを作成する手順を学んでいくうちに、何か自分個人でもプロダクトを作りたいなと思いはじめました。

### 問題１　『仲間が見つからない。』
そうは思ったものの、自分ひとりだと時間もかかるし、誰かと一緒に進めたいと思ったのですが、周りに __空き時間にプロジェクトを行おうという志向の友達がいない。__ どこかで見つけられないかなとイベントなどにも参加しますが、なかなかできない。コニュニケーション弱者であるためかもしれません、、、とにかく、この問題に大きな困難を感じる人も多くいるのではないかと思う体験になりました。

このコミュニティを通して、より簡単に自分に合った仲間が見つかるようになるといいなと思います。それぞれプロジェクトを行いたい理由やスキル、割ける時間は異なると思うので、その辺がマッチした人と仲間になれるといいかなと思っています。

### 問題２　『ネタがない』
その後、たまたま会社内で同じように空き時間で何かつくりたいと思っている人と出会え、プロダクトを作ることになったのですが、何を作るかが一向に決まらない。
問題はプロダクトのための __アイディア創生のスキル__ を持っていないことでした。「これに困っている」ということがあれば、それに対して開発が始められたのですが、なかなか人が何に困っているのか捉えるのに苦労しました。

この体験から、このコミュニティでは、ネタを探すことの手助けができるといいなと思っています。例えば、直接インタビューにいくフィールドワークを行うなど、解決可能な課題にはどんなものがあるか、またそれを見つける方法を共有することで、ネタを発見できるようになるといいなと思っています。

### 問題３　『作ったものを広め方がわからない』
なんとか、作るものを決めて、開発を始めました。開発自体はいつも業務でも行っていることなので、順調に進み、開発は完了しました。
ただ、ここで作ったものをどう広めたらいいか分からないという第三の問題に直面しました。広告など打ったこともないですし、強いツイッターアカウントを持っているわけでもなく、__どうしたら作ったサービスを知ってもらえるのか__。 個人運営者の方のインタビューなどで勉強しました。現状でも、この部分はよくわかっていないので、手探りで行っています。

「こうしてサービスは広がっていく」というノウハウがシェアされる場があるといいなと思いました。コミュニティにそういった機能を作ろうと計画しています。

# コミュニティについて
### ミッション
空き時間でも作成・参加できる小さなプロダクト『マイクロプロダクト』を作成する人たちの活動をサポートする。

### 活動
- 同じ思いを持つメンバーによるネットワークを構築する。
- 外部や内部の人々や組織にアプローチし、解決できる適切な課題を発見する、またはその手助けとなる情報を提供する。
- プロダクトの作成やマーケティングなどのノウハウを共有できる場を提供する。
- 協業が可能な場所を提供する。
- 成果を仲間や外部に発信できる場を提供する。
- プロダクトの作成やマーケティングなどのノウハウを学べる機会を提供する。

### メンバー属性
なんらかのスキルがある人

### メンバーの利益
チームメンバーのマッチング機能、プロダクトのコンペ、コワーキングスペースの運営、ノウハウの共有ノートなど

~~少しでも参加していただけるとありがたいです。よろしくお願いします🍣~~
~~http://offdev.bubbleapps.io~~
高い品質のWEBサイトを構築する上で、気を付けるべき「言葉使いのポイント」

#どうも7noteです。いいサイトは文字が読みやすく分かりやすい。

**いいサイトは言い回しや言葉の選び方が綺麗**です。
コピーライターという仕事があるくらい、文章や文字というのはとても繊細なものです。

デザインが綺麗なのに文章が綺麗でないと読みにくいサイトになってしまいます。
そうならないためには様々な方法がありますが、公開前に最低限これは見直しておきたいポイントをまとめました。


## ①「ターゲットに伝わる言葉」が使われているか

初心者向けサイトなのに、**専門用語ゴリゴリのサイトでは読む気をなくしてしまいます。**
その言葉が伝わる人に向けてしか発信しないのであればいいですが、一般ユーザーに公開しているのであればできるだけ**誰が読んでも分かりやすい言葉を使いましょう。**

### 対策方法：そのサイトの分野に詳しくない人に読んでもらい分からない言葉がないか聞く。


## ②「ひらがな」「カタカナ」「漢字」「英語」（「数字」）どの表記にするか

あっちのページではひらがな。こっちのページではカタカナ。はたまたこっちでは漢字。。。
読むことはできますが不格好になってしまいます。**同じ言葉は同じ表記で統一しましょう。**

### 対策方法：頻出する言葉はWEBサイト制作前からルールを決めておく。



## ③「送り仮名」をつける・つけない

これも②と同様ですね。不格好になってしまうので統一しましょう。

悪い例）・引っ越し
　　　　・引越し
　　　　・引越

### 対策方法：頻出する言葉はWEBサイト制作前からルールを決めておく。


## ④「表記のゆらぎ」がないか

これも②と同様です。言葉の前に「お」を付けるのかつけないのか等細かいところですが整理されている方が綺麗に見えます。

### 対策方法：頻出する言葉はWEBサイト制作前からルールを決めておく。

## ⑤「スペルミス」「読み方が同じ漢字」

これは気付かれない場合もあるかもしれませんが、もし見つかったらはずかしい。。。
**漢字や英語が苦手な人は特に注意しておくべきポイント**ですね。

### 対策方法：単語は必ずgoogleで翻訳する。もしくはWordのスペルチェック機能を使う。


## ⑥「句読点（、。）」が多すぎる・少なすぎる。

言いたい事をなんでもかんでも1行に詰め込んだ結果、主語と述語が噛み合わない文章ができたり、無理に句読点で繋いでいて**読みにくいものになっていることがあります。**

### 対策方法：声に出しながらおかしくないか、また読みやすいかを確認する。



## おまけ

文章の作り方や、言葉のルールなどは既に広告や新聞会社で決まっているものがあったりするそうです。
なかにはこのようなチェックツールがあるので参考に使用してみるのもいいかも。

文章チェックツール
https://so-zou.jp/web-app/text/proofreading/

## まとめ

最初の1行読んだだけで、その先を読むか読まないか、またそのサイトの評価が決まってしまうといっても過言ではありません。
地道で大変ですが、文章チェックは念入りに時間をかけて取り組んでいくとよりよいサイトになるかもしれません。

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)
【初心者目線】RubyでFizzBuzz問題を"簡単に"解いてみた！

この記事では、FizzBuzz問題についてまとめてみました！

皆さんはプログラミングの学習を初めてから、だいぶ初期にこの問題を目にしたのではないでしょうか。

FizzBuzz問題は初心者にもそこまで難しくない問題で、プログラミングの効果的な学習材料となります。

できるだけ初心者向けでわかりやすいように頑張りますので、是非最後までお付き合いください！

## FizzBuzz問題とは？

プログラミングで言うFizzBuzz問題とは、3で割ることのできる数字を入力したら"Fizz"、5で割ることのできる数字を入力したら"Buzz"、または両者で割ることのできる数字(すなわち15で割ることができる数字)を入力したら"FizzBuzz"と返事が来るプログラムを書く問題のことです。

Rubyの入門参考書などを買うとよく載っているので、皆さんの中には実際に解いたことがあると言う人も少なくないでしょう。

## FizzBuzzの書き方・考え方

まずは完成形のコードをみてみましょう。

```Ruby:FizzBuzz.rb
def FizzBuzz(n)

 if n % 15 == 0
  'FizzBuzz'
 elsif n % 3 == 0
  'Fizz'
 elsif n % 5 == 0
  'Buzz'
 else 
  n.to_s
 end

end

```

まず、nを15で割った時にあまりが0、すなわち15で割ることができる数字を入力されたら'FizzBuzz'と返すように命令しています。

次に3で割れる数字を入力されたら'Fizz'、5で割ることができる数字を入力されたら'Buzz'と返すようにしています。

最後に、それ以外の数字が入力された場合、その数字を文字列に変換して返すように命令しています。

実際にこのプログラムを実行してみましょう。

まず、今書いたメソッドの下に、メソッドを使った命令を書いてみます。

```Ruby:FizzBuzz.rb
def FizzBuzz(n)

 if n % 15 == 0
  'FizzBuzz'
 elsif n % 3 == 0
  'Fizz'
 elsif n % 5 == 0
  'Buzz'
 else 
  n.to_s
 end

end

FizzBuzz(1)
FizzBuzz(3)
FizzBuzz(4)
FizzBuzz(5)
FizzBuzz(10)
FizzBuzz(15)

```

そして、ターミナルに以下の命令をします。

```

$ ruby lib/FizzBuzz.rb
```

これは、libと言うディレクトリ（フォルダ）の直下にあるFizzBuzz.rbと言うファイルを実行しろと言う命令です。

実際に実行してみると、下記の結果が出るはずです。

```
1
Fizz
4
Buzz
10
FizzBuzz
```

これと同じように結果が出れば成功となります！

##　まとめ

FizzBuzz問題は初心者の登竜門的なプログラミングの練習問題です。

3の倍数を入力したらFizz、5だとBuzz、両方の倍数だとFizzBuzzが出力されるようにプログラムを書きます。

どうだったでしょうか？わかりにくいところなどがあったら教えていただけると幸いです！

この記事のリライトの材料にもなりますし、僕自身の成長にも繋がるので是非お意見お待ちしております！
React GoogleMapAPIで地名や住所から緯度経度を取得する方法

#はじめに
今回は、地名や住所を入力して緯度と経度の情報を取得する方法をまとめました。
これができると、入力した地名にピンを立てたり、地図が移動したりできるのではないかと思います。
Reactのライブラリreact-geocodeを使用します。
単にマップを表示させたいという方は[こちら](https://qiita.com/santa0809/items/3ccfc168924cde76de5a/)をご参考ください。
事前にGoogleMapのAPIキーの取得と有効化、GeocodingAPIの有効化をお願い致します。


#参考サイト
地名から緯度経度を取得するパターンと緯度経度から地名を取得するパターン両方載っています。
今回はHow to get lat and lng from addressで調べました。
https://www.npmjs.com/package/react-geocode

#導入方法
まずはライブラリを利用する準備をします。
react-geocodeの最新バージョンを調べます。

```
$ npm info react-geocode
```
結果の一部がこちら

```
react-geocode@0.2.2 | MIT | deps: 1 | versions: 15
A module to transform a description of a location (i.e. street address, town name, etc.) into geographic coordinates (i.e. latitude and longitude) and vice versa.
https://github.com/shukerullah/react-geocode#readme
```
今の最新バージョンはreact-geocode@0.2.2でしたので、これをyarn addします。

```
$ yarn add react-geocode@0.2.2
```
これでこのプロジェクトでreact-geocodeが使えるようになりました。

#地名から緯度経度を取得(コードの中)
まずはライブラリをimport

```react:Geo.js
import Geocode from "react-geocode";
```
アロー関数の中はこんな感じで書きます。

```react:Geo.js
const Geo = () => {

    Geocode.setApiKey("YOUR_APIKEY");
    Geocode.fromAddress("Eiffel Tower").then(
        response => {
            const { lat, lng } = response.results[0].geometry.location;
            console.log(lat, lng);
        },
        error => {
            console.error(error);
        }
    );
    return (
        <div>
            <h1>map</h1>
        </div>
    )
}
```
検証モードでconsoleを見ると、エッフェル塔の緯度と経度が確認できるかと思います。
下のdiv要素が無いとreturnするものが無いですというエラーが発生するので、とりあえず適当に入れています。
YOUR_APIKEYのところにご自身の取得したGoogleMapのAPIキーを入力してください。

#地名から緯度経度を取得(画面で入力した地名)
先ほどの"Eiffel Tower"の部分を画面上で入力した地名に置き換えたいと思います。
まずはinputタグとbuttonタグで入力する部分を準備します。
先ほどのh1タグの下に

```react:Geo.js
 <h1>map</h1>
 <input type='text'
        onChange={(e) => {
        setPlace(e.target.value)
 }}></input>
 <button onClick={() => {
         PushData();
 }}>search</button>
```
そして緯度経度を取得するコードの部分を関数に入れてあげます。
ボタンを押したらこの関数が走るように設定します。

```react:Geo.js
const [place, setPlace] = useState('');
    const PushData=()=> {
        Geocode.setApiKey("YOUR_APIKEY");
        Geocode.fromAddress(place).then(
            response => {
                const { lat, lng } = response.results[0].geometry.location;
                console.log(lat, lng);
            },
            error => {
                console.error(error);
            }
        );
    }
```
入力欄が変更されるとsetPlace関数が動いて、placeに入力した値が入ります。
searchボタンが押されると入力した地名の緯度と経度が取得できます。

あっ、useStateのimportもお忘れなく！

```react:Geo.js
import React, { useState } from 'react';
```
#終わりに
今回は入力した地名から緯度と経度を取得するまでをご紹介しました。
次の投稿で取得した緯度経度を用いて、Googleマップにピンの立て方をまとめてみたいと思います。
firebaseも使います。
最後まで読んでいただきありがとうございます。