OmniAICreator/Qiita-1.07M huggingface dataset:
ネオン風の文字を作る方法（無料フォントサイトも紹介）

# どうも7noteです。ネオン風の文字作成をする方法。

フォントの選び方から、雰囲気作りができるCSSまでまるっと紹介。

**見本**
![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/35a1dc3b-b84e-c52d-6db4-5dfd851466d6.png)

最高にオシャレなサイトが作れそう♪

## ネオン文字の作り方

```style.css
body {
  background: #000; /* 夜っぽく背景を黒にする。 */
}
	
.neon {
  color: #FFF;     /* 文字色を白に指定 */
  font-size: 50px; /* 適度な文字サイズを指定 */
  text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #ff00de, 0 0 70px #ff00de, 0 0 80px #ff00de, 0 0 100px #ff00de, 0 0 150px #ff00de; /* 薄い紫色の光を再現 */
  font-family: Beon; /* 読み込んだり、ダウンロードしたフォントを使う */
}
```

## フォント選び

以下のサイトから好きなネオンフォントを選ぶことができます。
私が今回使用したのは**「Beon」**というフォントです。大文字英語のみ対応。

https://fontmeme.com/jfont/neon-fonts/
![fonts.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/a536fa32-c4f5-90f4-98c1-117f955426c5.png)

## 解説

まぁネオンとうくらいなので、まずは背景を真っ黒にしてしまいましょう。
bodyタグに直接`background: #000;`を書いていますが、全体を覆うような要素を用意しておいて、それに背景黒を入れてもいいと思います。

次に**文字は白色**、**box-shadowでネオンのぼんやりした光を再現**します。
最後にダウンロード、もしくは読み込んだフォントをfont-familyで指定。
文字サイズは好みや用途に合わせて適当な大きさを指定してください。


## まとめ

無料のフリーフォントを使うので、思っている通りになるのは難しいかもしれません。
でもそれっぽい雰囲気は作れると思います。
そして、使用する際はしっかりとダウンロード元の利用規約などを読んでから使用しましょう！


>【フォントの些事】第1回 インストールする前に確認したいフリーフォントの基礎知識
https://www.granfairs.com/blog/staff/webfont-by-selfhosting

## おまけ

アニメーションを使えばチカチカさせることも可能。
結構やっている方多かったので「CSS 点滅」などで検索すれば好みのアニメーションを真似してつけることができると思います。

![movie.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/b7aa5ffb-43a2-08c4-2a50-8ce3b2144e8a.gif)

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


#数値の表示
printf()を利用し、ダブルコーテーション(")で囲まれた文字列を出力します。

```C
//C
#include <stdio.h>

int main(void){
    printf("犬が好き");//犬が好きと出力する
}

```
それと同じ容量で、数値を記載すればその数値が出力されます。

```C
//C
#include <stdio.h>

int main(void){
    printf("3");//3と出力する
}

```

でも、これはあくまで文字列として出力されたものであり、とても計算に使えたものではないでしょう。そこで__フォーマット指定子__というものを利用します。
フォーマット指定子とは、値を置き換えて出力するための記号のことです。

```C
printf("%d", x);//数値xを出力する
```
ここでは、__%d__がフォーマット指定子です。decimal（１０進数）という意味で、整数の値を__％d__と置き換えています。その後ろに__,（コンマ）__で区切って記載した値を出力することができます。

#計算
フォーマット指定子を利用すれば、以下のように計算を行うことができます。

```C
#include<stdio.h>

int main(void){
    printf("3たす7は%dです\n", 3+7);//足し算は＋を利用
    printf("8ひく5は%dです\n", 8-5);//引き算は-を利用
    printf("2かける6は%dです\n", 2*6);//掛け算は*を利用
    printf("20わる4は%dです\n", 20/4);//割り算は/を利用
    printf("30わる9のあまりは%dです\n", 30%9);//割り算をした際の余りを求めるときは%を利用
}
```

このコードの実行結果が以下の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1003936/db8bfe27-7904-34cc-e3fb-90e6874bbd69.png)


また、複数の値を__%d__で置き換えることも可能です

```C
#include<stdio.h>

int main(void){
    printf("%dたす%dは%dです",3,7, 3+7);
//１個目の%dには3、2個目の%dには７、３個目の%dには３＋７の解である10が代入される
}
```
Pardot Lightning アプリケーションを使用したエンゲージメントの向上とリードの育成 ⇒ Pardot のリード育成 (Pardot Lightning アプリケーション) ⇒ 計画と準備

１．Pardot のアセットのうち、アカウント全体の命名規則を作成することが最も重要なものはどれですか?
２．項目の差し込み印刷のデフォルト値はどこで設定しますか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/073759af-1f1d-79cc-3f04-9c30aca86ccc.png)
phpでdyld: Library not loaded: /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylibが出た時の対処法

`brew switch openssl 1.0.2s`で直るという記事が多いが、2021年2月時点でのbrew（バージョン3.0.0）ではbrew switchコマンドは使えない

https://cmichel.io/how-to-install-an-old-package-version-with-brew/
を参考に1.0.2sのopensslをインストールして

phpを入れ直したら、直りました（`brew uninstall php`→`brew install php`）
[生産性向上]google検索のテクニック

新卒で１年ほどエンジニアをやって来ましたが、「プログラミングができる」ことよりも、「より早く（生産性高く）」「問題解決するための方法」を身につける方が圧倒的に大切だと感じています。
特に問題解決においてgoogleを使わない日などありませんよね。
今回は自身が「生産性を高めるため」「問題解決するため」に役立った考え方・知識・スキルの一つである「google検索の小技」についてまとめました。

#検索方法#
###AND検索###
・スペースで区切る。複数のキーワードに関連するものを調べられる。左側に書くワードに一番ヒットしそうなワードを書くと良い。
例：M1 Mac 環境構築
###完全一致検索###
・ダブルクォーテーションで囲む。囲んだ文字に完全に一致するサイトのみ表示する. エラーコードとか電化製品の型番とかなど、それだけでは意味を持たない文字列や少しでも違うと意味が大きく変わってしまうものなどを検索するときに使う。
例："DOMA4019"
###マイナス検索3##
検索したいものが他の邪魔なワードによってうまく見つけられないときに使用する。使用頻度は低いが覚えておくとたまに役に立つ。
例：M1　-グランプリ
###OR検索###
どちらのキーワードもヒットするように検索できる。調べたいものが超超超ニッチなものでヒットしないときに試して見る程度のもの。あまり出番はない。
例：MacBook　OR　Surface
###曖昧検索###
ワイルドカード検索ともいう。半角で入力する。

*
０または１文字以上の言葉にマッチする。
例：じゅじゅつ*せん

！
1文字にマッチする
例：呪術!戦

?
１文字以上の文字にマッチする
例:いたどり?じ

