OmniAICreator/Qiita-1.07M huggingface dataset:
#Rails ( ActiveRecord ) で alias / alias_method がエラーを起こすので alias_attribute を使う

# Class

```rb
class User < ApplicationRecord
  alias_attributes :some_name, :name
end
```

# run example

```rb 
User.last.name
# Alice

User.last.alias_name
# Alice
```

# Error case ( alias / alias method )

```rb

  alias foo_alias_name name
  # NameError: undefined method `name' for class `User (call 'User.connection' to establish a connection)'

  alias_method :bar_alias_name, :name
  # NameError: undefined method `name' for class `User (call 'User.connection' to establish a connection)'
``` 

# Why?

- alias / alias_method が使えないのは評価順、ActiveRercord的なメソッド生成タイミングの問題と思われる
- ActiveRecord によってメソッド生成されたあとにOpenClass すると alias をつけることも出来る様子

Open class
Before ActiveRecord Model methods occur

```rb
class User
  alias alias_name name
end
# NameError: undefined method `name' for class `User'
```

Open class
After ActiveRecord Model methods occur

```rb
User.first # Maybe ActiveRecord method occurs in this timing

class User
  alias alias_name name
end

User.first.alias_name
# => "Alice"
```




# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/3068








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
C言語　ALDS1_7_A　Rooted Trees　根付き木の表現

##問題
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_7_A&lang=ja

##コード
```c
#include <stdio.h>
#define MAX 100005
#define NIL -1


/* 左子右兄弟表現(left-child, right-sibling representation) */
typedef struct
{
    /* 親のノード */
    int parent;
    /* 子のノード */
    int left_child;
    /* 左の兄弟ノード */
    int right_sibling;
} Node;

Node Tree[MAX];
int N, Depth[MAX];

/* 出力用関数 */
void print_node(int node_point)
{
    int i, child_node;
    printf("node %d: ", node_point);
    printf("parent = %d, ", Tree[node_point].parent);
    printf("depth = %d, ", Depth[node_point]);

    if (Tree[node_point].parent == NIL)
        printf("root, ");
    else if (Tree[node_point].left_child == NIL)
        printf("leaf, ");
    else
        printf("internal node, ");

    printf("[");

    for (i = 0, child_node = Tree[node_point].left_child; child_node != NIL; i++, child_node = Tree[child_node].right_sibling)
    {
        if (i)
        {
            printf(", ");
        }
        printf("%d", child_node);
    }
    printf("]\n");
}

/* 再帰的に深さを求める */
void recursive(int node_point, int depth)
{
    Depth[node_point] = depth;
    /* 右の兄弟に同じ深さを設定 */
    if (Tree[node_point].right_sibling != NIL)
        recursive(Tree[node_point].right_sibling, depth);
    /* 最も左の子に自分の深さ+1を設定 */
    if (Tree[node_point].left_child != NIL)
        recursive(Tree[node_point].left_child, depth + 1);
}

int main(void)
{
    int i, j, N_child, node_num, child_num, left_child, right_sibling,root;
    scanf("%d", &N);

    /* treeを初期化 */
    for (i = 0; i < N; i++)
    {
        Tree[i].parent = NIL;
        Tree[i].left_child = NIL;
        Tree[i].right_sibling = NIL;
    }

    /* 格納 */
    for (i = 0; i < N; i++)
    {
        /* ノード番号と持つ子の数 */
        scanf("%d %d", &node_num, &N_child);

        /* 子の関係を格納する */
        for (j = 0; j < N_child; j++)
        {
            scanf("%d", &child_num);

            /* 
            最初の子ノードはleft_childに格納
            次からは最初の子ノードの兄弟なので、right_siblingに入れる。
             */
            if (j == 0)
                Tree[node_num].left_child = child_num;
            else
                Tree[left_child].right_sibling = child_num;

            /* 親ノードの番号を入れる */
            left_child = child_num;
            Tree[child_num].parent = node_num;
        }
    }

    /* rootノードを見つける */
    for (i = 0; i < N; i++)
        if (Tree[i].parent == NIL)
            root = i;

    /* 深さD[]に格納する */
    recursive(root, 0);

    for (i = 0; i < N; i++)
        print_node(i);

    return 0;
}
```

##ポイント
根付き木構造の情報を記録するには「左子右兄弟表現」を使う

```c
/* 左子右兄弟表現(left-child, right-sibling representation) */
typedef struct
{
    /* 親のノード */
    int parent;
    /* 子のノード */
    int left_child;
    /* 左の兄弟ノード */
    int right_sibling;
} Node;
```

変数名をわかりやすく書いて、かつ、コメントも入れた。
この問題で変なのが、node番号0が必ずしもrootノードではないというところ。
左子右兄弟表現を使えば、どの順番で値を格納しても、根付きノードになるということを伝えるためかな？


##所感
- 変数名をわかりやすいものに書き換えるだけで、理解が深まる。
- 所要時間　２時間半
YubiKey 5 NFC + Windows 10で秘密鍵管理（2020年版）

ググると古い話も出てくるのでまとめる。YubiKey 5 NFC USA-Aしか持っていないのでその他の話はしない。以下、単に「YubiKey 5」と呼ぶ。

## 前置き
* YubiKey 5には4つのスロットがあり、4種類の秘密鍵を登録できる
* YubiKey Managerで秘密鍵の生成、自己署名証明書の生成までが数クリックでできる
* このやり方だと秘密鍵そのものには一切触れられない。手に入るのは証明書と公開鍵だけ
* 秘密鍵そのものが必要な場合（バックアップを取りたい、パスフレーズを設定したいなど）は自前で作った鍵をインポートする必要がある

###  YubiKey Managerインストール＆初期設定
* [公式](https://www.yubico.com/products/services-software/download/)からYubiKey Managerを普通に落としてきてインストールする
* しばらく認識しなかったが、YubiKey Personalization Toolsをあれこれ触っていたら認識するようになった
* トップメニューから Applications > PIV と進み、まずはPINコードの設定を済ませる
* Management Keyも生成して保存しておく

## (1) YubiKey Managerで全部やる場合
### 秘密鍵生成
* 次いでCertificatesへと進む。4つのスロットがある
  * Authentication (Slot 9a)
  * Digital Sinagure (Slot 9c)
  * Key Management (Slot 9d)
  * Card Authentication (Slot 9e)
* 好きなものを選び、Generateボタンを押す
* CSRを貰っても仕方がないのでSelf-signed certificateを選択する
* アルゴリズムを選択する。スタンダードなRSA2048で良い気がする
  * YubiKey 4ではRSA 4096ビットの鍵がインポートできたという話があるが、YubiKey 5では無理っぽい
* 名前(Common Name)、証明書の有効期限を設定するとGenerateで秘密鍵が生成される

### 証明書エクスポート
* Exportボタンで証明書が書き出せる
  * 書き出せるのは証明書だけで秘密鍵には一切手を出せない

### 証明書から公開鍵を取り出す
* 証明書には公開鍵が含まれている。opensslコマンドでPEM形式の公開鍵が取り出せる

```
openssl x509 -in hoge.crt -pubkey -noout > hoge.pem
```

* PEM形式の公開鍵を（GitHubで使えるような）OpenSSH形式に変換する

```
ssh-keygen -i -f hoge.pem -m pkcs8 > hoge.pub
```

これでGitHubの[管理ページ](https://github.com/settings/keys)にも登録できる。秘密鍵が手元にないので微妙と言えば微妙。

## (2) 秘密鍵を自分で生成する場合
### 秘密鍵＆公開鍵を作る
* puttyやssh-keygenでキーを作る
  * パスフレーズを設定することが望ましいことは分かっているがユーザー体験が著しく悪化するので微妙
  * RSA 4096ビットの鍵はインポートできなかった

```
ssh-keygen -t rsa -b 2048 -C "someone@example.com" -m pem -f ./id_rsa
```

### 自己署名する
* CSRを作る
* 対話式で色々聞かれる。自分しか使わないとはいえ後で困らないようにある程度ちゃんと書いておいた方が良さげ
  * 特にCommon NameはYubiKey Managerの画面上でも表示されるので見分けが付くようにしておく

```
openssl req -new -key id_rsa > id.csr
```

* 自己署名し、秘密鍵とセットにしてPKCS#12形式に変換する
* 有効期間はご自由に

```
openssl x509 -days 3650 -req -signkey id_rsa < id.csr > id.crt
openssl pkcs12 -export -inkey id_rsa -in id.crt -out id.pfx
```

### インポート
* YubiKey Managerから適当なスロットを選んでImportをクリック
* 作成したpfxファイルをインポートする

## 使い方
ここは他の記事でも解説されているので割愛。
[Android] Google Map APIキーのセキュリティ設定

# Google Map APIキーのセキュリティ設定
以下の手順となります。

・Android StudioからSHA-1キー（フィンガープリント）を作成する。
・Google Cloud PlatformにAPI キーの制限にこのSHA-1キー（フィンガープリント）を設定する。
# Android Studio
### Android StudioからSHA-1キーを作成する
**1. Modules で Signing Config 設定する**

- Project Structureを開く 1-1
<img width="1440" alt="ss_1.1.1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618722/086ef3a6-57a0-1c30-a79b-befa44908e7e.png">

- Signing Configを設定する 1-2
<img width="954" alt="ss_1.1.2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618722/3feb2465-f5a5-a84c-9661-676fa305d897.png">

- Default Configに設定する 1-3
<img width="953" alt="ss_1.1.3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618722/25ee90c5-d391-5b66-7990-57da45d54f8f.png">


**2. SHA-1キー作る**

- プロジェクトを実行する 2-1
<img width="396" alt="ss_1.2.1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618722/b1207818-b5e5-b680-63f8-abb1a4bf580b.png">

- Gradleメニューを開く 2-2
<img width="493" alt="ss_1.2.2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618722/02807d88-1d30-3ff5-9d5d-6df99ebffd53.png">

- Gradle Tasksツリーを展開 2-3
<img width="464" alt="ss_1.2.3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618722/f24dd587-dbe5-e093-e12f-6fba44b2c964.png">

- Android - > signingReportをダブルクリック 2-4
<img width="447" alt="ss_1.2.4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618722/6de74408-1194-54ef-4e8f-ab31a15a98aa.png">

- [実行]タブにすべての情報からSHA-1キー取得 2-5
<img width="1266" alt="ss_1.2.5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618722/3fcafde2-d295-f781-c780-6626db4da389.png">

# Google Cloud Platform
### API キーの制限を設定する
**1. アプリケーションの制限に「Android アプリ」設定する**
<img width="851" alt="ss_2.1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618722/42c0e9d8-5dc0-c4a6-9c31-2fcf7d7ef717.png">

**2. Android アプリに使用を限定に項目を追加する**
デバッグのパッケージ名とSHA1キーセットとリリースのパッケージ名とSHA1キーセット両方設定する
<img width="859" alt="ss_2.2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618722/32d04431-f2ad-bf70-22bb-4ff411a7c753.png">
【Rails】date_selectを使ってみた

#学習メモです
タスクに期限を設定したくてカレンダーだと面倒なので日付選択が簡単なdate_selectを使ってみた。
#型
html.slim

```rb

    = f.date_select(:カラム名,
                    use_month_numbers: true,
                    start_year:        Date型で最初の日付,
                    end_year:          Date型で終了の日付（interger型なので+5などでつければOK）,
                    default:           何も入力しなかった場合の値,
                    date_separator:    '区切りかた')
