OmniAICreator/Qiita-1.07M huggingface dataset:
Nginxログファイル/リアルタイム暗号化

Nginxのログファイルをリアルタイムで暗号化する方法を記載します。

POSTされたログ（リクエストボディ）は欲しいけど、ローカルに記録されるタイミング（リアルタイム）では暗号化したい見たいなシチュエーションを想定しています。

ログファイル自体を都度暗号化する方法はググればすぐ出てきますが、リアルタイムで 
暗号化する方法は意外となくて、OSの持つ機能で手軽にできないか模索していた際に思いついた内容です。 

セキュリティ面の問題やパフォーマンス、およびその他十分な動作検証をしている
わけではないので利用する際は十分検証を行ってください。  

## 1. 環境
- OS : CentOS7.9
- Kernel: 3.10.0-1160.49.1.el7.x86_64
- Nginx: 1.18.0
- rsyslog: 8.24.0-57
- openssl: 1.0.2k-22


## 2. Nginx設定

リクエストボディの内容がログに記録されるようにlogフォーマットを作成し、それをsyslogに転送できるように設定します。  
※下記設定はすべてがnginx.confだけで構成されている例となります。conf.d配下にserverディレクティブを分けて記載している場合、access_log 部分は適切な場所に設定してください。

```bash
vim /etc/nginx.conf  
log_format  custom  '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for" "request_body": "$request_body"';

access_log syslog:server=127.0.0.1:514,facility=local6,severity=debug custom;
:wq

nginx -t
systemctl restart nginx
```

## 3. SYSLOG設定 

Nginxから転送されたログを受け取れるようrsyslog.confの設定を変更します。

```bash
vim /etc/rsyslog.conf

$ModLoad imudp
$UDPServerRun 514
$AllowedSender UDP, 127.0.0.1
local6.debug	|/var/log/plain.fifo
:wq
```

## 4. fifoファイル作成/暗号化用Shell作成

fifo/ログファイル作成します。

```bash
mkfifo /var/log/plain.fifo
touch /var/log/crypt.log
systemctl restart rsyslog
```

スクリプト配置用ディレクトリ作成します。

```bash
mkdir -p /usr/local/encrypt/bin
cd /usr/local/encrypt/bin
```

暗号化用スクリプト作成します。

```bash
vim encryption.sh
#!/bin/bash

LOGBASE=/var/log

MONITORING_LOG=${LOGBASE}/plain.fifo
TARGET_LOG=${LOGBASE}/crypt.log

action() {
    while read plaintext
    do
        echo "${plaintext}" | openssl enc -pass pass:abc123 -e -aes128 | base64 -w 1000 >> ${TARGET_LOG}
    done
}

cat ${MONITORING_LOG} | action
```
※pass:abc123は暗号化/復号化実施時に利用するパスワードです。
　実運用では環境変数を利用するなど工夫して使ってください。

※base64 の「-w 1000」はログファイル１行の折り返し文字指定（デフォルト76文字）です。
  実際のログに合わせて値は調整してください。

あとは作成したencryption.shに実行権限をつけてバックグランドで起動。
自動起動したい人はrc.localとか .serviceファイルを作成して利用してください。

復号化させる場合は、暗号化されたログファイル自体を読み込んで１行ずつ復号化させれば
平文のログを閲覧できます。

```bash
vim decode.sh

BASEDIR=/var/log
TARGET_LOG=crypt.log

while read decrypt
do
    echo "${decrypt}" | base64 -d | openssl enc -pass pass:abc123 -d -aes128
done < ${BASEDIR}/${TARGET_LOG}
```
複数のPCから同一のGithubアカウントに接続する

普段、iMacでプログラムを書いているのですが、
新しくwindowsPCを購入し、
両方のPCで同一のGithubアカウントを使いたいと思いました。
ちょっと手こずってしまったので、メモとして残したいと思います。

```
# 公開鍵の作成
$ cd .ssh && ls
id_rsa id_rsa.pub

$ ssh-keygen
$ cat id_rsa.pub
```
publicが公開鍵ですね
出てきた、公開鍵の暗号を丸ごとコピー

![github.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700627/f804b0f5-3ad8-76ab-9c9f-25352375c945.png)

githubにとび、setting->SSH and GPG keys

画面右上のNEW SSH keyをクリックすると下記の画面になります。

![sshkey image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700627/1361463d-2ebc-c5d7-30a7-9d369d30fd0f.png)

好きなタイトル、keyにはさっきコピーしたものをそのまま貼り付けます。
その後、Add SSH keyクリックで登録します。

その後は下記のコマンドでグローバルにgithubに登録すればOKです。

```
$ git config --global user.name ユーザー名
$ git config --global user.email メールアドレス
```
ユーザー名、アドレスは既に登録されているものを入力します。
もう一つのPCから登録情報を見るには下記のコマンドになります。

```
$ git config user.name
$ git config user.email
```

これで2台のPCでGithubを管理できるようになります。
VSCodeでipynbファイルをHTML出力した時に等幅フォントにならない時の対処法

# 結論
`.CodeMirror pre` の CSS に `font-family: "Courier New", Consolas, monospace;` を加える。

```css:コピペ用
.CodeMirror pre {
  padding: 0 var(--jp-code-padding);
  font-family: "Courier New", Consolas, monospace;  /* add this line */
}
```

# 試したこと
VSCode で ipynb ファイルを HTML 形式で Export すると、次の写真のように等幅フォントになってないことがある。
![スクリーンショット 2022-01-03 0.44.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1583044/43442989-9323-00ee-54aa-e4ba1cf2a912.png)
出力された HTML ファイルに、次の写真における11947行目に当たる部分の1行だけを加えた。
![スクリーンショット 2022-01-03 0.59.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1583044/5c0e566e-058c-6880-e110-fcfe3232103b.png)

すると、次の写真のように解消することができた。
![スクリーンショット 2022-01-03 0.53.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1583044/4425ed9f-2cff-8006-eef2-ceb209d1ce0d.png)

# 参考文献
1. [CSS で font-family: monospace 指定だと等幅フォントが適用されない？](https://neos21.net/blog/2017/10/22-01.html)
2. [\[CSS\]等幅フォントにするためのおすすめのfont-family指定](https://wada811.blogspot.com/2012/12/monospace-font-family.html)
AWS データレイクハンズオン - Lab4 -

# 背景

データ分析に AWS を使えることを知ったので、AWS データレイクハンズオンを試して、実際に分析パイプラインを構築してみる。

https://github.com/aws-samples/amazon-s3-datalake-handson/tree/master/JP

# ハンズオンに取り組む

## Lab4: アプリケーションログの永続化と長期間データの分析と可視化

主に使用するサービス:

- Kinesis Data Firehose
- S3
- Athena
- QuickSight

### Section1: S3, Kinesis Data Firehose の設定

#### Step1: S3 バケットの作成

#### Step2: Kinesis Data Firehose の作成

特に問題なく作成できた。

### Section2: EC2 の設定変更

#### Step1: IAM ロールのポリシー追加

#### Step2: Fluentd の設定

特に問題なく設定できた。

### Section3: Glue Crawler, Athena の設定変更

#### Step1: IAM ロールのポリシー追加

#### Step2: Glue Crawler を使ったスキーマの自動作成

#### Step3: Athena でクエリ実行

#### Step4: QuickSight の設定

QuickSight は、スタンダード版で設定した。
SSL証明書の種類（メモ）

SSL証明書について勉強中

SSL証明書は以下の３種類が存在するとのこと。

①ドメイン認証
②企業認証
③EV認証


信頼性の順番は
①＜②＜③
になっている


#ドメイン認証(Domain Validation)
- ドメインの使用権があるかどうか


#企業認証(Organization Validation)

- 企業・組織が法的に存在しているかどうか

#EV認証（Extended Validation）

- 上記２つに加えて企業・組織が物理的に存在して事業が行われているか
- EV認証されたサイトはアドレスバーが緑色に表示される



参考サイト：https://www.rworks.jp/system/system-column/sys-entry/21283/
Mullvad VPNのLinuxクライアントを使用中にSSHを使えるようにする

Mullvad VPNは内部でnftablesを利用していて、接続中は外部からのトラフィックをすべてブロックしている。そのためその端末へSSHなどが繋がらない。

解決の方法はオフィシャルサイトに書いてある。
https://mullvad.net/en/help/split-tunneling-with-linux-advanced/

# 前提条件
nftables がインストール＆有効化されていること

```
sudo apt install nftables
sudo service nftables start
sudo systemctl enable nftables.service
```

# 設定
以下のようなファイル `mullvad-customized.nft` を作り、

```
#!/usr/sbin/nft -f

table inet excludeTraffic {
  chain allowIncoming {
    type filter hook input priority -100; policy accept;
    tcp dport 22 ct mark set 0x00000f41 meta mark set 0x6d6f6c65;
    tcp dport 3128 ct mark set 0x00000f41 meta mark set 0x6d6f6c65;
  }
 
  chain allowOutgoing {
    type route hook output priority -100; policy accept;
    tcp sport 22 ct mark set 0x00000f41 meta mark set 0x6d6f6c65;
    tcp sport 3128 ct mark set 0x00000f41 meta mark set 0x6d6f6c65;
  }
}
```

nftablesに読み込ませる。上記は22と3128の外部接続を許可する。

```
nft -f mullvad-customized.nft 
```

切断や再接続、`sudo service nftables restart` などをやるとSSHがつながるようになる。

この設定は再起動で消えるが、 `/etc/nftables.conf` に書いて永続化することも可能。
VSCodeでめちゃくちゃ簡単にNode.jsをデバッグする

`ctrl + shift + p`
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212159/340bc297-74b4-4e80-bfe1-038cad8b98e5.png)



`Debug: Toggle AutoAttach`
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212159/a3e61c18-d6af-5bbd-180b-04171a3e29e1.png)