#検索ワード#
下記の検索ワードをまるまる覚えるというよりはこんなのがあるんだ程度に認識しておき、いざとなったら見に来る程度で良いかと思います。
この記事を参考にさせていただきました。
[【Google検索方法のコツ】情報収集スキルを磨く完全ガイド36手法！](https://swingroot.com/google-search/)
・filetype:
・site:
・info:
・related:
・inurl:
・intitle:
・allintitle:
・intext:
・chache:

#最後に#
他に役立つテクニックなどがあればぜひ共有いただけると幸いです。
【Rails】リセットCSSが効かず苦戦した件

MVCの概念やRubyにおける7つのアクションを学習後、
実際にアプリ作成を行ってみました！
特にサーバーサイド実装で苦戦することが多いだろうな。。と思っていた私ですが、
まさかのビューファイルのレイアウト調整で苦戦するということに。。。:scream_cat:
ということで！
今回学んだことの振り返りを記録していこうと思います！

今回、<font color="LimeGreen">**本をテーマ**</font>にした投稿アプリを作ってみました！

以下トップページの画像です。
[![Image from Gyazo](https://i.gyazo.com/44e0ce62abe35f2b0a3935e1bd479682.png)](https://gyazo.com/44e0ce62abe35f2b0a3935e1bd479682)

共有したい本を投稿すると、
このページにどんどんアップされていく仕様になっています♪

ここからリセットCSSにて苦戦したことを挙げていきます！

# リセットCSSの導入
※今回はYahoo! (YUI 3) Reset CSSを導入しています。

そもそも何故リセットcssを導入する必要があるのか？
→各ブラウザ毎にデフォルトでかかっているcssがあり、
その作用を打ち消すコードを実装しておかないと、自身が想定する表示とならずレイアウト崩れが起きてしまいます。それを防ぐためのものなんですね！

仮にリセットCSSをなくすと、こんな感じになります↓
[![Image from Gyazo](https://i.gyazo.com/84a95fa2f9ee24703a7abb9f926499b1.png)](https://gyazo.com/84a95fa2f9ee24703a7abb9f926499b1)

変な余白が生まれたりして、レイアウト崩れが起きています。
これを防ぎ、まっさらな状態に戻して実装していく必要があるんですね！

ということで実装。
app>views>layouts>application.html.erb

```
<!DOCTYPE html>
<html>
  <head>
    <title>BookTalk</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>
    <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/3.18.1/build/cssreset/cssreset-min.css">
    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <%= yield %>
  </body>
</html>
```

これまで習っていたことを参考に、

```
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/3.18.1/build/cssreset/cssreset-min.css">
```
このコードでリセットCSSを読み込ませるようにしました。

よし！では進めていこうとカタカタ実装していた所、
妙な不具合に遭遇。
ローカル環境では問題なくリセットcssが適応されているものの、
herokuへデプロイするとリセットcssが読み込まれずレイアウト崩れが起きていることに気づく。。

ローカル環境では適応されているので、
記述が誤っているということではないな。。何が要因？？。。ハマりました泣

本番環境画面のコンソールにてエラーがどうなっているかを確認。
記載したhttp~のURLが読み込めていないというエラーになっていました。

そこで調べてみると、
**http通信**はいわゆる暗号化されていない通信(セキュリティ上安全でないページ)となるため、
そこで引っ掛かり読み込めず、
結果リセットCSSが適応されないといった事象になっていることが分かりました。
これに対し**https通信**は暗号化された通信(セキュリティ保護されたページ)として認識されるとのこと。

ということで、そもそもURLを読み込むのではなく、
stylesheetsフォルダにリセットcssファイルを作成し、
直接コードを打ち込んでいく方法に変えました。

すると、、、
heroku上のレイアウトにも適用されました！！！:smiley:

ここ躓く所ではないだろ！っとツッコミたくなる内容だなと感じましたが。。。

参考にする教科書通りのコードで進めようとすると、
思わぬエラーにぶつかることもあるんだと痛感しました。

シンプルな解決方法から複雑な解決方法まで様々あると思いますが、
常に広い視点で問題を解決していけるように、癖づけていこうと思いました！！

ここまで読んでいただき、ありがとうございます！
内容でおかしな点、誤っている点等あればご指摘いただけると幸いです！
[Swift] CoreLocationを使って現在地の経度と緯度を取得するサンプル

# 概要
`CoreLocation` を使って現在地の経度と緯度を取得するサンプルです。

# 環境
Xcode 12
Swift 5

# サンプルコード

```swift:ViewController.swift

import UIKit
import CoreLocation

class ViewController: UIViewController {

    let locationManager = CLLocationManager()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // locationManagerのデリゲートを受け取る
        locationManager.delegate = self
        // アプリの使用中に位置情報サービスを使用する許可をリクエストする
        locationManager.requestWhenInUseAuthorization()
        // ユーザーの位置情報を1度リクエストする
        locationManager.requestLocation()
    }
}

//MARK: - CLLocationManagerDelegate

extension ViewController: CLLocationManagerDelegate {
    // 位置情報を取得・更新したときに呼ばれる
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        // 最後に収集したlocationを取得
        if let location = locations.last {
            // 経度と緯度を取得
            let lat = location.coordinate.latitude
            let lon = location.coordinate.longitude
            print("lat: \(lat), lon: \(lon)")
        }
    }

    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print(error)
    }

}

```

```swift:info.plist

Key: Privacy - Location When In Use Usage Description
Value: "このアプリは位置情報を使用します"
```

## CoreLocation
デバイスの位置情報を取得するフレームワーク。
利用する際は `import` して使う。

## requestLocation()
このメソッドを利用する場合、`locationManager(_:didUpdateLocations:)` と `locationManager(_:didFailWithError:)` を実装しなければエラーとなる。

## info.plist
`Key` と `Value` をそれぞれセットし、利用目的を明記しなければ位置情報を取得できないので注意。
Gitのmainとmasterに弄ばれた話。

# masterはどこいった？
ある日、いつもどおり git push -u origin masterと叩いたら、、エラーが。
何だこれと思って調べてみたら、こんなことになってたんですね。

https://www.infoq.com/jp/news/2020/11/github-main-branch/

まぁ世の中の流れには従いましょうということで、mainに指を鳴らしてたのですが、、、

# master再び
。。。新しいレポジトリ作って、、git push - u origin main,,,でエラー。
。。。。え？

# git 2.28
少々ググってみたのですが、、、原因判明。
なんでも、上記の変更が反映されているのはgit 2.28以降とのこと。

メイン環境はubuntu 20.04を使っているのですが、こいつのgitはバージョンが2.25.1。
なので、最初にからのレポジトリ作って手元の環境にgit cloneしたり、git initしたりすると、ディフォルトブランチをmasterにしちゃうんですね。

じゃぁ私のmainはどこから来たのか、、、
手順を思い出すと、、、これGithub Actionsのテストするように作ったレポジトリで、最初にgit上でレポジトリ作った後、手元の環境に持ってこず、そのままActionsの編集画面で設定入れて、Web上でcommitしてたんですわ。。
GitのWeb上では、ディフォルトブランチがmainになっているようで。
で、その後そのレポジトリを手元環境にcloneしたもんで、ディフォブランチがmainになってたんですね。

びっくりしました。

あ、ディフォルトブランチの変更は、以下を参考にさせていただきました。
https://qiita.com/fk_chang/items/a4839a595fef9a2c3724

まぁ、そんだけの話です。
特定の文字列(日時)のアクセスログのステータスコードの数をカウントする方法

何かデプロイをして、エラーのテストをする時、膨大な量のアクセスログの中で、特定のエラーが発生しているかどうかをカウントするシェルコマンド集

## 50x エラーの数をカウントする


フォーマット

```
grep [絞り込みたい文字列（日付）] [アクセスログ保存先] | awk '( $8 ~ /50[0-9]/ ){print$0}'
```

例: 2021/2/1 の /var/log/nginx/access_log のアクセスログから、500~509 エラーの数をカウントする


```
grep 01/Feb/2021 /var/log/nginx/access_log | awk '( $8 ~ /50[0-9]/ ){print$0}'
```

## 4xx エラーの数をカウントする

フォーマット

```
grep [絞り込みたい文字列（日付）] [アクセスログ保存先] | awk '( $8 ~ /4[0-9][0-9]/ ){print$0}'
```

例: 2021/2/1 の /var/log/nginx/access_log のアクセスログから、400~499 エラーの数をカウントする


```
grep 01/Feb/2021 /var/log/nginx/access_log | awk '( $8 ~ /4[0-9][0-9]/ ){print$0}'
```

## 4xx & 5xx エラーの数をカウントする

ちょっと手抜きで 50x から 5xx に変わっている

フォーマット

```
grep [絞り込みたい文字列（日付）] [アクセスログ保存先] | awk '( $8 ~ /[4-5][0-9][0-9]/ ){print$0}'
```

例: 2021/2/1 の /var/log/nginx/access_log のアクセスログから、400~499 & 500~599 エラーの数をカウントする


```
grep 01/Feb/2021 /var/log/nginx/access_log | awk '( $8 ~ /[4-5][0-9][0-9]/ ){print$0}'
```
FlutterアプリへWebViewを追加する方法


#1,やり方
1-1,
pubspec.yamlにwebview_flutter: ^1.0.7
を追加

```yaml
dependencies:
  flutter:
    sdk: flutter
 ### 省略 ###
  webview_flutter: ^1.0.7
```

1-2,
flutter pub getします。

#2,使い方
使い方はimportしてWebViewウィジェットとして使用します。
下記のサンプルコードでは、
<font color="Red">BOTTOM OVERFLOWED BY ** PIXELS</font>
(黄色と黒の斜線)というエラーを回避するために
resizeToAvoidBottomPadding: false,
を付与してあります。

```hoge.dart
import 'package:webview_flutter/webview_flutter.dart';

// インスタの埋め込み
@override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomPadding: false,
      body:WebView(
              initialUrl: 'https://www.instagram.com', 
              javascriptMode: JavascriptMode.unrestricted
      ),
    );
  }
```
FlutterアプリへGoogleフォントを追加する方法



#1,やり方
1-1,
pubspec.yamlにgoogle_fonts: ^1.1.1
を追加

```yaml
dependencies:
  flutter:
    sdk: flutter
 ### 省略 ###
  google_fonts: ^1.1.1
```

1-2,
flutter pub getします。

#2,使い方
```hoge.dart
import 'package:google_fonts/google_fonts.dart';

// styleとして適用します。 antonというスタイルの例
  appBar: AppBar(
     title: Text('MyAppName',style: GoogleFonts.anton(fontSize: 22)),
  ),
```


#フォントの一覧
フォントの一覧は下記サイトにて確認できます。
気に入ったアイコンを使ってアプリを良い感じにしましょう！
https://fonts.google.com/
FlutterアプリへFontAwesomeを追加する方法



#1,やり方
1-1,
pubspec.yamlのdependenciesに
  font_awesome_flutter: ^8.11.0
を追加

```pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
 ## 省略 ##
  font_awesome_flutter: ^8.11.0
```
1-2,
flutter pub getする。


#2,使い方
Twitterやインスタグラムのアイコンなど、Iconsからは取れないようなものに対して使います。
下記はボトムナビゲーションバーのサンプルです。
(font_awesomeの用例がメインのため、切り替えなどのギミックは除いてあります)

```hoge.dart
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
return Scaffold(
        appBar: //
        body: //
        backgroundColor: //
        bottomNavigationBar: BottomNavigationBar(
          items: const [
            BottomNavigationBarItem(
              icon: Icon(Icons.home,color: Colors.grey),
              title: Text("Home"),
            ),
            BottomNavigationBarItem(
              icon: FaIcon(FontAwesomeIcons.twitter,color: Colors.grey),
              title: Text("Twitter"),
            ),
            BottomNavigationBarItem(
              icon: FaIcon(FontAwesomeIcons.instagram,color: Colors.grey,),
              title: Text("Instagram"),
            ),
          ],
       ),
      );
```

3,使えるアイコン一覧
使えるアイコン一覧はこちらです。
https://fontawesome.com/icons?d=gallery
【エラー】ActiveRecord::StatementInvalid: Mysql2::Error:



#はじめに

エラーに苦戦したため、解消方法を忘れないように備忘録として記述します。
もし参考になれば幸いです。

# 環境

現在のバージョン：
macOS Catalina 10.15.6

環境
ruby '2.5.8'
ruby on rails '5.2.2'
docker
MySql 5.7.33


# 背景

新しくgit branchを作成後PCをシャットダウンさせて再度開発をする際にlocalhost:3000でページ確認をしたところ下記エラーが発生。
ActiveRecord::StatementInvalid: Mysql2::Error: Tablespace 'データベース名.テーブル名' exists.: CREATE TABLE テーブル名 (version varchar(255) NOT NULL PRIMARY KEY)

調べてみたところ何らかの原因でデータベースの情報に相違があった、壊れているなどが原因とのこと。
ターミナルで下記を実行したが同様エラーで先に進めない


```ruby:ターミナル
$ docker-compose run web rails db:migrate:status
$ docker-compose run web rails db:migrate
$ docker-compose run web rails db:migrate:reset
```

# 解消方法

###①〜⑦対象のデータベース名を削除して再構築

①コンテナの一覧を表示してデータベース名の確認

```ruby:ターミナル
$ docker-compose ps #コンテナの一覧確認
```


②Dockerのデータベースコンテナに接続

```ruby:ターミナル
$ docker exec -it データベース名 /bin/bash 
#データベース名は【①】の際に表示されたmysqlのNAMESに記載されている
```


③mysqlに入る

```ruby:ターミナル
mysql -u root -p
#passwordはdocker-compose.ymlに記載されている
```


④mysqlデータベース表示

```ruby:mysql
mysql> show databases; 
```


⑤エラーに表示されていたデータベース削除しかし削除できず

```ruby:mysql
DROP DATABASE データベース名;

ERROR 1010 (HY000): Error dropping database (can't rmdir './データベース名', errno: 39)
```


⑥データベースの場所(パス)を確認してコマンドで削除
```ruby:mysql
mysql> show variables like 'datadir';
パスを確認
```

```ruby:ターミナル
$ docker-compose rm -rf /usr/local/var/mysql/データベース名
#確認したパスを使ってコマンドから削除
```


⑦その後データベース再構築したがコマンドが反応しない

```ruby:ターミナル
$ docker-compose run web rails db:migrate:create　→OK

$ docker-compose run web rails db:migrate:status　→エラー
$ docker-compose run web rails db:migrate　→エラー
$ docker-compose run web rails db:migrate:reset　→エラー
```


###⑧、⑨データ永続化フォルダを削除してビルド後db:migrate

⑧データ永続化フォルダを削除

docker/mysql/volumesフォルダを削除する
※永続化ファイルを置いてある箇所なので個々で異なります


⑨ファイルの編集した為ビルド後db:migrateしたらエラー解消されていた

```ruby:ターミナル
$ docker-compose build

$ docker-compose run web rails db:migrate
```


あくまでエラー解消の一例ですのでご参考になれば幸いです。
Amplifyをシンプルなライブラリとして使うサンプル

# 対象
Amplifyを使ってAWSのサービスを簡単に叩きたい人

# 準備
任意のディレクトリで

```
npm init
```
からの

```
npm i aws-amplify
```
としておきます。


# Amplifyライブラリの仕組み

amplify addやらでサービスを構築していくと、amplifyのconfigが自動的に構成されて、気が付かないうちに便利なツールになっているのが特徴です。
逆に言えばこれらを自分で書いてちょっとした便利ツールとして使うことも可能です。
Cogmnitoの認証やAPIの呼び出しなど、Amplifyライブラリを使用したほうが断然楽です。

例えばサインインでは

```javascript

const Amplify = require('aws-amplify')

const config {
  "aws_project_region":"ap-northeast-1",
  "aws_cognito_identity_pool_id":"ap-northeast-1:0000000....",
  "aws_cognito_region":"ap-northeast-1",
  "aws_user_pools_id":"ap-northeast-1_xxxxx",
  "aws_user_pools_web_client":"xxxxx"
}

Amplify.default.configure(config)

const userId = "hoge"
const password = "pass"

Amplify.Auth.signIn(userId,password).then(user => {
  // 成功時
  

}).catch(err => {
  // 失敗時
})

```

サインインを行うとCognitoUserオブジェクトが返ってきます。
[AWS Amplify API#signIn](https://aws-amplify.github.io/amplify-js/api/classes/authclass.html#signin)

CognitoUserの中身はJSON.stringfyでもしてダンプすれば見れます。
大体は

```javascript

Amplify.Auth.signIn(userId,password).then(user => {
  // 成功時
  user.signInUserSession.idToken
}).catch(err => {
  // 失敗時
})
```
などして使いたいトークンを取得するのかと思います。

で、サインイン後は、任意のタイミングでログイン情報を取得することが可能です。
トークンなども取得できるので、便利です。

```javascript
Amplify.Auth.currentAuthenticatedUser()
```

ここで取得できるのもまたCognitoUserオブジェクトです。
たしかトークン期限が切れている場合でも、このメソッドを呼ぶと更新トークンを使用して新らしいトークンが取得出来るはずです。

トークン期限切れの場合は、エラーで返してくれると嬉しいんですけどね。


# APIも同じようにconfigに追加して初期化すればいつでも簡単に呼び出しできます。
Amplify add apiとしてREST APIを一度生成してみれば、どういう設定をAmplifyに食わしているかがわかります。
あとはAPI名とメソッドだけ指定すればサクッと呼べるので便利ですね。

```javascript
const apiname = "hogeApi"
const path = "/test"
const params = {
  headers:{
    hoge:"foo"
  }
  body: {
    id:"aaaa"
  }
}
await Amplify.API.post(apiname,path,params).then(response => {
  // 成功時
}).catch(err => {
  // エラー時
})
```
【GCP】7 PERMISSION_DENIED: Missing or insufficient permissions


CloudFunctions for Firebaseでローカルエミュレーターではfirestore へデータの登録ができるが、deployしてクラウドから実行すると下記のエラーが出ていた。

>7 PERMISSION_DENIED: Missing or insufficient permissions

ここを参考にFirebase Admin SDKのserviceAccountKeyを設定する
https://firebase.google.com/docs/admin/setup?hl=ja

Firebaseコンソール → （左上の）設定 → サービスアカウント
から、

新しい秘密鍵の生成
xxx.json
を任意の場所へ配置する。

<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477820/b47f812a-9df0-1a2d-802d-e83d3bc6e0b2.png">

```
var admin = require("firebase-admin");
var serviceAccount = require("path/to/serviceAccountKey.json");
admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "https://[APPの名前].firebaseio.com"
});
```

これでdeploy後にクラウド側から関数実行をしてもエラーが出ず、正常にデータの登録ができた。

ちなみにこの時のfirestoreのルールはこれ。
※これはセキュリティがざるなので、あくまでも開発用に使用し、本番のプロダクトなどでは使わない方が良いです。

```
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if true;
    }
  }
}
```
特定のメンバ関数有無で、呼び出す関数を変えたい

## ことの発端

開発チームのメンバーが「やってみたらできた」ということで、そのコードを元に深堀りしてみて記事にするという、他人の手柄を自分の手柄にする典型。
SFINAEの存在は知ってたんだけど「特定のメンバ関数有無で、呼び出す関数を変えたい」ってことができるとは知らなかった。
コードを分解して解説するとワケワカラン。。。なので、ソースコードにそのままコメントでツッコミする形式とした。

## そしてコード

一番下の main() で、 call() に渡すオブジェクトに funcA() がある場合と、funcA() が無い場合で、呼び出す call() を切り替えたい、というコード。

```cpp
#include <iostream>
#include <type_traits>

struct A {
    void funcA() {
        std::cout << "funcA called" << std::endl;
    }
};

struct B {
    void funcB() {
        std::cout << "funcB called" << std::endl;
    }
};


struct C {
    void funcC() {
        std::cout << "funcC called" << std::endl;
    }
};


// class T に funcA が存在するかを確認する
template <typename T> class has_funcA {
private:
    // 「int = (&X::funcA, 0)」が謎めいているが順を追って考えると
    //  「&X::funcA」とあるが、こいつはX::funcAの関数へのポインタ（実アドレス）
    // つまり、この時点で X に funcA が存在しないとエラーとなり
    // オーバーロードしている test() 関数の候補から外れる。
    // 更に「(&X::funcA, 0)」の表現であるが、これはコンマ演算子であり、
    // 左から順に評価していって、一番右側の値が採用される。
    // https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%B3%E3%83%9E%E6%BC%94%E7%AE%97%E5%AD%90
    // すなわち、「&X::funcA」を評価（関数の実アドレスという即値）を行った後、
    // 「0」が採用されるのだけど、代入先が無い！
    // んだけど、仮引数が無くてもデフォルトパラメータは指定できるという気持ち悪い仕様なので
    // 「int value = (&X::funcA, 0)」 ではなく 「int = (&X::funcA, 0)」 としている。
    // まぁ、未使用変数的な感じだし、アリといえばアリだが、なんか気持ち悪いね。
    // （普通の関数でも void foo(int=0) {} は気持ち悪いが問題ないコード）
    // ちなみに、test() 関数は実体が定義されていないが、これは後述する decltype で
    // 返却される型のみを渡すために存在するもので、実行されることはない。
    // （仮に実行されるのであれば、リンク時にエラーとなるけど、実行されることがないのでエラーにならない）
    template <typename X, int = (&X::funcA, 0)>
        static std::true_type test(X*);
    static std::false_type test(...);
public:
    // private では test(X*) と test(...) が定義されている。
    // そして、test((T*)nullptr) を実行した場合（decltypeは評価のみで実行されない）
    // T* を引数にした場合、どちらの関数が採用されるかを判定する。
    // さらに、decltype でその採用される関数の返却値を取得し、valueとする。
    // ちなみに、decltype内では、引数を渡しているが、呼び出しは行われない。
    // つまり、オーバーロードされている関数を選択させるために値を入れるだけで実行されない。
    static constexpr bool value = decltype(test((T*)nullptr))::value;
};


// enable_if_t を使用して、オーバーロードされた call() 関数のうち、どれを採用するかを制御する。
// ただし、enable_if_t は C++14以降の実装

// class T に funcA が存在する場合に呼び出される call()
// ちなみに、テンプレート引数の
//「std::enable_if_t< has_funcA< T>::value, bool> = true」
// こいつが、何やってるのという疑問があると思うが、こいつも、さっきの仮引数の省略（未定義っていうのか？）
// と同じ理屈で
// 「std::enable_if_t< has_funcA< T>::value, bool> bValue = true」
// の bValue を省略している表現。
// んで、本題の採用候補をどうやっているかというと
// enable_if_t の第一テンプレート引数が false の場合、型を返さずエラーとなる（代入できないっちゅうエラー）
// つまり、オーバーロードされた関数の採用候補から外れるという理屈になる。

template <typename T, std::enable_if_t< has_funcA< T>::value, bool> = true >
    void call(T& x)
{
    std::cout << "funcA exists" << std::endl;
    x.funcA();
}

// class T に funcA が存在しない場合に呼び出される call()
template <typename T, std::enable_if_t< !has_funcA< T>::value, bool> = true >
    void call(T& x)
{
    x.funcB();
    std::cout << "funcA does not exist" << std::endl;
}

int main(void){
    A a;
    B b;
    C c;
    call(a);
    call(b);
    // call(c);  もし、funcA, funcB, funcC を個別に呼びたいなら、個別に判定する hax_xxxx を作成する必要がある。
}
```

## 戒め

SFINAE知ったかぶりだったという事実。
MSVCの文字列定数をデマングリングする

Visual C++(MSVC)でC/C++コードをコンパイルすると、文字列定数は例えば下記のようにマングリングされます。

```cpp
" %u: wFuncFlags: 0x%08X<%s>\n"
```
↓

```
??_C@_0BN@OHAHGLIK@?5?$CFu?3?5wFuncFlags?3?50x?$CF08X?$DM?$CFs?$DO?6@
```

ASCII部分が辛うじて読み取れますが、訳がわからない文字列です。

このマングリングされたシンボル名を`UnDecorateSymbolName`関数でデマングリングすると、素っ気なく``string'`とだけ返ってきます。
復元できそうなので、大変もどかしいです。

そこでデマングリングする方法を調べたところ、下記で言及されてました。
[Visual C++ name mangling](https://en.wikiversity.org/wiki/Visual_C%2B%2B_name_mangling)

どうやら、`@`で分割して(1つ目は特殊)

- `_C@_0`で始まればシングルバイト文字、`_C@_1`で始まればマルチバイト文字
- その次に文字列長(エンコードされている)
- なんかわからんハッシュみたいな文字
- ルールに従ってエンコーディングされた文字列

になっているようです。

ではそれを実装しましょう。
したものがこちらです。

https://github.com/udaken/UnDecorateStringSymbolName/blob/main/UnDecorateStringSymbolName.c

試してみると、ほぼうまくいってそうですが、`\n`がVT（垂直タブ）になってしまっていますね。
もとの表で、`{ctrl-K}{ctrl-J}`が逆の気がします。

まぁそこを直せば使えるんじゃないでしょうか。
ProgateのRailsで「We’re sorry, but something went wrong.If you are the application owner check the logs for more information.」が出たときの対処法

ProgateでRailsを勉強している際に、あまり見慣れないエラーメッセージに遭遇しました。
お問い合わせすることなく、解決したので記載します。

<h2>症状</h2>

エラーの内容は、<br>
<B>「We’re sorry, but something went wrong.If you are the application owner check the logs for more information.」</B>
<br>
日本語だと、<br>
<B>「申し訳ありませんが、問題が発生しました。アプリケーションの所有者である場合は、ログで詳細を確認してください。」</B>
<br>
スタックトレースなど出ていないため、今回コードに手を入れたところでエラー箇所を類推する必要がありました。
<p>また、特定の画面ではなく、どの画面でもこのメッセージが出てくる模様。</p>
<p>ちなみに、Railsの道場コースⅢの「ログアウト機能を作ろう」で発生しました。</p>

![progate.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/708c8182-da42-ade9-61fa-3d8da436ba10.jpeg)

<h2>解決策</h2>

<p>下記の記事を参照して、View側のRubyの処理がエラーの原因になっていると推察できました。<br>
<a src=https://yonepiano.com/2019/06/06/post-438/>
Viewの編集中に「We’re sorry, but something went wrong.If you are the application owner check the logs for more information.」と表示された</a></p>
<p>
さらに、どの画面URLでも同様の症状が出ていることから、Viewの共通部分である「application.html.erb」に該当のエラーがあると断定。
</p>
<p>
さらに、どの画面URLでも同様の症状が出ていることから、Viewの共通部分である「application.html.erb」に該当のエラーがあると特定できました。
</p>
<p>
エラーの原因となっていたのは下記でした。
</p>

```progate_logout.rb
<%= link_to("エラーしている箇所", "/index",{method :post}) %>
```

そしてこのように直して解決。

```progate_logout.rb
<%= link_to("エラーしている箇所", "/index",{method: "post"}) %>
```

<h2>原因</h2>
ViewでRubyコードを記述するための<%= %>で構文ミス同じ怒られ方をしてしまったので、<%= %>で構文ミスすると発生する模様。
今回の場合は、{}の中の:の位置がおかしかったせいで、このように怒られたみたいです。
(postのダブルクオートだけ直したら、怒られなくった)

お問い合わせすることなく、解決できたので一件落着。
(入門) LINE Developersに登録してプッシュメッセージ送信してみた

## コンソール

https://developers.line.biz/console/

* `Channel ID`
* `Channel secret`

をメモっておく。

## 短期のチャネルアクセストークンを取得

* [公式HP](https://developers.line.biz/ja/reference/messaging-api/#issue-shortlived-channel-access-token)
* 有効期間は30日

```sh:get_access_token.sh
CHANNEL_ID="0000000000"
CHANNEL_SECRET="ffffffffffffffffffffffffffffffff"

curl -v -X POST https://api.line.me/v2/oauth/accessToken \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode "client_id=${CHANNEL_ID}" \
--data-urlencode "client_secret=${CHANNEL_SECRET}"
```

### プッシュメッセージ

* 1人以上のユーザーに同時に送信する。
* TOKEN値は上で取得したものを設定。
* TOは、今は自分のID以外知らないので、テストで自分のUserIDを指定。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/402e0805-ce6f-6b57-aea2-47a6f7f365e7.png)


```sh
TOKEN="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

curl -v -X POST https://api.line.me/v2/bot/message/multicast \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer ${TOKEN}" \
-d '{
    "to": ["Uffffffffffffffffffffffffffffffff"],
    "messages":[
        {
            "type":"text",
            "text":"Hello, world3"
        },
        {
            "type":"text",
            "text":"Hello, world4"
        }
    ]
}'
```

![DB57E687-AD53-4DF3-95C7-57B3D114C44A.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/1cda99df-12db-2612-e2ff-1d4087e7f0da.jpeg)


## その他リンク

### LINE 公式アカウントログイン

* https://manager.line.biz/

### 参考

* [Line APIでメッセージを送る – naotomato](http://naotomato.jp/2020/10/07/line-api%E3%81%A7%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E3%82%92%E9%80%81%E3%82%8B/)
* [ LINEPush - LINEメッセージを送信](https://help.asteria.com/documentation/warp/ja/current/flow/designer/reference/component/LINEPush.html)
命名規約

##自分の最適だと思う命名規則
クラス：UserController//必ず先頭は名詞
関数：getUserData()//必ず先頭は動詞
変数：userName//必ず先頭は名詞
定数：USER_NAME　

##変数がObject:{}の場合
dataObj

##変数が配列:[]の場合
dataList
godotenvを使って.envから環境変数を読み込む


## リポジトリ
https://github.com/joho/godotenv

## envファイルを用意

```.env
AZURECLIENTID=f81b5350-09dc-480e-8c03-1xxxxxxxxxxxxxxxxx
```

## 例

```golang
package main

import (
    "fmt"
    "os"
    "github.com/joho/godotenv"
)

func main() {
    err := godotenv.Load(fmt.Sprintf("%s.env", os.Getenv("GO_ENV")))
    if err != nil {
    }

    ID := os.Getenv("AZURECLIENTID")
    fmt.Println(ID)
}
```

## 使い方

```
yuta:~/go-env $ go run main.go
f81b5350-09dc-480e-8c03-xxxxxxxxxxxxxxx
```
HoloLens2がおしゃれメガネ（文鎮）にならないために試したこと

HoloLens2がおしゃれメガネにならないために試したことを記述します。
##事の発端
期待を胸になんとか手に入れたHoloLens2、
起動してみるも以前の使用者のアカウントと紐付いており、使用することはできなかった（私調べ）。
なんとか以前の使用者に協力してもらい、端末のリセットを実行するところまで漕ぎ着けるも、
HoloLens2は読み込み中の画面のまま動かなくなってしまった…
##試したこと
・デバイスの再起動
・ハードリセット
・デバイスを回復モードに
・Advanced Recovery Companionを使用し再フラッシュ

いずれも、十分充電した上で行ってください。
###デバイスの再起動
トラブルシューティングの基本は再起動。

1. デバイスからUSB-Cケーブルから取り外す
1. 電源ボタンを15秒押し続け、LEDがオフになったことを確認
1. 数秒待った後に電源ボタンを短く押す
1. 再起動完了


###ハードリセット
再起動してもだめな場合はハードにリセットしましょう。

1. デバイスからUSB-Cケーブルから取り外す
1. 音量減 + 電源ボタンを15秒押し続ける
1. ハードリセット完了

ピロピロ音がなるのでそれが合図です。

###デバイスを回復モードに
ここまでやってダメならクリーンフラッシュするしかありません（たぶん）。
まずはデバイスを回復モードにします。

1. デバイスからUSB-Cケーブルから取り外す
1. 電源ボタンを15秒押し続け、LEDがオフになったことを確認
1. 1分ほど放置
1. 音量増ボタンを押しながら、電源ボタンを押して離す。（このとき音量増ボタンは押したまま）
1. 電源ボタンを離してから15秒待ってから音量増ボタンを離す
1. 回復モードになります。（電源LEDの真ん中のみが点灯します。） 

デバイスをPCに接続し、デバイスマネージャーから確認すると「Microsoft HoloLens Recovery」になっていれば回復モードです。

###Advanced Recovery Companionを使用し再フラッシュ
デバイスが回復モードに入ったのでツールを使用し再フラッシュします。

1. Windows ストアから Advanced Recovery Companion をインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428437/eaddb324-89de-b463-4c0f-9a7e9d41a166.png)

1. Advanced Recovery Companionを起動し、デバイス一覧からHoloLens2を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428437/425f84bd-dbcf-92da-c514-a7bc93c0101c.png)


1. ツールの指示に従って再フラッシュ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428437/65c22e76-fcb8-83bc-691a-aac508d52bad.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428437/239a6943-ed14-d014-aa66-83a0bb17443b.png)


![install.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428437/c848e1c5-21e4-7d5a-69a9-0a4e21e1c6a6.png)

1. 以下画面が表示されれば完了です

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428437/d3d7b50b-f24d-b1ac-6c53-82fe06b07599.png)

私の場合、これで解決することができました。
暫く経つとHoloLens2が爆音を鳴らしながら起動します。

この手順を試しても直らない場合は、
Microsoftへ問い合わせると良いかもしれません。


##感想
初期画面が表示されるまで生きた心地がしませんでした。
##参考資料
HoloLens 2 を再起動、リセット、または回復する
https://docs.microsoft.com/ja-jp/hololens/hololens-recovery
【Chrome】『このページのQRコードを作成』を消す

# 何それ？

↓この邪魔な奴です。

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/66a9ff59-dfb2-35d0-15f8-1bd7599c2839.png)

# 方法

`chrome://flags/#sharing-qr-code-generator`をURLにペーストして移動。
プルダウンを『Disabled』に変更。
再起動。

![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/2f7cf4d7-b5ed-63d0-c7c0-b2f257ccbb38.png)


これでOKです。

# PWAインストールボタンを消させろ

QRコードはまだ実害がさほど大きくないからいいのですが、隣にあるPWAインストールボタンは存在が害悪です。
しかも、かつては『Desktop PWAs installable from the omnibox』という設定から消すことができたのですが、[消せなくしやがった](https://support.google.com/chrome/thread/29653018?hl=ja)クソが
railsでフォームに入力された文字数をカウントする方法(jQueryなし)

# 開発環境
Mac OS Catalina 10.15.7
ruby 2.6系
rails 6.0系

# 前提

- 投稿フォームのビューは実装済み

- JavaScriptのフレームワーク等は使っていません



#  ビューにIDを付与する


まずはビューにIDを付与していきます。
IDを付与する要素は2箇所で、文字数を出力する要素と、文字数をカウントしたいフォームの要素に付与していきます。

```new.html.erb
<div class="new-postss">
  <div class="weight-bold-text">
    写真のタイトル
    <span class="indispensable">必須</span>
    # IDを付与
    <span class="count" id="count_title">0文字</span>
  </div>
    # IDを付与
  <%= f.text_area :title, id:"post_text", placeholder:"タイトル（必須 40文字まで)", maxlength:"40", rows:"1" %>
</div>
```

# Count.jsファイルを作成

文字数をカウントする関数を記述するためのファイルを作ります。

ディレクトリのパス
```app/javascript/packs/count.js
```

ファイルを作ったら、忘れずにapplication.jsで読み込みましょう。
また、turbolinksが原因で、正常な挙動にならないケースもあるので、コメントアウトしています。(2行目)

```app/javascript/packs/application.js
require("@rails/ujs").start()
//require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
//この１行を追加
require('./count')
```

# Count.jsファイルを編集

ここまでできたら、いよいよJavaScriptを書いていきます。

まずは関数countを作り、window.addEventListenerで、ページが読み込まれた後に関数が起動するように記述します。

```app/javascript/packs/count.js
function count (){ 
}
window.addEventListener('load', count);
```

その後、先ほど付与したID(フォームの方)を取得して、定数に代入します。

```app/javascript/packs/count.js
function count (){ 
  const postText = document.getElementById('post_text');
}
window.addEventListener('load', count);
```

その後、先ほどの変数に対して、ユーザーがキーボードを離したときに発火するkeyupを用いて文字数がカウントされるイベントを書いていきます。

完成形は以下の通りです。(後から順を追って説明します。)

```app/javascript/packs/count.js
function count (){ 
  const postText = document.getElementById('post_text');

  postText.addEventListener("keyup", () => {
   let titleLength = postText.value.length
   let countTitle = document.getElementById('count_title')
   if (titleLength > 40){
     titleLength = 40
   }
   countTitle.innerHTML = `${titleLength}文字`
  });
}
window.addEventListener('load', count);
```

---

まず、イベント発火させるための記述をします。

```app/javascript/packs/count.js
  postText.addEventListener("keyup", () => {
  });
```
---
次に、フォームに入力された文字数( postText.value.length )と文字数を出力したい要素を変数に代入します。

```app/javascript/packs/count.js
postText.addEventListener("keyup", () => {
  let titleLength = postText.value.length
  let countTitle = document.getElementById('count_title')
});
```
---
次に、文字数を出力したい要素を代入した変数(この場合は countTitle)のHTMLを書き換える記述をします。
そのHTMLを書き換える際に文字数を代入した変数 titleLength を使います。

```app/javascript/packs/count.js
postText.addEventListener("keyup", () => {
  let titleLength = postText.value.length
  let countTitle = document.getElementById('count_title')
  countTitle.innerHTML = `${titleLength}文字`
});
```
---

最後に、おまけにはなりますが、自分の場合は、フォームで40文字以内という制限を設けているので、if文で、40文字を越える際は、強制的に40文字に止まるように記述しています。

```app/javascript/packs/count.js
postText.addEventListener("keyup", () => {
 let titleLength = postText.value.length
 let countTitle = document.getElementById('count_title')
 if (titleLength > 40){
   titleLength = 40
 }
 countTitle.innerHTML = `${titleLength}文字`
});
```

以上が、railsでJavaScriptを使って文字数のカウントをする方法です。
文字数をカウントしたいフォームが複数ある場合でも、新しくIDを付与して、関数count内に同様の手順で記述していけば実装できます。

参考になれば幸いです。
画面遷移図とは？


#画面遷移図

どの画面でどんな操作をしたらどのページに移動するかを表記した図のことです。
サービスの全体像を捉えたり、画面間の相互関係を把握しやすいといったメリットがあります。
紙に描いたり、draw.ioなどのツールを使ったりします。

まず、アプリケーションで必要な画面を洗い出します。

- 記事一覧（トップページ）
- 新規登録ページ
- ログインページ
- ユーザー情報詳細ページ
- ユーザー情報編集ページ
- ユーザー情報削除ページ
- プロフィール登録ページ
- プロフィール詳細ページ
- プロフィール編集ページ
- 記事投稿ページ
- 記事詳細ページ
- 記事編集ページ
- 記事削除ページ
- いいね後のページ
- いいねしたユーザー 一覧
- フォロー後のページ
- フォローしたユーザー 一覧

洗い出しが終わったら、図にしていきます。

ー 完成形 ー
[![Image from Gyazo](https://i.gyazo.com/b006919e9e189d4786958efeb714bf91.png)](https://gyazo.com/b006919e9e189d4786958efeb714bf91)

ー 画面遷移図の種類 ー

- 画面名だけで作る
- 画面名と機能で作る
- 画面デザインを使って作る

上記は「画面名だけで作る」になります。


ー おすすめツール ー

- Overflow
- Prott
- Draw.io

今回は「Draw.io」を使いました。
アソシエーションの不備によるNoMethodErrorの解決の一例

NoMethodError in TweetsContoroller#show
undefined method 'comment' for <Tweet:~> Did you mean? comments comments =

undefined method 'comment'
この文はcommentというメソッドがエラーという意味です。

Did you mean? comments comments =
この文はcommentではなくcommentsですかという提示です。

TweetsContorollerのshowアクションを確認します。
commentをcommentsに修正します。

commentsに修正する必要性はアソシエーションです。

ツイートとコメントの関係性は一つのツイートに複数のコメントがされる
１対多の関係となっています。

アソシエーションは多を複数形で表記するのでツイートに関連するコメントを取り出す場合
@tweet.commentsという複数形の表記になります。
ドットインストール 詳解CSS基礎文法編　メモ

html内でcssを使うにはstyleタグ
要素に直接スタイルを付ける場合はstyleタグ

border等のように継承されないプロパティでも継承したい場合は、inheritを使う

command + option + i でデベロッパーツール

ｈ１の打ち消し線はtext-decoration: line-through;
pに下線を付けるには、text-decoraton: underline;
リンクの下線を消すには、text-decoration: none;

font-familyでフォントを変更できるが、注意したいのは、このフォントが反映されるにはこのページを見ている人の PC にそのフォントが存在している必要があるという点.
そこで、１つ目のフォントがなければ次のフォントというように、コンマで区切って指定する。

フォント名に空白が含まれる場合は ' （シングルクォーテーション）か " （ダブルクォーテーション）で囲ってあげる必要がある

CSS に日本語が含まれる場合、ブラウザによっては文字化けする可能性があるので CSS ファイルの先頭に @charset "utf-8"; と書いてあげる

日本語フォントを先に書くと、英字に日本語のフォントが適用されてしまうので、それが嫌な場合は英文フォントのあとに書いてあげる

sans-serif ですが、これは総称フォントファミリーと呼ばれていて、個々のフォント名ではなくてフォントのカテゴリーを指定するものになります
sans-serif がゴシック体系、 serif だったら明朝体系、 cursive だったら筆記体系、 monospace だったら全ての文字が同じ幅になる等幅フォント
この総称フォントファミリーを最後に指定しておくことによって、これらが全て見つからなかった場合、このカテゴリーのフォントからあるものを自動的に選んでくれるので必ず指定しておくようにしましょう

line-height を文字サイズの 3 倍にしたかった場合、いちいちこのように計算しなくても、 1 文字分を表す em という単位を使うこともできます。 line-height: 3em;（もしくは単位なしのline-height: 3;　でも可）

line-height は継承されるプロパティなのですが、このように単位ありで書いた場合、計算された値がそのまま子要素に継承されます。

単位なしで指定した場合、設定された文字サイズの 2 倍という設定のみが継承されて、子要素のほうで再計算されます。

vertical-alignは垂直方向で画像などのbaselineからの位置変更を可能にする
topは上、bottomは下
middle とすると行ボックスの中央ではなくて、 英小文字の中央と画像の中央が合わせられるという点にも注意
長さの単位で設定することもできて、その場合は baseline からどれだけ離れるかという意味になります。
2pxとすると、baselineから2px上で、-2pxとすると、baselineから2px下という意味
vertical-align を使えば画像に限らず、文中で配置される要素の位置を調整できる

rgbaとHSLA

list-style-type: circleで白丸
olタグでa,b,cにするには、lower-alpha
記号を内側にしたい場合は、list-style-position: inside;　とする
記号の代わりに画像にするには、list-style-img: url(); 
→list-style:circle lower-alpha url();  のように、半角区切りで指定すると、上記をまとめて指定できる。
list-style に限らず、一括指定プロパティで値を省略した場合は、その前に書いた個別の設定が初期値で上書きされてしまう点に注意する

領域から溢れた文字などは overflow: hidden;
overflow: scroll;　にすると、領域内でスクロールできる

border-style: dashed; で点線

垂直方向でmarginが重なると、小さい方が打ち消される

z-indexは要素の重なり順を指定するもので、数値が大きいほど上に表示される

ブラウザ幅を変えてもboxの間隔が20pxで、かつそれぞれのboxの幅が同じになるようにする
3x + 40px = 100%  
→ width: calc((100% - 40px) / 3 
演算子の前後にはスペース必須

box-shadow: 10px 5px 3px 10px
１つ目はx方向、２つ目はy方向、３つ目は影のぼかし具合、４つ目は影の拡大

text-shadowは４つ目は不可

画像の縦横比を維持したまま表示したい場合は background-size: cover;
デフォルトだと左上を起点に伸縮するが、画像の中心を起点に伸縮させたいなら、
background-position: center;

背景も一括指定が可能。
background-size と position はまとめて指定する必要があって、その場合は / （スラッシュ）で区切って background: center/cover にしてあげて

float された要素は通常の配置から外れるので、そのあとに続く要素は画像がなかったかのように配置されるのですが、テキストだけは画像を回り込むように配置される

h２など以降を画像の下に表示したいときに使う、clear が適用できるのは display プロパティの値が block の要素だけ
Hölderの不等式(ヘルダーの不等式)とその証明

#Youngの不等式
積に関してのYoungの不等式より以下が成り立つ. $a, b \geq 0$, $p, q \geq 1$, $\frac{1}{p} + \frac{1}{q} = 1$とすると,
$$ ab \leq \frac{a^p}{p} + \frac{b^q}{q} $$
証明は, $x = \frac{a^{p-1}}{b}$とすると $\frac{\frac{a^p}{p} + \frac{b^q}{q}}{ab} = \frac{x}{p} + \frac{1}{q}x^{1 - q}$であるのでこれが $x \in (0, \infty)$で1以上であることを言えればよく, これは微分すればわかる.

#Hölderの不等式
- $L^p$ノルム
$1 \leq p < \infty$に対して, $f \in L^p(\Omega)$のノルムを
$$\\|f\\|_{L^p(\Omega)} := \left( \int _\Omega |f(x)|^p dx \right)^\frac{1}{p}$$
とする. また $p = \infty$のとき, 
$$ \\|f\\| _{L^{\infty}(\Omega)} := \inf\\{C > 0 \mid |f(x)| \leq C \; (a.e. x \in \Omega)\\}$$
と定める.

- Hölderの不等式
Hölderの不等式より以下が成り立つ. $1 \leq p, q \leq \infty$, $\frac{1}{p} + \frac{1}{q} = 1$とすると $f \in L^p(\Omega)$, $g \in L^q(\Omega)$に対して,
$$\int_{\Omega} |f(x)g(x)| dx \leq \\|f\\|_{L^p(\Omega)} \\|g\\| _{L^q(\Omega)}$$
となる.

- 証明
$f, g$をそれぞれ$\\|f\\| _ p, \\|g\\| _ q$で割ることで$\\|f\\| _ p = \\|g\\| _ q = 1$である場合に帰着できる.
Youngの不等式で$a = |f(x)|, b = |g(x)|$とすると,
$$|fg(x)| \leq \frac{|f(x)|^p}{p} + \frac{|g(x)|^q}{q}$$
が成り立つ. $x$に関して両辺積分すると,
$$\int_{\Omega} |f(x)g(x)| dx \leq \frac{\\|f(x)\\|^p_p}{p} + \frac{\\|g(x)\\|^q_q}{q} = 1 = \\|f\\|_{L^p(\Omega)} \\|g\\| _{L^q(\Omega)}$$
となり, 求める式が得られた.

#一般化
Hölderの不等式は一般化でき, 以下が成り立つ. $1 \leq p_i \leq \infty (i = 1, 2, \dots, n)$で$\frac{1}{p_1} + \frac{1}{p_2} + \dots + \frac{1}{p_n} = 1$に対して,
$$\int_{\Omega} \left|\prod_{i = 1}^n f_i(x)\right| dx \leq \prod_{i = 1}^n \\|f_i\\|_{L^{p_i}(\Omega)}$$
が成り立つ.
FileZillaでPHPファイルをDLしたら本来ないはずの改行が発生した

うっかり設定をいじらずにサーバーからダウンロードして、改行だらけのファイルを爆誕させてしまった（ファイルサイズも変わった）のでメモ。


#対処法

メニュー＞編集＞設定＞転送＞FTP:ファイルの種類＞デフォルトの転送タイプを「バイナリ」に変更
※改行が発生するときは「自動」か「ASCII（アスキー）」になってるはずです。
初期設定は自動でした。HTMLやCSS、JSファイルをアップしたりダウンロードするときは問題なく使えていたのでしばらく気付かなかった。


FileZillaに限った話でもないんでしょうけど、あたらしいFTP入れたらまず転送モード確認したいですね。
ErrorException Undefined variable: ×××の解決方法

Laravel初学者です。
オリジナルアプリを作成しているのでその過程を記事にしています。

理解が曖昧なところも多いため、ご指摘等ありましたらご連絡いただければ幸いです。

今回は
`ErrorException Undefined variable: ×××`
が出たのでその解決方法を記録として残します。


## 環境

|                | Version     |
|:---------------|------------:|
| PHP            | 7.4.14      |
| Laravel        | 8.24.0      |
| mysql          | 8.0.23      |
| docker         | 20.10.2     |
| docker-compose | 1.27.4      |


## エラーが出た流れ

投稿データをDBから取ってきて一覧表示させたいと思い、
indexアクションとforeachで表示させる実装をしていました。

```PHP:resources/views/game/index.blade.php
@foreach($games as $game)
    @if($game->image_path)
      <div class="game-lists">
        <img src="{{ $game->image_path }}">
      </div>
    @endif
  @endforeach
```

上記がviewの記述です。
foreachで`$games`から1つずつ`$game`として取り出して表示させています。

```PHP:app/Http/Controllers/GameController.php
public function index()
    {
        $games = Game::all();
        return view('game.index');
    }
```

上記がコントローラーの記述です。
Gameモデルからallで全てデータを取り出し$gamesに入れています。

この状態でindexを表示させると
`ErrorException Undefined variable: ×××`
のエラーが出ました。

![スクリーンショット 2021-02-06 12.37.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1051152/316ee7eb-eae7-678d-c0cf-77d80878f845.png)

`Undefined`とは`未定義のデータですよ`という意味だと思ったのですが
コントローラーで`$games`で定義をしているはずなのでどういうことか分かりませんでした。


## 解決方法

[こちら](https://stackoverflow.com/questions/54064882/errorexception-undefined-variable-laravel)の記事を参考にさせて頂きました。
ありがとうございます！

viewにデータを渡す時は

```PHP
return view('welcome', compact('tasks'));
```

上記のように`compact`で変数名を渡す必要があるみたいです。
勉強になりました。

ということで

```PHP:app/Http/Controllers/GameController.php
public function index()
    {
        $games = Game::all();
        return view('game.index', compact('games'));
    }
```

上記のように編集することで表示ができました。

以上です。
Javaベースの翻訳メモリ"OmegaT"で、タイ語と日本語を混在使用できるようにする方法

#OmegaTとは
まあ、検索でこの記事にたどり着いた人には必要のない文章だが、念のためこのタイトルから始めておこう。
OmegaTとは"Javaベースで開発が進められている**翻訳メモリ**ソフトウェア"である。翻訳メモリという言葉に馴染みがない人には全く知らない言葉だろうが、私もそんなに使いこなせているわけではないので

1. マークアップとか制御情報とかが含まれているファイルの中から
1. 異国の言葉だけを抜き出して
1. それを文章ごとに切り分けて
1. 文章ごとに翻訳した内容を覚えていてくれて
1. 同じ文章には同じ翻訳を当てはめつつ
1. 後でそれぞれ違う翻訳を付けることも出来る

という、"ズボラにはとてもありがたい翻訳支援ツール"程度の認識しかない。そして、私のOmegaTの利用法といえば、「**他のツールで作り出したSRT字幕ファイルを日本語に翻訳する**」という利用一択だったりもするのである。

#OmegaTの設定方法がわかりにくい理由

さて、そのOmegaTだが、設定方法はとてもわかりにくい。それは、OmegaTが「きっちり設定が出来たらあとは設定変更などいらない」ツールであることもある。特に、*英語のファイルを日本語に翻訳する*くらいの用途であれば、何の設定変更もなしで使えてしまうのだ。そして、私のような**文字で書いてあればなんとか分かるけれどもタイ訛りで喋られたら何がなんだかわからないんだよ**な翻訳者がそれでも手持ちの情報を使ってなんとかしようと思った時にはまるのである。

ただ、こうやってはまると検索に難儀することになる。ほとんどの人はOmegaTではまっていないから情報がないのである。しょうがないので私も小手先の設定変更でなんとかこなしていたのだが、ついに3言語の同時表示ではまることになってしまった。そして表題のことがOmegaTの設定で解決できない理由に気がついてしまった。そう、**複数言語できちんと表示する設定はOmegaTにはない**のである。OmegaTはJavaで動いているから、そういうどうでもいいことはJavaで設定しなければならないのであった。これはわかりにくい。

ちなみに自分はJavaプログラミングの経験はほとんどない。野良iアプリを1,2個作って、**ケータイ用Javaは完璧に理解した**とうそぶくくらいの経験だ。ぜんぜん経験がないのがわかってもらえると思う。

#Javaのフォント設定はきちんとドキュメント化されているが……

さて、フォントについては
https://docs.oracle.com/javase/jp/1.5.0/guide/intl/fontconfig.html
こんなところにある。ただしJavaのドキュメントの面倒なところはどこからがプログラミングに直接関わるところで、どこからがアプリのユーザー向けかわからないところだ。

足りない脳みその私が知恵をしぼってこれを読んだ結果、わかったのは、ユーザーでもJREの入っているフォルダ内のlibフォルダにある
fontconfig.properties
をいじればなんとかなるということである。

だから、表題のことをしたい人はとりあえずOmegaTのインストールされているフォルダにあるJREの中を探して「fontconfig.properties」を探していただきたい。

そして、似た名前のファイルはあるが、そんなファイルはないことに気がつくはずだ。

#最初の状態では、設定ファイルなどない

そうなのだ。最初の状態ではJREにユーザー設定ファイルなどないのだ。ただありがたいことに、fontconfig.properties.srcなるファイルはある。これをfontconfig.propertiesにコピーリネームして置けば、最初の準備が完了する(管理者モードでfontconfig.properties.srcを開いて、fontconfig.propertiesと名前をつけて保存すればいい)。

#どこにフォントの指定をするか。

Javaは複数のOS下で動くようになっているため、論理フォントなるフォントが用意されているそうなのである。Serif,Sans-serif,Monospace,Dialog,DialogInputなる5つのフォントがそれだ。OmegaTで字体設定をやった時に、入れたような気がするフォントの他にこれらのフォント名を見たことがあると思う。おそらく何がなんだかわからない人は他のサイトを見てDialogにフォント設定しているような気がする。だから、Dialogにタイ語の設定もしておけば、Dialogでは豆腐になってしまうタイ文字もきちんとタイ語で表示されるはずなのだ。

#解決方法(使用フォントをDirectにしている場合)

具体的にはdialog.plain.ほにゃららと並んでいるところの一番下に
```dialog.plain.thai=Noto Sans Thai```
こう書く。
ここまで全く説明していなかったが、私のPCにはNoto Sans Thaiが既にインストールされている。
https://www.google.com/get/noto/
入っていない人は適宜自分のところに入っているタイ文字フォント名を書くか、上記ダウンロードサイトからインストールすべし。日本語フォントと違ってそんなにファイルサイズも大きくない。

で、これ以外にbold,italic,bolditalicについても適宜書く。
```dialog.bold.thai=Noto Sans Thai Bold```
```dialog.italic.thai=Noto Sans Thai```
```dialog.bolditalic.thai=Noto Sans Thai Bold```

そして、ここに書いたフォント名を実際のフォントファイルと関連付ける
```filename.Noto_Sans_Thai=NotoSansThai-Regular.ttf```
```filename.Noto_Sans_Thai_Bold=NotoSansThai-Bold.ttf```
これらのことを管理者モードで開いたファイルに書いたら保存する。
これでタイ語と日本語を混在使用できるようになったはずだ。

#残る謎

昔はOmegaT上の設定でDialogを選んでおけばこんなことはしなくてもタイ文字が出ていたはずなのだが、いつの間にか、タイ語フォントを選ぶと日本語が出ず、日本語フォントを選ぶとタイ語が出なくなるようになってしまっていた。それが何に起因するものなのかは調べられていない。

日本語フォントとタイ語フォントは、慣れの問題もあるが同じフォントサイズで表示すると見づらい。例えば日本語で12ポイントにしたらタイ語は16～20ポイントにしないと同等の大きさに見えない。混在使用するならこの大きさもなんとかしたいのだが、大きさの設定方法は見つけていない。

タイ語以外でも、どこの非欧米アルファベット文字でも、そのロケール名がわかれば似たような設定が出来るはずだが、タイ語以外の設定はわからない。聞かれても調べるつもりもない。
vuexでフォームを扱う（getとset）

#概要
Vueを使ってフォームのinput要素を双方向データバインディングを作成する場合、dataに変数を宣言してv-modelから取得していましたが、vuexを導入してstateに変数を宣言していた場合の方法を起筆します。

#実装方法
##改善前(Vuexを導入していない)
```comment.vue
<template>
    <div class="comments">
        <form v-on:submit.prevent="submit">
            <textarea name="comment" id="comment" cols="30" rows="10" v-model="comment"></textarea>
            <button>コメントを送信する</button>
        </form>
    </div>
</template>
<script>
export default {
    data(){
        comment:''
    },
    methods: {
        submit() {
            this.$store.dispatch('comment/pushComment');
        }, 
    },
}
</script>
```

##改善後(Vuexを導入した手法)
```comment.vue
<template>
    <div class="comments">
        </div>
        <form v-on:submit.prevent="submit">
            <textarea name="comment" id="comment" cols="30" rows="10" v-model="comment"></textarea>
            <button>コメントを送信する</button>
        </form>
    </div>
</template>
<script>
export default {
    computed: {
        comment:{
            get(){
                return this.$store.getters['comment/comment'];
            },
            set(value){
                this.$store.commit('comment/updateComment', value);
            }
        },
    },
    methods: {
        submit() {
            this.$store.dispatch('comment/pushComment');
        }, 
    },
}
</script>
```

```comment.js
import axios from "axios";

const state = {
    comment: null,
};
const getters = {
    comment: state => state.comment ? state.comment: '',
};
const mutations = {
    updateComment(state,comment){
        state.comment = comment;
    }   
};
const actions = {
    pushComment({context}, data){
        axios.post('/api/comment').then(result=>{

        }).catch(error=>{

        })
    }
};
export default {
    namespaced: true,
    state,
    getters,
    mutations,
    actions
}
```
#まとめ
```.js
computed: {
    comment:{
        get(){
            return this.$store.getters['comment/comment'];
        },
        set(value){
            this.$store.commit('comment/updateComment', value);
        }
    },
},
```

・値を返すときはget()を利用して、gettersを返す
・値を変更するときはset()を利用して、mutationsを呼び出す

#参考文献
[vuex公式](https://vuex.vuejs.org/ja/guide/forms.html)
[v-modelでstateやgettersを変更したい時に使える算出プロパティ](https://designsupply-web.com/media/knowledgeside/4884/)
初めての投稿...

初めまして、Ryoと申します。

Qiitaアカウント作成しました。

去年からプログラミングの勉強はしていたのですが、未だにQiitaのアカウント作ってなかったので作りました。

プログラミングの勉強にはオンラインスクール（卒業済み）「codevillage」とProgateを利用しております。
学習したものはHTML/CSS/Javascript/React/Node/SQLです。

よろしくお願い致します。
【Python】BeautifulSoupでHTMLをパースすると勝手に構造が変わる問題


# 問題
BeautifulSoupで書き方の間違ったHTMLをパースすると，勝手に構造を変えられてしまいます。


# 問題の発生するコード例

```py
html = '<h3><p>テキスト</p></h3>'
soup = BeautifulSoup(html, 'lxml')
print(soup.prettify())
```

```期待する出力.
<html>
 <body>
  <h3>
    <p>
     テキスト
    </p>
  </h3>
 </body>
</html>
```

```実際の出力.
<html>
 <body>
  <h3>
  </h3>
  <p>
   テキスト
  </p>
 </body>
</html>
```



# 解決方法
パーサーを`lxml`から`html.parser`に変更すると解決します。
ただし，ルートに`htmlタグ`と`bodyタグ`が自動で追加されなくなるので，必要な場合は自分で追加しましょう。

```py
html = '<h3><p>テキスト</p></h3>'
soup = BeautifulSoup(html, 'html.parser')
print(soup.prettify())
```

```出力.
<h3>
 <p>
  テキスト
 </p>
</h3>
```
WSL 2 環境で miniconda を使って JupyterLab を簡単に起動できるようにした話

# はじめに

WSL 2 で JupyterLab を使いたいと思ったのですが、Anaconda の商用利用有償化の話など色々あって結構手順が長くなったので、今回備忘録がてら記事にしてみました。

ついでにこれまでずっと抱き続けていた「JupyterLab 起動するときいつもコマンドが長くてクソめんどくさいんだよな……」というモヤモヤを解決しました。

# 環境構築

## 環境

- Windows: Windows 10 20H2 (19042.746)
- WSL 2: Ubuntu 20.04 LTS

## miniconda インストール

```shell
cd ~
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
chmod +x Miniconda3-latest-Linux-x86_64.sh
sh Miniconda3-latest-Linux-x86_64.sh
rm Miniconda3-latest-Linux-x86_64.sh
```

インストール手順の最後に

```
Do you wish the installer to initialize Miniconda3
by running conda init? [yes|no]
```
と聞かれますが、ここは yes としておきます。

パスを通します。 (厳密には既に .bashrc に追加されているので再読み込みします)

```
source ~/.bashrc
```

## conda の channel 設定

conda-forge を唯一の channel に設定します。

Anaconda の商用利用有償化の話[^1]があります。WSL 2 環境下では検証環境を作ったりとか色々やるわけですが、今後誰かに Python を使って何かしらをする手順を案内した場合に「その手順はライセンスの都合で使用できない」みたいなことになると面倒なので、とりあえず conda-forge で実行可能な手順なら誰でも実行可能だろうという理屈でこの手順を実施しています。

不要な人は飛ばしてください。

```
conda config --add channels conda-forge
conda config --remove channels defaults
```

既存のパッケージも全部 conda-forge 由来のものに置換しておきます。

```
conda update conda
conda update --all
```

## JupyterLab インストール

一通り標準的なパッケージをインストールします。

```
conda install jupyter jupyterlab pandas scikit-learn matplotlib git
```

試しに起動してみます。

```
/home/<your-name>/miniconda3/bin/jupyter lab --no-browser
```

miniconda をデフォルトのままインストールした場合上記のようにユーザーのホームディレクトリにインストールされます。\<your-name\> を自分の環境に応じて置換して実行します。


表示された URL にアクセスしてきちんと動けばとりあえず OK です。

## JupyterLab 設定

デフォルトのワーキングディレクトリを変更します。（必要ない人は飛ばして大丈夫です）

設定ファイルを生成します。

```
/home/<your-name>/miniconda3/bin/jupyter lab --generate-config
```

下記文字列を検索し、コメントアウトした上でデフォルトにしたいディレクトリを指定します。

```
c.ServerApp.root_dir = '/mnt/c/workspace'
```

## コマンド化

WSL 2 では systemd が動いていないので、JupyterLab をサービス化して自動起動しておいていつでもブラウザでアクセス、とはいきません。（サーバーならともかく WSL 2 はローカル実行するものなので、その性質上あまりすべきではない気もします）

代わりに WSL 2 でコマンド一発で JupyterLab を起動できるようにしておきます。

```alias```コマンドを使って長ったらしい JupyterLab 起動コマンドを jupyterlab というコマンドに丸め込みます。

.bashrc には .bash_aliases というエイリアス記述用のファイルが存在する場合にそれを読み込むコマンドが予め記述されている[^2]そうです。

ということで、まず .bash_aliases を作成します。

```
vim ~/.bashrc
```

コマンド定義を記述します。

```
alias jupyterlab="/home/<your-name>/miniconda3/bin/jupyter lab --no-browser"
```

最後に .bashrc を読み込みます。

```
source ~/.bashrc
```

# 終わりに

```
jupyterlab
```

WSL 2 のコンソールで上記コマンド一発で JupyterLab が立ち上がるようになりました。

# 余談

## やっておかないといけないこと

ginza のインストール時にビルドでこけて何事かと思ったらこういうことだった。

```
sudo apt install build-essential
```

## コマンドメモ

### 環境追加

Python 3.9 環境を構築する場合

```
conda create -n py39 python=3.9
```

-n 以後は自由

### Jupyter カーネル追加

```
conda activate py39
conda install notebook ipykernel
ipython kernel install --user --name=py39 --display-name=Python3.9
```

## CUDA

WSL 2 は CUDA に対応し、GPU 利用が可能です。[^3]
まだ正式リリースではありませんが、利用可能な状態が整いつつあります。

https://qiita.com/ksasaki/items/ee864abd74f95fea1efa

この記事は、Windows 環境で自作のロマンでつい搭載してしまった宝の持ち腐れとしか言いようのない GPU を機械学習用途できちんと動かせる日に向けた準備を兼ねています。

[^1]: https://qiita.com/tfukumori/items/f8fc2c53077b234384fc
[^2]: https://qiita.com/miriwo/items/0a3bce6bb04aaca6a7a6
[^3]: https://www.publickey1.jp/blog/20/wsl_2linuxguimicrosoft_build_2020.html
ScratchとPCの接続

#はじめに
scratchとmicrobitを接続するために、PCとmicrobit双方にソフトのインストールが必要であるため、その覚書です。


#手順

##1.PCにScratchLinkをインストールする

1.![スクリーンショット 2021-01-25 15.36.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/88030318-9154-48f8-0f00-b414a825f7aa.png)

##2.Microbitにドライバをインストールする(２種類)

2-1.

https://github.com/yokobond/pxt-scratch-microbit-more/releases/download/v0.5.0/microbit-pxt-scratch-microbit-more-v050.hex

2-2.

https://downloads.scratch.mit.edu/microbit/scratch-microbit.hex.zip


3.起動して、Microbitのモニターが埋まるように、上下左右に傾ける
https://www.youtube.com/watch?v=_3YZ_JBVtNs
【解決法】VScodaでconda環境が効かない場合：Mac環境 Python

こんにちは。かをるです。

Vscodaの環境でcondaが効かない場合の解決策を記載させていただきます。

ハマってしまった方の参考になれば幸いです。

詳細はブログに記載しました。
https://kaworublog.com/vscoda-conda/