OmniAICreator/Qiita-1.07M huggingface dataset:
【Rails】いいねした投稿一覧表示実装

# 目的
Railsでいいね機能を導入したアプリに、いいねした投稿一覧を表示する、

# 開発環境
macOS: *Big Sur*
Rubyバージョン: *2.6.5*
Railsバージョン: *6.0.0*

# 前提

- `いいね機能`が作成されている。
[【Rails】いいね機能の実装（非同期）](https://qiita.com/oak1331/items/3e5508d9405c96ae6786)

# 手順

1. [はじめに](#はじめに)
1. [ルーティングの設定](#ルーティングの設定)
1. [アクションの定義](#アクションの定義)
1. [一覧ページの作成](#一覧ページの作成)

# はじめに

今回は一覧表示させるために、
ユーザー詳細ページから、いいねした投稿一覧ページへ飛ぶようにします。

# ルーティングの設定

まずはルーティングの設定です！

```ruby:config/routes
#省略
resources :users do
  member do
    get :likes
  end
end
```

idが必要なため、`member`を使用しています。

# アクションの定義

アクションの定義です。
`usersコントローラー`に新たに設定していきます。

```ruby:
class UsersController < ApplicationController
  before_action :set_user, only: [:likes]
#省略
  def likes
    likes = Like.where(user_id: @user.id).pluck(:post_id)
    @like_posts = Post.find(likes)
  end

private
  def set_user
    @user = User.find(params[:id])
  end
end
```

いいねした投稿を探し、`@like_posts`に格納しています。

# 一覧ページの作成

ユーザー詳細ページにリンクボタンを設置し、一覧表示をさせます。

```html:app/views/users/show.html.erb
<%= link_to "いいねした投稿", likes_user_path(@user) %>
```

続いて部分テンプレートを呼びます。
`collection`を使用することで`each`の記載が不要になります。

```html:app/views/users/followers.html.erb
<p>いいねした投稿一覧</p>
<%= render partial: "posts/post", collection: @like_posts %>
```

部分テンプレートとして切り出したビューファイルです。

```html:app/views/posts/_post.html.erb
<%= link_to image_tag( post.image.variant(resize: '100x100') ), post_path(post.id) %>
<%= link_to post.user.name, user_path(post.user.id) %>
<i class="fa fa-heart unlike-btn"></i>
<%= post.likes.length %>
<%= link_to post.title, post_path(post.id) %>
```

投稿された`画像`、`ユーザー名`、`いいねアイコン`、`タイトル`を表示しています。

# 最後に

以上で、一覧表示の実装は完了です。
CSSは実装していないため、簡素な見た目となっています。
必要に応じて各自編集をお願いします。
では。
Windows Terminalを0から構築してハマった

新しいPC買って、新規にWindows TerminalとOh My Poshその他諸々を設定しているときに、Oh My Poshのメジャーアップデートにぶち当たって昔のPCから持ってきた設定ファイルが動かなかったので、メモ。

## 今までの設定

[こちら](https://docs.microsoft.com/en-us/windows/terminal/tutorials/powerline-setup
)の設定を使ってPowerlineを使えるようにして、よしなな見た目にしていた。
Windows Terminal, PowerShell Core, Git for Windowsをダウンロード後

```powershell
Install-Module oh-my-posh -Scope CurrentUser -AllowPrerelease
Install-Module posh-git -Scope CurrentUser -AllowPrerelease -Force
code $Profile #以下ファイルを修正
. $Profile #設定を反映
```

```powershell:Microsoft.PowerShell_profile.ps1
Set-Alias k kubectl.exe
Set-Alias code code-insiders.cmd
Set-Alias which gcm
Set-Alias tig  'C:\Program Files\Git\usr\bin\tig.exe'
Set-Alias grep select-string
Import-Module posh-git
Import-Module oh-my-posh
Set-Theme Agnoster

$global:DefaultUser = [System.Environment]::UserName #Promptを簡易化するために記述
```

## Oh My Poshのアップデート

V3になってめちゃくちゃ変わってる。。。
すべて変更おいきれてないですが。
https://ohmyposh.dev/docs/

### Profileを読み込むと、Set-Themeがないと怒られる

起動時に `$Profile` を読み込むと、そんなメソッドはないとおこられる。
コマンドすべて変更されている模様。

```powershell
Set-PoshPrompt -Theme Agnoster
```

のように変更になったらしい。

### プロンプトのアイコンが出ない

今までCascadia Code PLを使えばGitのブランチのアイコンが表示されていたが、アップデートによってNerd fontを使うようになったらしい。

https://ohmyposh.dev/docs/fonts

ここにあるように、MesloLGM NFをおすすめされてるが、個人的にしっくりこなかったので、Cascadia CodeのNF対応版Caskaydia Codeをダウンロードしてインストール後、Windows Terminalのフォントの設定とVS Codeの `Terminal > Integrated: Font Family` を変更

https://www.nerdfonts.com/font-downloads

### プロンプトのカスタマイズができない

ユーザ名とホスト名はリモートで作業してない限り、いらないので消してたんですが、これが今まで通りだとうまく行かない。Agnosterとか1行でコマンド入力とプロンプトの両方を表示したいので、なんとかする方法を調べてみたら[Stackoverflowにあった](https://stackoverflow.com/questions/60544366/how-to-remove-the-usernamehost-from-powershell-prompt)。

Exportコマンドをうつと、絵文字類が文字化けするので、Githubからテーマのファイルをダウンロードして、.oh-my-posh.jsonとかで保存。Agnosterの場合[こちら](https://github.com/JanDeDobbeleer/oh-my-posh/blob/main/themes/agnoster.omp.json)

```diff_powershell:Microsoft.PowerShell_profile.ps1
- Set-Theme Agnoster
+ Set-PoshPrompt -Theme ~/Documents/PowerShell/.oh-my-posh.omp.json
- $global:DefaultUser = [System.Environment]::UserName
+ $env:POSH_SESSION_DEFAULT_USER = [System.Environment]::UserName
```

```diff_json:.oh-my-posh.omp.json
...
        {
          "type": "session",
          "style": "powerline",
          "powerline_symbol": "\uE0B0",
          "foreground": "#100e23",
          "background": "#ffffff",
+          "properties": {
+            "display_default": false
          }
        },
```

### Posh Gitがデフォルトで有効にならない

Git Repositoryを開いて気づいた。

https://ohmyposh.dev/docs/poshgit

```diff_json:.oh-my-posh.omp.json
+        {
+          "type": "poshgit",
+          "style": "powerline",
+          "powerline_symbol": "\uE0B0",
+          "foreground": "#ffffff",
+          "background": "#0077c2"
+        }
```

```diff_powershell:Microsoft.PowerShell_profile.ps1
+ $env:POSH_GIT_ENABLED = $true
```

色々修正してプロファイル読み込みし直し

```powershell
. $Profile
```

上記4つで一旦マトモに使えるようになりました。
というメモでした。
【初心者向け】details・summaryタグについてくる黒矢印を消す方法

#どうも7noteです。使ってみたはいいものの、summaryタグについてくる黒い矢印の消し方が分からない人へ

details・summaryタグを使用した時に「▶」←こんな矢印が表示されて消えない場合の非表示にする方法です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/a72f9282-f552-ff07-a1b8-89c7c1c5a2d4.png">
↑この黒矢印を消します。

```style.css
summary {
  display: block;
  list-style: none;
}

/* 一部ブラウザで消えなかった場合は以下も追記 */
summary::-webkit-details-marker {
  display:none;
}
```


検証ツール(F12)でみてみると分かりますが、「::marker」とかかれたものがあります。こいつが原因です。
これはlist-style-typeの一種なので、よく使われる`<li>`についてくるリストマーク（・）と同種にあたります。

![f12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/3879a1ea-fbcf-2ccd-05ad-2d932667fab1.png)


そのため、`<li>`のリストマークの点(・)を消す時と同じ方法で、`list-style: none;`で非表示にすることができます。


## まとめ

使用していたreset.cssなどによっては、初期値を無効化していなかったりするので、もし黒矢印が残っていたら、個別にCSSを書いてもいいでしょうし
今後も必要ないという場合であればreset.cssなどのCSSファイルに追記してもいいかもしれませんね。


参考：https://teratail.com/questions/155649


#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)
STM32G031のGPIOの速さを測る


目的
GPIOのテスト
WS2812Bを光らせる。

digitalWriteの速さは、446khz
ODRの速さは、1.681Mhz

```c++

/*
  Blink

  Turns an LED on for one second, then off for one second, repeatedly.

  Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO
  it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to
  the correct LED pin independent of which board is used.
  If you want to know what pin the on-board LED is connected to on your Arduino
  model, check the Technical Specs of your board at:
  https://www.arduino.cc/en/Main/Products

  modified 8 May 2014
  by Scott Fitzgerald
  modified 2 Sep 2016
  by Arturo Guadalupi
  modified 8 Sep 2016
  by Colby Newman

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/Blink
*/

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(PA8, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(PA8, HIGH);   // turn the LED on (HIGH is the voltage level)
  //delay(1000);                       // wait for a second
  digitalWrite(PA8, LOW);    // turn the LED off by making the voltage LOW
  //delay(1000);                       // wait for a second
}


```




```c++




void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(PA8, OUTPUT);  
}
                      //     65432109876543210
    int on1  = GPIOA->ODR | 0b0000000100000000;
    int off1 = GPIOA->ODR & 0b1111111011111111;

// the loop function runs over and over again forever
void loop() {
  GPIOA->ODR = on1;
  //delay(1000);                       // wait for a second
  GPIOA->ODR = off1;
  //delay(1000);                       // wait for a second
}



```
Slack仕草 - 補講


https://qiita.com/e99h2121/items/6a6f06cfaf4a74fca0f3

というのを結構な以前に社内Lightning Talkで喋ったのだが、やはり依然「使い方」が議論になるのでもう少し書いた。送り手も受け手も悩まず、心地よく、最大限それぞれが楽しく働くにはどうSlackをどう使うべきかのはなし。

## はじめに

何でこんな議論になるのか場合を分けることにした。

```
    - メッセージが伝わるタイミング
    - 誰に伝わるか
    - 相手は返答する必要があるか
    - 相手はいつ返答するか
    - 相手以外の人が返答できるか
```

## 比較

|  | 電話 | メール | Slack DM | Slack Private channel | Slack Public channel |
|:-:|:-:|:-:|:-:|:-:|:-:|
|**メッセージが伝わるタイミング**| 今 | 相手が読んだ時 | 相手が読んだ時 | 相手が読んだ時 | 相手が読んだ時 |
|**誰に伝わるか**| 通話相手 | 宛先To、Cc、Bccの相手 | 宛先 | メンション宛先、channel内の相手 | メンション宛先、channel内の相手、Slack参加者全員 |
|**相手は返答する必要があるか**| ある | **相手が決める** | **相手が決める**| **相手が決める**| **相手が決める**


乱暴に言えば電話以外、返答するしないは受け手の自由だ。

### しかし

こんな偏見があると想定する。

|  | 電話 | メール | Slack DM | Slack Private channel | Slack Public channel |
|:-:|:-:|:-:|:-:|:-:|:-:|
|**相手は返答する必要があるか**| ある | 相手が決める | 相手が決める| 相手が決める| 相手が決める
| (但し...) | - | 関係力学のある場合は基本的に返答する | 関係力学のある場合は基本的に返答する | 関係力学のある場合は基本的に返答する | 関係力学のある場合は基本的に返答する
|**相手はいつ返答するか**| 今 | 相手が決める | 相手が決める | 相手が決める | 相手が決める | 
| (但し...) | - | **なるべく早く返答する** | **なるべく早く返答する** | **なるべく早く返答する** | **なるべく早く返答する** | 
| (なぜなら) | - | **他に返答できる人がいない** | **他に返答できる人がいない** | **それがビジネスマナー？** | **それがビジネスマナー？** | 

### 特に

太字！
しかし、こう考えても良いんじゃないだろうかと答えたい。


|  | 電話 | メール | Slack DM | Slack Private channel | Slack Public channel |
|:-:|:-:|:-:|:-:|:-:|:-:|
|**相手は返答する必要があるか**| ある | 相手が決める | 相手が決める| 相手が決める| 相手が決める
| (但し...) | - | 関係力学のある場合は基本的に返答する | 関係力学のある場合は基本的に返答する | 関係力学のある場合は基本的に返答する | 関係力学のある場合は基本的に返答する
|**相手はいつ返答するか**| 今 | 相手が決める | 相手が決める | 相手が決める | 相手が決める | 
| (但し...) | - | なるべく早く返答する | なるべく早く返答する | なるべく早く返答する | なるべく早く返答する | 
| (なぜなら) | - | 他に返答できる人がいない | 他に返答できる人がいない | **それがビジネスマナー？** | **それがビジネスマナー？** | 
| (だったら) | - | **使わなくていい** | **使わなくていい** | **チームで解決しよう** | **チームで解決しよう** | 
|**相手以外の人が返答できるか**| できない | できない | できない | **channel内の相手なら返答できる** | **誰でも返答できる** |
|**気づいた人同士で助け合うことができるか**| できない | できない | できない | **channel内の相手ならできる！** | **誰でもできる！！** |
|**結論**| - | - | - | **場合に応じて使おう** | **使おう！！** |



## 考察

電話、メール時代のマナーに囚われすぎていないか、ツールへの理解不足ではないだろうか。そこがエンジニア勢以外に伝わりづらい面は否定しきれないので、地道に布教活動するしかないのかなあ...。

メンションしたからといって相手がすぐに返答できるとはかぎらない。する必要もない。**Slackの特長は非同期コミュニケーション。** 仮にすぐに回答が欲しい場合は、その旨も合わせて相手に伝えればよい。でも返答がなくてもそれは送り手の責任。

https://slack.com/intl/ja-jp/help/articles/360025054173-Slack-%E3%81%A7%E5%8B%A4%E5%8B%99%E6%99%82%E9%96%93%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B-

受け手を尊重するためにDMでない連絡で良いときは、DMでないチャンネルを選択してみよう。もちろん例外的に、人事、労務、営業情報などを秘匿するなど合理的な理由はある。しかし可能な限りパブリックなチャンネルでやり取りすることにより、ある特定の人に負荷が集中することがなくなる。**結果あなたの仕事が捗る。**


### 結論
チームで働くなら、SlackのPublic channel。

## まとめ

これまでに調べたSlack話。

- [Slack仕草](https://qiita.com/e99h2121/items/6a6f06cfaf4a74fca0f3)
- [既読機能を搭載しないSlack - リアクションこそが読んだ証拠](https://qiita.com/e99h2121/items/40e7eea415faa53614c4)
- [Slack社はSlackをどう使っているのか - Slack利用ガイドラインの話](https://qiita.com/e99h2121/items/71f607a0b46de5013730)

以上なにがしか参考になればさいわいです。
YouTube Live のリアルタイム視聴者数の取得方法

#YouTube Live のリアルタイム視聴者数の取得方法

##はじめに
とあるYoutuberさんのラジオを聞いていたらチャンネル解析のためにLiveのリアルタイム視聴者の数を
定期的に目視確認していると仰っていたので、YouTubeAPIを使用したら自動化できるだろうなぁと思ったのがことの発端。
自動化することで本当にやりたいことができるのかは別。。。

元々Pythonは触ったことがある程度。。。
なにか不具合があったら教えて下さい。

##リファレンス
以下URLの記事を参考にしました。
  ●YouTube APIキーの取得 (2020/03/25時点)
   https://qiita.com/iroiro_bot/items/1016a6a439dfb8d21eca
  ●YouTube Live チャット欄をAPIでリアルタイム取得
   https://qiita.com/iroiro_bot/items/ad0f3901a2336fe48e8f
  ●YouTube Data API v3でライブ配信の状態を取得する
   https://coolish.hatenablog.com/

##実行環境
M1 mac　mini
python3はインストール済み

##最初にやったこと
まずはYouTube　APIキーの取得
以下参照
 https://qiita.com/iroiro_bot/items/1016a6a439dfb8d21eca

以下ライブラリのインストール
```$ pip3 install google-api-python-client
$ pip3 install oauth2client
$ pip3 install httplib2
$ pip3 install isodate
$ pip3 install schedule
$ pip3 install csv
```

##コード説明
1.以下コードの内「YT_API_KEY」の’’で囲まれた部分に上記で取得したAPIキーを記入する（’’は残しておく）
2.以下コード内の「YT_LIVE_URL」の’’でかこまれた部分に視聴者数を取得したいYoutube　LiveのURLを貼り付ける（’’は残しておく）

##コード
```python3:getCountViewers.py
import time
import datetime
import requests
import json
import schedule
import csv

YT_API_KEY = 'ここにYoutube API　キーを貼り付け'
YT_LIVE_URL = '※※※ここに取得したいYouTube　LiveのURLを貼り付け'
DP_FILE_NAME = './getLiveCountViewers.csv'

def get_currentViewers(yt_url):
    '''
    https://developers.google.com/youtube/v3/docs/videos/list?hl=ja
    '''
    videoId = yt_url.replace('https://www.youtube.com/watch?v=', '')
    #print('videoId : ', videoId)

    url    = 'https://www.googleapis.com/youtube/v3/videos'
    params = {'key': YT_API_KEY, 'id': videoId, 'part': 'liveStreamingDetails'}
    data   = requests.get(url, params=params).json()

    liveStreamingDetails = data['items'][0]['liveStreamingDetails']
    countViewers = liveStreamingDetails['concurrentViewers']

    dtNow = datetime.datetime.now()
    dumpTimes = dtNow.strftime('%Y/%m/%d %H:%M:%S')

    print(dumpTimes,",",countViewers)
    with open(DP_FILE_NAME, "a") as f:
        f.write("{0}, {1}\n".format(dumpTimes, countViewers))
        f.close()

def job():
    get_currentViewers(YT_LIVE_URL)

#test
#schedule.every(1).seconds.do(job) #テスト用1秒毎に取得
#schedule.every(1).minutes.do(job) #テスト用1分枚に取得
# 毎時00分に実行
schedule.every().hour.at(":00").do(job)

def main():
    while True:
        schedule.run_pending()
        time.sleep(1)

if __name__ == '__main__':
    main()
```

##実行
上記ファイルをコピペで「getCountViewers.py」として保存する
ターミナルで以下コマンドを実行
```$ python3 getCountViewers.py
```

##出力
毎時00分にYouTubeLiveの視聴者数が「日時,視聴者数」で追加されていく
例：```
2021/06/09 04:00:00 , 42
2021/06/09 05:00:00 , 41
2021/06/09 06:00:00 , 42
2021/06/09 07:00:00 , 39
```

実行場所に以下ファイルが出力されるのでExcelで開いてグラフ化等で確認
```getLiveCountViewers.csv
```

##注意事項
終了処理は書いていないので、終了したい場合は「CTRL-C」でお願いします。

##備考
###python導入方法
 ●MAC
 https://prog-8.com/docs/python-env
 ●windows
 https://prog-8.com/docs/python-env-win

###Excelでグラフ化した際にうまく表示されない場合
 http://www4.synapse.ne.jp/yone/excel2010/faq/graph_x.html
 https://xtech.nikkei.com/atcl/nxt/column/18/00286/121200083/


##最後に
読んで頂きありがとうございます。
初めてのQiita投稿で不安が一杯
シシドカフカジェネレータを作る上で得られた知見

[シシドカフカジェネレータ](https://mt-experience.github.io/sidohuka/)を作るうえで得た知見を、**夜中に作りたいものを思いついてしまったときの**知見と共にメモします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619160/42c65295-f346-d311-5a56-9c4ef23a6106.png)


# 開発の進め方
## 最小の構成から作る
1. ボタンを押したらテキストエリアに何かがでるモノ
2. 「シドカフ」から無作為に取ってきて6文字作るモノ
3. 文字数、文字プールを指定できるモノ
4. 絵文字対応

という流れで作りました。1ができてなきゃ2も実現できないので、基礎から作っていくというのは当たり前のことです。
基礎を作る作業が面倒なので「3」を目指して作り始めがちでした。そういう場合は大抵途中で力尽きます。作ろうとしているものが（見かけ上）大きすぎるので、途方にくれてしまいます。
夜中に始めたので、途中で寝て起きても成果が残るように細かく目標を変えたのが功を奏してこうして深夜に草稿を構想しております。

## ちゃんとした道具を使おう
GitHubのWebエディタ(?)で書くのは少しつらい。
普通、ローカルで書いてテストしたものをまとめて履歴に残す。そうしないとソースの変更とコメントから読み取れる意図を一致させにくい。
せっかく4段階に分けて開発したのに履歴からその歴史が読み取れない。

# 文字加工

## 区切られた数字 ⇒ 数値配列 (0は無視)
`filter(v=>v)`は未定義やNaN、数値の0などを通さない(出典は失念)。parseIntが返すNaNを通さない。さらには0を通さないのが今回の要件ではマッチしたので楽だった。

```javascript:カンマ区切りの数字を数値配列に変換
"1,2,3".split(',').map(c => parseInt(c, 10)).filter(v => v)
//  [1, 2, 3]

" 1 , AA2BB ,, 3,0,1 ".split(',').map(c => parseInt(c, 10)).filter(v => v)
//  [1, 3, 1]
```

## 絵文字はsliceしづらい
2つのUnicode（サロゲートペア）で構成されているので、文字列のまま扱うと、分断されかねない。
今回は想定する文字数が少なく、処理も軽いので一文字ずつ配列に入れて扱った。

```javascript:虫をスライス
"A🐞B".slice(1,2)
// "\ud83d"  おそらく？で表示される

"A🐞B".slice(2,3)
// "\udc1e"  おそらく？で表示される

"A🐞B".slice(1,3)
// "🐞"
```

## misc

- 文字配列を文字列に  `["a", "b"].join === "ab"`
- 文字列を1文字ずつの配列に  `"ab".split("")`
- 草稿をメモ代わりに使えば時短だし、Qiitaにアクセスできる様々な端末から閲覧できる。

## 追記(7/5の深夜)
FirebaseのHostingを利用した。(ttps://ssdkhk-gen.web.app/)
↑なんか間違えて消したわ2024/02

1. googleアカウントを用意する。この時点でFirebaseを利用できるようになっているはず(うろ覚え)。
1. Firebaseでプロジェクトを作っておく。
1. [クライアント](https://firebase.google.com/docs/cli?hl=ja#sign-in-test-cli)を用意する。Windows用のバイナリまで用意されてる。
1. 起動して`firebase login`するとブラウザが開いたりしてログインできる。
1. プロジェクト用のディレクトリを用意して、そこで`firebase init`する。
1. Hostingを選択し、プロジェクトを関連付ける。
1. Configure as a single-page app はNoにする(ページは1つしかないけど)。
1. `public`のindex.htmlの内容を書き換えて`firebase deploy`する。

Firebase CLI の「バイナリ」はインストールが要らないし、おそらく持ち運べる（意味はなさそう）。1つの道具を1つの目的で使えるのが嬉しい。
minecraft java edition マルチーサーバーで1.17にしたら動かないときの対処

# minecraft java edition ver1.17実行したらエラーでた
GCE(Google Cloud Engine)でマイクラのマルチサーバーをたてているのですがそれに1.17を入れて実行しようとすると以下のエラーが出ました。

```
Error: LinkageError occurred while loading main class net.minecraft.server.Main
        java.lang.UnsupportedClassVersionError: net/minecraft/server/Main has been compiled by a more recent version of the Java Runtime (class file version 60.0), this version of the Java Runtime only recognizes class file versions up to 55.0
```

どうやらjavaのruntimeでバージョンエラー？？  

## 実行環境
- GCE
- Ubuntu 20.04.2 LTS
- minecraft Java Edition Ver.1.17
- openJDK 11.0.11

## 対処法
詳しいことはわかりませんがとりあえずjavaの実行環境が合っていないっぽいのでopenJDKを最新？の16に入れなおすと動きました。  
入れ方はQiita記事の[「OpenJDK（Java）を最新のUbuntuにインストールOpenJDK（Java）を最新のUbuntuにインストール」](https://qiita.com/terappy/items/537c069923144a9d9755) がいいと思います。 

## おまけ 
minecraftのwiki(日本語、英語ともに)openJDK-8をインストールするようになっていたので試しに入れて動かしてみたら同様のエラーがでました。(エラーに出てるバージョンが55から52になってましたｗ)  
おそらくopenJDKの11以前のものは動かないと思われるのでお気を付けください。そのうちminecraft wikiも変わると思うけど
Windowsでcreate-react-appでテンプレートが作成されないとき

#　create-react-appで作成されない

create-react-appで二度目以降、
固まって

```
...
yarn eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

  cd myapp
  yarn start

Happy hacking!
```
のところまでいかず

```
...
Done in ~s
```
と出て何も変わらない人向けの記事です。
ちなみに一度固まったらいくら待っても
```
installing
```
とはなりません。ご注意を。

#　上のメッセージに関わらず、きちんと実行できないときの対策
1.後述
2.グローバルにcreate-react-appを過去installした場合
→https://qiita.com/dhythm/items/92b3188d32ab5a5fd0e2
理由は知りませんがcreate-react-appはグローバルにインストールしない方がよさそうです。
3. package.jsonがどこかしら残ってる場合。
消しましょう。アプリは専用のホームディレクトリでなく専用フォルダを作って実装した方が良いらしいです。

4.npmのキャッシュが多すぎる場合
下のコマンドを実行
npm cache clean --force

5.エラーメッセージ：npm, yarnでインストールに時間がかかります！と出た場合。
```
into There appears to be trouble with your network connection . Retrying...
```
yarn installを行うディレクトリで
.yarnrcというファイルを作り中に
network-timeout 600000
と記述する。もしくは下記のコマンドを実行。
yarn add YourPackageHere --network-timeout 100000


6.1~5まででは解決できなかった場合
npx の後に--ignore-existing を挟むと上手くいくことがある
例：npx --ignore-existing create-react-app my-app --template typescript

7.nodeのヴァージョンが古すぎたり、新しすぎると上手くいかない。こともあるらしい

8.最後の手段
フォルダ内のデータをすべて削除、create-react-appグローバルもローカルもアンインストール、npm, yarnアンインストール、nodeアンインストールしてもう一度色々とインストール。(でもウィンドウズだと結構メンドクサイ。。。)

# 1
参照先→https://stackoverflow.com/questions/58738299/cannot-create-react-app-template-npm-hangs/64535070#64535070?newreg=5c66d561771e4371ba76a29623b107bb 

デスクトップ左下の検索欄から「リソースモニター」を実行。
そのCPUタグを押したうえで
create-react-appコマンドを実行。
それで中断したcmd.exeを右クリックして「プロセスの再開」をクリック。

# 原因
多分ずぼらな性格のせいで、勝手に作動するセキュリティソフト？ByteFenceを放置していたから。

# 最後

役に立ったらグッド反応ください。
ユーザアカウント制御(UAC)を回避するスタートアップ登録方法

# はじめに

Windowsをしばらく使っていると、お気に入りの常駐ソフトの一部は管理者権限で実行したくなるものです。

単純に、管理者権限設定を施したショートカットをスタートアップに登録する方法では、PC起動直後にUACが表示されてしまい、いろいろ不都合があります。

下記の方法を用いると、**確認なしに、管理者権限において自動起動できます**。

# 通常の方法

まずは通常の方法を説明しておきます。
単純に、スタートアップフォルダに配置するだけです。

`Win`+`R`→`shell:startup`→`Enter`でスタートアップフォルダを開きます。

![2021-06-09_00h56_09.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/936879/67b532ec-e9e0-54ed-beff-f7eda54e0a4c.jpeg)


そのフォルダ内に、起動したいソフトのショートカットを配置します。

必要に応じて、プロパティから管理者権限の設定をしておきます。

以降、`Ctrl`+`Shift`+`Esc`により開けるタスクマネージャーより、スタートアップの有効無効を切り替えられます。

# UACを回避する方法

こちらは、タスクスケジューラに適切な設定で登録する方法です。

とりあえず、タスクスケジューラを開き、適当なフォルダを作っておくとよいでしょう。
※下記の画像で、今回の記事に関連するエントリは、`Startup`のみです。

![2021-06-09_00h48_26.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/936879/bc31a320-e47d-e1e0-0fb0-a6d7b429db61.jpeg)

ではタスクを作成していきます。

下記において、`最上位の特権で実行する`に忘れずチェックします。

![2021-06-09_00h45_12.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/936879/f37f2690-a49c-d466-60b2-6b6d18d1e1cc.jpeg)

設定を進めます。

![2021-06-09_00h45_49.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/936879/2f7387ad-b6e2-7163-9f7b-6db31f1c06d5.jpeg)

複数のプログラムを実行したい場合は、下記において操作を複数登録する方法ではなく、バッチファイルを利用します。
前の操作が終了するまで次の操作が行われないため、常駐ソフトの場合一番上の操作しか実行されないためです。
バッチファイルを利用する場合、そのバッチファイル内では単にプログラムを起動する命令をしているだけであるため、タスクスケジューラ視点では、即時正常終了した扱いになります。

![2021-06-09_00h46_21.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/936879/fb85c54f-671a-173d-05cd-a198fdd5cc7c.jpeg)

```:startup_taskscheduler.bat
start C:\app1.exe
start C:\app2.exe
```

あとは適当に設定すれば登録完了です。

![2021-06-09_00h46_38.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/936879/38412d75-15c8-187f-cfcb-d00b56e50fb7.jpeg)


![2021-06-09_00h46_54.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/936879/e8474e00-296d-36c2-31ed-055e33666285.jpeg)

作成したタスクを右クリックして実行することにより、動作確認するといいでしょう。
React appで作成したポートフォリオをGitHub Pagesでデプロイできた

#React app(ポートフォリオサイト)をやっとデプロイできた
##最終的に成功した時に参考にしたサイト
https://btj0.com/blog/react/github-pages/

試した中でこのページ以外のやり方だと、なぜかエラーが出てデプロイできなかった。


<details><summary>エラーメッセージ</summary><div>

```shell-session
npm ERR! missing script: build

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/kakizakimanato/.npm/_logs/2021-06-07T14_05_58_985Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! portfolio@0.1.0 deploy: `npm run build && gh-pages -d build`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the portfolio@0.1.0 deploy script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/kakizakimanato/.npm/_logs/2021-06-07T14_05_59_032Z-debug.log
kakizakimanato@kakiMacBook-Air portfolio % npm run deploy

> portfolio@0.1.0 deploy /Users/kakizakimanato/deploy/portfolio
> npm run build && gh-pages -d build

npm ERR! missing script: build

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/kakizakimanato/.npm/_logs/2021-06-07T14_06_57_636Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! portfolio@0.1.0 deploy: `npm run build && gh-pages -d build`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the portfolio@0.1.0 deploy script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/kakizakimanato/.npm/_logs/2021-06-07T14_06_57_690Z-debug.log
```
</div></details>

まだ自分がデプロイできるかわからない時は、ファイルをコピーしてデプロイテスト用のディレクトリ内で試すといいかもしれません
(色々な方法試しているうちにpackage.jsonファイルなどぐちゃぐちゃになります...)

##少し追加でやらないといけないこと
###GitHubのアカウント情報を紐付ける

```sh
$ git remote add origin https://github.com/<GitHubアカウント名>/<GitHubリポジトリ名>.git
```

を実行する前に、GitHubアカウントの情報を設定する必要があった

```sh
$ git config --global user.name "[githubユーザー名]"
$ git config --global user.email "[githubで使用しているメールアドレス]"
```

これでgit remote add originができる

###GitHub Pagesの設定
ソースブランチをmasterに設定し、rootファイルをdocsに変更し、["Save"]をクリック
![スクリーンショット 2021-06-09 1.01.33.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1522373/850da435-ae90-5c8d-0043-cbd0b3a0e523.jpeg)

###数分待ってURLをクリックすると、成功していればWebサイトが見られるはず
次はファイルを編集後、再デプロイできるようになりたい
networkxでSNSのつながりをグラフ化

## データのダウンロード
```shell
!wget https://snap.stanford.edu/data/facebook_combined.txt.gz
!gunzip facebook_combined.txt.gz
```

## グラフの表示
```python
import numpy
import matplotlib.pyplot as plt
import networkx as nx

# データの読み込み
G = nx.read_edgelist("facebook_combined.txt")

# 描画
pos = nx.spring_layout(G)
plt.figure(figsize=(10, 10), dpi=200)

nx.draw_networkx(G, pos, node_size=1, with_labels=False, edge_color='gray', width=0.1)

plt.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614092/5fba1f7b-cc27-c09b-2c35-f6391d46153d.png)
Rails でアプリ作成時に[Sprockets::DoubleLinkError in Users#new] エラーが出た時の対処！

#はじめに
RailsでCRUD処理を実装している時のことです。
いざコードを書き`rails s`でサーバーを開こうとした時、いきなりエラーが発生。
初めて見たエラーコードで何故なったのか悩みましたが無事解決できたので記事にしていきます。

**　原因はかなり単純なことでした。**

##エラーコード

### `Sprockets::DoubleLinkError in Users#new`

```
Sprockets::DoubleLinkError in Users#new
Showing /Users/motoki/Desktop/crud_sample/app/views/layouts/application.html.erb where line # raised:
Multiple files with the same output path cannot be linked ("users.css")
In "/Users/motoki/Desktop/crud_sample/app/assets/config/manifest.js" these files were linked:
  - /Users/motoki/Desktop/crud_sample/app/assets/stylesheets/users.css
  - /Users/motoki/Desktop/crud_sample/app/assets/stylesheets/users.scss
```

`DoubleLinkError`と出ています。エラーコードを見ると５、６行目で確かにパスが被っています。
ですが何故こうなったのでしょうか。ターミナルのログを見てみると`rails g controller users`実行の際に
`/Users/motoki/Desktop/crud_sample/app/assets/stylesheets/users.scss`は作成されていました。こちらは普段から自動で作成されているので、必要ない方は`/Users/motoki/Desktop/crud_sample/app/assets/stylesheets/users.css`と分かりました。
こちらファイルを削除してサーバーを立ち上げると無事アクセスできました。

##解決策

```
/Users/motoki/Desktop/crud_sample/app/assets/stylesheets/users.css
```
重複してしまっていたこちらのパスのファイルを削除するだけです。

##なぜこうなったのか
初めは`stylesheets`なんか触った覚えはないのに何故なったのか全然分かりませんでした。
色々と調べていくうちに、VScode に watch sass という機能があるらしいことを知り、色々と見ていると
VScode を開くと下にある青色のバーのところに **watch sass** と書いてあるところが！！

**そこを押すと`watching...`となりcssファイルが作成されました。**
いつインストールした機能なのか覚えておらず、普段使わないので知らない間に押していたみたいです。

##まとめ
　Rails アプリでは使用しないそうなので皆さんもご注意ください。
【Android】DFMをローカルで試す

こんにちは。
DFMを実装した時に毎回GooglePlayのInternalAppSharingにアプリをアップロードして試していたのですが、
デバッグができないことや毎回apkやaabをアップロードする手間が発生して大変でした。
さすがに大変だったのでローカルでできる方法はないかと思い、調べていたところ公式でやり方が書いてあったのでここにまとめておきます。

# 準備しておくこと
- bundletoolを使えるようにしておく
    - [公式ページ](https://developer.android.com/studio/command-line/bundletool?hl=ja)
    - `brew install bundletool` でもできます
- aabを用意しておく
    - `./gradlew bundleDebug` 等で作成

# やり方
## 1. aabをapksに変換
bundletoolを使ってaabをapksに変換します。
以下コマンドをコマンドライン上で実行します。

```zsh
bundletool build-apks --local-testing
  --bundle my_app.aab
  --output my_app.apks
```

これが成功するとoutputで指定した名前のapksが作成されます。
### 余談
apksは実態がzipなのでunzipできます。
unzipしてみると中にapkが複数入ってます。
気になる方は見てみてください。

## 2. apksをインストール
次に、apksを端末にインストールします。
これもbundletoolを使ってやっていきます。
すでにアプリがインストールされている場合はアンインストールしておきましょう。

以下コマンドを実行します。

```zsh
bundletool install-apks --apks my_app.apks
```

## 3. アプリを実行
インストールがうまくいったらいよいよアプリを起動してみましょう。
アプリでDFMをインストールするフローに行くとしっかりインストールされることが確認できると思います。


以上がやり方になります。

# 最後に
意外と簡単にローカルで試すことができました。
また、やり方では説明していませんでしたが、SplitInstallManagerをFakeSplitInstallManagerというものに置き換えると通信エラーなどの状態も再現することができるので気になる方はぜひそちらも試してみてください。


# 参考ページ
- https://developer.android.com/guide/app-bundle/test/testing-fakesplitinstallmanager?hl=ja
Linux基礎学習まとめ③ 管理者と権限(useadd, groupadd, chmod, ertc.)

##概要
Linuxのファイルやディレクトリには、それぞれを管理するユーザやグループが割り当てられています。
また、ユーザやグループ毎に、読み書きや実行できるアクセス権なども割り当てられています。

ここでは、ユーザアカウントやグループ名の追加、変更、削除や、アクセス権を変更するコマンドなどをメモしておきます。


##実行環境
- macOS BigSur 11.4
- CentOS7 (macOS上でLinux環境を構築する方法は[こちら](https://qiita.com/tamago3keran/items/781728815e359243ff33)を参考にしました)

##管理者系
###1. ユーザアカウント
```
書式
$ useradd/usermod/userdel [option] [username]
```
ユーザーアカウントの追加、変更、削除を行うコマンド
`/etc/passwd`ファイルを参照することで、登録されているユーザーの情報を確認することができる。

```
例:
[hogehoge@localhost ~]$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
･･･
hogehoge:x:500:501:KAZMAX_ADMIN:/home/hogehoge:/bin/bash
```

|項目|意味 |
|:---- |:------|
|`x`   |'x'という文字か、暗号化されたパスワード、etc/shadowファイルに暗号化されたパスワードが記述されている。    |
|`500` | ユーザーID|
|`501` | グループID|
|`KAZMAX_ADMIN` | コメント（本名とか電話番号とか）。コメント無しの場合は何も記入されない。|
|`/home/hogehoge` | そのユーザーのホームディレクトリ。|
|`/bin/bash` | そのユーザーのログインシェル名。|

以下、よく使いそうなオプション

- `-g` : グループ名指定(/etc/group)
- `-c` : コメント指定
- `-u` : ユーザーID番号の指定
- `-s` : シェルの指定
- `-d` : ホームディレクトリの指定

###2. グループ
```
書式
$ groupadd/groupmod/groupdel [option] [groupname]
$ cat /etc/group
group_name:password:GID:user_list
```
グループ名の追加、変更、削除を行うコマンド

###3. パスワード
```
書式
$ passwd [username]
$ cat /etc/passwd
account:password:UID:GID:GECOS:directory:shell
```

###4. su, sudo
このコマンドは見たことあったけど意味よくわかってませんでした。
sudo(super user do)って意味らしい。
簡単にいいうと、Linux内で全てのファイルやディレクトリへのアクセス権を持つrootユーザとか、他のユーザにログインして、そのユーザでしか行えない操作を行うためのコマンドらしい

```
例：
$ su (rootユーザになる)
$ cat [dir/file]
$ sudo cat [dir/file] (rootユーザ権限でコマンド実行)
```


##ユーザ権限とアクセス権限
###1. 所有ユーザ・グループの変更
```
書式
$ chwon/chrtop [target]
```
対象ファイルやディレクトリの所有ユーザ(owner)やグループ(group)の変更コマンド

- `-R` : ディレクトリを再帰的に変更

###2. アクセス権を変更する
```
書式
$ chmod [access_permission] [target]
```
対象ファイルやディレクトリのアクセス権を変更するコマンド。
`ls -l`コマンドと併用して使うことが多い。
[こちらのページ](https://qiita.com/shisama/items/5f4c4fa768642aad9e06)がパーミッションについて非常にわかりやすく解説してくれている。

setuid/setgidビット : 所有者or所有グループの権限で実行される
stickyビット : ディレクトリないのファイルは所有者以外削除できなくなる 

```
例：
$ chomod g+t test (setuid/setgidビット)
$ chomod g+t test (stickyビット)
```

###3. アクセス権を制御する

```
書式
$ umask [mask_value]
```
ファイル作成時のアクセス権を制限するコマンド。
許可しないビットを指定する。

```
例：
$ touch test (default)
$ ls -l test
-rw-rw-rw- ... test (touchコマンドは0666でファイルを作成しようとする)

$ umask
0000 (現在のマスク値を表示)
$ umask 0022
$ touch test
$ ls -l test
-rw-r--r-- ... test (みたいな感じでアクセス権を制限できる)

$ umask -S
u=rwx,g=rwx,o=rwx (このオプションつけると見やすくなる(8進数表記じゃなくなる))
```



##終わりに
かなり雑にまとめました。
コマンドのメモ程度に置いておきます。

##参考文献
この記事は以下の情報を参考にして執筆しました。
- [Linux標準教科書(ver.3.0.2)](https://linuc.org/textbooks/linux/)
【Php】PDOでdatabaseに接続する

# 初めに
PDOについて学習した内容のoutput用記事です。

※内容に間違いなどがある場合はご指摘をよろしくお願いします。
※こちらの記事はあくまでも個人で学習した内容のoutputとしての記事になります。

# PDOとは
Php Database Objectsの略でphpを使ってdatabaseに接続するためのクラス。

# PDOクラスからインスタンスを生成する
PDOクラスにはあらかじめコンストラクタが定義されており、インスタンスを生成すると同時にデータベースへ接続する関数が実行されます。引数としてDSN（Database source name)とユーザーネーム、パスワード、その他のオプションを指定します。

```php
//DSN,ユーザーネーム,パスワードをそれぞれDB_HOST,DB_USER,DB_PASSWORDに格納
const DB_HOST = 'mysql:dbname=hogehoge;host=127.0.0.1;charset=utf8';
const DB_USER = 'fugafuga';
const DB_PASSWORD = '12345678'; 
```
それからPDOクラスのインスタンスを作り変数$pdoに格納します。

```php
$pdo = new PDO(DB_HOST, DB_USER, DB_PASSWORD);
```
これで簡単にデータベースに接続できます。前提としてmysqlにdatabaseとアカウントを作成しておく必要があります。

# DSNとは
DSN（Database source name)はデータベースのソースネームで接続するデータベースを識別するための情報。データベースの名前や種類、ホスト、文字コードなどが入る

# よく使うPDOのoption
PDOのインスタンスを生成する時に、よく使われるオプションは以下の3つです。

<b>① PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC</b>
→ データベースと接続して帰ってくる値を連想配列という形で受け取る
<b>② PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION</b>
→ 例外を表示する
<b>③ PDO::ATTR_EMULATE_PREPARES => false</b>
→ SQLインジェクション対策
 （フォームに不正な入力をし、データベースを改ざんすることを防ぐ）

```php
   $pdo = new PDO(DB_HOST, DB_USER, DB_PASSWORD, 
    [                                                   //追記
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, 
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => false,
    ]);
```

# データベース接続に失敗した時の処理
try catch文を使ってデータベース接続に失敗した時のエラーメッセージを表示するようにします。catchの引数にPDOExceptionのインスタンス?$e(変数名はなんでも構いません）を渡すことによってエラーの内容を表示することができます。

```php
 try{
    $pdo = new PDO(DB_HOST, DB_USER, DB_PASSWORD, [ 
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, 
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => false,
    ]);
    echo 'connection successful';
  }catch(PDOException $e){
    echo $e -> getMessage() . "\n";
    exit();
  }
```
PDOExceptionクラスが持つgetMessage()を使えば、PDOの接続失敗時のエラーメッセージを表示することができます。また、exit();によって処理を終わらせます。
![スクリーンショット 2021-06-08 20.46.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/d7c6fc7f-6101-8499-2e67-9535c117d903.png)


# 参考サイト
https://www.php.net/manual/ja/class.pdo.php
https://www.php.net/manual/ja/pdo.construct.php
https://www.php.net/manual/ja/exception.getmessage.php
https://www.php.net/manual/ja/class.pdoexception.php
https://www.php.net/manual/ja/language.oop5.paamayim-nekudotayim.php
https://www.php.net/manual/ja/language.oop5.decon.php
https://techacademy.jp/magazine/19296
phpMyadminにcsvから特定のカラムだけupdateは無理なのでSQLを書こう

## 概要
phpMyadminにCSVの特定の列の値で特定のカラムをupdateしようとして1時間迷子になったので。
もし、同じように必死にやり方を探しているのであれば、CSVを使ってSQL文を書くべき。

## CSVを利用してSQLを書く
| A | B | C | D
-- |-- |-- |-- |
1 |id | updateしたい値の列 | SQL文（関数表記）
2 |1 |A |"UPDATE 'テーブル名' SET '更新したいカラム名' =" & B2 & "WHEN 'id' =" & A2 ";"
3 |2 |A |"UPDATE 'テーブル名' SET '更新したいカラム名' =" & B3 & "WHEN 'id' =" & A3 ";"

D列のように書くことで簡単にコピーができるSQL文が完成する。
上記は関数での書き方なので一見歪だが、出来上がるのは下記のようなSQL文。
**UPDATE 'テーブル名' SET '更新したいカラム名' = 'A' WHEN 'id' =　1;**

注意点としてはテーブル名やカラム名を囲うのは「’」ではなく「｀」であること。
（今回はマークアップで上手く表現できないので、「’」を使ってます。）
流石に１００００件等になってくると別の方法を考えた方が良い気がするが、ある程度ならばこれですぐに対処できるはず。
あとは、D列にて作成したSQL文を、phpMyadminにコピペ＆実行すればOK
（画像は一部内容が見えないように塗りつぶしてます。）
![スクリーンショット 2021-06-09 0.42.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696590/bf249884-c745-7e79-6fba-79b0a46215a3.png)
InDesign スクリプト  属性を選択（構造の属性の値の検索結果から）

構造の属性の値の検索結果から属性を選択するスクリプトはこれで良いのかな・・・？

~~~JavaScript
/*
構造の属性の値の検索結果から属性を選択
更新 2021/06/09
*/

// アプリ指定
#target "indesign";

// スクリプト名
var scriptName = "属性を選択（構造の属性の値の検索結果から）";

// 検索文字を入力
var findGrepText = prompt("検索する属性の値（JavaScriptの正規表現）\r（選択された構造内の属性がある場合はその中から検索）","",scriptName);

// キャンセルされた時の処理
if(findGrepText == null){

    // スクリプトを終了
    exit();
}

// エラーが発生した場合の処理
try{

    // 正規表現オブジェクトを作り検索文字に入れる
    // mでマルチラインモード（^と$を各行の行頭、行末に一致させる為）
    findGrepText  = new RegExp(findGrepText,"m");

// エラーの場合
}catch(e){

    // 検索文字にnullを入れる
    findGrepText = null;
}

// 選択されているオブジェクト記憶用
var selectObjects = [];

// 選択が存在しない場合
if(app.activeDocument.selection.length == 0){

    // 構造内のすべての要素を選択する関数を使用
    selectObjects = selectAllAttributes(app.activeDocument.xmlElements,selectObjects);

// 選択が存在する場合
}else{

    // 選択されているオブジェクト
    selectObjects = app.activeDocument.selection;

    // すべての選択を解除
    app.activeDocument.selection = null;
}

// 選択オブジェクトの数だけ繰り返す
for(var i = 0; i < selectObjects.length; i++){

    // 選択オブジェクトが属性の場合
    if(selectObjects[i].constructor.name == "XMLAttribute"){

        // 属性名を検索して引っかかった場合
        if(selectObjects[i].value.match(findGrepText)){

            // 選択に追加
            selectObjects[i].select(SelectionOptions.addTo);
        }
    }
}

// 結果表示
alert("選択数 " + app.activeDocument.selection.length,scriptName);

/* 構造内の全ての属性を選択する為の関数、引数（xmlElements,再帰的処理の為の選択を記憶する配列） */
function selectAllAttributes(hierarchyElements,selectObjects){

    // 要素の数だけ繰り返す
    for (var i = 0; i < hierarchyElements.length; i++) {

        // 要素に子要素が存在するか
        if(hierarchyElements[i].xmlElements.length > 0){

            // 存在する場合再帰的処理
            number = selectAllAttributes(hierarchyElements[i].xmlElements,selectObjects);
        }

        // 属性の数だけ繰り返す
        for (var ii = 0; ii < hierarchyElements[i].xmlAttributes.length; ii++) {

            // 要素を選択を記憶する為の配列に追加
            selectObjects.push(hierarchyElements[i].xmlAttributes[ii]);
        }
    }

    // 選択する為のオブジェクトの値を戻す
    return selectObjects;
}
~~~
ロジスティック回帰とは

#ロジスティック回帰とは
Wikipediaによると
>ロジスティック回帰はベルヌーイ分布に従う変数の統計的回帰モデルの一種である。
ベルヌーイ分布とは確率pで1を、確率q=1-pで0をとる、離散確率分布である。
0 でない確率をとる確率変数値がある程度数えられる個数である確率分布のこと。

>また、ロジスティック回帰は、一般化線形モデルの一種である。
一般化線形モデルは、残差を任意の分布とした線形モデル。残差とは誤差の推定量。

まずロジスティック回帰とは、ある事象が発生する確率を予測する式を作ることです

重回帰分析との違いは、重回帰分析は目的変数が連続値なのに対し
ロジスティック回帰は目的変数が**二値**です
二値とはある事象が起こる/起こらないというデータです

起こる確率を計算するためグラフの形は直線ではなく、シグモイド曲線(S字型)になります。
(直線だと0を下回ったり、1を上回ってしまうから)

**式** expは底をネイピア数eとした指数関数()内が指数
![8f3e11e948bdcd8217d7de7aa0a0ea0c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1514389/94abcfaa-8c1f-010e-c650-26627b4e0e67.png)

**グラフ**
![ロジスティック回帰.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1514389/6cdbdcc4-743f-7f7e-9004-9f5ce5377115.png)

ここまで、ロジスティック回帰の大まかな説明をしてきましたが
ここからは実際に使用する際の注意点を書きます。

#注意点
まずロジスティック回帰では使えない説明変数があります。
それが以下の4つです。
①優劣のない3つ以上のカテゴリーデータ（例：血液型）
②データがすべて同じ値の説明変数
③説明変数の個数が「個体数－1」より多い変数
④数値以外のデータがある個体（基本的には数値データだが、記号や空白が含まれているデータ）  
ちなみに説明変数の数として、(少ない方の事象のデータ数÷10)までが投入できる数だと考えられています。


もう一つの注意点として、ロジスティック回帰は**線形分離可能**な分類問題に向いています。
線形分離可能とは簡単に言うと、データ空間に対し直線でうまく分類できることを言います。
2つの変数(x1,x2)があったときにx1とx2がともに高いときのみ
クラス1に分類されるというのであれば線形分離可能です

しかし、x1とx2がともに高いとき　x1とx2がともに低いときのそれぞれでクラス1に分類されるときは、線形分離可能でなく、分類が難しくなることが予想されます。
そのような問題には、非線形分類に適している決定木などの手法を試すのがいいかと思います。

次は実際に動かしてみたいと思います
Androidで動くLinux環境

# 概要

* android端末上で動かすことができるLinux環境について軽く説明します
* 日本語化などの設定方法は今回は見送ります。

# 候補

android上で動かすことができるLinux環境としては主に以下があります。

* Termux
* ubuntu-in-termux
* UserLAnd

どれもRoot化は不要なので簡単に試すことができます。

それぞれについて特徴を解説しますが、結論を先に言ってしまえば、個人的なおすすめはUserLAndのUbuntuです。

# Termux

* Google PlayおよびF-Droidからインストールできます。
* Google Play
    * https://play.google.com/store/apps/details?id=com.termux
* F-Droid
    * https://f-droid.org/packages/com.termux/
* F-Droidの方が新しいようなので、F-Droid版の方がおすすめです。
* 特徴・良い点
    * ストアから簡単インストール可能
    * 他の選択肢にくらべて動作が速い（chrootに似た仕組みであるprootを使っていないため）
    * 基本的に端末のみ
    * 専用Widgetなどが用意されている
* 残念な点
    * パッケージが少ない
    * 特にmozcなどの日本語入力パッケージがない
        * Emacs上でskkによる日本語入力が可能
    * ディレクトリ構成が通常のLinuxディストリビューションとは大きく異なる
        * prootを使っていないためなので、速さの代償
    * GUI環境が必要な場合は、別途XServerやVNCなどを立ち上げるなど手間が必要

# ubuntu-in-termux

* termux上で、さらにubuntuを立ち上げることが可能
* https://github.com/MFDGaming/ubuntu-in-termux
* セットアップが済んだあとは、termuxを立ち上げたあと、startubuntu.shを実行する
* 特徴・良い点
    * ubuntuのパッケージ群が利用できる
    * mozcなどの日本語入力用のパッケージもある
    * ディレクトリ構成が通常のLinuxと近い
* 残念な点
    * prootベースなのでtermuxよりも動作が遅い
    * GUIについてはtermuxと同様、別途XServerやVNCの立ち上げが必要
    * termuxを立ち上げたあとに、startubuntu.shを実行するので一手間入る

# UserLAnd

* Google PlayおよびF-Droidからインストールできます。
* google play
    * https://play.google.com/store/apps/details?id=tech.ula
* F-Droid
    * https://f-droid.org/packages/tech.ula/
* 特徴・良い点
    * UbuntuやDebianなどアプリ画面から選択して使うことができる
    * それぞれのディストリビューションのパッケージが使える
    * 日本語入力系のパッケージもあれば使える
    * ワンタッチでデスクトップ環境が立ち上がる
        * android上のVNCアプリや、XServerアプリを立ち上げてくれる
        * Linux側でVNCサーバーの立ち上げや、デスクトップ環境の立ち上げもできる
    * ディレクトリ構成は通常のLinuxと近い
* 残念な点
    * prootベースなのでtermuxよりも動作が遅い
    * 毎回パスワードが求められる
        * 端末モードでの最初のパスワードはスキップするには改造が必要。
    * GUIはスマホの画面ではあまり現実的でない
        * タブレットにするか、PCからVNCでつなぐかになると思う

# まとめ

* Termux
    * 日本語入力がいらない or Emacs+SKKで大丈夫なら選択肢になる
* ubuntu-in-termux
    * 基本Termuxだけど、緊急で日本語入力したい場合に良いかもしれない
* UserLAnd
    * 最初からUbuntuが立ち上がるのが楽
    * ちょっとした用途なら遅さはそれほど気にならない
DockerでFirebase Local Emulator Suiteを使う

# はじめに

Firestoreを使ったwebアプリケーションを作る際、Dockerでローカル用のFirestoreが必要になった
[mtlynch/firestore-emulator](https://hub.docker.com/r/mtlynch/firestore-emulator/)も選択肢としてはあったが、調べるうちにFirebaseのエミュレータ入れるほうが無難そうに感じた

以上が本記事を書くことになった背景

# 環境
- macOS: Catalina 10.15.7
- docker: 19.03.8
- firebase-cli: 9.12.1

# 事前準備としてFirebaseにプロジェクト作成

先にFirebaseにプロジェクトを作成しておくとスムーズに進むので作成しておく
→ここは難しくないので詳細は割愛

今回はFirestoreを使用するため、プロジェクト作成後にFirestoreも作成する
（リージョンは``asia-northeast``を選択）

# Dockerfile

```Dockerfile:Dockerfile
FROM node:14-buster-slim

RUN apt-get update -y \
  && mkdir -p /usr/share/man/man1 \
  && apt-get install -y curl openjdk-11-jre-headless \
  && npm install -g firebase-tools
```

どうやらopenjdkインストール前に``man``ディレクトリが必要らしい
→たしかに``mkdir -p /usr/share/man/man1``なしだとエラーなった

# docker-compose.yaml

```yaml:docker-compose.yaml
version: "3"

services:
  my-firebase:
    container_name: firebase
    build:
      context: .
      dockerfile: ./Dockerfile
    volumes:
      - ../firebase/emulators/:/opt/workspace:cached
      - ../firebase/bin/:/root.cached:cached
      - ../firebase/config/:/root/.config:cached
    ports:
      - 4000:4000 # Emulator Suite UI
      - 5000:5000 # Firebase Hosting
      - 5001:5001 # Clound Functions
      - 9000:9000 # Realtime Database
      - 8081:8081 # Cloud Firestore
      - 8085:8085 # Cloud Pub/Sub
    working_dir: /opt/workspace
    command: bash
    tty: true
```

ポート番号など、細かい部分はお好みで

# Emulatorを起動する

コンテナ入ってfirebaseにログイン
``no-localhost``オプション忘れずに！

```
$ firebase login --no-localhost
```

下記の質問にはYesで答える
→Noでもいけるかも！

```
? Allow Firebase to collect CLI usage and error reporting information? [Y/n]
```

下記のようにURLが表示されるので、ブラウザで表示確認
→Firebaseを使うGoogleアカウントを選択
→認証コードが表示されるのでコピー

```
Visit this URL on any device to log in:
https://accounts.google.com/hogehoge...
```

下記で、上記で取得した認証コードをペースト

```
? Paste authorization code here: 
```

以下が表示されれば成功！

```
✔  Success! Logged in as [Firebaseを使うGoogleアカウント]
```

あとは、``firebase init``コマンドを打ち、質問に答えて必要なFirebaseのサービスをセットアップすれば環境構築完了！

# ``firebase init``コマンドでの質問

プロジェクトは既存のものを選ぶのが楽
→何もプロジェクト選択しないと、後のエミュレータ起動時にエラーになる
→新規プロジェクトを作る選択肢もある

# エミュレータ起動してみる

```
$ firebase emulators:start
```

# さいごに

取り急ぎ備忘録としてまとめたので、抜け漏れあれば追加していく

# 参考
- [Local Emulator Suite のインストール、構成、統合  |  Firebase](https://firebase.google.com/docs/emulator-suite/install_and_configure?hl=ja)
  - 公式様
- [Firebase Emulator SuiteをDocker on RaspberryPiで動かす](https://sunday-morning.app/posts/2021-04-17-firebase-emulator-suite-docker-on-raspberrypi)
  - ラズパイではないがDockerfileの記述で大変参考にさせていただいた
- [DockerでFirebase Local Emulator Suiteを起動する。 - Qiita](https://qiita.com/kyhei_0727/items/343602fa184c84d593c4)
  - docker-compose.yamlの書き方で参考になった
- [Windows - firebase loginで正常にfirebaseが起動してくれません。｜teratail](https://teratail.com/questions/135344)
  - 開発環境はMacだが、``firebase login``まわりで詰まった際に参考になった
Laravel csvファイル読み込み＆出力

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954863/147d8c3d-395f-e021-8ade-af6f87249cd3.png)


# csvファイル

storage/app/**members.csv**

```php
山田太郎,東京都港区,090-0000-0000
佐藤花子,東京都杉並区,090-2222-2222
山本二郎,東京都豊島区,090-3333-3333
田中三郎,神奈川県横浜市,090-4444-4444
斎藤さくら,東京都台東区,090-5555-5555
加藤桃,東京都世田谷区,090-6666-6666
```


# ルーティング

/<font color="Red">アプリ名</font>/routes/**web.php**

```php
<?php
Route::get('/csv_sample', 'SampleController@csvSample');
```

# コントローラー

app/Http/Controllers/**SampleController.php**

```php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
 
class SampleController extends Controller{

public function csvSample(){
      // SplFileObjectの作成
      $file = new \SplFileObject(storage_path('app/members.csv'));
 
      // 読み込み設定
      $file->setFlags(
        \SplFileObject::READ_CSV | // CSVを配列形式で読み込む
        \SplFileObject::READ_AHEAD |
        \SplFileObject::SKIP_EMPTY | // 前の行と合わせて、空行があったら読み飛ばす
        \SplFileObject::DROP_NEW_LINE // 改行コードは無視する
      );
      // 1行ずつ読み込んで配列に保存
      $members = [];
      foreach($file as $member){
        $members[] = $member;
      }
 
      return view('samples.csv_sample', [
        'title' => 'CSV読み込みのサンプル',
        'members' => $members,
      ]);
    }

```



# ビュー

resources/views/samples/**csv_sample.blade.php**

```php
@extends('layouts.default')
 
@section('title', $title)
 
@section('content')
<h1>{{ $title }}</h1>
@foreach($members as $member)
  <p>{{ $member[0] }}: {{ $member[1] }} TEL: {{ $member[2] }}</p>
@endforeach
@endsection
```

### dd は「dump and die（データを吐いて終了）」の省略形。
画像認識をするために OpenCV をインストールしたときの記録

### 出発地

Python実践データ分析100本ノック

https://www.shuwasystem.co.jp/book/9784798058757.html

の「第9章　潜在顧客を把握するための画像認識10本ノック」で用いられているライブラリ
cv2
のインストールで迷ったので記録しておきます。
環境によって対処方法が異なると思いますが、私の場合はこうでした。

### 環境
OS: windows 10.0
python: 3.7.3
Anaconda: conda 4.10.1

### 実施日
2021/06/08

### 利用ツール
Anaconda Prompt
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/58a833a5-7ab0-3733-fb75-c5166cf19508.png)


### 実施コマンド
```
pip install opencv-python
```

### 到着地
opencv-python: 4.5.2.54


```
conda list
# packages in environment at C:\ProgramData\Anaconda3:
#
# Name                    Version                   Build  Channel
（中略）
opencv-python             4.5.2.54                 pypi_0    pypi
（後略）
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/3c7cc397-5225-3f79-de67-1d864e4449d7.png)
pipとpip3の違いを調べた

# 結論
pipコマンドはどのPython環境から呼ばれているかわかりにくいため、**Python3環境へのパッケージインストールであれば明示的にpip3コマンドを利用し```pip3 install <package>```とした方が良い。** pip3を利用すれば確実にPython3環境に紐ついているが、pipはマシンの状況に依る。
https://teratail.com/questions/46066

pip/pip3コマンドがどのPython環境のpipコマンドかは```pip -V```で確認可能。Pythonのバージョンと環境のパスが出力される。
「**Pythonなんて一つしか無いよ！**」もしくは、「**pipコマンドは自分の使いたい環境にしっかり紐ついてます！！**」と、わかっている場合はpipでもpip3でもどっちでも良いです。

なおUbuntuの場合は標準でPythonが提供されており、pipもUbuntuが提供する[```python3-pip```を利用することが推奨されている。](https://www.python.jp/install/ubuntu/pip.html)

# 推奨
そもそも```pip install <package>```ではなく```python3 -m pip install <package>```が推奨されている。（```python3```部分は利用するPython環境へのパスです。Python2なら2です。）

### 調べたところ
> **基本的な使い方**
> パッケージングのための標準ツールはすべてコマンドラインから使われることを想定しています。
> ```python -m pip install SomePackage```

https://docs.python.org/ja/3/installing/index.html?highlight=pip

> **Usage**
> Unix/macOS
> ```python -m pip <command> [options] ```

https://pip.pypa.io/en/stable/cli/pip/?highlight=pip3#cmdoption-disable-pip-version-check


> python3 コマンドを使わず、pip3 コマンドを使っても実行できますが、初心者の方には python3 -m pip ... の形式をおすすめします。

https://www.python.jp/install/ubuntu/pip.html

> Unix/macOS
> ```python3 -m pip install "SomeProject"```

https://packaging.python.org/tutorials/installing-packages/
学習記録１日目(Git/Ruby on Rails基礎)

はじめまして、今日から“文系未経験のプログラミング学習記録”と題し、
日々の学習のアウトプットをしていきます！　
内容が間違っていることもあるかもしれませんが、暖かい目でご覧いただけると嬉しいです。
（何かお気づきの点があればコメント等いただけますと幸いです。）


6月28日（月）
☆本日の目標☆
・GitHubが使えるようになる
・Ruby on Railsとは何か大枠を理解する

☆達成できたか☆
未達

☆未達成の場合、原因☆
GitHubについて、コードを書く場所だと思っていたが、想像以上に複雑で、理解が難しかった。
Ruby on Railsも同様、理解自体が難しい…

☆感想☆
GitHubはUdemyの講座で、Ruby on Railsについては本で学習しました。
どちらも理解自体が難しい箇所が多々あり、詰まりに詰まりました…
いつか繋がると信じて、毎日触れていきます！

☆本日のアウトプット☆
●GitHubについて●
・そもそもGitとは？
→バージョン管理システム。
どのファイルの何を、誰が、いつ、何のために編集したかなどの管理ができるため、個人はもちろん、複数人での作業にも○

・Gitの仕組み
ファイルの変更
        ↓
ステージングエリア（控え室のようなもの。commitするファイルを選択するためにある。）
        ↓commit
ローカルリポジトリ（個人のパソコンに変更履歴を記録）
 pull↑  ↓push
リモートリポジトリ（サーバー上に変更を上げる、共有）
（※リポジトリ…変更履歴を記録する場所）

このように、変更を段階的に操ることができるようです。


コマンドとしては、

ファイルの変更
↓ git add ファイル名　/ git add .（全ての変更をステージングエリアへ）
ステージングエリア
↓ git commit
ローカルリポジトリ
↓ git push
リモートリポジトリ

このように、段階を踏んでいきます。


-----※この辺りでつまづいたポイント----------------------------------------

git addか、commit どちらかをした際に（すみませんあやふやです）、vim？という特殊なゾーンに飛んでいきます。
ファイルを変更した内容と理由を記すときに飛んでいくのですが、触り方が特殊です。

まず、半角英数キー　→ iキー　→ 変更内容、理由を一番上に記述　→
→ escキー　→ :wq で、元の世界に戻ります。

この際注意なのが、変更内容と理由を記すときに、
”git addを追記”などのように半角英数以外の文字で終わるとき！
一旦半角英数キーを押してからescキーを押さないと、
同じ文字列の中に:wqが記述され、元の世界に戻りません…！

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

・ちなみにGitHubとは、
Gitリポジトリのホスティングサービス（預かってくれる）。
ソーシャルコーディングの場で、その登場によりオープンソース公開への敷居が下がった！



続いて、
●Ruby on Railsについて●
今日は、Railsを使用するための環境づくり、
Rubyの基礎の基礎を総ざらい、
Controllerについて少しかじりました！

・Railsとは？
→フレームワーク！
⇨フレームワークとは？
→webアプリケーションを制作する際の骨組みのようなもの

・オブジェクト、クラス、インスタンスなどが理解に苦しみました…
もはや理解できていないので要繰り返しです。

・Controllerは、webアプリケーションには欠かせないもの
Model→データベース
View→画面表示
Controller→上記2つを制御
合わせてMVCで動いているのがwebアプリケーション




長くなりましたが、今日の概要はこんな感じです。
明日はLPICの学習を始め、Ruby、Railsも進めていく予定です。
pyinstaller with-open セキュリティソフト

pyinstallerで作ったexeファイルでファイル生成するところがセキュリティソフトに引っかかる

下のコードはセキュリティソフトに引っかかる

```python
with open(filename,mode="w") as f:
    f.write("")
```

下はok

```python
f=open(filename,mode="w")
f.write("")
f.close()
```
openSUSEでmozc ut2のrpmをビルドする

自分用メモ
気が向いたらわかりやすく書き直す
http://linuxplayers.g1.xrea.com/mozc-ut.html

依存ライブラリ

``` shell
zypper in fcitx-devel gtk2-devel ibus-devel ninja pkgconfig zinnia-devel libQt5Core-devel libQt5Gui-devel libQt5Widgets-devel
```

1. src.rpmを落としてくる
        https://software.opensuse.org/package/mozc?locale=ja

1. ```rpm -ivh mozc-2.18.2612.102-lp152.6.9.src.rpm```
1. ~/rpmbuildに移動
1. ```wget -nc https://osdn.net/users/utuhiro/pf/utuhiro/dl/mozcdic-ut-20210627.tar.bz2 -O ./SOURCES```
        適宜新しいファイルに変更
1. SPECS/mozc.specを修正（下参照）
1. ```rpmbuild -bb ./SPECS/mozc.spec```

SPECS/mozc.spec の修正内容

```patch
--- mozc.spec   2020-05-17 10:05:58.000000000 +0900
+++ ../backup/mozc.spec 2021-06-28 23:52:22.994284857 +0900
@@ -76,6 +76,8 @@
 # License: SUSE-Public-Domain
 Source10:       jigyosyo.zip
 Source11:       ken_all.zip
+
+Source12:       mozcdic-ut-20210627.tar.bz2
 #
 %if %{with_fcitx}
 # add fcitx as mozc module
@@ -227,6 +229,12 @@
 python ../../dictionary/gen_zip_code_seed.py --zip_code=KEN_ALL.CSV --jigyosyo=JIGYOSYO.CSV >> dictionary09.txt
 popd
 
+# prepare ut2 dictionary
+pushd data/dictionary_oss
+tar xf %{SOURCE12}
+cat mozcdic-ut-20210627/mozcdic-ut-20210627.txt >> dictionary00.txt
+popd
+
 %build
 %define target Release
 export QTDIR=%{_libdir}/qt5

```
残プロ　第-27回

# 概要の修正

[第-5回](https://qiita.com/R1nY1x1/items/ab210aada75d082d0e43#%E7%8F%BE%E7%8A%B6%E7%A2%BA%E8%AA%8D)で作成した概要図を修正しました．利用するサービスの確定は済んだのであとは実装するだけ...

![タスク管理_概要_確定分.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578927/79051c14-e879-ffff-c655-490fdc6a06af.png)
仕様の曖昧さをカバーしていたらnullチェックで型から追放されてしまったnullability。いまさら帰ってこいと言われてももう遅い

[Narrowing](https://www.typescriptlang.org/docs/handbook/2/narrowing.html)(型の絞り込み)の話です。この記事で言いたかった事はもう全て言い終えました。残りは雑談コーナーです。

```typescript
  const narou = (message: string | null) => {
    if (message === null) {
      throw new Error('もう遅い')
    }
    return message
  }
  type NarouReturnType = ReturnType<typeof narou>
```

こういう時にNarouReturnTypeは`string | null`から`string`へNarrowingされます。

```typescript
  const narou = (message: { type: string | null; body: string }) => {
    if (message.type === null) {
      throw new Error('もう遅い')
    }
    return message
  }
  type NarouReturnType = ReturnType<typeof narou>
```

でもこの場合NarouReturnTypeは`{ type: string; body: string }`になってくれたりはしません。`{ type: string | null; body: string }`のままです。あくまで親オブジェクトの型としては1つなので子が絞り込まれようともそれによって新しい型は作ってくれないという事でしょうかね。親子といえど所詮他人。

```typescript
  const narou = (message: { type: string | null; body: string }) => {
    if (message.type === null) {
      throw new Error('もう遅い')
    }
    return { ...message, type: message.type }
  }
  type NarouReturnType = ReturnType<typeof narou>
```

こうするとNarouReturnTypeは`{ type: string; body: string }`になってくれます。実装としても新しいオブジェクトを生成しているので、よろしい新しい型を作ってやろうという事でしょうか。

```typescript
  const narou = (message: { type: string; body: string } | { type: null; body: string }) => {
    if (message.type === null) {
      throw new Error('もう遅い')
    }
    return message
  }
  type NarouReturnType = ReturnType<typeof narou>
```

なおこの場合もNarrowingされます。以上、TS4.2.4からでした。