```
#実際に書いたコード
```rb

    = f.date_select(:start_at,
                    use_month_numbers: true,
                    start_year:        Date.today.year,
                    end_year:          Date.today.year + 5,
                    default:           Date.today,
                    date_separator:    '/')
```
今paramsになにが来ているのかbinding.pryで見てみる

```rb
 <ActionController::Parameters {"utf8"=>"✓", "authenticity_token"=>"e12hjdLpjd/M5iuOGCkPaK5gZE6oR5US4HLybq1zKMNP178svzeGhjg6y2a3Fu6XnrlFuIKnkKtJgvIFqs6rkQ==", "task"=>{"name"=>"", "description"=>"", "start_at(1i)"=>"2020", "start_at(2i)"=>"2", "start_at(3i)"=>"30", "priority"=>"low", "completed"=>"doing"}, "commit"=>"Create Task", "controller"=>"tasks", "action"=>"create"} permitted: false>
```
ちゃんと"start_at(1i)"=>"2020", "start_at(2i)"=>"2", "start_at(3i)"=>"30"がきていたのでこれをsaveする。

controllerのcreateアクションで

```rb

time = Date.new(params[:task]["start_at(1i)"].to_i,params[:task]["start_at(2i)"].to_i,params[:task]["start_at(3i)"].to_i)
if time.save
  redirect_to :index
else
  render :new
end
```
これはparamsに入っているhashから要素を取り出しDateクラスの引数に入力してインスタンスを生成している。
Documentsパス取得且つConvert NSString to String,

```sample.mm
std::string datapath = "";
NSArray *paths = NSSearchPathForDirectoryInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *doucmentDirectory = paths[0];
datapath = [documentDirecotry UTF8String];
printf("%s",datapath.c_str());
```
よく使う正規表現 ～初心者編～

私が良く使う正規表現を書きます。
毎回ググってるので、ここを見ればわかるようにしたいです:relaxed:
超基本編です。書く意味もないかもしれません。練習です。

##文の先頭・お尻を指定したいとき


```ruby:文の先頭を指定
^  
```
（例） **あ**いうえお  ←**あ**が指定されるよ


```ruby:文のお尻を指定
$
```
（例） あいうえ**お**  ←**お**が指定されるよ

##任意のｎ文字を指定したいとき


```ruby:1文字を指定
.
```
（例） **あ**いうえお  ←**あ**が指定されるよ


```ruby:3文字を指定
...
```
（例） **あいう**えお  ←**あいう**が指定されるよ

##空白・改行を指定たいとき

```ruby:空白を指定
\s
```
（例） あ□いうえお  ←□が指定されるよ      ※□＝空白

```ruby:空白以外を指定
\S
```
（例） **あ**□**いうえお**  ←**あいうえお**が指定されるよ      ※□＝空白



```ruby:改行を指定
\r（CR：キャリッジリターンの場合） または、
\n（LF:ラインフィードの場合） 
```
（例） あいうえお↴   ←        ↴が指定されるよ※↴＝改行
※CR+LFの場合は\r\nとすれば指定できます。

##数字を指定したいとき


```ruby:数字を指定
\d 
```
（例） **1**あいうえお  ←**1**が指定されるよ


```ruby:数字以外を指定
\D
```
（例） 1 **あいうえお**  ←**あいうえお**が指定されるよ
SAP HANA ユーザ情報確認用SQL

```
select 
 user_name,
 CREATE_TIME,
 LAST_SUCCESSFUL_CONNECT,
 LAST_INVALID_CONNECT_ATTEMPT,
 LAST_PASSWORD_CHANGE_TIME,
 PASSWORD_CHANGE_NEEDED,
 IS_PASSWORD_LIFETIME_CHECK_ENABLED,
 USER_DEACTIVATED,
 DEACTIVATION_TIME
from users
where user_name like 'ユーザー名'
--  and (LAST_SUCCESSFUL_CONNECT is null or USER_DEACTIVATED = 'TRUE')
order by user_name
```
railsのversion確認でエラーが出た時

 ```$gem install rails -v 5.2.3
```
でinstallして

```$rails -v
```
でversion確認すると

```
Rails is not currently installed on this system. To get the latest version, simply type:

   $ sudo gem install rails
You can then rerun your "rails" command.
```

んんんん、さっきインストールしたよな？
ま、この通りやってみるか

```$sudo gem install rails
```
実行

また同じエラーが出ました

#色々試してみました

http://tomoprog.hatenablog.com/entry/2017/02/03/015936

https://qiita.com/arashida/items/ae982df5e534fd4bc97a

上を参考にさせてもらって試してみました

けど全く同じエラー

##そうだ、passを確認
```$which rails
~/.rbenv/shims/rails
```
```$which ruby
~/.rbenv/shims/rails
```

うん、全く同じ
rubyのversionを確認
```ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x86_64-darwin19]
```
出るやんどういう事？

##解決策

色々調べた結果、アプリを再起動してみた
そして
```$rails -v
```

すると

```Rails 5.2.4.1
```

結構しょうもなかったが、色々勉強させてもらった
Yarnでローカルのパッケージをaddする方法

この投稿では`yarn`コマンドで、ローカルのパッケージをインストールする方法を紹介します。

通常`yarn add`はnpmjs.comで公開されたパッケージをダウンロードしてきてインストールしますが、ここで説明するのはローカルにのみ存在する自作のライブラリを`add`する方法です。

(`npm`で同様のことをする方法は、「[npmでローカルのパッケージをinstallする方法](https://qiita.com/suin/items/c9c342f557bd885dbe06)」をご覧ください)

## やりかた

ローカルのパッケージをインストールには、単純にインストールしたいパッケージのファイルパスを`yarn add`の引数にします:

```bash
yarn add インストールしたいパッケージのパス
```

node_modulesにインストールされるパッケージをシンボリックリンクにしたい場合:

```bash
yarn add link:インストールしたいパッケージのパス
```

## ローカルパッケージをインストールする具体例

少し具体例をもとに説明します。

以下の図のように、`myapp`パッケージと`mylib`パッケージがあり、`myapp`から`mylib`を使いたい例を見てみましょう。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/b34f25db-4b8e-e872-5270-d6d29079071b.png)

`mylib`の`index.js`では、`helloWorld`変数が提供されていて、`myapp`の`main.js`でそれを使いたいとします。

このとき、`myapp`パッケージにて`yarn add ../mylib`を実行するとこれが実現します:

```
$ yarn add ../mylib