`スマートを選択`
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212159/0e9f6d93-9e96-5d73-8e16-d876c1303602.png)



`起動`
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212159/c363bf1e-a9cf-8d8a-5907-0a1b1a2225c5.png)
selenium から Twitter にログインして投稿

TwitterにPythonからログインして投稿する方法のメモ。
AlmaLinux, Chrom で確認。

Python 3.6.8
Google Chrome 98.0.4758.102, 96.0.4664.110 
selenium 3.141.0


## 起動

```python
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
import chromedriver_binary
import time

# seleniumを起動
options=Options()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
driver=webdriver.Chrome(chrome_options = options)
```

## Twitterログイン
HTMLがよく変わるから注意。
アカウントとパスワードの入力画面が別れたため２画面の処理。
各所に2秒のスリープを入れる。

```python

def login_twitter(account, password):
    # ログインページを開く
    driver.get('https://twitter.com/login/')
    time.sleep(2)

    # account入力
    element_account = driver.find_element_by_name("text")
    element_account.send_keys(account)
    time.sleep(2) 
    # 次へボタンのXPathがこれでしか取れなかった・・・
    # 次へボタンクリック
    element_login = driver.find_element_by_xpath('/html/body/div/div/div/div[1]/div/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div[1]/div/div[6]')
    element_login.click()
    time.sleep(2) 

    # パスワード入力
    element_pass = driver.find_element_by_name("password")
    element_pass.send_keys(password)
    time.sleep(2) 
    # ログインボタンクリック
    element_login = driver.find_element_by_xpath('//*[@data-testid="LoginForm_Login_Button"]')
    element_login.click()
    time.sleep(2) 
```

各画面のスクリーンショットを撮ってデバッグしたい場合は、

```python
driver.save_screenshot('保存する画像名')
```
のコードで実装可能


## 投稿

```python
def send_tweet(text):
    # テキスト入力
    element_text = driver.find_element_by_class_name("notranslate")
    element_text.click()
    element_text.send_keys(text)
    # ツイートボタン
    tweet_button = driver.find_element_by_xpath('//*[@data-testid="tweetButtonInline"]')
    driver.execute_script("arguments[0].click();", tweet_button)
```

click()は失敗することもあるので、execute_scriptメソッドで実行