yarn add v1.22.4
info No lockfile found.
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
success Saved lockfile.
success Saved 1 new dependency.
info Direct dependencies
└─ mylib@1.0.0
info All dependencies
└─ mylib@1.0.0
✨  Done in 0.08s.
```

インストールされると、`package.json`に`mylib`への依存設定が追加されます:

```package.json
{
  "name": "myapp",
  "version": "1.0.0",
  "license": "MIT",
  "dependencies": {
    "mylib": "../mylib"
  }
}
```

`main.js`を実行してみます:

```
$ node main.js
Hello World!
```

しっかりと`mylib`の変数が使われているが分かります。

ちなみに、インストールされた`myapp/node_modules/mylib`は`mylib`をごっそりコピーしたものになります。`../../mylib`へのシンボリックリンクではないので注意です。

シンボリックリンクにしたい場合はファイルパスの頭に`link:`を付けます:

```
yarn add link:../mylib
```

---

最後までお読みくださりありがとうございました。Twitterでは、Qiitaに書かない技術ネタなどもツイートしているので、よかったらフォローお願いします:relieved:→[Twitter@suin](https://twitter.com/suin)
Androidアプリのアプリ名

#アイコンと一緒に表示されるアプリ名
/res/vales/string.xml の,
下記の名称(●●)がアプリ名として表示される。

    <string name="app_name">●●</string>

このタグ自体がない場合は、package名が表示される。

多言語対応のときはどうするんだろう?
git 過去の複数コミットのコメントを修正する

# これはなに
過去の複数のコミットのコメントを一斉に修正した際のメモ。

# 考え方
git rebase を使用して、既存のコミットを新規コミットで置き換える際に、コメントを書き換える。

# 手順
まず、修正するコミットのハッシュを調査する。

```
$ git log --first-parent <branch-name>
```
修正したいコミットの、ひとつ前のコミットのハッシュを調べる。

つぎに、git rebase を開始する。

```
$ git rebase -i <target-hash>
```
指定した hash の次以後が rebase の対象となる。
標準 editor で以下のような編集画面が開く。

```
pick d66d1fc3a feat: define placeholder at patients
pick fa93d61e7 feat: define placeholder at groups
pick 4a015ad56 wip: rem placeholder
pick 73c8ae6a4 feat: add place holder

# Rebase d860920d9..73c8ae6a4 onto d860920d9 (4 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
```

ここで、修正したいコミットの `pick` を `edit` に変更し save する。
もし行を消去すると、該当行はコミットから除外されるので注意。

`edit` と `reword` の違いについて（たしかこんな感じだった）
- `edit` は、コミット毎に amend が実行され、コメントを編集する。
- `reword` は、対象コミットのすべてのコメントを（同一の内容で）置き換える

そして、`edit` に修正したコミットの編集を開始する。
`git commit --amend` を実行する。

```
$ git commit --amend
```
コミットを編集し、save する。
つぎのコミットを編集するため、`git rebase --continue` する

```
$ git rebase --continue
```
前述と同様に、`git commit --amend`を実施する。
これを `edit` に変更した全コミット分繰り返す。
全コミットに分完了すると、` git rebase` の完了となる。

```
$ git rebase --continue
Successfully rebased and updated refs/heads/fix/10541_hoge_fuga.
```

つぎに、この変更した branch をリモート（origin）に反映する。

```
$ git push -f origin <branch-name>
```
-f オプションを付与し、強制的に更新する。
TextAssetに対応してない拡張子のファイルをInspectorで設定する

## TextAssetは拡張子が特定のものじゃないと許容してくれない

[テキストアセット ドキュメント](https://docs.unity3d.com/ja/current/Manual/class-TextAsset.html)

上記によるとTextAssetは

- .txt
- .html
- .htm
- .xml
- .bytes
- .json
- .csv
- .yaml
- .fnt

をサポートしているそうで

今回[xLua](https://github.com/Tencent/xLua)というUnityでluaを扱うライブラリのサンプルをみているとluaのファイルの拡張子を.txtにしていた。テキストエディターで開いた際に設定をしなければハイライトなどが適応されないので.luaのままで設定できた方が楽じゃね？と思ったので作ってみました

[LuaTextAsset.cs](https://gist.github.com/MizoTake/ac635dc0f83f78ad35a7fa0b4a15f448)

そこで今回作ったのが.luaを許容するEditor拡張で上のgistで公開しています

xLuaのExample/02_U3DScriptingを変えて

- LuaBehaviour.csのLuaScript変数の型をTextAsset → LuaTextAsset
- LuaTestScript.lua.txt → LuaTestScript.lua

に変更させていますが正しく動いているのがわかります(実行が遅いのは低スペックmacなのでご愛嬌)
![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127761/e299759e-40f8-7e02-40e0-1fd1aa5cec0b.gif)


### 中身

<details><summary>LuaTextAsset.cs</summary><div>

```csharp:LuaTextAsset.cs
using System;
using System.IO;
using System.Text;
using UnityEngine;
using Object = UnityEngine.Object;
#if UNITY_EDITOR
using UnityEditor;
#endif

[Serializable]
public class LuaTextAsset
{

	public const string Extension = ".lua";
	
	[SerializeField] private string path;
	
	[SerializeField] private string textString;

	[SerializeField] private string byteString;

	public string text => textString;

	public byte[] bytes => Encoding.ASCII.GetBytes(byteString);
	
	public static implicit operator TextAsset(LuaTextAsset textAsset)
	{
		return new TextAsset(textAsset.textString);
	}

	public static implicit operator LuaTextAsset(TextAsset textAsset)
	{
		return new LuaTextAsset { textString = textAsset.text };
	}
}

#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(LuaTextAsset))]
public class LuaInspectorEditor : PropertyDrawer
{
	
	public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
	{
		var path = property.FindPropertyRelative("path").stringValue;
		var loaded = AssetDatabase.LoadAssetAtPath(path, typeof(Object));
		var field = EditorGUI.ObjectField(position, label, loaded, typeof(Object), false);
		var loadPath = AssetDatabase.GetAssetPath(field);
		var fileExtension = Path.GetExtension(loadPath);
		if (field == null || fileExtension != LuaTextAsset.Extension)
		{
			property.Set("path", "");
			property.Set("textString", "");
			property.Set("byteString", "");
		}
		else
		{
			var pathProperty = property.FindPropertyRelative("path");
			property.Set("path", loadPath.Substring(loadPath.IndexOf("Assets", StringComparison.Ordinal)));
			property.Set("textString", File.ReadAllText(pathProperty.stringValue));
			property.Set("byteString", Encoding.ASCII.GetString(File.ReadAllBytes(pathProperty.stringValue)));
		}
	}
}

public static class SerializedPropertyExtension
{
	public static void Set(this SerializedProperty property, string name, string value)
	{
		var pathProperty = property.FindPropertyRelative(name);
		pathProperty.stringValue = value;
	}
}

#endif
```

</div></details>

基本的にTextAssetと互換を保ちつつ、TextAssetと同じ変数名で扱えるように設定をしています。今回はluaに限定していますが少し変えれば好きな拡張子で設定が可能になると思います。
npmでローカルのパッケージをinstallする方法

この投稿では`npm`コマンドで、ローカルのパッケージをインストールする方法を紹介します。

通常`npm intall`はnpmjs.comで公開されたパッケージをダウンロードしてきてインストールしますが、ここで説明するのはローカルにのみ存在する自作のライブラリを`install`する方法です。

(`yarn`で同様のことをする方法は、「[Yarnでローカルのパッケージをaddする方法](https://qiita.com/suin/items/409dc019de605830b4c2)」をご覧ください)

## やりかた

ローカルのパッケージをインストールには、単純にインストールしたいパッケージのファイルパスを`npm intall`の引数にします:

```bash
npm install インストールしたいパッケージのパス
```

## ローカルパッケージをインストールする具体例

少し具体例をもとに説明します。

以下の図のように、`myapp`パッケージと`mylib`パッケージがあり、`myapp`から`mylib`を使いたい例を見てみましょう。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/b34f25db-4b8e-e872-5270-d6d29079071b.png)

`mylib`の`index.js`では、`helloWorld`変数が提供されていて、`myapp`の`main.js`でそれを使いたいとします。

このとき、`myapp`パッケージにて`npm install ../mylib`を実行するとこれが実現します:

```bash
$ npm install ../mylib

+ mylib@1.0.0
added 1 package and audited 1 package in 0.74s
found 0 vulnerabilities
```

インストールされると、`package.json`に`mylib`への依存設定が追加されます:

```package.json
{
  "name": "myapp",
  "version": "1.0.0",
  "license": "MIT",
  "dependencies": {
    "mylib": "file:../mylib"
  }
}
```

`main.js`を実行してみます:

```
$ node main.js
Hello World!
```

しっかりと`mylib`の変数が使われているが分かります。

ちなみに、インストールされた`myapp/node_modules/mylib`は`../../mylib`へのシンボリックリンクになります:

```
$ ls -la myapp/node_modules
lrwxr-xr-x 11 suin 14 Apr  9:35 mylib -> ../../mylib
```
#Ruby gem install で過去のバージョンを指定するには -v オプションでバージョン指定 ( 例: gem install rubocop -v 0.77 )

# 方法

- -v でバージョン指定してインストールする
- 他のバージョンがインストールされている場合は gem uninstall <gem_name> で削除する


# 動作の例

バージョン指定してインストール

```
$ gem install rubocop -v 0.77
Successfully installed rubocop-0.77.0
Parsing documentation for rubocop-0.77.0
Done installing documentation for rubocop after 6 seconds
1 gem installed
```

バージョン確認
前に別バージョンもインストールしていたので、2個のバージョンが表示された

```
$ gem list rubocop

*** LOCAL GEMS ***

rubocop (0.81.0, 0.77.0)
```

複数バージョンがインストールされていると、新しいほうが使われそう？

```
$ rubocop -v
0.81.0
```

コマンド単位でのバージョン指定もできそうだけど

```
$ rubocop _0.77_ -v
0.77.0
```

gem use  / gem switch みたいな切り替えコマンドが見当たらない

```
$ gem
RubyGems is a sophisticated package manager for Ruby.  This is a
basic help message containing pointers to more information.

  Usage:
    gem -h/--help
    gem -v/--version
    gem command [arguments...] [options...]

  Examples:
    gem install rake
    gem list --local
    gem build package.gemspec
    gem help install

  Further help:
    gem help commands            list all 'gem' commands
    gem help examples            show some examples of usage
    gem help gem_dependencies    gem dependencies file guide
    gem help platforms           gem platforms guide
    gem help <COMMAND>           show help on COMMAND
                                   (e.g. 'gem help install')
    gem server                   present a web page at
                                 http://localhost:8808/
                                 with info about installed gems
  Further information:
    http://guides.rubygems.org
```

使わない方を uninstall する

```
$ gem uninstall rubocop

Select gem to uninstall:
 1. rubocop-0.77.0
 2. rubocop-0.81.0
 3. All versions
> 2
Successfully uninstalled rubocop-0.81.0
```

過去バージョンだけになる


```
$ gem list rubocop

*** LOCAL GEMS ***

rubocop (0.77.0)
```

過去バージョンが利用できるのがわかる

```
$ rubocop -v
0.77.0

```

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/3067








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Jetson TX2の電力モードを切り替える

Jetson TX2の電力モードをシェルから切り替えたり確認したりする方法についてのメモです。

参考 : [オフィシャル情報](https://docs.nvidia.com/jetson/archives/l4t-archived/l4t-3231/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide/power_management_tx2_32.html)

## 電力モードについて
Jetson TX2にあるいくつかの電力モードは以下のようになっています。
<img width="988" alt="jetsontx2-power-mode.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416221/5eb8f0f7-c23f-4aae-442a-65d9038883ce.jpeg">
上から
- 最大電力
- モードID
- A57 CPUの使用数
- D15 CPUの使用数
- A57 CPUの最大周波数
- D15 CPUの最大周波数
- GPUの最大周波数
- メモリの最大周波数
となっています。`MAXN`,`MAX-Q`などはそれぞれのモードの名前で、デフォルトは`MAX-P`モードになっています

## 電力モードを確認する
```
$ sudo nvpmodel -q
```
と打つと

```
NVPM WARN: fan mode is not set!
NV Power Mode: MAXP_CORE_ALL
```
などの表示が帰ってきます。

## 電力モードを変える
```
$ nvpmodel -m <Mode ID>
```
<Mode ID>には数字を入れてください。例えば`MAXN`にしたれば

```
$ nvpmodel -m 0
```

で`MAXN`になります。

##終わりに
```
NVPM WARN: fan mode is not set!
```
これの警告を解決する必要/方法がわかる方がいらっしゃいましたら教えて下さい。
jupyter-notebookでpython3が動かない

# jupyter-notebook起動

ターミナルで

```
jupyter notebook 
```

jupyter-notebookを開き、new→python3で新たにファイルを開いた。

```py
print('python')
```

を入力しても反応がなく出力されない

# ターミナルエラー確認
```
ImportError: cannot import name 'create_prompt_application'
```
`create_prompt_application`を検索すると下記の記事を見つけた。

[jupyterが動作しなかった時の対応メモ](https://qiita.com/aj1m0n/items/a4cd872fc60c51305acd)

調べていると上記エラー以外にも、jupyter-notebookが動かないエラーは様々あるみたいです。

# 解決法
一旦 jupyter-notebook を起動しているターミナルを control + C で閉じ、

prompt-toolkitをインストール

```
pip install prompt-toolkit
```

prompt-toolkitは自動補完などの便利ツールキット
[python prompt toolkitの紹介と動作を理解するメモ](https://vaaaaaanquish.hatenablog.com/entry/2019/07/06/213909)

# jupyter-notebook再起動
再度ターミナルで

```
jupyter notebook 
```

new→python3

```py
print('python')
```

無事`python`が出力された。
動的SQLと静的SQLの違いを経験２ヶ月の人がまとめたからきっと初心者でもわかり易いはず



こんにちは、しゅんです！

病院勤務からエンジニアになって2ヶ月経ちました。

仕事の流れはつかめてきましたが、

業務の中で他の職場の先輩が発する言葉の中には、知らない単語が当たり前のように、大量にでてきます。

二ヶ月経っても日々脳内はパニック状態です( ;∀;)




その都度Google先生にお世話になっていますが、

これからは合間を見つけて、noteに備忘録を残していきたいと思います。

きっと間違った解釈をしてしまっていることもあると思うので、あまりあてにしないでください。笑

間違っている箇所は、暖かくご指摘いただけると嬉しいです。




動的SQLとは？




実行するときにSQL文を作り出し実行します。

つまり、コンパイル時(作成したSQLを登録するとき？)には未完成の状態。

SQLを実行するときに、何かしらの引数を受け取って初めて完成するSQL文。

(例)

「〇〇を削除する」というSQL文　←動的SQL

実行するときに、「住所」という引数を渡すことで

「住所を削除する」という完成した文が実行される




みたいな感じですかね？

動的SQLの対義語は静的SQLというらしいです。




静的SQLのメリット

〇 性能がいい！

〇 コンパイルが正常終了した時点で、参照しているDB・オブジェクトが間違っていないこと、必要な権限があることを確かめることができます。

基本的には静的SQLを使いましょう




動的SQLのメリット

実行するまで分からない情報を反映できます。

ユーザーが入力する情報、前後の処理の結果を使用する場合など。

予めSQL文を完成することが不可能な場合に活躍するのが動的SQLです！







調べたきっかけ




今回調べることになったきっかけは、

僕がしたある質問に対して、先輩が確認するために書いてくれたクエリが意味不明だったからです。その中に動的SQLが使われていました。




質問の内容としては、

子SPを使用するSPを作成する際に、
子SPから取得したSELECT結果を直接INSERT INTOで一時テーブルに受け取れることができるのか、一時テーブルの指定したカラムに正しい順番で入るのかを
実際にSSMSで動かして確認したい、というもの。




さらさらっと書いて、「ほら、ちゃんとできるよ！」と。

かっこいい。







sp_executesqlという組み込みストアドプロシージャを使用します。

sp_executesqlを使えば、変数に格納したsqlを実行することができます。




思い出しながら、僕が作成した確認クエリはこちら。

use master

create table a (
  A int NOT NULL
 ,B int null
)

CREATE table #test(
a int 
,b int
)

INSERT INTO a
SELECT 6,7 UNION all
SELECT 8,9 

DECLARE @a nvarchar(2000)
SET @a = 'SELECT A,B FROM a'

INSERT INTO #test 
EXEC sp_executesql @a

SELECT * FROM #test




　　 a	b
-----------
１ 　6	7
２　 8	9

無事に確認できました。




さいごに

覚えることはアホほどあってきりがないけど、

確認方法さえ覚えておけば、その都度確認できるから覚える量を減らせる。

丸暗記したものは時間がたつとあいまいになるけど、
確認したものは確実。

確認方法は、他にも応用が利く。

全く別業界で1から学ぶ際のコツなのかなと思います！


〜〜

過去にnoteで書いていたやつ、Qiitaに移動しました〜
数ヶ月前ですがはるか昔のことのように感じます。。

今は入職して９ヶ月目になりました。
職場ではSQL書いたり、案件のマネジメント補佐的なことをしてます。

家ではSQL全くしておらず、
web系のフロントとバックエンドを５：５くらいの感じで勉強してます
最近ははJavaScriptの「これさえできれば何でもできる感」に魅力を感じていて
Reactとか触ってます。
時々気が向いたらそのへんの内容を更新しますね！


参考記事


sq_executesql の使い方 - 月のあかり - IT編SQLの文字列を組み合わせて作成をし、動的に発行するプログラムをVBやC#などアプリケーションで作成したことがあると思う。rezev-hikaru.hatenadiary.org


静的SQLと動的SQLitdoc.hitachi.co.jp

動的SQLのコーディングotndnld.oracle.co.jp
find: warning: you have specified the -maxdepth option after a non-option argument -type, but options are not positionalとなった時の対応方法

- 環境
    - CentOS Linux release 7.6.1810 (Core)
    - find (GNU findutils) 4.5.11

# 事象 : findに`-maxdepth`オプションをつけたらなんか注意された
```bash
$ find -type d -maxdepth 2
find: warning: you have specified the -maxdepth option after a non-option argument -type, but options are not positional (-maxdepth affects tests specified before it as well as those specified after it).  Please specify options before other arguments.