[サンプル](https://github.com/katafuchix/twitter_post_selenium_sample)


### seleniumのバージョンアップ対応
例）

```python
def login_twitter(account, password):
    # ログインページを開く
    driver.get('https://twitter.com/login/')
    time.sleep(1)
    
    # account入力
    element_account = driver.find_elements(By.NAME, 'text')[0]
    element_account.send_keys(account)
    time.sleep(1) 
    # 次へ
    element_account.send_keys(Keys.RETURN)
    time.sleep(1) 
    
    # パスワード入力
    element_pass = driver.find_elements(By.NAME, 'password')[0]
    element_pass.send_keys(password)
    time.sleep(1) 
    # ログインボタンクリック
    element_login = driver.find_elements(By.XPATH, '//*[@data-testid="LoginForm_Login_Button"]')[0]
    element_login.click()
    time.sleep(1)
[Laravel]ログインの有効時間を個別に設定する方法


管理者と一般ユーザーなどで複数のログインフォームを持つ場合に、個別にログインの有効時間を設定する方法
意外と難しいやり方をしている記事が多かったため、メモ用に作成

## やり方
```php:app/Providers/AppServiceProvider.php
public function boot()
    {
        // 以下を追加する
        if (request()->is('admin*')) {
            // urlのpathに「admin」が含まれる場合はadmin用の設定を適応する            
            config(['session.cookie' => config('session.cookie_admin')]);
            config(['session.lifetime' => config('session.lifetime_admin')]);
        }
    }
```

```php:config/session.php
    'lifetime' => env('SESSION_LIFETIME', 120),
    //以下を追加する
    'lifetime_admin' => env('SESSION_LIFETIME_ADMIN', 240),
```
```php:
    'cookie' => env(
        'SESSION_COOKIE',
        Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
    ),
    // 以下を追加する
    'cookie_admin' => env(
        'SESSION_COOKIE_ADMIN',
        Str::slug(env('APP_NAME', 'laravel'), '_').'_session_admin'
    ),
```
```console:.env
    SESSION_LIFETIME=120
    // 以下を追加する
    SESSION_LIFETIME_ADMIN=240 

```
上記の設定だと以下のようになります
(例) http://localhost/login  ←pathに「admin」を含まないのでログインの有効時間は120分間
(例) http://localhost/admin/login  ←pathに「admin」を含むのでログインの有効時間は240分間
マウントする要素　Vue備忘録#1

#気づいたこと
初めてVueの本を買ってサンプルコードをいじっていたところ、jsファイルのel:直後の'#...'と、
htmlファイルの[div id=...]の名前が同じじゃないといけないことに気づいた。

「el」はマウントする要素
らしいけど、要はどのhtmlの要素とつなげるかって感じ。

```Javascript:main.js
var app = new Vue({
    el: '#aha',
    data: {
        message: '初期メッセージ'
    }
})
```


```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>Vue.js app</title>
    <link rel="stylesheet" href="main.css">
</head>
<body>
    <div id="aha">
        <p>{{ message }}</p>
        <input v-model="message">
    </div>
    <script src="vue.js"></script>
    <script src="main.js"></script>
</body>
</html>
```
rails sできないのは権限が付与されていないからだった

###コトの発端〜
railsアプリをローカルで確認してみようと`rails s`すると、`config/boot.rb`に対して`cannot load such file`とエラー文が出てアプリが開けない状態に、、

`config/boot.rb`に原因がありそうなのでVScode上で開いてみても開けなくなっていた。
ここでもエラー文を見てみると、
<FONT SIZE=4>**「**`config/boot.rbを読み取れません。(NoPermissions (FileSystemError): Error: EACCES: permission denied`**」**</FONT>
とのこと。自分にboot.rbを開く権限がないからファイルが開けない。従ってrails sに必要なboot.rbが使えないからアプリが開けなくなっていました。

#権限を確認する

cdはアプリのディレクトリで以下のコマンドを打つ。

```:ターミナル
ls -l
```

そうすると各ファイル・ディレクトリに対する自分の権限の範囲がどこまでなのか一覧で見れると思います。
以下一部抜粋したものです。
![スクリーンショット 2022-01-02 22.32.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293293/01040f71-cf3b-22cc-674c-d8a040dbdffd.png)
所有者権限において**「実行権限（=x）」**が付与されていない！
という訳で実行権限を持たせます。
（権限を変えた覚えが無いというのがもっとタチが悪いです:skull:）


※権限(パーミッション)のもっと詳しい見方は[こちらの記事](https://kitsune.blog/linux-permission)が大変見やすかったです

#実行権限を持たせる

```:ターミナル
chmod 700 config
```

もう一度権限を確認してみます。

![スクリーンショット 2022-01-02 23.04.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293293/086c5494-ce4b-e6c3-b624-9f110fc560d7.png)

実行権限付与された！

これでもう一度`rails s`するとうまくアプリが開けました。よかった〜

#参考
今回のエラーを対処する過程で`chmod`というコマンドを勉強することができてよかったです。こういうのを少しずつ積み重ねて行くんだろうなあと思いました。
[Linuxのパーミッション（権限）とは？確認や変更などの設定方法を紹介！](https://kitsune.blog/linux-permission)
[chmod コマンド](https://qiita.com/ntkgcj/items/6450e25c5564ccaa1b95)
SQLiteの使い方

#目的
ざっくりしたSQLiteの使い方を自分向けにメモする。

#ダウンロード

[このサイト](https://www.sqlite.org/download.html)からダウンロードする。
Windowsの場合は(作者はコマンドラインツールが欲しいので)以下をダウンロードする(バージョンは記載時点)。
sqlite-tools-win32-x86-3370100.zip
ＬPrecompiled Binaries for Windows

リナックスでは下記だが、`sudo apt-get install sqlite`でもインストール可能。
Precompiled Binaries for Linux
Ｌsqlite-tools-linux-x86-3370100.zip

#起動

Windowsではダブルクリックで起動可能。
コマンドラインから起動する場合、コマンドライン引数でDBのファイルを渡すことが可能。
ダブルクリックでの起動や、起動引数なしの場合はメモリモードで起動する。

- 引数なし

```
C:\Users\misaka\Downloads\sqlite-tools-win32-x86-3370100>sqlite3.exe 
SQLite version 3.37.1 2021-12-30 15:30:28
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite>
```

- 引数あり

```
C:\Users\misaka\Downloads\sqlite-tools-win32-x86-3370100>sqlite3.exe test.db
SQLite version 3.37.1 2021-12-30 15:30:28
Enter ".help" for usage hints.
sqlite>
```

Linuxではターミナルから起動可能。エイリアスやパスを通すなどすると使用しやすくなる。
コマンドライン引数でDBのファイルを渡すことが可能。
ダブルクリックでの起動や、起動引数なしの場合はメモリモードで起動する。

- 引数なし

```
misakayuni@misaka-dsktop:/mnt/c/$ sqlite
SQLite version 2.8.17
Enter ".help" for instructions
sqlite>
```

- 引数あり

```
misakayuni@misaka-dsktop:/mnt/c/$ sqlite
SQLite version 2.8.17
Enter ".help" for instructions
sqlite>
```

#コマンド

| コマンド | 効果 |
|:-:|:-:|
| .q | 終了する。 |
| .databases| アタッチされているデータベースの一覧を表示する。 |
| .schema | テーブルの構造を表示する。 |

#通常のSQLと違う点

- データ型は存在しているが意味をなしていない。
例えば、テーブル定義時にdateで入れていてもtextとして扱われてしまうため「A」をinsertできてしまう。

- アタッチをして複数のDBを横断してSQLを発行できる。アタッチできるDBの最大数は10個。
アタッチする場合は` attach '(DB名)' as (使用するときのエイリアス名);`。
デタッチする場合は` detach (使用するときのエイリアス名);`。

- ファイルに書き込む作業があるので毎回コミットを行うと処理が重い。
なので必要な範囲で自分でbegin-endを行うと高速化が可能。


#終わりに
気が向いたら追記します。
アドベントカレンダー大遅刻でごめんなさい。
SQLのHAVING句で全称量化（Vol.2）

## はじめに

前回の記事をご覧ください。

https://qiita.com/ryosuketter/items/c6f7d83e2d832b249bf8

### 今回の例題にて用いるデータ

実行結果はこちらで確認できます。

https://www.db-fiddle.com/

#### 用いるデータ

前回の記事をご覧ください。

https://qiita.com/ryosuketter/items/c6f7d83e2d832b249bf8

#### 今回の例題

`members`テーブルには何かしらの行動が開始できるかどうかのステータスがデータ化されています。

この時「クラスの全メンバーが行動可能な状態（`ready`）であることがわかるクエリ」を書いてください。

本日はCASE3を見ていきます。

##### CASE3

クエリ

- 以下のクエリは
    - ある要素　（今回ならグループ化された各行（集合））の最大値と最小値が同じであることが`TRUE`である
        - ということは、その集合は1つの値（`status`）今回なら`ready`のみしかない
    - ことを利用しています
    - 極値関数は、引数の列のインデックスを利用できるのでパフォーマンスもいいです

```sql
SELECT class
FROM members
GROUP BY class
HAVING MAX(status) = 'ready' AND MIN(status) = 'ready'
```


結果

| class |
| ----- |
| C     |
| D     |

##### CASE4

別の視点ですが、集合に対する条件をSELECT句に移して、欲しい条件の集合かそうじゃないかのラベリングをつけるものいいでしょう

- OK,全員が`ready`
- NO

クエリ

```sql
-- (MySQL v5.6)
SELECT
	class,
	CASE
		WHEN MAX(status) = 'ready' AND MIN(status) = 'ready'
		THEN 'TRUE' ELSE 'FALSE' END AS IS_READY
FROM members
GROUP BY class
```

結果

| class | IS_READY |
| ----- | -------- |
| A     | FALSE    |
| B     | FALSE    |
| C     | TRUE     |
| D     | TRUE     |
| E     | FALSE    |


ただし、このクエリはMySQL（v5.6）までしか使えないでしょう（デフォルトの設定しかしていなければ）。

なぜならば、MySQL(v5.7)からはデフォで`ONLY_FULL_GROUP_BY`オプションが有効になっているからです。

有効の場合、GROUP BYするカラムだけしか参照できなくなります（無効だと、GROUP BYしたカラムじゃなくても参照できます）。

https://dev.mysql.com/doc/refman/8.0/ja/group-by-handling.html

本日は以上です。

## 参照

https://www.amazon.co.jp/dp/4798157821/

123p

## アウトプット100本ノック実施中

https://qiita.com/ryosuketter/items/713474dbd009870e4103
コンピュータ・システム　シンボルテーブル

# シンボルについて

自分用のメモです。

グローバル変数についてはこちらに。
[C言語　グローバル変数の正しい使い方 - Qiita](https://qiita.com/keitean/items/919effbcbc674d0cece8)

ELFファイルについてはこちらにまとめています。
[コンピュータ・システム　オブジェクト・ファイル 3つの形式 - Qiita](https://qiita.com/keitean/items/1515470e35dd9b614369)

## リンカにおけるシンボルおよびシンボル・テーブル

再配置可能オブジェクト・モジュールmには、mで定義・参照されているシンボルに関する情報を含むシンボル・テーブルが存在する。リンカの文脈では3種類に区別されるシンボルがある。

| 種類 | 説明 | 相当 |
| - | - | - |
| 大域シンボル | モジュールmで定義され、他のモジュールから参照可能な大域シンボル | 静的でないCの関数、グローバル変数 |
| 外部的大域シンボル | 他のモジュールで定義されている大域シンボル | 他のモジュールで定義された静的でないCの関数、グローバル変数 |
| 局所シンボル | モジュールmでのみ定義・参照される局所シンボル | 静的なCの関数およびstatic属性付きで定義されたグローバル変数。モジュールm内のみで参照可能。 |

## readelfコマンドでシンボルテーブルを見る

```c
int	ft_strlen(char *str)
{
    int i;

    i = 0;
    while (str[i])
        i++;
    return (i);
}
```

Symbol table '.symtab'の中身をreadelfコマンドで参照します。
.symtab内のシンボル・テーブルは局所的であり静的でないプログラム変数に対応するシンボルを含みません。これらは実行時にスタック上で管理されるため、リンカは関心を持ちません。

```shell
❯ clang --target=aarch64-unknown-linux-gnu -c strlen.c
❯ readelf -s strlen.o

Symbol table '.symtab' contains 7 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS strlen.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    2 .text
     3: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT    2 $x.0
     4: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT    3 $d.1
     5: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT    5 $d.2
     6: 0000000000000000    60 FUNC    GLOBAL DEFAULT    2 ft_strlen
```

## nmコマンドでシンボルを見る

nmコマンドを使います。

```shell
❯ nm strlen.o  
0000000000000000 T ft_strlen
```

Macに最初からインストールされているnmコマンドでは`--format=darwin`オプションのエイリアスであるmが使えます。
strlen.oの中身だと違いがわからないので、別のファイルのシンボルを参照しています。

```shell
❯ /usr/bin/nm -nm a.out   
                 (undefined) external _printf (from libSystem)
                 (undefined) external dyld_stub_binder (from libSystem)
0000000100000000 (__TEXT,__text) [referenced dynamically] external __mh_execute_header
0000000100003f70 (__TEXT,__text) external _main
0000000100008008 (__DATA,__data) non-external __dyld_private
```

## 参考

[コンピュータ・システム](https://amzn.to/3mlYzwZ): 7章
【Kotlin】Explicit API modeで可視性修飾子を必須にする

# TL;DR
- `build.gradle.kts`に`kotlin { explicitApi() }`と書くことで、可視性を指定していないコードがコンパイルエラーになる
  - 警告に留めるオプションも存在する
- `Kotlin 1.4`から利用可能

# Kotlinのデフォルト可視性の不都合な点
`Kotlin`ではデフォルトの可視性が`public`となっています。
例えば、以下のように定義した`Foo`は、モジュールを問わずどこからでも参照することができます。

```kotlin
class Foo {}
```

一方、ライブラリやマルチモジュールプロジェクトで`API`を不用意に公開してしまうと、想定外の使われ方をされてしまったり、後から隠すための作業が必要になるなどの不都合が生じます。
また、このような可視性修飾子の有無を一々レビューでチェックしていくことは非現実的です。

`Kotlin`では、そのような状況に対応するため、`Explicit API mode`が用意されています。

# Explicit API modeを利用する
`Explicit API mode`は`Kotlin 1.4`から追加されたコンパイルオプションです。
これを指定することで、コンパイラで以下2つのチェックが行われるようになります。

- 可視性修飾子が設定されているか
- 可視性修飾子が`public`な関数で、戻り値の型が明示されているか

`Explicit API mode`は、ビルドスクリプトもしくはコンパイラ引数として設定が可能です。

```kotlin:build.gradle.ktsで指定した場合（ドキュメントから引用）
kotlin {
    // for strict mode
    explicitApi()
    // or
    explicitApi = ExplicitApiMode.Strict

    // for warning mode
    explicitApiWarning()
    // or
    explicitApi = ExplicitApiMode.Warning
}
```

```bash:コンパイラオプションとして指定した場合（ドキュメントから引用）
-Xexplicit-api={strict|warning}
```

詳細は以下のドキュメントをご覧下さい。

https://kotlinlang.org/docs/whatsnew14.html#explicit-api-mode-for-library-authors

## 使ってみる
`explicitApi = ExplicitApiMode.Strict`と指定した上で、少し使ってみた例を示します。

### クラスの場合
まず、冒頭で紹介した可視性の指定されていないクラスをコンパイルしてみます。

```kotlin:可視性の指定されていないクラス
class Foo {}
```

すると、以下のようなエラーが発生します。

```:発生したエラー
Foo.kt: (3, 1): Visibility must be specified in explicit API mode
```

`Intellij IDEA`では、`IDE`上でも以下のようなエラーを確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280230/88b0aa60-ffec-cf53-243e-f7455511c0cf.png)

### 関数の場合
関数の場合も試してみます。

```kotlin:可視性・戻り値の型が指定されていない関数
fun foo() = "aaa"
```

この場合、以下のような2つのエラーが発生します。

```:発生したエラー
Foo.kt: (3, 1): Visibility must be specified in explicit API mode
Foo.kt: (3, 5): Return type must be specified in explicit API mode
```

可視性・戻り値の型ともにエラーになっていることが分かります。
また、`IDEA`上での表示も同様に機能していました。
ハニーポット とは

## 勉強前イメージ

聞いたことないかも・・・
なんのこと？

## 調査

### ハニーポット とは

蜂蜜の入った壺という意味で、
セキュリティの分野で攻撃者が何を狙ってるのかなどを確認するために
設計されたシステムのことを指します。
ハニーポットは通常主要な本番環境から切り離されており、
データやシステムに対して危険がないように罠を仕掛けておびき寄せます。

### ハニーポットの種類

ハニーポットにはいくつか種類があって、以下3点とされています。

- 低対話型ハニーポット

実際のアプリケーションは使用せずに、エミュレートしたシステムを用意し
そのシステムで監視を行います。
そのシステムの行動範囲が制限されるためリスクが減らせますが、
リアルな攻撃ではないため、得られる情報は少ない可能性があります。

- 高対話型ハニーポット

OSやアプリケーションは実際のものを使用して脆弱性はそのままにし、
攻撃を待つタイプのものです。
実際のアプリケーションを使用するのでリアルな攻撃対象であることがメリットですが
攻撃された際に他の箇所に影響を及ぼさないようにしないといけないので注意が必要です。

- 仮想型ハニーポット

vmwareなどの火葬場で構成されるハニーポットで、
侵入前の状態に戻したり侵入直後に戻したりできます。

### ハニーポットの特徴

- 脅威が見える

システムへの攻撃が可視化できます。
攻撃が見える状態にすることで資料となります。

- リスク管理ができる

社内のサーバの改ざん・不正行為に関しても未然に防ぐことが可能です。

- 構成が複雑

基本的には導入しているアプリケーションに対して導入されるので、
他の侵入や不正な行為の監視、またデータを記録する必要もあります。
いろいろなデータを取得する必要があるので、設計が複雑なものになりがちです。

## 勉強後イメージ

わざと攻撃させてログを取得するみたいな感じか....
そもそもそんなのあるって知らなかった。

## 参考

- [ハニーポットとは？仕組みやメリット、課題について徹底解説](https://cybersecurity-jp.com/security-measures/29299)
- [ハニーポット 【honeypot】](https://e-words.jp/w/%E3%83%8F%E3%83%8B%E3%83%BC%E3%83%9D%E3%83%83%E3%83%88.html)
- [ハニーポット](https://eset-info.canon-its.jp/malware_info/term/detail/00085.html)
Chartsというライブラリーを使ってみた!

# 正月休みに、Swiftでグラフアプリを作ってみる
スクールの課題がなかなか進まなくて、正月休みが長いのを利用して書籍やYouTubeでアプリ作成をやってみてAutolayoutやライブラリーの使い方をより詳しく学習してみる。

# 作ってみたアプリ

**動画がアップロードできなかったので、代わりに画像を投稿します。**

![スクリーンショット 2022-01-02 21.37.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2303722/d1258c61-2cf8-67e7-59bb-51b669ea4f97.png)

![スクリーンショット 2022-01-02 21.45.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2303722/6c3a2c63-95e7-4b62-bd90-c9901b5393e7.png)

![スクリーンショット 2022-01-02 21.45.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2303722/69dfa342-55f6-cd7a-3782-a7d85bde67d3.png)


## 参考にした動画
- https://www.youtube.com/watch?v=J9hl7HHXNHU

## やって見た感想
Swiftはライブラリーを使えばグラフやデータベース便利な機能を簡単に導入できる。とても便利だと感じた。
バージョンアップして破壊的な変更がされていることもあるので、公式ドキュメントを翻訳しながら、確認はしてみた。
今のバージョンだと影響はないようです。

## 最後に
Swift初めて1ヶ月半ぐらい立ちました。FlutterやJavaScriptを勉強していた頃にもライブラリーを使う機会はありましたが、自分で機能を作り出すのは、大変ですがライブラリーを使えば簡単にカッコイイUIを作れたりします。
ライブラリーは便利です。使えるものはどんどん使いましょう。
JavaScriptで昔カレンダーを0から作った時は、すごく大変だった😅
Reactだとnpmのパッケージでカレンダー簡単に作れる便利なのがありました!

## Githubのソースコードがあるので載せておきます。
- https://github.com/sakurakotubaki/SwiftChartsApp

Storybordの設定は最初はやること多くて大変ですが、複雑ではないので、動画を見ながらやればコントローラーを紐付ける設定について学べるので、TabBarの仕組みについて学べました。
Visual Studio2019からVisual Studio2022に移行したら"NETSDK1004"が吐かれてビルドが通らなくなった話

これまで、MSBuildを使ってVSCode上でビルドできるようにしていた。
しかし、PCを新調してVisual Studio2022に移行した結果タイトルのようなエラーが出た。
# エラー内容
```terminal:terminal
 error NETSDK1004: 資産ファイル ~~\project.assets.json' が見つかりません。NuGet パッ 
ケージの復元を実行して、このファイルを生成してください。
```

# 原因
NuGetパッケージを復元する必要があった模様。

# どうすればいいのか
プロジェクトのslnファイルがあるディレクトリで

```terminal:terminal
dotnet restore
```

と実行したら解決された。

# 参考
https://docs.microsoft.com/ja-jp/dotnet/core/tools/sdk-errors/netsdk1004
『VSCode Remote Container』で『Cython』をDockerコンテナにインストール

『VSCode Remote Container』で、
『Cython』をインストールしたDockerコンテナを作成します。
『devcontainer.json』の"postCreateCommand"に、"sh setup.sh"と記載し、
コンテナ作成の際にシェルスクリプトで『Cyhon』をインストールします。
Dockerイメージは、『Ubuntu』を使用しています。
開発環境は、Windows11です。

【フォルダ構成】
project
├ devcontainer.json
├ Dockerfile
setup.sh


```setup.sh
#!/bin/bash
shopt -s expand_aliases
alias python="python3"
ln -s /usr/bin/python3.8 /usr/bin/python
cd /tmp
git clone https://github.com/cython/cython
cd cython
python setup.py build
python setup.py install
make
```

1段目:『#!/bin/bash』
シバン
2・3段目：『shopt -s expand_aliases』、『alias python="python3"』
コマンドを統一するため、
エイリアスで『python3』を『python』にしていてます。
自分の環境だと『cython』の『make』の際、
『python3』コマンドだとエラーが起こりました。
4段目：『ln -s /usr/bin/python3.8 /usr/bin/python』
自分の環境だと、pythonライブラリは、『/usr/bin/python3.8』のフォルダのみの環境です。
『cython』の『make』の際に『python』フォルダがないとエラーが起こりました。
ですので、『python3』のシンボリックで『python』を作成しました。
『python』ライブラリは、環境によって変わると思われますので、適宜変更してください。
5・6・7段目：『cd /tmp』、『git clone https://github.com/cython/cython』、『cd cython』
『cython』のgitコマンド一連。
8・9・10：『python setup.py build』、『python setup.py install』、『make』
『cython』のビルド
Splunk: _timeの値の形式は「UNIX時間」である

時々忘れがちなのでメモ。

###### 実施環境： Splunk Free 8.2.2

 Splunk のログイベントは、デフォルトで _time というフィールドを持ちます。
検索結果を見た際、この値は基本的には一般的な日時形式で表示されます。

```Splunk:Splunk
| makeresults count=1
```

![スクリーンショット 2021-11-28 20.32.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/35107a0d-e5fb-592a-244b-e314c56a3d69.png "_time")

ですが実際は内部的には _time は UNIX 時間として格納されています。
以下のように行と列を入れ替えるとよくわかります。

```Splunk:Splunk
| makeresults count=1
| transpose
```

![スクリーンショット 2021-11-28 20.35.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/689b4299-1d8c-22f9-63a3-4a8630a9c9be.png "transpose")

「 _time フィールドの値」である限り、実際の中身が UNIX 時間であっても Splunk は上記のように一般的な日時の形式で表示してくれます。
そのため、通常の検索ではこのことをあまり意識する必要はありません。
ただ、「 _time フィールドの値」でなくなる場合は話は別です。
例えば、 rename コマンドを使用してフィールド名を _time から別の名前に変更した場合、その値は元の UNIX 時間の形式で表示されてしまいます。

```Splunk:Splunk
| makeresults count=1
| rename _time AS "ログ出力日時"
```

![スクリーンショット 2021-11-28 20.41.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/41befa6b-e243-5f4d-1cf8-ae10686425eb.png "rename")

他にも、先ほどのように transpose で行と列を入れ替えたり、 _time の値を別のフィールドにコピーした際にも同様のことが起こります。
このような場合、 eval コマンドの strftime 関数を使用して、 UNIX 時間を任意の日付形式に変換する必要があります。

```Splunk:Splunk
| makeresults count=1
| eval _time = strftime(_time, "%Y/%m/%d %H:%M:%S")
| rename _time AS "ログ出力日時"
```

![スクリーンショット 2021-11-28 20.45.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/55f390e8-cc95-6e51-546b-e72b2ec36cb3.png "strftime")

結果の列名を日本語名に変換する際等意外とひっかかるので、気をつけましょう。
AndroidManifest.xml をビルド環境ごとに使い分ける(結合する)

AndroidManifest.xml は

* 主流の方 ( `src/main/AndroidManifest.xml` ) を
* 環境ごとの `AndroidManifest.xml` に結合してビルドできる

本記事では、release の buildTypes のみ下部設定値を追加する(結合する)例を記述する。

```
    <application>
        <meta-data
            android:name="serial_code"
            android:value="serial_code_1234" />
    </application>
```

手元の環境

* Android Studio 2020.3.1
* gradle 7.0.3
* JDK 1.8
* Windows 11(21H2)
* Android SDK
    * compile, target, min 共に 28

## (1) 環境ごとに AndroidManifest.xml を定義する

`{プロジェクト名}/app/src` 配下を次のように構成する。

```
{プロジェクト名}/app/src
├─main
│  └ AndroidManifest.xml
.
.
├─release
   └ AndroidManifest.xml << 新規で作るか、main からコピーしてくる
```

目的のディレクトリ ( release ) 直下に、`AndroidManifest.xml` を作成する。

面倒な場合は `app/src/main` 直下にあるものをコピーしてくる。

配置が終わったら、buildVariants 切替やプロジェクトを同期をする。

( [Project] タブ > app を右クリック > `Reload from Disk` )

`AndroidManifest.xml` が `manifests` ディレクトリ直下に2つ見えれば取り込み成功。

![01_sync.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31223/6249a8be-e7ff-830a-c129-e9fff65fa684.png)

## 環境ごとに追加設定を記述する

release のみ設定追加したいため、 `app/src/release/AndroidManifest.xml` を以下のように記述する。

```app/src/release/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android">
    <application>
        <meta-data
            android:name="serial_code"
            android:value="serial_code_1234" />
    </application>
</manifest>
```

プロジェクトタブから `AndroidManifext.xml` をクリック後、`MergedManifest` タブが出来ているのでクリックする。

結合後の成果物を確認できる。

![02_before_merge_am.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31223/a1863d6f-ca46-43f1-c48f-cf31005a47f6.png)

## 捕捉

`buildTypes` 前提で話を進めたが、同じ要領でやれば `productFalvors` でも対応可能。

追加だけでなく「主流の方の特定属性だけ削除する」など柔軟な対応ができる。

詳細なやり方は参考の (1) を確認お願いしたい。

## 参考

* (1) https://developer.android.com/studio/build/manifest-merge
* (2) https://stackoverflow.com/questions/25496597/is-it-possible-to-add-an-androidmanifest-to-a-specific-buildtype-with-gradle-no
* (3) https://developer.android.com/guide/topics/manifest/manifest-intro?hl=ja
iPhoneでお気に入りのニュースをさくっと表示できるように改良してみた

## 背景

ニュースをろくに読まないという悪癖がありまして、今年はこれをすこしでも前進させよう😤と、施策第１弾「[macOSのメニューバーにお気に入りのニュースを表示してみた](https://qiita.com/hann-solo/items/46d2bd25667618c36a5d)」にひききつづき、施策第２弾。iPhoneでの、ショートカットアプリからのニュース表示を改良してみました。

### 環境

本記事で書いていることは、下記のバージョンで実施しました。

- iOS 15.1
- macOS Monterey 12.1
- MacBook Pro (13-inch, 2020, Four Thunderbolt 3 Ports)

## 動作の新旧比較

### これまでのニュース表示がどうだったかというと

iOSの`ショートカット.app`のギャラリーにあった「トップニュースをブラウズ」をカスタマイズしてつかっていました。

ショートカットを起動すると、ニュースソースの選択画面が出て、
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/cb1f049f-35c7-8bf5-6acf-f09e0522238d.jpeg" width=50%>

そのうちひとつを選ぶと記事のリストが出ます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/3f13f09c-d536-8d8a-1ed9-93015a339c5e.jpeg" width=50%>

記事のリストから選択して（複数選択可）、完了を押すとSafariで開きます。

### あたらしいニュース表示がどうなるかというと

ショートカットを起動すると、ニュース記事の一覧が表示されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/7d0bce8f-e922-3cae-5f6d-a4d70b032afb.jpeg" width=50%>

記事のリストから選択して（複数選択可）、完了を押すとSafariで開くのは、同じです。

### プロコン（Good-Bad）

いまのところ感じている良い点悪い点はこんなかんじですが、こればかりはしばらくつかってみないとわからないかもです。

- 旧版：配信元選択→記事表示
    - Good: 読みたい記事の方向性を選べる
    - Bad: 配信元を選択してからが遅い
- 新版：いきなり記事表示
    - Good: 記事のリストを目にするまでが速い
    - Bad: 古い記事が読みにくい（だいたい半日でリストから消える）

## ソースコードの新旧比較

新バージョンのほうがスッキリしました。

### 旧バージョン

![220102_before.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/22bda17e-395f-f522-614b-e3721a3c56c7.png)

### 新バージョン

![220102_after.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/cbdfbebd-0f68-2b7e-3814-d7ed24ed73d8.png)

## おわりに

### Montereyのショートカットアプリ

macOS Montereyの、個人的な目玉は「ショートカットアプリがつかえること」！

iPhone/iPadでつかうショートカットも、macOSで書けるのでめっちゃラク。

Montereyのショートカットアプリの挙動が怪しすぎて困ることも多々あるものの、ツールを書きやすい（改良しやすい）のはたいへんありがたいです。

### ニュースを見るにあたっての壁

- 記事へのアクセスまでが遠い
- キュレーションサービスの偏りかたと、自分が求めている偏りかたが違う
- ヘッドラインだけはもうすこし多めに見たい

あたりが壁だとおもっていまして、たぶん

- 信頼できる配信元に限る（どれが良いかの試行錯誤はつづく）
- ヘッドラインだけは多めにさくっと見えるところにおく
- 読みたい記事にはジャンプできるようにしておく

ことができれば、もうちょっと見るようになるのではないかと仮説をたてて、自分自身の行動を観察中です。
Cell Language for Excel VBA

Excelをコンパイラにして動的HTMLページを作成するアイデアを思いついたので
つくってみた。
確定申告書の動的ページを参考に役所の申請書で作成してみた。
役所の申請書などは膨大で一ヶ所でも間違や訂正があると全ページに波及する危険が
あって修正が大変だけど、Excelで管理するといつもの手順で修正出来るなぁ。

Mac M1  

Feature
HTML Generator は、Excelシート上にHTML(Webページ)の属性を記述し
Visual Basic for Applications で HTMLファイルを生成するツール。
従来、HTMLはCSS機能を使うと複数ページで色、使用フォント、幅など単純な表示属性を同時に変更すことができたが、HTML Generator は大規模Webサイトの仕様変更による動的再構成を瞬時で行うことを目標にしておりセルを使ってコートレスでJava Script コードをHTMLページへ動的に埋め込むミニコンパイル機能(Cell Language)があり仕様変更が頻繁に起こる複雑で大規模なWebサイトをExcelで開発および管理を行うことができる。								

![スクリーンショット 2022-01-02 18.56.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2460250/a6b5d5ec-8eef-e637-6108-c2aae1a15572.png)

![スクリーンショット 2022-01-02 19.04.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2460250/1a0177a5-e359-1b8d-e80c-688be0a4c5e0.png)

![スクリーンショット 2022-01-02 19.05.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2460250/2ea87fd3-7f7d-a698-b99c-bf74a3a53df1.png)

![スクリーンショット 2022-01-02 19.19.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2460250/a14c7f3a-2b73-fd09-d26e-73b391e57a05.png)
Photoshopのツールバーが画面外に消えてしまったときの対処法

Photoshopのツールバーが消えてしまったときの対処法として、以下の2つがよく挙げられている。

- Tabキーを押す
- ウィンドウ > ツールを選択

この2つの対処法やphotoshopの再起動等をしてもツールバーが出てこないときは、ツールバーが画面外に出てしまった可能性が考えられる。その場合、以下の3つ目の対処法が有効だった。

- ウィンドウ > ワークスペース > 初期設定をリセットを選択

参考文献

https://0begin.net/photoshop/photoshop-trouble/ps-toolbar-workspace-error/#%E5%91%A8%E3%82%8A%E3%81%AE%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%B9%E3%83%9A%E3%83%BC%E3%82%B9%E3%81%8C%E3%81%99%E3%81%B9%E3%81%A6%E6%B6%88%E3%81%88%E3%81%9F%E5%A0%B4%E5%90%88
GCC　__attribute__((パラメータ))とはなにか

# `__attribute__((パラメータ))`とはなにか？

ソースコードリーディングをしていると、`__attribute__((◯◯))`によく出くわします。気になったので調べてみました。

## 機能

GNU CおよびC++では、関数属性を使用して、コンパイラが呼び出しを最適化したり、コードが正しいかどうかをより注意深くチェックしたりするのに役立つ特定の関数プロパティを指定できます。
たとえば、属性を使用して、関数が決して返さない`noreturn`、引数の値のみに依存する値を返す`const`、またはprintfスタイルの引数を持つ`format`等を指定できます。

属性を使用して、注釈が付けられている関数内のメモリ配置、コード生成オプション、または呼び出し/戻り規則を制御することもできます。

GCCは、変数宣言、ラベル、列挙子、ステートメント、および型の属性もサポートします。

## Syntax

関数属性は、関数の宣言で`__attribute__`キーワードによって導入され、その後に二重括弧で囲まれた属性指定が続きます。
宣言で複数の属性を指定するには、二重括弧内でコンマで区切るか、1つの属性指定の直後に別の属性を指定します。

```cpp
__attribute__ ((パラメータ))
```

## 具体例

`__attribute__((destructor))`で関数に`destructor`属性を付与することができます。

[C言語　`__attribute__((destructor))`を使用したメモリリークチェック - Qiita](https://qiita.com/keitean/items/6cf92f0f32f1cfefd623)

## 参考

[__attribute__ ‐ 通信用語の基礎知識](https://www.wdic.org/w/TECH/__attribute__#x86x20Functionx20Attributes)
[Function Attributes (Using the GNU Compiler Collection (GCC))](https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html)
【エラー解決】errno: 150 "Foreign key constraint is incorrectly formed"

#errno: 150 "Foreign key constraint is incorrectly formed"について

php artisan migrate
上記コマンドを実施すると出現したので、解決した方法を記載していきます。

UsersテーブルとArticlesテーブルは1対多の関係


```php:2021_〇〇_create_users_table.php
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name')->unique();
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password')->nullable();
            $table->rememberToken();
            $table->timestamps();
        });
    }
```



```php:2021_〇〇_create_articles_table.php
    public function up()
    {
        Schema::create('articles', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('title');
            $table->text('body');
            $table->bigInteger('user_id');
            $table->foreign('user_id')->references('id')->on('users');
            $table->timestamps();
        });
    }
```



上記コードでphp artisan migrateを実施すると
General error: 1005 Can't create table `n_sns`.`articles` (errno: 150 
"Foreign key constraint is incorrectly formed") (SQL: alter table `articles` add constraint `articles_user_id_foreign` foreign key (`user_id`) references `users` (`id`))
このようなエラーが出現。








2021_〇〇_articles_table.php側にコードを修正した事でエラー解消。

```php:2021_〇〇_create_articles_table.php
    public function up()
    {
        Schema::create('articles', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('title');
            $table->text('body');
            $table->unsignedBigInteger('user_id');
            $table->foreign('user_id')->references('id')->on('users');
            $table->timestamps();
        });
    }
```

            $table->bigInteger('user_id');

ここのコードを

            $table->unsignedBigInteger('user_id');
こう書き換えました。


idカラムのデータ型は unsignedBigIntegerを選択するという事が分かりました。
符号なしBIGINTカラムと呼ばれており、マイナス部分がないBIGINTという意味だそうです。
今日の日付を取得する　Carbon

こんにちは。ソウタです。

特定のデータの取得の仕方についてメモも兼ねて、アウトプットしていきたいと思います。

Laravelで料理注文アプリを作っていたので、アプリのコードを元に説明していきたいと思います！

まず、ユーザーが料理を注文し、注文を受けたレストランが「今日の注文履歴」をみたいので、それをフロントに表示させたい過程にいると仮定します。（ユーザーが注文する所は省略）

```php.RestaurantController.php
use Carbon\Carbon;
```

Carbonを使うので、use宣言をコントローラに書く。

```RestaurantController.php
public function RestaurantAccount()
    {
        $restaurantId = Auth::user()->id;

        // クエリ（SQL）を変数へ一旦入れておくとコードがスッキリする。
        $query = Restaurant::find($restaurantId)->orders();
        // ログインしているレストランに紐づく注文を全件取得
        $orders = $query->get();
　　　　　　　　　　　　　　　　// デバックで注文がちゃんと取得できているか確認。
        // dd($orders);
        // レストランに紐づく注文のうち、今日の注文のみ取得
        $today_orders = $query->where('created_at', Carbon::today())->get();
　　　　　　　　　　　　　　　　　// デバックで注文がちゃんと取得できているか確認。
        // dd($today_orders);
        return view('restaurant.restaurant_account', ['orders' => $orders, 'today_orders' => $today_orders]);
    }