.
./.settings
./src
./src/main
./src/test
./target
./target/classes
$
```

# 原因 : オプションの指定順序を間違えているから

注意文を訳してみた。やりたい気持ちの強い順にオプションを指定すればいいわけではない。

```text:訳
find:警告:オプションではない引数-typeの後に-maxdepthオプションを指定しましたが、オプションの位置が正しくありません(-maxdepthは、前に指定されたテストと後に指定されたテストに影響します。)。他の引数の前にオプションを指定してください。
```

使い方を見てみるとちゃんと「他の式の前に指定」って書いてある。

```bash
$ find --help
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
...省略...
# normal options (always true, (訳)他の式の前に指定):
normal options (always true, specified before other expressions):
      -depth --help -maxdepth LEVELS -mindepth LEVELS -mount -noleaf
      --version -xautofs -xdev -ignore_readdir_race -noignore_readdir_race

tests (N can be +N or -N or N): -amin N -anewer FILE -atime N -cmin N
      -cnewer FILE -ctime N -empty -false -fstype TYPE -gid N -group NAME
      -ilname PATTERN -iname PATTERN -inum N -iwholename PATTERN -iregex PATTERN
      -links N -lname PATTERN -mmin N -mtime N -name PATTERN -newer FILE
      -nouser -nogroup -path PATTERN -perm [-/]MODE -regex PATTERN
      -readable -writable -executable
      -wholename PATTERN -size N[bcwkMG] -true -type [bcdpflsD] -uid N
...省略...
```

## 対応 : `-type`の前に`-maxdepth`を指定する

```bash:注意されなくなった
$ find -maxdepth 2 -type d
.
./.settings
./src
./src/main
./src/test
./target
./target/classes
```
slim4の"Hello World"で詰まった

# Step 4: Hello World
参考にしたのはこの公式ドキュメント
https://www.slimframework.com/docs/v4/start/installation.html

# 出たエラー
- "http://127.0.0.1/public/index.php" にアクセスすると、500のHTTP Error
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124948/b9f8b8d8-8244-790b-cb2f-dd94c1abec3b.png)

- エラーログを確認すると、以下のメッセージ

```
$ less /var/log/apache2/error.log
PHP Fatal error:  Uncaught Slim\\Exception\\HttpNotFoundException: Not found.
```

全文

```
$ less /var/log/apache2/error.log
[Mon Apr 13 08:14:45.967574 2020] [php7:error] [pid 12654] [client ::1:34874] PHP Fatal error:  Uncaught Slim\\Exception\\HttpNotFoundException: Not found. in /home/taro/www-data/vendor/slim/slim/Slim/Middleware/RoutingMiddleware.php:93\nStack trace:\n#0 /home/taro/www-data/vendor/slim/slim/Slim/Routing/RouteRunner.php(72): Slim\\Middleware\\RoutingMiddleware->performRouting(Object(Slim\\Psr7\\Request))\n#1 /home/taro/www-data/vendor/slim/slim/Slim/MiddlewareDispatcher.php(81): Slim\\Routing\\RouteRunner->handle(Object(Slim\\Psr7\\Request))\n#2 /home/taro/www-data/vendor/slim/slim/Slim/App.php(211): Slim\\MiddlewareDispatcher->handle(Object(Slim\\Psr7\\Request))\n#3 /home/taro/www-data/vendor/slim/slim/Slim/App.php(195): Slim\\App->handle(Object(Slim\\Psr7\\Request))\n#4 /home/taro/www-data/index.php(15): Slim\\App->run()\n#5 {main}\n  thrown in /home/taro/www-data/vendor/slim/slim/Slim/Middleware/RoutingMiddleware.php on line 93
```

# 何が悪かったか
サンプルスクリプトの10 ~ 13行目の通り、サンプルスクリプトは`/`のpathでレスポンスを待ち受けているので、"http://127.0.0.1/public/index.php" のpathではなく、"http://127.0.0.1/" のpathでアクセスする必要がある。

- 10~13行目

```php
$app->get('/', function (Request $request, Response $response, $args) {
    $response->getBody()->write("Hello world!");
    return $response;
});
```

# 解決策1
1. 以下のように"index.php"のpathを変更する
2. "index.php" の `require_once`のpathを変更する
3. "http://127.0.0.1/" にアクセスする。

```
$ ls -ltr
total 36
-rw-r--r-- 1 root www-data    17  3月 28 22:15 phpinfo.php
-rw-r--r-- 1 taro www-data    78  4月 13 08:17 composer.json
-rw-r--r-- 1 taro www-data 20193  4月 13 08:17 composer.lock
drwxr-sr-x 8 taro www-data  4096  4月 13 08:17 vendor
drwxr-sr-x 2 taro www-data  4096  4月 14 08:17 public

$ mv public/index.php ./
$ ls -ltr
total 40
-rw-r--r-- 1 root www-data    17  3月 28 22:15 phpinfo.php
-rw-r--r-- 1 taro www-data   378  4月 13 08:14 index.php
-rw-r--r-- 1 taro www-data    78  4月 13 08:17 composer.json
-rw-r--r-- 1 taro www-data 20193  4月 13 08:17 composer.lock
drwxr-sr-x 8 taro www-data  4096  4月 13 08:17 vendor
drwxr-sr-x 2 taro www-data  4096  4月 14 08:26 public
```

```diff
- require __DIR__ . '/../vendor/autoload.php';
+ require __DIR__ . '/vendor/autoload.php';
```

# 解決策2
1. DocumentRootを変更する
2. apache2をreloadして変更を反映する
3. "http://127.0.0.1/" にアクセスする。

```
$ sudo vi /etc/apache2/sites-enabled/000-default.conf
```

```diff
- DocumentRoot /home/taro/www-data
+ DocumentRoot /home/taro/www-data/public
```

```
$ systemctl apache2 reload
```

# 環境
Ubuntu 18.04
apache2

# おわりに
なんか変なエラーログが出たので、それを解決しようと変な方向に努力してしまった。

https://qiita.com/ryu19maki/items/10518cb1e306e213c2ac でやってるみたいに、

```
$ php -S localhost:8080 -t public
```
ってphpにコンテンツをServeさせた方が良かったのかもしれない。
2つの日付の月数の差分の計算

仕事で月数の差分を出す必要があったのですが、なかなかこれだっていうのが見つからなかったので書きました。

## 月数の差分を出す
baseを基準日として差分を出すための過去の日付をpastとし、どちらもDate型とします。
baseとpast共に年(year)に12を掛けて年月を月数に直してから減算し、最後に調整値を加算することで算出できます。

```Ruby
def diff_months(base, past)
  adjusted_value = base.day >= past.day ? 1 : 0
  ((base.year * 12) + base.month) - ((past.year * 12) + past.month) + adjusted_value