```

コードは書いてみたのの、データがとれていない。あらら。

色々とググり。判明。
以下のサイトを参考にしてみました。
https://biz.addisteria.com/laravel_carbon/

まず、日本時間でデータを取得しないといけないので、、、、timezoneをconfig.app.phpで変更。
デフォルトでUSで設定されている。

```config/app.php
　// これを消す
'timezone' => 'US',
// 追加
'timezone' => 'Asia/Tokyo',
```
どうやら、whereではなく、whereDateにしないといけないらしい。

```RestaurantController.php
 $today_orders = $query->whereDate('created_at', Carbon::today())->get();
```

修正し、デバック。

```
 "created_at" => "2022-01-02 20:17:29"
 "updated_at" => "2022-01-02 20:17:29"
```

具体的な注文情報は、割愛しますが、しっかり取得できていました。よかった。。。。

新年も頑張っていきたいと思います。
よかったと思ったら、LGTMボタンを押してください！！やる気が出るんです！！笑
RecyclerViewを反転させる方法

# はじめに
チャットなどで、最下部を最新にしたいケースがあると思います。
その際の設定を備忘録的に残しておきます。

# 反転方法

反転させること自体は簡単です。
以下を対象に設定するだけで反転します。

```xml
app:reverseLayout="true"
```

# 注意点
反転させることで、0番目が最下部になります。
その為、追加読み込み時や特定のポジションに移動させる際には少々工夫が必要になります。

# さいごに
反転させる設定自体は簡単でも、取り巻く環境によっては工夫が必要になります。
この辺りの設定は慎重に行いたいところですね。
時間ができたらPagingあたりの実装も記事にしていこうと思います。
mac OS アップデート後に C++ のコンパイルができなくなった時の対処法チェックリスト

Mac の OS アップデートをしたら gcc でコンパイルが通らなくなることがよくありその度に試行錯誤してるので、備忘録として書いておく。

# チェックリスト
- コマンドラインツールは最新か 

コマンドラインツールが消えてる場合は `$ xcode-select --install` でダウンロードする。

- Homebrew の gcc が呼ばれるようになってるか

`$ which g++` で `/usr/local/bin/g++` となるか。`$ ls -l /usr/local/bin | grep g++` でシンボリックリンクを確認。
Arduinoの勉強　第10弾：LED (2) - 明るさ調整

# #LEDの明るさ調整
##はじめに
ハードウェアの勉強のためにArduinoを復習も兼ねて参考教材に沿って，勉強する．細かな部分の理解までして，自在に扱えるようになることが目的である．その第1弾として，「LEDの明るさ調整」を扱う．

## Arduinoでの擬似アナログ出力
![slide1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/563466c6-1e3c-8e7f-7289-ef21f5b70d88.png)
![slide2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/bc998d91-6283-b328-cc79-7b715a16451c.png)

## 回路の模式図
<img width="700" alt="LED_off_ブレッドボード.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/b9fdd61c-4c62-d18c-b229-7ed192f02725.png">

- LED（赤）
- 半固定抵抗（1kΩ）
- 抵抗（220Ω）


## 感想
今回，PWMの利用例として，LEDの明るさ調整を少し詳細に学んだ．非常に単純な話しかまとめられていないが，導入としてはよいのではないかと思う．

ちなみに回路の模式図はfritzing（現在有料）を用いて作成した．見た目は非常に分かりやすい図が描けてよい．今回初めて使ったため，まだまだ勉強して使い慣れていく必要がある．自在に使いこなせるようになれば，回路設計もできるようになる（そのまま印刷願いができるようなフォーマットへの出力も可能らしい）．

次回はトランジスタについてまとめる．

## 参考文献
- 電子部品ごとの制御を学べる！Arduino電子工作実践講座 改訂第2版 福田和宏 著 ソーテック社
Pythonによる気象庁APIからの降水確率の監視と通知

気象庁の半分公式のようなAPIを使って、気象データを監視し、降水確率が50%以上のときには通知をするというサンプルコードです。
通知の部分はLINEAPIなどの通知を使ってください。



```
import json
import requests
import time

def weatherMan():
    # 気象庁データの取得
    jma_url = 'https://www.jma.go.jp/bosai/forecast/data/forecast/170000.json'
    data = requests.get(jma_url).json()
    
    # 時間帯の取得
    pop_0_time = data[0]["timeSeries"][1]["timeDefines"][0]
    pop_1_time = data[0]["timeSeries"][1]["timeDefines"][1]
    pop_2_time = data[0]["timeSeries"][1]["timeDefines"][2]
    pop_3_time = data[0]["timeSeries"][1]["timeDefines"][3]
    pop_4_time = data[0]["timeSeries"][1]["timeDefines"][4]

    # 地域の取得
    pop_0_name = data[0]["timeSeries"][1]["areas"][0]["area"]["name"]
    pop_1_name = data[0]["timeSeries"][1]["areas"][0]["area"]["name"]
    pop_2_name = data[0]["timeSeries"][1]["areas"][0]["area"]["name"]
    pop_3_name = data[0]["timeSeries"][1]["areas"][0]["area"]["name"]
    pop_4_name = data[0]["timeSeries"][1]["areas"][0]["area"]["name"]

    # 降水確率の取得
    pop_0 = data[0]["timeSeries"][1]["areas"][0]["pops"][0]
    pop_1 = data[0]["timeSeries"][1]["areas"][0]["pops"][1]
    pop_2 = data[0]["timeSeries"][1]["areas"][0]["pops"][2]
    pop_3 = data[0]["timeSeries"][1]["areas"][0]["pops"][3]
    pop_4 = data[0]["timeSeries"][1]["areas"][0]["pops"][4]

    # 表示
    print(pop_0_name + "：" + str(pop_0_time) + "：" + str(pop_0))
    print(pop_1_name + "：" + str(pop_1_time) + "：" + str(pop_1))
    print(pop_2_name + "：" + str(pop_2_time) + "：" + str(pop_2))
    print(pop_3_name + "：" + str(pop_3_time) + "：" + str(pop_3))
    print(pop_4_name + "：" + str(pop_4_time) + "：" + str(pop_4))
    
    if (int(pop_0) >= 50):
        print("今雨が降っているようです" + "　降水確率:" + str(pop_0))
    if (int(pop_1) >= 50):
        print("数時間後に雨が降るようです！" + "　降水確率:" + str(pop_1))
        sendNotify()
    time.sleep(5)
    weatherMan()
    