end
```

## 調整値について
1を足す基準が基準日の日にちが過去日の日にち以上というのは実際に例を出したほうがわかりやすいので例示します。

#### ex. 基準日を2020年3月15日、差分を出す過去日を2019年3月16日とする場合
この場合はちょうど丸1年です。なので差分は12ヶ月となってほしいです。
基準日の日にちbase.dayが15日、過去日の日にちpast.dayが16日なので調整値は0となります。

```
(24240(= 2020年*12) + 3) - (24228(= 2019年*12) +3) = 12
```

調整値が0なら12ヶ月となります。

#### ex. 基準日を2020年3月16日、差分を出す過去日を2019年3月16日とする場合
この場合は2020年の3月16日は13ヶ月目の1日目です。なので差分は13ヶ月となってほしいです。
基準日の日にちbase.dayが16日、過去日の日にちpast.dayが16日なので調整値は1となります。

```
(24240(= 2020年*12) + 3) - (24228(= 2019年*12) +3) + 1 = 13
```

以上のように基準日の日にちが差分計算に用いる過去日の日にち以上の場合は調整用に1を足す必要があります。

以上です。とにかく1を足すんだみたいに書いてあったりしたのも見かけましたが、それではうまくいかず調べていくうちにかなり腑に落ちる説明をできるようになったと思います。
【Python】Switchのアルバムをゲーム別にフォルダ分けする

# 概要

- ファイルの名前を取得し、ファイルをディレクトリ毎に仕分けする

# ゲーム、楽しんでますか？

どうも、JoyconでSplatoon2を1000時間やったのを知り合いに頭おかしいよ…と蔑まれるSotonoです。  
最近はスプラしてないんですが、他のゲームプレイしてると**スクショとか動画とか溜まってSDがパンパンになったり**してる日々です。~~新しいSD買えや~~

それではいけないな、でも消すの嫌だな…というわけでSDカードをPCにうつしてスクショを管理してるのですが、**日付別でしか分類されていない**のでちょっとこれが気に食わない…  

というわけでファイルの名前をよく見るとゲーム毎で違うIDが振り分けられているので、これを使ってゲーム別にフォルダ分けしたほうが個人的に管理が楽チンだな！

では早速やっていきましょう。

# 画像の名前の分析

Switchのアルバム内に記録されているファイル名は、だいたい次の形式になっています。

> `[日時]-[ゲームID].[拡張子]`

- 日時
    - 見たまんま、桁数が多すぎるのでコンマ秒まで記録してると思う(適当)
- ゲームID
     - 今回のメインディッシュ、ゲーム毎に違うIDが振り分けられている。
     - 体験版と製品版で違うIDが振られているのでそこは注意。
     - 別筐体で違う可能性がないとは否めないのでちゃんと確認しよう。
- 拡張子
    - 画像は`jpg`、動画は`mp4`で保存されている。

> 余談
> - Swtich内で設定されている日時を参照しているので、時間捜査とかしてるとその分だけズレるので、時間旅行勢は気をつけよう。
> - `Extra`という謎のフォルダの中はスマブラで作った動画が保存されている、これだけ保存場所変えてあるので注意。

さて、分析をしたところで**ゲーム毎に違うIDが振り分けられている**ことがわかったので、これを利用して早速仕分けをしていく。

# 仕分けをPythonで記述する

~~だって俺がPythonしか使えないし…~~

## ゲームIDとゲームタイトルを紐づけする

CSVでもなんでもいいので、`ゲームID`と`ゲームの名前`を紐づけする。  
これをしないとランダムでつけられたIDで管理する羽目になるのでそんなの分かりづらい…

というわけで、アホでズボラな僕は辞書で管理しようと思った。~~CSV回り使うのめんどくさくて…~~

```py
dict = {
    'hogehoge': 'Splatoon2',
    'fugafuga': '大乱闘スマッシュブラザーズSP',
}
```

## 仕分け本番

適当に以下のようなフォルダ階層を組み立てます

```
.
└── (任意のフォルダ名A) 
    └── sw_hogehoge(ゲームタイトル)
        ├── img
            └── ~.jpg
        └── movie
            └── ~.mp4
```

これで`※1`に、Switch内の`Album`フォルダの中身をそのまま入れれば、後は仕分けてくれるという算段で組み立てていきます。


だいたいのフローはこんな感じ。

> - Album内にある画像、動画ファイルのみを、すべてAfterフォルダに移動する
> - Afterフォルダの画像を取得し、対応するフォルダに仕分けていく
> - フォルダがなかったら新たに作成する

```py
import glob
import re
import os
import shutil

PYDIR = os.path.dirname(os.path.abspath(__file__))
INBOX = os.path.dirname(PYDIR)
INBOX_AFTER = f'{INBOX}/After'

ARCHIVE = os.path.dirname(INBOX)
MOV = '/movie'
IMG = '/img'


def main():

    # ----- AlbumからAfterへ移動
    before = f'{INBOX}/Album/????/??/??/*'
    for i in glob.glob(before):
        shutil.move(i, INBOX_AFTER)

    # ----- Afterの中を走査してゲームフォルダへ
    dir_game = ARCHIVE + '/sw_'
    dir_inbox_glob = f'{INBOX_AFTER}/*'

    for file in glob.glob(dir_inbox_glob):
        for id in fold_id.dict:
            if id in file:
                to = dir_game + fold_id.dict[id]

                # ゲームフォルダがない場合作成
                if os.path.exists(to) is False:
                    FOLD_NAMES = ('', MOV, IMG)
                    [os.mkdir(to + fold_name) for fold_name in FOLD_NAMES]

                to += MOV if '.mp4' in file else IMG
                shutil.move(file, to)


if __name__ == '__main__':
    main()

```


実行すると以下のような構成で`任意A`にフォルダが作成されます。

```
.
└── sw_hogehoge(ゲームタイトル)
    ├── img
        └── ~.jpg
    └── movie
        └── ~.mp4
```

フォルダ階層については各々で好きにカスタマイズしてください。



# キミだけの最強のスクリーンショット管理システムを作り出せ！！

というわけでSwitchでPythonのファイル管理の基礎的なところをやってみました。  
この人本当にPython仕事で2年間いじってたんですか？  
終わりです、無人島戻ります…
【Unity初心者】関数(メソッド)って何？　

#環境
Unity 2019.3.7f1

#はじめに
メソッドメソッド言われてもわかりませんよ！
と思っていた過去の自分へ向けて書きました。

メソッドは日本語でいうと関数
なかなか馴染みがない言葉ですよね。
今回は概略を説明していきます。


#関数(メソッド)とは？
関数とは**処理をまとめたもの**です。
ざっくり図にするとこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613985/9788879d-ffc0-651c-e766-9dc120a18396.png)




そして、大きくわけると次の２つに分かれます。
**・C#やUnity側であらかじめ処理内容が用意されている関数**
**・自分で処理内容を決める関数**
さらに**返り値の有無**、**引数の有無**で細分化されていきます。
下図が関数の分類と使い方になります。(イベント関数は使い方が特殊なので別で書きました。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613985/48857931-0855-704d-bda9-56cf5030dbcd.png)






全11種類です！(多いわ！)
1.用意されている関数-返り値有-引数必要
2.用意されている関数-返り値有-引数不要
3.用意されている関数-返り値無-イベント関数-引数必要
4.用意されている関数-返り値無-イベント関数-引数不要
5.用意されている関数-返り値無-引数必要
6.用意されている関数-返り値無-引数無-①
7.用意されている関数-返り値無-引数無-②
8.自作の関数-返り値有-引数有
9.自作の関数-返り値有-引数無
10.自作の関数-返り値無-引数有
11.自作の関数-返り値無-引数無


##関数を使うと具体的に何ができるの？
大分類２種類でそれぞれ説明

**C#やUnity側であらかじめ処理内容が用意されている関数**
スクリーンサイズを取得したり、変数の値をコンソールに表示したり様々なことができます。

関数の種類については非常にたくさんありますので、
詳細はkimamaさんのサイトを参考にして下さい。↓
http://kimama-up.net/unity-functions-application/



**自分で処理内容を決める関数**
if文や四則演算やfor文などの自分のやりたい処理をひとまとめにすることができます。
・何回も同じコードを書かなくて良い
・コードが見やすくなる
といったメリットがあります。

#使い方をちゃんと説明してよ
全11種類の関数の使い方、自作関数の作り方については今後記事作成していきます。
→追加しました！

【Unity初心者】関数(メソッド)説明シリーズ　その１　自作関数の作り方　
https://qiita.com/Maru60014236/items/2373c5582be82c63158f
【Unity初心者】関数(メソッド)説明シリーズ　その2　用意されている関数-返り値有り 使い方
https://qiita.com/Maru60014236/items/379635372d5ea4446c27
【Unity初心者】関数(メソッド)説明シリーズ　その3　イベント関数 使い方
https://qiita.com/Maru60014236/items/5108c8b784da66f89964
【Unity初心者】関数(メソッド)説明シリーズ　その4　用意されている関数-返り値無し 使い方
https://qiita.com/Maru60014236/items/4985a851819b5f583a2e
初心者によるプログラミング学習ログ 290日目

#100日チャレンジの290日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
290日目は、

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>290日目　2h<br>・xdデザインカンプからのサイト模写<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1249790646988095488?ref_src=twsrc%5Etfw">April 13, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
メモ：C#でregeditからコピーしたバイナリを受け取る

regeditからバイナリをコピーしてきてC#でデコードしたりするときに、クリップボードを経由できるとちょっと便利。

バイナリの編集画面からコピーすると"RegEdit_HexData"形式でクリップボードに入る。IDataObject経由で取り出して、GetFormatsでこのフォーマットが含まれているか確認して、GetDataで取り出す。取り出したデータはMemoryStreamなので、キャストしてバッファにコピーする。
今回は全体を取り出したが、バッファの先頭4バイトに32bitLEで長さが入っているらしいので、最初に4バイト取り出して長さを得る、もしくは最初の4バイトを読み捨てる、といった処理をやっても良さそう。

```c#
const string format = "RegEdit_HexData";

IDataObject clipboardObj = Clipboard.GetDataObject();

if (!clipboardObj.GetFormats().Contains(format))
{ throw new Exception("ひたいおうのけいしき！！"); }

byte[] buff;

using (MemoryStream ms = (MemoryStream)clipboardObj.GetData(format))
{
    buff = new byte[ms.Length];
    ms.Read(buff, 0, buff.Length);
}

int length = BitConverter.ToInt32(buff, 0);
```

そもそもMicrosoft.Win32.Registry使えって話なんだが(結局それ経由で取り出すようにしたのでClipboard経由は不要になったんだが、せっかく方法を調べたので捨てるにしのびなくメモ)。
FirebaseでcollectionGroupを使う際の注意

いや、Firebase便利ですね。
さて、SubCollectionで結構悩んだので備忘録です

## 最初に
* typescript使ってます。
* Firebaseのインストールとかはここでは触れません

## データ構造
```
channels
|
+- events(Sub Collection）
   +- event1
   +- event2
   +- event3
   ...続く
```

channelはこのような構造を持ちます

```typescript
{
  id: string, // doc.idと同じ
  status: "active" | "inactive",
  name: string
}
```
eventはこのような感じにしました。

```typescript
{
  id: string, // doc.idと同じ
  status: "open" | "close" | "draft",
  name: string
}
```
...まぁほぼ同じですが

TOPページにイベント一覧を表示させたいですね。
ここで様々なチャンネルが有るわけですが、こういう時にCollection Groupが便利です。

```typescript

firebase
  .firestore()
  .collectionGroup("events")
  .where("status" "==", "open")
  .limit(20)
  .get()
```
Rulesはこんな感じです

```
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{path=**}/events/{event} {
      allow list: if resource.data.status == "open";
    }
    match /channels/{channel} {
      allow list, get: if resource.data.status == "active";
      match /events/{event} {
        allow list, get:
          if resource.data.status == "open"
          && get(/databases/{database}/documents/channels/{channel}).data.status == "active"
      }
    }
  }
}
```

## 望む機能
```
channels [x]inactiveの場合
|
+- events(SubCollection）
   +- event1 [x]表示できない 
   +- event2 [x]表示できない
   +- event3 [x]表示できない
   ...続く
```

さて、ここで一つ問題があります。
statusが"inactive"の場合でもchannelのeventドキュメントがcollectionGroup経由で取得できてしまいます。


良い方法ご存じの方教えて下さい(ToT/
Microsoft Teams | 10分でできる Microsoft Teams を使った授業 | Microsoft Teams の仕様

関連記事は[**「Microsoft Teams の授業での活用」**](https://qiita.com/hisaho/items/12837a169bd6f1d90d5c)をご参照ください。

#はじめに
この記事では、Teams に適用される制限、仕様、およびその他の要件について解説します。

# Teams とチャネル
|機能|上限|
|---|---|
|ユーザーが作成できるチームの数|オブジェクト制限 250¹|
|ユーザーがメンバーの一員になることができるチームの数|1,000|
|チームのメンバーの数|5,000|
|チーム 1 つあたりの所有者数|100|
|テナントで許可されている組織全体のチームの数|5|
|組織全体のチームのメンバーの数|5,000|
|グローバル管理者を作成できるチームの数|500,000|
|Office 365 テナントが持てるチームの数|500,000<sup>2</sup>|
|チームごとのチャネル数|200 (削除されたチャネルを含む)<sup>3</sup>|
|チームごとのプライベートチャネル数|30|
|チャネル会話の投稿サイズ|投稿ごとに約 28KB<sup>4</sup>|
<sup>1</sup> Azure Active Directory の任意のディレクトリ オブジェクトは、この制限にカウントされます。 グローバル管理者は、アプリケーションのアクセス許可を使用して Microsoft Graph を呼び出すアプリと同様に、この制限から除外されます。
<sup>2</sup> この制限には、アーカイブ済みのチームが含まれます。
<sup>3</sup> 削除したチャネルは、30 日以内であれば復元できます。 この 30 日間、削除されたチャンネルはチームごとの制限である 200 チャンネルとしてカウントされ続けます。 30 日を経過すると、削除されたチャネルとそのコンテンツは完全に削除され、チャンネルはチームごとの制限である 200 チャンネルとしてカウントされなくなります。
<sup>4</sup> 28 KBは、メッセージ自体 （テキスト、画像リンクなど）、@メンション、コネクタの数、およびリアクションを含むため、おおよその制限です。

#メッセージ
##チャット
Teams のチャット リストの一部である会話に参加したユーザーは、管理者がチャットの会話を検索するための Exchange Online (クラウドベース) メールボックスを持っている必要があります。 これは、チャット リストの一部である会話が、チャット参加者のクラウドベースのメールボックスに保存されるためです。 チャット参加者が Exchange Online メールボックスを持っていない場合、管理者はチャットの会話を検索または保留することはできません。 たとえば、Exchange ハイブリッド展開では、オンプレミスのメールボックスを持つユーザーは、Teams のチャットリストの一部である会話に参加できる場合があります。 ただし、この例では、ユーザーがクラウド ベースのメールボックスを持っていないために、これらの会話のコンテンツを検索できないし、保留することもできません。
Teams チャットは、Microsoft Exchange のバックエンドで動作するため、Teams 内のチャット機能に Exchange メッセージングの制限が適用されます。

|機能|上限|
|---|---|
|プライベート チャットに参加できるユーザー数<sup>1</sup>|100|
|添付ファイルの数<sup>2</sup>|10|
|チャットのサイズ|投稿ごとに約 28 KB<sup>3</sup>|

<sup>1</sup> チャットに 20 人以上いる場合、次のチャット機能は無効になります。Outlook の自動応答と Teams 状態メッセージ、入力インジケーター、ビデオおよび音声通話、共有、開封確認。
<sup>2</sup> 添付ファイルの数がこの制限を超えると、エラー メッセージが表示されます。
<sup>3</sup> 28 KBは、メッセージ自体 （テキスト、画像リンクなど）、@メンション、およびリアクションを含むため、おおよその制限です。

##電子メールでチャネルを送信する
ユーザーが Teams のチャネルにメールを送信する場合、チャネルのメール アドレスを使用します。 メールがチャネルの一部の場合、誰でもそれに返信して会話を開始できます。 チャネルにメールを送信するための適用可能な制限の一部を次に示します。

|機能|上限|
|---|---|
|メッセージ サイズ<sup>1</sup>|24 KB|
|添付ファイルの数<sup>2</sup>|20|
|各添付ファイルのサイズ|10 MB 未満|
|インライン画像の数<sup>2</sup>|50|
<sup>1</sup> メッセージがこの制限を超えると、プレビュー メッセージが生成され、ユーザーは提供されたリンクから元のメールをダウンロードして表示するように求められます。
<sup>2</sup> 添付ファイルまたは画像の数がこの制限を超えると、エラー メッセージが表示されます。
LINE BOTで位置情報を使って天気予報を取得する

railsで位置情報で天気予報を取得できるBOTを作成したので、APIの搭載の仕方をご紹介します。今回はXML形式で取得した場合です。

LINEBOTの作り方はこちらを参照いたしました。
https://qiita.com/takashico/items/edb6050a8e54dd137148

apiはこちらから取得いたしました。
https://openweathermap.org/

apiの搭載はこちらの記事を参考にいたしました。
https://yoheikoga.github.io/2016/08/14/weather-in-the-area-now-on-by-gps-module/
http://tokin-kame.hatenablog.com/entry/2015/05/31/105245


## ライブラリーを記載
controller.rb

```rb

  require 'line/bot'
  require 'open-uri'
  require 'kconv'
  require 'rexml/document'
```

## XMLファイルから必要なものを取得

URLからXMLを取得しパースしていきます。
OpenWeatherMapは属性の中に必要な情報が記載されていたため、情報の取得に苦労しました。
API KEYは環境変数にセットしましょう。

controller.rb

```rb

# 省略
      when Line::Bot::Event::Message
        case event.type
        when Line::Bot::Event::MessageType::Location
　　　　　　# LINEの位置情報から緯度経度を取得
          latitude = event.message['latitude']
          longitude = event.message['longitude']
          appId = "取得したAPI KEY"
          url= "http://api.openweathermap.org/data/2.5/forecast?lon=#{longitude}&lat=#{latitude}&APPID=#{appId}&units=metric&mode=xml"
         # XMLをパースしていく
          xml  = open( url ).read.toutf8
          doc = REXML::Document.new(xml)
          xpath = 'weatherdata/forecast/time[1]/'
          nowWearther = doc.elements[xpath + 'symbol'].attributes['name']
          nowTemp = doc.elements[xpath + 'temperature'].attributes['value']
          case nowWearther
　　　　　# 条件が一致した場合、メッセージを返す処理。絵文字も入れています。
          when /.*(clear sky|few clouds).*/
            push = "現在地の天気は晴れです\u{2600}\n\n現在の気温は#{nowTemp}℃です\u{1F321}"
          when /.*(scattered clouds|broken clouds|overcast clouds).*/
            push = "現在地の天気は曇りです\u{2601}\n\n現在の気温は#{nowTemp}℃です\u{1F321}"
          when /.*(rain|thunderstorm|drizzle).*/
            push = "現在地の天気は雨です\u{2614}\n\n現在の気温は#{nowTemp}℃です\u{1F321}"
          when /.*(snow).*/
            push = "現在地の天気は雪です\u{2744}\n\n現在の気温は#{nowTemp}℃です\u{1F321}"
          when /.*(fog|mist|Haze).*/
            push = "現在地では霧が発生しています\u{1F32B}\n\n現在の気温は#{nowTemp}℃です\u{1F321}"
          else
            push = "現在地では何かが発生していますが、\nご自身でお確かめください。\u{1F605}\n\n現在の気温は#{nowTemp}℃です\u{1F321}"
          end
      }