def sendNotify():
    print("雨が降る確率が高いです")

weatherMan()
```
Python#3_演算子

#python入門その3

###演算子
pythonにも算術演算子、比較演算子、連結演算子、論理演算子、ビット演算子など多くの演算子があります。
基本的にc#と同じですが、所々違うものもあるのでそれをみていきましょう。

***算術演算子***

|0|演算子|例|説明|
|:---:|:---:|:---:|:--:|
|1|+|a+b|足し算をする|
|2|-|a-b|引き算をする|
|3|*|a*b|掛け算をする|
|4|/|a/b|割り算をする|
|5|//|a//b|aをbで割った商の整数値|
|6|%|a%b|aをbで割った時のあまり|
|7|**|a**b|aをn回かけた数(ベキ乗と言います)|

これらを***算術演算子、数値演算子***などと呼びます。
基本的には使ったことがある演算子がほどんどだと思いますが、５行目と７行目はあまり馴染みがないと思います。実際に使ってみましょう。

>ex3-1
・1024を3で割った時の整数値(あまりを無視した答え)は幾つでしょうか
・12の３乗は幾つでしょうか

***比較演算子***

|0|演算子|例|説明|
|:---:|:---:|:---:|:--:|
|1|==|a==b|aとbが等しい|
|2|!=|a!=b|aとbが等しくない|
|3|>|a>b|aはbより大きい|
|4|<|a<b|aはbより小さい|
|5|>=|a>=b|aはb以上|
|6|<=|a<=b|aはb以下|
|7|is|a is b|aとbのオブジェクトが同一|
|8|is not|a is not b|aとbのオブジェクトが同一ではない|

比較も大きくはc#と変わりません。
ただ7,8行目は見慣れないかなと思います。
下が``is``,``is not``を使った例です。

```php
list1 = [1,2,3,4]
list2 = [2,3,4,5]

if list1 is list2:
    print "true"
elif list1 is not list2:
    print "false"
```

出力するとfalseと表示されます。リストなどをpythonでは***オブジェクト***と呼びますが、その場合にこの``is``,``is not``は使用されます。

>ex3-2
・変数aとbに数字を代入し、aがbより大きければ「big」、小さければ「small」、同じなら「equal」と表示させてみましょう。
・永久ループを書き、その中で変数に入力を続けるプログラムを書きます。変数が５で割り切れたらループが終わるプログラムを書いてください。
・変数aとbに数字を代入し、a×bが偶数ならOdd,奇数ならEvenと表示させてみましょう。


***論理演算子***

|0|演算子|例|説明|
|:---:|:---:|:---:|:--:|
|1|not|not b|否定。bではない時。|
|2|and|a and b|論理積。aとb|
|3|or|a or b|論理和。aあるいはb|

c#では``a&&b``(論理積)や``a||b``(論理和)と書いていました。
pythonでは英語でそのまま``and``,``or``と書きます。

ここでは`not`が見慣れていないかと思います。
`not`は`not 式`という形式で使用します。次のプログラムは、入力されたnが10でなければ「yes」と表示するプログラムです。

```php
n = input()

if not n == 10:
    print "yes"
```

頭がこんがらがるかもしれませんが、要するに後ろに書いた式を***満たさない***という意味です。
勘の良い人なら次のプログラムと同じ意味だと分かると思います。

```php
n = input()

if n != 10:
    print "yes"