# 省略
```
## 最後に
OpenWeahterMapは降水確率がないので、簡易的な天気予報しか作れませんでした。もう少し精度の高い天気予報APIが欲しいですが、おそらく有料になってくると思います。
LINE BOTは一度形ができてしまえば、意外と簡単に作ることができました。
ぜひ、皆さんもオリジナルボット作り試してみてください。
画像有り投稿を検索する(画像有フィルター)

#実装したいこと
画像が投稿されている投稿に絞って一覧表示できるようにします。(imageカラムの中身が存在するレコード一覧を取ってくる)

#indexページ
indexページの適当な場所に以下を追記します。

```tweets/index.html.erb
  <%= form_tag({controller:"tweets",action:"index"}, method: :get) do %>
  画像有りフィルター<%= radio_button_tag("image", "image") %>
  <%= submit_tag '🔎'  %>
  <% end %>
```

これは以下のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614347/d7d267c3-d629-f7cb-2125-2755cf839015.png)

ラジオボタンをクリックして、送信すると、tweetsコントローラーのindexアクションに「image」というパラメーターが送られます。それを、コントローラーにて後述のような処理をすることで、画像有り投稿の一覧を取得し表示できます。

#コントローラー
tweetsコントローラーのindexアクションに以下のように書きます。

```tweets_controller.rb
def index
  if params[:image]
     @tweets = Tweet.where.not(image: nil)
  else
     @tweets = Tweet.all
  end
end
```
ややこしいですが、**imageカラムの中身が存在しないもの以外のレコード**を取ってこいという命令になってます。(カラムの中身が存在するものを取ってこいというストレートな書き方の情報が、意外と見当たらないんですよね～)

また、検索機能などと組み合わせる場合は、if文が入れ子になります。もしくは、あまりおすすめしませんが、検索機能付きのif文の下に追記する形でも問題なく動くっちゃ動きます。
以下参考

```tweets_contoroller.rb
def index
    if params[:search]
      @tweets = Tweet.where("content LIKE ? ",'%' + params[:search] + '%')
    else
      @tweets= Tweet.all
    end

    if params[:image]
        @tweets = Tweet.where.not(image: nil)
    end
end
```
Djangoの管理サイトでオブジェクトを追加する際に保存前処理を追加する方法

## 開発環境
- Python 3.7.3
- Django 3.0.5

※Class-Basedで開発していきます。

## models.py

```python:models.py
from django.db import models


class Word(models.Model):
    """単語モデル"""

    word = models.CharField(max_length=15, unique=True)
    # 文字数フィールド
    word_count = models.PositiveSmallIntegerField(blank=True, null=True)

    def __str__(self):
        return self.word

```

## admin.py

```python:admin.py
from django.contrib import admin

from .models import Word


class WordAdmin(admin.ModelAdmin):

    # save_model関数をオーバーライド
    def save_model(self, request, obj, form, change):
        word = obj.word  # wordフィールドの入力値

        # word_count
        word_count = len(word)

        obj.word_count = word_count
        obj.save()  # オブジェクトを保存


# モデルとsave_model関数を指定
admin.site.register(Word, WordAdmin)

```

## 完成！
これで、管理サイトでオブジェクトを追加・更新する際に、指定した事前処理が実行されます。
Pythonでひらがなをローマ字に変換する（ベータ版）

## 最初に
PyKakasiという日本語→ローマ字変換モジュールがあるので、忙しい方はそちらの導入をオススメします。

- 自分で書いてみたい！
- モジュール使うほどのものではない
- 後々自分でカスタムしたい

という方向けの記事です。

## 開発環境
- Python 3.7.3

## コード

```python:chars_dict.py
hiragana = {

    # vowel
    'あ': 'a',
    'い': 'i',
    'う': 'u',
    'え': 'e',
    'お': 'o',

    # consonant K
    'か': 'ka',
    'き': 'ki',
    'く': 'ku',
    'け': 'ke',
    'こ': 'ko',

    # consonant K"
    'が': 'ga',
    'ぎ': 'gi',
    'ぐ': 'gu',
    'げ': 'ge',
    'ご': 'go',
    
    ...

}

```

```python:main.py
from .chars_dict import hiragana as dict


def hiragana_to_romaji(hiragana):
    romaji = ''
    for char in hiragana:
        if char in dict:
            romaji += dict[char] + '-'
        else:
            romaji = 'ERROR_'
            break
    romaji = romaji[:-1]

    return romaji


hiragana = input()
romaji = hiragana_to_romaji(hiragana)
print(romaji)

```

```bash:run
こんにちは  # hiragana = input()
ko-n-ni-chi-ha  # print(romaji)

こんにちは世界  # hiragana = input()
ERROR  # print(romaji)
```

## 改善すべき点
- ひらがなとローマ字の対称データを事前に辞書型で書く必要があるのでそれを改善
- 小文字（っ, ゃ など）が含まれる場合の処理をまだ書いていない（ちょいめんどい）
- カタカナにも対応してない（辞書データを追加すれば解決）