```

>ex3-3
・変数aに数字を代入し、50以上100以下であれば「True」と表示するプログラムを書いてください。
・変数aに数字を代入し、その数字が2で割り切れる数字だった時、あるいは5で割り切れる数字であった時、「true」と出力するプログラムを書いてください。
・100までのすべての素数を出力するプログラムを書いてください。(素数とは、その数自身と１でしか割れない数です。)(ヒント：1と、2,3,5,7の倍数をすべて除いた数が素数です。if文をたくさん使います。for文で1~100を数えてあげるようにします。)
・ある数字を入力し、その年が夏季オリンピックの年か、冬季オリンピックの年か、あるいは何もない年か出力してください。ただし、東京オリンピックは2020年にします。(ヒント、夏季オリンピックは4の倍数年です)
Natural Language APIを触ってみる【GCP】

# やりたいこと
GCPのNaturalLanguageAPIをローカルから実行して触ってみる。

# 実行環境
- macOS Catalina 10.15.5
- Python 3.7.4 

# 環境構築

### APIを有効にする
「Natural Language API」で検索すると、MARKETPLACEの欄に「Cloud Natural Language API」が出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320845/62455234-32a5-a064-ef6b-2dc015c165fe.png)

「有効にする」を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320845/34744bb4-63ac-3929-1dcc-4e336e5a3383.png)

### サービスアカウントの設定
NaturalLanguageAPI用のサービスアカウントを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320845/2d3a6dee-73a8-3b8f-13f8-9a8fb5b63fb2.png)


「IAMと管理」→「サービスアカウント」→「サービスアカウント作成」から、以下のようなサービスアカウントを作成します。


| 項目 | 内容 |
| --- | --- |
| サービスアカウント名 | natural-language-api-test |
|サービスアカウントの説明 | NaturalLanguageAPIテスト用 |
| このサービスアカウントにプロジェクトのアクセスを許可する| 設定しない |
| ユーザーにこのサービスアカウントへのアクセスを許可 | 設定しない |

作成したサービスアカウントの編集画面から「キー」→「鍵を追加」→「新しい鍵を作成」を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320845/9a03976f-7efc-413f-ab32-7a18ac808c2a.png)
形式をJSONにして鍵を作成し、ローカルにダウンロードします。


### ローカルの設定

先程ダウンロードしたJSONファイルのパスを通します。

```bash
# Macの場合
export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/hoge.json"
```


クライアントライブラリをインストールします。

```bash
pip install --upgrade google-cloud-language
```

# 感情分析
Natural Language APIでできる分析のうち、今回は感情分析を行ってみます。
以下のようなPythonスクリプトを作成し、実行します。

```py:sample.py
from google.cloud import language_v1
client = language_v1.LanguageServiceClient()

document = {"content": "今日はいい天気だ。だが、寒くて震えそうだ。", "type_": "PLAIN_TEXT"}
response = client.analyze_sentiment(request = {"document": document})
print(response)
```

こちらの結果は以下のようになりました。

```json
document_sentiment {
  magnitude: 1.100000023841858
  score: 0.10000000149011612
}
language: "ja"
sentences {
  text {
    content: "\344\273\212\346\227\245\343\201\257\343\201\204\343\201\204\345\244\251\346\260\227\343\201\240\343\200\202"
    begin_offset: -1
  }
  sentiment {
    magnitude: 0.699999988079071
    score: 0.699999988079071
  }
}
sentences {
  text {
    content: "\343\201\240\343\201\214\343\200\201\345\257\222\343\201\217\343\201\246\351\234\207\343\201\210\343\201\235\343\201\206\343\201\240\343\200\202"
    begin_offset: -1
  }
  sentiment {
    magnitude: 0.4000000059604645
    score: -0.4000000059604645
  }
}
```

- document_sentiment
    - magnitude: 1.1
    - score: 0.1
- language: "ja"
- sentences
    - text
        - content: 省略
        - bigin_offset: -1
    - sentiment
        - magnitude: 0.7
        - score: 0.7
- sentences
    - text
        - content: 省略
        - bigin_offset: -1
    - sentiment
        - magnitude: 0.4
        - score: -0.4

「document_sentiment」は、すべての文章を通しての感情分析で、２つの「sentences」は、それぞれ「。」で区切られた２つの文章の感情分析となっています。
「magnitude」は感情の強さ、「score」は感情のポジティブ・ネガティブ（ポジティブが正）を表しています。


# 参考にした記事
- [公式ドキュメント　クイックスタート：NaturalLanguageAPIの設定](https://cloud.google.com/natural-language/docs/setup?hl=ja)
- [Cloud Natural Language API で日本語感情解析](https://qiita.com/ma7ma7pipipi/items/7999cd1a36bc5a400385)
- [GCPの「Natural Language API」を試してみた](https://dev.classmethod.jp/articles/yoshim_gcp_natural-language-api/)
クリックアクティビティについてメモ

#はじめに

クリックアクティビティの

* ウィンドウメッセージを送信
* クリックをシュミレート　

というプロパティがそれぞれあるんですが、これってどっちがどっちだっけ？と頻繁にこんがらがるので、
これを機にメモとして残そうと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/98a8227c-679e-07b3-5020-cd21313666b7.png)
実際のプロパティの画像。
シュミレートがうまく動かなかった場合はウィンドウメッセージを送信に切り替えて…という風に使用しているが、その違いについて説明を求められたとき多分しどろもどろになる。


#参考文献

https://docs.uipath.com/studio/lang-ja/docs/input-methods

やっぱり公式ドキュメントが最強ですよね。
今回の記事はこちらからの引用がほとんどです。

#そもそも使い方はあっているのか？
シュミレート→ウィンドウメッセージを送信→デフォルトの順番で使用していますが、その順番で問題ないのでしょうか？
公式ドキュメントによると…

>通常は、3 つのうち最も処理が速くバックグラウンドで動作する [入力をシミュレート/クリックをシミュレート] メソッドをお勧めします。ただし、これが使用できるのは、特殊なキーボード ショートカットを送信する必要がない場合に限られます。このメソッドで対応できない場合は、[ウィンドウ メッセージを送信] メソッド、さらに最も処理の遅いデフォルト メソッドをお試しください。

おお、よかった！
やはりシュミレート→ウィンドウメッセージを送信→デフォルトの順番で問題ないようです。
では、いよいよそれぞれの違いについても調べてみます。

#それぞれの違い

違いについては公式ドキュメントにものすごいわかりやすい表があったので、引用します。

>|機能メソッド|対応率  |BGでの実行  |速度  |ホットキーのサポート  |フィールドの自動消去  |
|---|---|---|---|---|---|
|デフォルト|100%|×|50%|〇|×|
|ウィンドウメッセージを送信|80%|〇|50%|〇|×|
|入力をシミュレート/クリックをシミュレート|99% - Web アプリケーション<BR>60% - デスクトップ アプリケーション|〇|100%|×|〇|

この表ペタリだけでは将来自分がまた忘れてここを見に来るときに？？？となってしまいそうなので、
追記しておきます。

|機能メソッド|説明  |
|---|---|
|デフォルト|速度は遅く、バックグラウンドで動かすことはできない。ホットキーを使用可能。必ず対応はしている。|
|ウィンドウメッセージを送信|基本はデフォルトと同じだが、バックグラウンドで実行ができる代わりに、対応率がやや下がる。|
|入力をシミュレート/クリックをシミュレート|速度は速く、バックグラウンドでも動かせるがホットキーのサポートはなし。|

#おわりに

こういった基本的なことですが、こうして記録に残すことでより自分の中に定着させられると思っています。また、記録を残しておけば何かあったときにそこを参照すればわかる…という状態に持っていけたらと思います。
Vue.jsのv-modelについて学ぼう

##はじめに
v-modelを使うことによって、
フォームの扱いがとても楽になってこのようなこともできます。
![_2022-01-02 18 09 34](https://user-images.githubusercontent.com/86521768/147871359-2395afda-3ccc-4246-9fe2-6fbe0e098681.gif)

それでは、上の例のソースコードを見ていきましょう。


```html:HTML
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <title>Document</title>
</head>

<body>
  <div id="app">
   <input type="number" v-model="number"> = {{number}}
  </div>
<script>
let app = new Vue({
    el: "#app",
    data: {
        number:0
        //0は初期値としているが数字なら0でなくても良い。
    }
})
</script>
</body>

</html>
```
##解説
それでは、どのようなことをしているのかを解説していきます。

まず、**el: "#app"**の部分で、HTML内のid名**app**にアクセスしていきます。

次に、フォームの部分の構文を見ていきましょう。

input type="number"で、数字入力用のフォームに限定している。

続いて、**data: { number:0 }**の部分は、
inputタグ内の**v-model="number" と {{number}}**に連携しています。
(厳密にいうと**input type="number"**とも関係はある。)

これらの連携によって、入力された数字の値を受け取り、表示しています。

追記：
**v-model="number"と　{{number}}**　と **data: { number:0 }**の中の、
**number**の命名は基本的に自分でつけて大丈夫です。

##次は文字を受け取ってみよう

まずは、こちらから見ていきましょう↓

![_2022-01-02 18 51 03](https://user-images.githubusercontent.com/86521768/147872291-3f3a13b4-b395-4c20-9fa4-3bace9720e67.gif)

次にソースコードを見ていきましょう。

```html:HTML
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <title>Document</title>
</head>

<body>
  <div id="app">
   <input type="string" v-model="string"> = {{string}}
  </div>
<script>
let app = new Vue({
    el: "#app",
    data: {
        string:""
    }
})
</script>
</body>

</html>
```
##解説

それでは、解説をしていきます。

基本的な動きは先ほどとなんら変わりはありません。
変わった部分は先ほどまで、**number**だったものが**string**に変わったくらいです。

あと、気をつけるポイントとしては、
**data: { number:0 }**から**data: { string:"" }**に変わった部分です。
文字列なので、**""**は忘れないようにしましょう。

##おわり

ご覧いただきありがとうございました。

また別の記事でお会いしましょう〜👋