OmniAICreator/Qiita-1.07M huggingface dataset:
Pythonでesa.ioのAPIを触る

# はじめに
ドキュメント共有サービスであるesa.ioではAPIを公開していて、APIを通して記事やコメントの取得や作成、スターをつけたりけしたり等広くesa.ioの機能を利用できます。

今回は、pythonでesa.ioのAPIを触ってみましょう！

# インストール
pythonで作成されたesa APIのクライアントライブラリを利用して、APIにアクセスします。
ライブラリ: [piyo](https://github.com/argonism/piyo)

``` shell
pip install piyo
```

# APIを叩いてみる

とりあえず、クライアントをnewします。
`<access_token>`と`<team_name>`は自分のアクセストークンとチーム名に置き換えてください。
Clientにアクセストークンを渡す代わりに、環境変数のESA_ACCESS_TOKENにアクセストークンをセットしても大丈夫です。

``` python3
from piyo import Client

def main():
    client = Client(access_token='<access_token>', current_team='<team_name>')

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

後はclientのメソッドから、各種エンドポイントにアクセスできます。
今回は基本的な使い方の確認が目的なので、一部の機能のみ紹介します。

## 記事一覧

``` python3
    posts = client.posts()
    print(posts)
    # => {'posts':[...] 'prev_page': None, 'next_page': 2, 'total_count': 134, 'page': 1, 'per_page': 20, 'max_per_page': 100}
```

## 記事詳細情報

``` python3
    post = client.post(1)
    print(post)
    # => {'number': 1, 'name': 'README.md', 'full_name': 'README.md', 'wip': False, 'body_md': ... }
```

## 記事作成
``` python3
    post = client.create_post({"post": {"name": "hi!"}})
    print(post)
    # => {'number': 2031, 'name': 'hi!', 'full_name': 'hi!', 'wip': True, 'body_md': '', ...
```

## 記事更新
``` python3
    post = client.update_post(post["number"], {"post": {"name": "updated test"}})
    print(post["name"])
    # => updated test
```

## 記事削除
``` python3
    post = client.create_post({"post": {"name": "test"}})
    client.delete_post(post["number"])
    # => None
```

## スター関連
``` python3
    # 記事にスターをつける
    post = client.add_post_star(2007)
    print(post)
    # => None

    # 記事にスターをつけた人一覧
    stargazers = client.post_stargazers(2007)
    print(stargazers)
    # => {'stargazers': [{'created_at': ..., 'body': None, 'user': {'myself': True, ...

    # 記事につけたスターを取り消す
    client.delete_post_star(2007)
    # 記事にスターをつけた人一覧
    stargazers = client.post_stargazers(2007)
    print(stargazers)
    # => {'stargazers': [], 'prev_page': None, ...
```

## チーム関連
``` python3
    # チームの情報を取得する
    team = client.team()
    print(team)
    # => {'name': '...', 'privacy': 'closed', ...

    # メンバーの一覧を取得する
    members = client.members()
    print(members)
    # => 'members': [{'myself': False, 'name': ...
```

# 最後に

快適なesaライフを！
ターミナル起動時に/Users/ユーザー名/.zshrc:1: command not found: rbenvと表示されるのを消しさる

ホームフォルダーの隠しファイル.zshrcを開く

　eval "$(rbenv init -)"
　export PATH="/usr/local/opt/~

を全て消して上書き保存

私はこれで表示されなくなりました。


参考にした記事
https://teratail.com/questions/272063
.vue ファイルで css をインポートすると scoped が効かない問題

# 困ったこと
.vue ファイルの `<style>` タグで下記のように css ファイルを読み込むと、`scoped` を指定しているにも関わらず、sample1.css のスタイルが全ファイルに適用されてしまいました。

```vue
<style scoped>
@import '../styles/sample1.css';
</style>
```

# 原因は今のところ分からず
[同じ現象で困っている人は他にもいる](https://forum.vuejs.org/t/import-style-file-doesnt-scoped/7479)ようですが、原因までは辿り着けず。誰か分かる方がいたら教えて頂けると幸いです。

## 追記 2021/10/20

@felis さんが詳しくコメントしてくれました。ありがとうございました。

>前提として、HTMLのスコープ付きCSSは実験的に実装された後、廃止されています。
>vue（vue-loader）ではコンパイル時に属性を追記する変換を行う事でスコープ付きCSSの動作を疑似的に再現する仕組みです。
>
>\<style scoped>の中に定義されたCSSはプリプロセッサによってスコープ付きCSSに書き換えられます。
>この時、src属性で読み込ませたCSSファイルは\<style>要素の中に展開されてから処理されるようです。
>@import命令による別ファイルの読み込みはCSS自体の仕様でありWebブラウザが解釈するのでプリプロセッサでは関知しません。
>（SASS/SCSSではすべてがコンパイラの処理対象なので\@importの先もスコープ内に展開したかの様に処理されます）
>
>スコープ付きCSS - vue-loader

# とりあえず解決方法
次のようにすれば解決するということが分かりました。

## その１： SCSS ファイルに置き換える
`lang="scss"` を指定して、css ファイルを scss にリネームすると正しく動きます。

```vue
<style lang="scss" scoped>
@import '../styles/sample1.scss';
</style>
```

## その２： `src=xxx` で読み込む
`<style>`タグで `src=cssファイル名`を指定して読み込む。

```vue
<style src="../styles/sample1.css" scoped>
</style>
```
Twitter検索コマンド

#### 検索
###### AND検索（スペース区切り）
``` aaa bbb ```

###### OR検索
``` aaa OR bbb ```

###### 完全一致検索
``` "aaa bbb" ```

###### ハッシュタグ検索
``` #hashtag ```

#### 特定アカウントの検索
###### {Twitter ID}へのツイートを検索
``` @{Twitter ID} ```

###### {Twitter ID}からのツイートを検索
```from:{Twitter ID}```

###### {Twitter ID}への返信を検索
``` to:{Twitter ID} ```

#### 言語の指定
###### 日本語だけ
``` lang:ja ```

###### ※英語だけ
``` lang:en ```

#### 期間の指定
###### いつからのツイート？
``` since:YYYY-MM-DD ```

###### いつまでのツイート？
``` until:YYYY-MM-DD ```

#### 最小値の指定
###### {n}以上のいいねがあるツイート
``` min_faves:{n} ```

###### {n}以上のRTがあるツイート
``` min_retreets:{n} ```

###### {n}以上の返信（リプライ）があるツイート
``` min_replies:{n} ```

#### フィルター
###### リプライのみ
``` filter:replies ```

###### フォロワーのみ
``` filter:follows ```

###### 認証アカウントのみ
``` filter:verified ```

###### スペース
``` filter:spaces ```

###### 画像あり
``` filter:images ```

###### 動画あり
``` filter:videos ```

###### リンク付き
``` filter:links ```

#### 除外
###### キーワードを除外({abc})
``` -{abc} ```

###### 特定ユーザーを除外
``` -{Twitter Id} ```

###### 認証アカウントのみ
``` -filter:verified ```

###### 画像あり
``` -filter:images ```

###### 動画あり
``` -filter:videos ```

###### リンク付き
``` -filter:links ```


#### 応用例
###### 例 {Twitter ID}の2021年9月の投稿
``` from:{Twitter ID}  since:2021-09-01  until:2021-09-30 ```


#### 参考
https://developer.twitter.com/en/docs/twitter-api/v1/rules-and-filtering/search-operators
Windows11のWinPEのメモ

＊ほぼただのメモですので。

Windows11ベースのWindows ADKは以前から配布されていますね。ネット上でもこれで早速作ったって人は私は見ていないな...ちなみに私はAMD64(x86_64)で作成→virtualboxで起動、だけは試しています。

ADKを見ていて思ったこと。
・なぜかx86のPEも作成できる。Win11は32bit版ないはずなのに...
・そして、BIOSブートもできる。Win11はUEFI起動だけのはずなのに...

まぁ実際作るときはほぼAMD64のUEFIブート(Boot\bootfix.binだっけ？を抜いてイメージ作成するとUEFI強制になる)でしょうね。
Azure ExpressRouteプライベート接続で痛い目を見た

# はじめに
AzureとオンプレミスをExpressRouteのプライベート接続で通信検証を実施した際に、オンプレミスと通信ができなかった事象が発生しました。
そこで何が原因であるかを紐解いてたどり着いた話を書いております。

# 前提
以下のリソースは設定済みとしております。
【Azure】
・ExpressRoute回線
・仮想ネットワークゲートウェイ
・接続

# 構成
・VNet1：172.16.0.0/16
・VNet2：10.0.0.0/24
・オンプレミス：17.16.50.0/24

![express.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1206533/f680c090-6eac-5a60-3f86-ed11d88315ae.png)




#何があったか
まず大前提としてネットワーク重複していることはわかった上で検証していました。
オンプレミスとの通信はルーティングのロンゲストマッチで問題ないであろう、という固定概念ですね。

この構成でオンプレミスのサーバーからAzure VMにping疎通できませんでした。
Azure VMからオンプレミスのサーバ宛ても当然疎通できません。

まず通信に影響が出そうな箇所を確認してみます。

+ オンプレミスのサーバ側のルート情報は問題なし（デフォルトルートのNext-hopはL3SW）
+ NW機器とExpressRoute間のBGPネイバーも問題なし
+ NW機器側のルートテーブルにもAzure VNetのルートがあるので問題なし
+ Azureへオンプレミスのルート広報も問題なし
+ ネットワークセキュリテグループも制限していないので問題なし

どこまでping疎通できているかわからない。
ということで、Azure VM側でtcpdumpを打って確認してみました。

```
root@DEVLINUX:~# tcpdump src host 10.0.0.5 | grep ICMP
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
07:16:30.468597 IP devlinux.internal.cloudapp.net > 172.16.50.10: ICMP echo reply, id 6220, seq 1, length 64
07:16:31.468175 IP devlinux.internal.cloudapp.net > 172.16.50.10: ICMP echo reply, id 6220, seq 2, length 64
07:16:32.468155 IP devlinux.internal.cloudapp.net > 172.16.50.10: ICMP echo reply, id 6220, seq 3, length 64
07:16:33.468032 IP devlinux.internal.cloudapp.net > 172.16.50.10: ICMP echo reply, id 6220, seq 4, length 64
07:16:34.467977 IP devlinux.internal.cloudapp.net > 172.16.50.10: ICMP echo reply, id 6220, seq 5, length 64
```


echo replyは返しているのに、オンプレミスのサーバには返されていない・・・
一応、VNetピアリングを削除してみました。ここは関係ないよな・・・

**ぎゃー！！ping通った！！**




# 結論
答えはココにありました。

>注意
仮想ネットワーク、仮想ネットワークのピアリング、または仮想ネットワーク サービス エンドポイントに関連したトラフィックに使用されるシステム ルートは、BGP のルートの方が具体的であったとしても、優先されるルートとなります。

https://docs.microsoft.com/ja-jp/azure/virtual-network/virtual-networks-udr-overview#how-azure-selects-a-route



AzureではBGPで広報された具体的なルート情報があってもVNetピアリング側を優先するとのことです。
重複したネットワークでもルーティングのロンゲストマッチングでオンプレミス側に通信できるだろうと甘い考えで検証をした結果、痛い目を見ました。


# AWSの挙動は？
AWSの場合はロンゲストマッチとなったルートが参照されるみたいです。
そのため、VPCピアリング接続しているVPCとDirectConnect接続の場合は今回の事象は発生しなかったということですね。

>仮想プライベートゲートウェイを VPC にアタッチし、サブネットルートテーブルでルート伝達を有効にしている場合は、Site-to-Site VPN 接続を表すルートが伝達済みルートとしてルートテーブルに自動的に表示されます。伝達されたルートが静的ルートと重複し、最長プレフィクス一致を適用できない場合、伝達されたルートよりも静的ルートが優先されます。

https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/VPC_Route_Tables.html



# 回避方法の模索
一応、回避できるか方法を探ってみました。
カスタムルートテーブルを作成して、ユーザ定義でオンプレミスのルートをオーバーライドしてしまう方法をまず思い浮かんだ。
ドキュメントを参照してみると・・・

>[仮想ネットワーク ゲートウェイ] :特定のアドレス プレフィックス宛てのトラフィックを仮想ネットワーク ゲートウェイにルーティングする場合に指定します。 種類が VPN の仮想ネットワーク ゲートウェイを作成する必要があります。 ExpressRoute では、カスタム ルートに BGP を使用する必要があるため、種類が ExpressRoute として作成された仮想ネットワーク ゲートウェイをユーザー定義ルートで指定することはできません。

https://docs.microsoft.com/ja-jp/azure/virtual-network/virtual-networks-udr-overview

はい、ダメでした。
ExpressRouteで使用の仮想ネットワークゲートウェイは、ユーザー定義ルートで指定できません。
ちなみにですが、ユーザ定義でオンプレミスのルートを仮想ネットワークゲートウェイに向けた設定を入れてみましたが、通信できませんでした。


AWSでもAzureでもネットワーク重複しないのが一番ということですね。（当たり前）
Discord Botがエラーを吐いたときにエラーIDを発行して通知する その2

Discord Botでエラーが発生したときにコンソールをわざわざ見に行くの、めんどくさいですよね？
エラーが発生したときにユーザーにその旨を通知したいですよね？
IDを振って管理したいですよね？
__*それならコーデディングだ！*__
## しくみ
#### エラー発生時
1. on_command_errorでエラーを拾う
2. そのエラーに関する情報を専用のチャンネルに送信する
3. そのメッセージのIDを36進数に変換
4. 変換したIDをつけてエラー情報を実行者に返す

#### エラー情報取得時
1. 36進数のIDを10進数に直す
2. 直したIDを用いてエラー情報を取得し、そのメッセージのembedをそのまま送信する

こんな感じで。

## れっつこーでぃんぐ！

numpyとtracebackをインポートしておいてください。

```py
@bot.event
async def on_command_error(ctx, error):
    if isinstance(error, commands.CommandNotFound):
        await ctx.send(discord.Embed(title="エラーが発生しました", description="そのコマンドは見つかりませんでした。ごめんなさい。"))
    elif isinstance(error, commands.NotOwner):
        await ctx.send(discord.Embed(title="エラーが発生しました", description="そのコマンドは見つかりませんでした。ごめんなさい。")) # 私は隠したいから..
    elif isinstance(error, commands.MissingRequiredArgument):
        await ctx.send(discord.Embed(title="エラーが発生しました", description="パラメータが不足しています。ヘルプコマンドなどで確認してください。"))
    elif isinstance(error, commands.CommandOnCooldown):
        await ctx.send(discord.Embed(title="エラーが発生しました", description=f"現在クールダウン中です...\nあと{error.retry_after}秒後に再試行してください。"))
    else:
        ch = 123456789 # エラー情報を送信するチャンネル
        embed = discord.Embed(title="エラー情報", description="")
        embed.add_field(name="エラー発生サーバー名", value=ctx.guild.name, inline=False)
        embed.add_field(name="エラー発生サーバーID", value=ctx.guild.id, inline=False)
        embed.add_field(name="エラー発生ユーザー名", value=ctx.author.name, inline=False)
        embed.add_field(name="エラー発生ユーザーID", value=ctx.author.id, inline=False)
        embed.add_field(name="エラー発生コマンド", value=ctx.message.content, inline=False)

        t = f"```py\n{''.join(traceback.TracebackException.from_exception(error))}```"
        embed.add_field(name="発生エラー", value=t if len(t < 2048) else f"```py\n{error}\n```", inline=False)

        m = await bot.get_channel(ch).send(embed=embed)
        await ctx.send(discord.Embed(title="エラーが発生しました", description="何らかのエラーが発生しました。ごめんなさい。\nこのエラーについて問い合わせるときは下記のエラーIDも一緒にお知らせください").set_footer(text=numpy.base_repr(m.id), 36))
```

```py
@bot.command()
@commands.is_owner()
async def get_error(ctx, error_id):
    await ctx.send(embed=(await bot.get_channel(123456789).fetch_message(int(error_id, 36))).embeds[0])
```

もし、[以前書いた記事](https://qiita.com/jun50/items/546f61f371087fe58a5b)と共存させたい場合、

```py
await ctx.send(discord.Embed(title="エラーが発生しました", description="何らかのエラーが発生しました。ごめんなさい。\nこのエラーについて問い合わせるときは下記のエラーIDも一緒にお知らせください").set_footer(text="A" + numpy.base_repr(m.id), 36))
```
例えばこのようにIDの前にAをつけて区別します。

```py
await ctx.send(embed=(await bot.get_channel(123456789).fetch_message(int(error_id[1:], 36) if error_id.startswith("A") else int(error_id))).embeds[0])
```

情報を取得するときはIDがAから始まっていればAを削除したIDを10進数に変換し、Aから始まっていなければ単純にint型に変換してメッセージを取得します。

## p.s.
[以前書いた記事](https://qiita.com/jun50/items/546f61f371087fe58a5b)が今見るとちょっと初心者の方などに申し訳ないなという記事だったのでこの記事を書きました。
だけど、ちょっと難易度上がってしまった...かも？
LANG環境変数（文字コード）を変更する

###シェルの文字コードを変更する
```
# 日本語表記にする
export LANG=ja_JP.utf8

# 英語表記にする
export LANG=C
```
###SQLPLUSの文字コードを変更する
```
※oracleユーザーで以下を実行する

# UTF8にする
export NLS_LANG=Japanese_Japan.AL32UTF8

# SJISにする
export NLS_LANG=Japanese_Japan.JA16SJISTILDE
```
※exportをつけなくてもよいが、子プロセスまで反映させたい場合はexportをつける。
※再起動しても設定を保持したい場合は「.bash」か「.bash_profile」にこれを追記する
【個人開発】新旧漢字コンバートAPIを作成しました。

# 概要
* 旧漢字もしくは旧漢字がある漢字を受け取り、文字列を置換して返すAPI

例) 蛍柄の螢光灯

|No| 説明       |  返値      |
|:------------------:|-------------------|-------------------|
|1|新漢字→旧漢字|螢柄の螢光灯|
|2|旧漢字→新漢字|蛍柄の蛍光灯|
|3|旧漢字が含まれるか|true|
|4|旧漢字存在する新漢字が含まれるか|true|
|5|存在した旧漢字数|1|


# きっかけ
業務上で旧漢字と新漢字を変換するプログラム開発があり、
API経由でコンバートしてくれる仕組みがあれば便利だと思い開発に至った。
※その時は一から実装しましたが、自分と同じ考えの人も少なからずいると思ったので…

またAPIを作成しても**周知しなければ使用してもらえない**と思い、初めてQiitaに投稿することにした。

# 環境
|環境        | 名前       | バージョン
|------------------|-------------------|------------------|
| 実行環境|              Docker| 20.10.8
| エディタ|              VSCode|1.61.1
| 言語|            Node.js|15.14.0
| フレームワーク|              Express|4.16.1
| バージョン管理|                Git,GitHub|2.25.1
| ホスティング|             Glitch|

# API仕様

## URI

```
GET http://api.lesson-pg.com/v1/kanji/
```

## Request

|パラメータ| 型       | 例 | 備考
|------------------|-------------------|------------------|-----------------|
|**article**|String |/v1/kanji/?article=螢が飛んでいる|旧漢字/新漢字を含む文章を渡す<br>(※500 文字まで)


##  Response Body

<font color=#84C98B>&nbsp; Response 200 (application/json)</font>

```json
{
  "old": "螢が飛んでいる",
  "new": "蛍が飛んでいる",
  "includedOld": true,
  "includedNew": false,
  "count": 1
}
```

|プロパティ| 型       | 例 | 備考
|------------------|-------------------|------------------|-----------------|
|**old**|String |螢が飛んでいる|新漢字を旧漢字へ変換した値
|**new**|String |蛍が飛んでいる|旧漢字を新漢字へ変換した値
|**includedOld**|Bool |true|旧漢字が含まれるか
|**includedNew**|Bool |true|旧漢字が含まれるか
|**count**|Integer |1| 存在した旧漢字数

<font color=#FA2019>&nbsp; Response 400 (application/json)</font>

```json
{
  "message": "The maximum number of characters (500 characters) has been exceeded"
}
```

<font color=#FA2019>&nbsp; Response 404 (application/json)</font>

```json
{
  "message": "Not Found"
}
```

<font color=#FA2019>&nbsp; Response 405 (application/json)</font>

```json
{
  "message": "Method Not Allowed"
}
```

# 実行テスト

API開発では今まで「**`Postman`**」を使用していたが、今回はVSCode拡張機能「**`Thunder Client`**」を使用 ※VSCodeで完結できるため採用

## Thunder Clientをインストール/有効化
![WS000000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119803/0452ae7f-4b0e-64e5-62f4-afc8048d1c07.jpeg)
## リクエスト作成
![WS000001.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119803/83e7b198-1074-3762-37e8-be8c5a835e0c.jpeg)
![WS000004.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119803/e69c4267-67de-9dc4-fd7a-79342b142127.jpeg)

パラメータを入力後「**Send**」ボタンをクリック

## 実行

![WS000003.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119803/cda43f50-cffd-52bc-a4df-52904a06ee2e.jpeg)
※値が返ってきていることを確認できた

*** 
# リンク
細かい仕様やソースコードはこちらにあります↓
https://github.com/uswebk/KanjiConvertAPI

# 今後
* 一般の人向けに、今回作成したAPIを流用して管理画面から使用できるようにしたい。
* アクセス数が分かるようログを取りたい。

**アドバイスや改善点があればお申し付けください。**
[Gnuplot]３Dプロットで軸の比率固定

動作環境：Gnuplot 5.4 in MacOS

Gnuplotで3Dプロットをしていると、気になってくるのが座標軸の単位長さを同じにしてその比率が固定できないというところ。
２Dプロットであれば
```set size square```
で比率を固定できるが、３次元の場合には適用されない（過去には反映されていたようだ）。

それで、調べてみると、Gnuplot4.2から設定が追加されたようだ。
```set view equal xyz```
解除する場合は、
```set view noequal```
でいける。

## 出力例
```
set parametric
set size equal xyz
splot cos(v)*cos(u), cos(v)*sin(u), sin(v)
```
![graph.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62130/d547dbde-52a9-438f-6255-e4c16075594e.png)

きれいな球体が表示されたがxy軸の座標軸がかぶっている。最初に表示される向きの指定ってどうやるんだろう。。

（参考：https://dosei.hatenadiary.jp/entry/20110206/p1）
アクセスコントロールについて　簡単まとめ

#今回の内容

アクセスコントロールについて調べたことを簡単にまとめておきます。

#種類

* `open`
* `public`
* `internal`
* `fileprivate`
* `private`

#それぞれの役割

* `open`
 *  アクセスへの制限が無い。
 *  継承することも出来る。

* `public`
 * モジュール内であれば制限が無いと考えられる。
 * モジュール外だと`override`や`継承`が出来なくなる。

* `internal`
 * 同じモジュール内であれば、アクセスすることが出来ます。
 * デフォルトで設定されるアクセスコントロールは`internal`になっている。

* `fileprivate`
 *  同じファイルの中でだけ、アクセスすることができる。

* `private`
 * 同じスコープ内でだけ、アクセスすることが出来ます。
 * 一番アクセス制限が厳しい

# 終わり
ご指摘、ご質問などありましたら、コメントまでお願い致します。
ALDS1 13 A 8クイーン問題 順列全探索

<script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?config=TeX-MML-AM_CHTML">
</script>
<script type="text/x-mathjax-config">
 MathJax.Hub.Config({
 tex2jax: {
 inlineMath: [['$', '$'] ],
 displayMath: [ ['$$','$$'], ["\\[","\\]"] ]
 }
 });
</script>

これの解答です。
https://onlinejudge.u-aizu.ac.jp/problems/ALDS1_13_A

>8クイーン問題とは、$8 \times 8$ のマスから成るチェス盤に、どのクイーンも他のクイーンを襲撃できないように、8 つのクイーンを配置する問題です。チェスでは、クイーンは次のように８方向のマスにいるコマを襲撃することができます。
すでにクイーンが配置されている k 個のマスが指定されるので、それらを合わせて8つのクイーンを配置したチェス盤を出力するプログラムを作成してください。


##方針
解においては、各行各列に唯ひとつのクイーンが存在するのだから、そのような配置候補を総当りする。あるクイーンが斜め移動で他クイーンに到達する配置は弾いていき、生き残ったものが答え。

数列 $a[i]$ を $ (1,2,...,N)$ の permutation とすると、$ (i,a[i]), i=1,...N $ がクイーンの候補配置となる。
斜めで他クイーンに到達できるか否かは、候補クイーン同士のx座標の差の絶対値がy座標の差の絶対値と等しいかをテストすればよい。

##コード

```cpp
#define rep(i, a, n) for (int i = a; i < n; ++i)
#define all(x) (x).begin(), (x).end()
using namespace std;

int main() {
    // store input
    const int N = 8;
    int k;
    cin >> k;
    vector<pair<int, int>> fixed(k);
    rep(i, 0, k) { cin >> fixed[i].first >> fixed[i].second; }

    vector<int> queen(N);
    rep(i, 0, N) queen[i] = i;

    auto is_good_pos = [&]() -> bool {
        const int size = queen.size();
        rep(q, 0, size) rep(r, q + 1, size) {
            // q = (x,y), r = (w,z)
            // not ok iff abs(x-w) = abs(y-z)
            if (abs(q - r) == abs(queen[q] - queen[r])) {
                return false;
            }
        }
        return true;
    };

    auto as_given = [&]() -> bool {
        for (auto p : fixed)
            if (queen[p.first] != p.second) return false;
        return true;
    };

    // find good permutation
    do {
        if (!as_given()) continue;
        if (is_good_pos()) break;
    } while (next_permutation(all(queen)));

    // set the answer board
    vector<string> board(N, "........");
    rep(i, 0, N) board[i][queen.at(i)] = 'Q';
    // show
    rep(y, 0, N) cout << board[y] endl;
    return 0;
}

```
【SwiftUI】"@"って何ですか？

## ゴール
SwiftUIの"@"とは何か理解する

## 結論
Property Wrapperというものを使用するときに先頭につけるもの

## やったこと
1. "@"がついているものの共通点探し
2. Property Wrapperについて理解する

## 1. "@"がついているものの共通点探し
まずは、"@"がついているものの共通点を探しました。
ぱっと思いついたものはこんな感じです。

```
- @State
- @Binding
- @ObservedObject
- @Published
```
それぞれの公式ドキュメントでの説明を見てみたところ
ほとんどに`A property wrapper type`という説明がされていました。

### `@State`

https://developer.apple.com/documentation/swiftui/state

> A property wrapper type that can read and write a value managed by SwiftUI.

### `@Binding`
https://developer.apple.com/documentation/swiftui/binding

> A property wrapper type that can read and write a value owned by a source of truth.

### `@ObservedObject`
https://developer.apple.com/documentation/swiftui/observedobject

> A property wrapper type that subscribes to an observable object and invalidates a view whenever the observable object changes.

### `@Published`
https://developer.apple.com/documentation/combine/published/

> A type that publishes a property marked with an attribute.

## 2. Property Wrapperについて理解する
Published以外の"@"がついているものの説明文に`A property wrapper type`と記載されていたため
Property Wrapperについて調べました。
### Property Wrapperとは何か
SwiftのLanguage GuideのPropertiesにProperty Wrappersという項目がありました。 
https://docs.swift.org/swift-book/LanguageGuide/Properties.html

ざっと要点をまとめると
- "@propertyWrapper"というattributeをstruct, enum, classにつけることでProperty Wrapperにできる 
- Property Wrapperを使って変数を定義すると、Property Wrapperで定義したgetterとsetterが反映される
- Property Wrapperには１つ以上のstored propertyを定義する必要がある
- Property WrapperにはwrappedValueというpropertyを定義する必要がある
- Property Wrapperにはprojected valueというpropertyを定義することができ、それには"$"でアクセスできる

"@"がついているState、Binding、ObservedObject、Publishedは、このProperty Wrapperでそれぞれwrapped valueやprojected valueを持っているという理解で良いのでしょうか。
rails データの並び替えまとめ

orderの使い方がうろ覚えだったので忘備録

```ruby:
User.all.order(id: "DESC") # 最後から並べてくれます
User.all.order(:id)  # 指定なしなら最初から並べてくれます
User.all.order(id: "DESC").limit(3) #3件のみ表示します。多すぎる時に使うと良き。
```
データを見やすくするGemを入れてない時は

```ruby:Gemfile
gem 'hirb'
gem 'hirb-unicode'
```
bundle installしやす

```ruby:
$bundle install
```
hirbを有効にしやす

```ruby:
$rails c
irb(main):001:0> Hirb.enable
=> true
```
見やすくなりましたね！mysqlで見るまでもない時にドゾー。
Laravel 6.xで削除機能

自分用の削除機能の備忘録。
今回は削除画像を押下→「削除しますか？」という確認→OKで削除　の流れを実装します。

**view**

```php:index.blade.php
<div class="postList">
   @foreach($posts as $post)
   <div class="postName">
     <p>{{ $users->username }}</p>
   </div>
   <div class="postListText">
     <p>{{ $post->post }}</p>
   </div>
   <div class="postListImage">
     <a href=""><img src="images/edit.png"></a>
     <div class="postListDeleteImage">
       <a class="postDelete" href="{{ $post->id }}/delete" onclick="return confirm('この投稿を削除します。よろしいでしょうか？')"><img src="images/trash.png"></a>
       <input type="image" name="postdelete2" class="postDelete2" src="images/trash-h.png">
     </div>
   </div>
   @endforeach
 </div>
```

**Controller**

```php:PostsController.php
public function delete($id){
     \DB::table('posts')
       ->where('id', $id)
       ->delete();
     return redirect('/top');
}
```

**ルーティング**

```php:web.php
Route::get('/{id}/delete', 'PostsController@delete');
```

これでいけました
M1 Mac Angular環境構築でやったことメモ

# homebrewのインストール

https://brew.sh/

```shell:homebrewのインストール
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

# mvnのインストール
node.jsのversion管理ツール

```bash
brew install nvm
```

パスを通して使用できるようにする

```bash
mkdir ~/.nvm

vi .zshrc
```

```bash:.zshrc
export NVM_DIR="$HOME/.nvm"
[ -s "/opt/homebrew/opt/nvm/nvm.sh" ] && . "/opt/homebrew/opt/nvm/nvm.sh"
[ -s "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm" ] && . "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm"
```

ターミナルを再起動。バージョン確認

```bash
nvm --version
```

# node.jsのインストール

```bash
nvm i v14.18.1
```
上記はバージョン14.18.1をインストールしています。
インストール可能なnode.jsのバージョンを確認したい場合

```bash
nvm ls-remote
```

インストールされたversion確認

```bash
node -v
```

# Angular
TypeScriptのインストール
Angularのインストール

```bash
npm install -g typescript
npm install -g @angular/cli
```

Angularプロジェクトの作成

```bash
ng new [project名]
```

プロジェクトディレクトリ配下で起動

```bash
ng serve --open
```

コンポーネントの作成

```bash
ng new c [component名]
```
Go言語の時刻のフォーマットが終わってるので書きやすくするパッケージを書いた

Go言語の時刻フォーマットをまずご覧ください

```go
const (
    stdLongMonth      = "January"
    stdMonth          = "Jan"
    stdNumMonth       = "1"
    stdZeroMonth      = "01"
    stdLongWeekDay    = "Monday"
    stdWeekDay        = "Mon"
    stdDay            = "2"
    stdUnderDay       = "_2"
    stdZeroDay        = "02"
    stdHour           = "15"
    stdHour12         = "3"
    stdZeroHour12     = "03"
    stdMinute         = "4"
    stdZeroMinute     = "04"
    stdSecond         = "5"
    stdZeroSecond     = "05"
    stdLongYear       = "2006"
    stdYear           = "06"
    stdPM             = "PM"
    stdpm             = "pm"
    stdTZ             = "MST"
    stdISO8601TZ      = "Z0700"  // prints Z for UTC
    stdISO8601ColonTZ = "Z07:00" // prints Z for UTC
    stdNumTZ          = "-0700"  // always numeric
    stdNumShortTZ     = "-07"    // always numeric
    stdNumColonTZ     = "-07:00" // always numeric
)
```
これ別に具体例を書いているわけではないんです。

現在時刻をyyyymmdd形式で出力したかったら、

```go
now := time.Format(time.Now(),"20060102")
```
と書かないといけなくて、年なら2006、月なら01、日なら02、これ以外の数字は許されません。

```go
now := time.Format(time.Now(),"20071130")
```
とかは書けません。

アメリカでは月日年の順で書くので具体的で分かりやすいでしょ？ってことらしいですが…
むしろアメリカ順を採用してない国の人にとっては分かりにくいこと極まりないです。

そこで、こんなパッケージを書きます。

```go
package timeconv

import (
	"strings"
	"time"
)

func Parse(layout, value string) (time.Time, error) {
	return time.Parse(convert(layout), value)
}

func Format(t time.Time, expression string) string {
	return t.Format(convert(expression))
}

func convert(expression string) string {
	res := strings.ReplaceAll(expression, "yyyy", "2006")
	res = strings.ReplaceAll(res, "yy", "06")
	res = strings.ReplaceAll(res, "MMMM", "January")
	res = strings.ReplaceAll(res, "MMM", "Jan")
	res = strings.ReplaceAll(res, "MM", "01")
	res = strings.ReplaceAll(res, "M", "1")
	res = strings.ReplaceAll(res, "dddd", "Monday")
	res = strings.ReplaceAll(res, "ddd", "Mon")
	res = strings.ReplaceAll(res, "dd", "02")
	res = strings.ReplaceAll(res, "d", "2")
	res = strings.ReplaceAll(res, "HH", "15")
	res = strings.ReplaceAll(res, "hh", "03")
	res = strings.ReplaceAll(res, "h", "3")
	res = strings.ReplaceAll(res, "mm", "04")
	res = strings.ReplaceAll(res, "m", "4")
	res = strings.ReplaceAll(res, "ss", "05")
	res = strings.ReplaceAll(res, "s", "5")
	res = strings.ReplaceAll(res, "Ztttt", "Z0700")
	res = strings.ReplaceAll(res, "Ztt:tt", "Z07:00")
	res = strings.ReplaceAll(res, "-tttt", "-0700")
	res = strings.ReplaceAll(res, "-tt", "-07")
	res = strings.ReplaceAll(res, "-tt:tt", "-07:00")
	res = strings.ReplaceAll(res, "+tttt", "-0700")
	res = strings.ReplaceAll(res, "+tt", "-07")
	res = strings.ReplaceAll(res, "+tt:tt", "-07:00")
	return res
}
```
自分はVB系言語に慣れているのでVBっぽく書けるように改良してみました。
文字を置き換えるだけの簡単な仕組みですがこれだけでずいぶん快適になりました。

```go
date := time.Format(time.Now(),"2006年01月02日")    // 2021年10月19日
// ↓
date = timeconv.Format(time.Now(),"yyyy年MM月dd日") // 2021年10月19日


now := time.Format(time.Now(),"15:04:05")    // 22:36:15
// ↓
now = timeconv.Format(time.Now(),"HH:mm:ss") // 22:36:15
```
RAMとROMについて

# はじめに
本記事では、`RAM`と`ROM`について記述します。

# 半導体メモリ
RAMとROMは、半導体メモリの特性を分けたものになります。

`半導体メモリ`は、半導体集積回路から構成される記憶装置です。

# RAM
Random Access Memoryの略。
電源の供給が途絶えると記憶していた内容が消えてしまう`揮発性`があります。

また、RAMには、
`DRAM`と`SRAM`に大別されます。

#### DRAM
Dynamic RAMの略。
`コンデンサ`と呼ばれる回路で構成されています。
[コンデンサはなんの役割を担う電子部品？　仕組みをわかりやすく解説](https://www.matsusada.co.jp/column/capacitor.html)

`主記憶`として用いられています。

#### SRAM
Static RAMの略。
フリップフロップと呼ばれる回路で構成され、
`DRAM`に比べて高速ですが、製造コストがかかります。

`キャッシュメモリ`として用いられています。

# ROM
Read Only Memoryの略。
電源の供給が途絶えても記憶していた内容は消えない`不揮発性`の特性があります。

また、ROMは`マスクROM`と`PROM`に大別できます。

#### マスクROM
製造時にデータを書き込むと利用者が書き換えができないです。

#### PROM
紫外線でデータ消去して書き換えられる`UV-EPROM`、
電気的にデータ消去して書き換えられる`EEPROM`、
書き込みや、消去とも電気的に行い、一括もしくは、ブロック単位で消去ができる`フラッシュメモリ`
などがあります。

# まとめ

```
「揮発性」
半導体メモリ
|
RAM
|
DRAM(主記憶)
SRAM(キャッシュメモリ)

「不揮発性」
半導体メモリ
|
ROM
|--------|
PROM  マスクROM
|
UV-EPROM
EEPROM
フラッシュメモリ
```

以上です。

# 終わりに
ITパスポート内容が多いですが、
今できることを覚えていきます。

以下参考サイトです。
[知らないと恥ずかしい？　メモリの「RAM」と「ROM」の違い](https://www.itmedia.co.jp/news/articles/1706/01/news051.html)

明日も頑張ります。
無料で使える仕様書作成ツールを使ってみた

C#を学習中です。
まだテキストを写経するレベルなのですが、ついでだから仕様書等のドキュメントについても勉強しています。
その過程で、どのドキュメントにどのツールを使ったか覚え書きです。
今のところ、自分の中で「こうやって設計する」という流れを理解するために作成しており、アウトプットとして人に見せることを想定していないです。
とりあえずクライアントがいるわけでもないので、自分がわかればいいかなー、と。

というか、仮にクライアントが存在するとしたら、ドキュメントの書式やファイル形式はクライアントごとにルールがあるのではなかろうかという気がします。
あるいは開発側組織でルールが定まっていて、いずれにせよ個人がツール選定する必要に駆られることはまずなさそう。

## 作成したいドキュメント
+ 画面設計
+ 画面遷移
+ 要求定義
+ 機能一覧
+ クラス図
+ アクティビティ図
+ テーブル定義

### 画面設計
Power Point
#### チョイスした理由
前職で画面設計をしたことがあって、そのとき使ったのがパワポだった。
一画面一スライドで作っていけばいいので、画面設計はパワポで(今のところ)十分

### 画面遷移
Power Point
#### チョイスした理由
画面設計にパワポを使った流れで。
画面数が少ないうちはいいけど、遷移が複雑になると手に負えなくなるので、他のツールを検討したい。


### 要求分析
OneNote
#### 選択理由
階層構造で書けるから。あと使い慣れているから。

### 機能一覧
OneNote
#### 選択理由
要求分析をOneNoteに書いた流れ。

### クラス図
Visual Studio Code + [Preview Sequence Diagrams](https://marketplace.visualstudio.com/items?itemName=arichika.previewseqdiag-vscode)
テキストベースでUMLを作成できる [mermaid](https://mermaid-js.github.io/mermaid/#/) というサービスがある。
それを使って、Visual Studio Code 上でプレビューできるようにしてくれるのが、Preview Sequence Diagrams。


#### 選択理由
何はともあれUMLを書きたかった。
テキストエディタなら何でもいいんだけど、インテリジェンスがあってプレビューできるのでVS Code で記述するのが大変楽だった。

### アクティビティ図
[diagrams.net](https://app.diagrams.net/?src=about)
ブラウザで動くベクター作図ツール。
UML作成に必要なパーツが用意されている。
#### 選択理由
[mermaid](https://mermaid-js.github.io/mermaid/#/) ではいい感じのアクティビティ図が書けなかったので、UMLが書けるフリーのツールってことでとりあえず試してみた。
修正回数制限などがなく、今のところ快適に使えている。
Udemy「ネットワークエンジニアを目指す初心者はここから始めよう！「ゼロから学ぶネットワーク基礎」1019

リピータハブ
・物理層に相当し、複数のポートを持つ。
・信号の修正、増幅を行う。
・受信ポートを除く全てのポートから送出する。
・Unicast通信も全てのポートから送出する。

コリジョンドメイン
・電気信号の衝突が起こりえる範囲を指す。
・リピータハブに接続された範囲がコリジョンドメインになる。

スイッチ
・データリンク層に相当する。
・スイッチングハブ、Layer2スイッチ（L2スイッチ）と呼ばれる。
・複数のポートを持つ。
・MACアドレスを学習する。
・コリジョンドメインを分割する。

MACアドレス学習（１）
・受信データの送信元MACアドレスを参照し、どのポートから受信したかを学習する。
・管理表をフォワーディングデータベース、MACアドレステーブルと呼ぶ。

MACアドレス学習（２）
・フォワーディングデータベースの内容は一定時間で削除される。
・再度通信がおこなわれることで学習される。

フラッディング
・該当するポートが無い場合は全てのポートから同じデータを送信する。
・FF-FF-FF-FF-FF-FFが宛先の場合もフラッディングする。

コリジョンドメイン分割
・L2スイッチでは衝突は起きないのでコリジョンドメインが分割される。
・L２スイッチではブロードキャストドメインの分割はできない。

転送方式
・ストアアンドフォワード方式
　・受信フレームの全てを一度読み込む。
　・フレーム破損をチェックする。
　・他と比較すると遅延が多くなる。
・カットスルー方式
　・受信フレームの先頭６バイトまで読み込む。
　・フレーム破損はチェックしない（破損フレームもそのまま転送）。
　・他と比較すると高速な処理が可能となる。
・フラグメントフリー方式
　・受信フレームの先頭64バイトまで読み込む。
　・ストアアンドフォワードとカットスルーの中間の位置づけ。

ループ構成とそのリスク
・ブロードキャスト通信により何度も同じ機器を巡回してしまう状態をブロードキャストストームと呼ぶ。
・Ethernetには常にループ構成によるリスクがある。
ABC223 C - Doukasen が解けた

https://atcoder.jp/contests/abc223/tasks/abc223_c

![abc223c_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/c5fc6065-2f12-5597-64f2-83909063f669.png)
![abc223c_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/c1f93b29-2754-112e-e1c1-a29b733c1752.png)
![abc223c_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/61c27a35-dc6a-0fb1-5394-f63850ad9a65.png)

本番当日は気が付かなかったけど、
距離/速さ = 時間、だよね。
ってことは全てが燃えきるまでの時間/2 の時間までに
左から何センチまで燃えるか分かれば回答になるよね。

```abc223c.py
N = int(input())
lis = []
sum_time = 0

for _ in range(N):
    a,b = map(int,input().split())
    lis.append([a,b,a/b])
    sum_time += a/b
target_time = sum_time/2

cnt = 0
memo = 0
rest_time = 0
for i in range(N):
    if cnt + lis[i][2] == target_time:
        memo = i+1
        rest_time = target_time-(cnt+lis[i][2])
        break
    elif cnt + lis[i][2] > target_time:
        memo = i
        rest_time = target_time-cnt
        break
    else:
        cnt += lis[i][2]
ans = 0
for j in range(memo):
    ans += lis[j][0]

print("{:.5f}".format(ans + rest_time*lis[memo][1]))
```

ちょっと大きくなったけど、通った。
修行してまた来よう、その時はもっとシンプルに書けるはず
自分ちの猫をGoogleCloudVision APIに読み込ませてみた結果

# GoogleGloudVision APIを使って画像を解析するコード

こちらの動画を実践しました。

https://www.youtube.com/watch?v=F4oevQ-BUm8&list=PLLFOC5fk1ILnTq3nM-xm8uIFL3FwY32v4&index=4

サクッと出来てめちゃくちゃ良かったです。


index.pyと同じ階層にimage.jpgという解析したい画像を入れて実行するだけ。

## 下準備
- GoogleCloudに登録しVisionを有効にする
- PCにgoogle-cloud-visionをインストール
　```$ pip install google-cloud-vision```

- jsonでcloud-visionのクレデンシャルを発行してpythonファイルと同じ階層に入れる
- シェルのprofileにクレデンシャルファイルのパスを登録
自分の環境はシェルがbashだったので~/.bash_profileに登録

```
echo 'export GOOGLE_APPLICATION_CREDENTIALS="/Users/xxxxx/Documents/vision-ai-test/oceanic-citadel-329512-8xxxxxxxxxxxx.json"' >> ~/.bash_profile
```
### 設定反映

```
source ~/.bash_profile
```

##pythonファイルを記述

```index.py
from google.cloud import vision

# image.jpg を開いて読み込む
with open('./image.jpg', 'rb') as image_file:
    content = image_file.read()

# Kite というプラグインでサジェストしてくれる

image = vision.Image(content=content)
# vision APIが使えるようにイメージを変換してくれ他ものをimage変数に入れる
# 別の引数がある場合指定していないのでcontent=contentとcontentのみに引数を入れている

# print(image)
# index.pyを実行して確認すると数字の羅列になる

annotator_client = vision.ImageAnnotatorClient()
# ImageAnnotatorというクラスがある
#　Annotator とは音声や画像などにタグつけをするものという意味
# annotator_clientという変数にクラスをつけてインスタンスを作った
# インスタンスを読んでいく

# print(annotator_client.label_detection(image=image))
#確認すると現在の結果がわかる

""" label_annotations {
  mid: "/m/01yrx"
  description: "Cat"
  score: 0.9558032155036926
  topicality: 0.9558032155036926
}
label_annotations {
  mid: "/m/01lrl"
  description: "Carnivore"
  score: 0.8897402882575989
  topicality: 0.8897402882575989 """

  #description とかだけ抽出する

response_data = annotator_client.label_detection(image=image)
labels = response_data.label_annotations


print('----RESULT----')
for label in labels:
    #print(label.description)
    #print(label.score)
# みやすくする
    print(label.description, ':', round(label.score * 100, 2), '%')
print('----RESULT----')

```

##python実行

```$ python index.py```

```
----RESULT----
Cat : 95.58 %
Carnivore : 88.97 %
Felidae : 86.93 %
Grey : 83.98 %
Small to medium-sized cats : 82.86 %
Whiskers : 81.12 %
Flooring : 78.75 %
Tail : 75.43 %
Snout : 74.93 %
Fur : 69.51 %
----RESULT----
```
![image.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482703/4ecf4b1f-a2d5-8884-3bbc-659728a57fe0.jpeg)

おお~
紛れもない猫でした。
備忘録を残すためのテンプレート

# 背景
<!-- 発端や概要を記載 -->
開発を行っている際、備忘録を残したい時が多々あり、自分用のテンプレートがあればいいなあと思ったので
色んな方も載せているが、Markdownにも慣れる為に書いてみた。
随時追記予定

# テンプレート文

```
# 背景・概要

# ソースコード

    ```
    コードブロック
    ```

# 参考文献
- [リンクテキスト](URL)

```

# 参考文献
- [公式ガイドライン](https://help.qiita.com/ja/articles/qiita-article-guideline)
git管理アプリforkとLFSを併用するときの注意

僕はgit管理アプリの [fork](https://git-fork.com/) の大ファンなのだけどgitの仕様バグみたいなものでforkの動作がおかしくなる条件を発見したので、ちょっとメモとして残しておく。

1. リポジトリAがあり、リポジトリBがある、BはAからforkされたもので、外注さんとのやりとりのために使うリポジトリである。
1. リポジトリAがいろいろな都合でLFSを使いだす。

LFSを知っている人なら、.gitattributeが作られるとクライアント側でLFSがオンになるというのは知っているだろう。
.gitignoreと似た構造だが、1つ大きく違うのはgitignoreはサーバーにモノを上げるか上げないかを決めるルールだが .gitattributeはサーバー上でLFS Objectにするかを決めるルールだってことだ。
そしてLFSは結構頭が良くてサーバー上でupstream側から取得しようとしたオブジェクトがLFS Objectだと、スルっとautomaticでダウンロードしてくれる **ことになっている**。

では **リポジトリBで別段LFSをオンにせずに upstream、つまりAからLFSを使っているブランチをpullしたとき何が起こるか？**

fork君はLFSをクライアント側でオンにせずにLFSの入っているリポジトリをpullするとLFS Objectをautomaticに引っ張ってくれない挙動をするのである。

 **結論**

:::note
LFSではなかったリポジトリからLFSのリポジトリを引っ張るときは、まず先にLFS Initを実行して、LFSが有効になるようにしてから引っ張りましょう。
:::

なお、.gitattributeの処理はclient側の話なので、clientの作りによって変わる。そしてsource treeは **なんだかDLされていないLFS ObjectがあるようだけどDLするかい？** とダイアログを出して聞いてくる。
少々気が利いている…利いているがだ。知っての通りwindows 版のsource treeはあまりに **ナニ** なので使いたくないのである。
railsチュートリアル第八章 現在のユーザー

###現在のユーザー
今度はそのユーザーIDを別のページで取り出すことにしましょう。

####セッションに含まれる現在のユーザーを検索する
app/helpers/sessions_helper.rb

```rb
module SessionsHelper

  # 渡されたユーザーでログインする
  def log_in(user)
    session[:user_id] = user.id
    #sessionメソッドで作成した一時cookiesは自動的に暗号化される
    # ユーザーのブラウザ内の一時cookiesに暗号化済みのユーザーIDが自動で作成
  end
  
  # 現在ログイン中のユーザーを返す（いる場合）
  def current_user
    if session[:user_id]
    # ログインしているユーザーが有効か？
    # このどちらかの状態の場合、Cookieの有効期限をブラウザ終了時にしても、
    # Chrome側の仕様でCookieを保持し続ける
      @current_user ||= User.find_by(id: session[:user_id])
      # current_userかUser.find_by()のどちらかに入っていればいい。
    end
  end
end
```
####演習
1.Railsコンソールを使って、User.find_by(id: ...)で対応するユーザーが検索に引っかからなかったとき、nilを返すことを確認してみましょう。

```rb
>> User.find_by(id:2)
  User Load (0.1ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 2], ["LIMIT", 1]]
=> nil
```

2.先ほどと同様に、今度は:user_idキーを持つsessionハッシュを作成してみましょう。リスト 8.17に記したステップに従って、||=演算子がうまく動くことも確認してみましょう。

```rb
>> session = {}
=> {}

>> session[:user_id] = nil
=> nil

>> @current_user ||= User.find_by(id: session[:user_id])
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."id" IS NULL LIMIT ?  [["LIMIT", 1]]
=> nil

>> session[:user_id]= User.first.id
  User Load (0.2ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> 1

>> @current_user ||= User.find_by(id: session[:user_id])
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
=> #<User id: 1, name: "a", email: "abc@def.com", created_at: "2021-10-05 04:11:41", updated_at: "2021-10-05 04:11:41", password_digest: [FILTERED]>

>> @current_user ||= User.find_by(id: sessiond[:user_id])
=> #<User id: 1, name: "a", email: "abc@def.com", created_at: "2021-10-05 04:11:41", updated_at: "2021-10-05 04:11:41", password_digest: [FILTERED]>
```
どちらかが返るようになっている。
railsチュートリアル第八章 ログイン

##ログイン
Sessionsコントローラを生成した時点で既にセッション用ヘルパーモジュールも自動生成されています
Railsのセッション用ヘルパーはビューにも自動的に読み込まれます。
どのコントローラでも使えるようになります
実際にログイン中の状態での有効な値の送信をフォームで正しく扱えるようにします。
####ApplicationコントローラにSessionヘルパーモジュールを読み込む
app/controllers/application_controller.rb

```rb
class ApplicationController < ActionController::Base
  include SessionsHelper
end
```
###log_inメソッド
事前定義済みのsessionメソッドを使って、単純なログインを行えるようにします
sessionメソッドで作成された一時cookiesは、ブラウザを閉じた瞬間に有効期限が終了
####log_inメソッド
app/helpers/sessions_helper.rb

```rb
module SessionsHelper

  # 渡されたユーザーでログインする
  def log_in(user)
    session[:user_id] = user.id
    # sessionメソッドで作成した一時cookiesは自動的に暗号化される。
    # ユーザーのブラウザ内の一時cookiesに暗号化済みのユーザーIDが自動で作成
  end
end
```

####ユーザーにログインする
app/controllers/sessions_controller.rb

```rb
class SessionsController < ApplicationController

  def new
  end
  
  def create
    user = User.find_by(email: params[:session][:email].downcase)
    # 送信されたメアドを使ってデータベースから取り出す。
    #emailを小文字にする
    if user && user.authenticate(params[:session][:password])
    # user  取得したユーザーが有効かどうか？
    # その後にデータベース上にパスワードがあるか？
    # ユーザーログイン後にユーザー情報のページにリダイレクトする
      log_in user
      # ユーザーのブラウザ内の一時cookiesに暗号化済みのユーザーIDが自動で作成
      redirect_to user
      # 名前付きルート/userのビューを表示する
    else
      flash.now[:danger] = 'Invalid email/password combination'
      # flash.nowでリクエストが発生後メッセージを消滅する
      # エラーメッセージを作成する
        render 'new'
        # newアクションのビューを表示
    end
  end

  def destroy
  # ユーザー削除
  end
end
```

###演習
1.有効なユーザーで実際にログインし、ブラウザからcookiesの情報を調べてみてください。このとき、sessionの値はどうなっているでしょうか? ヒント: ブラウザでcookiesを調べる方法が分からない? 今こそググってみるときです!（コラム 1.2）

どういう意味かはわからないが、確認できた。

2.先ほどの演習課題と同様に、Expires(有効期限）の値について調べてみてくだい。
ブラウザセッションの終了時　と書いてあった。
mod_rewrite とは

## 勉強前イメージ

httpに関係する・・？ってくらいしかわかってない

## 調査

### mod_rewrite とは

apacheで利用されているモジュールで、URLの書き換えやリダイレクト処理を行ってくれるものです。
正規表現を使用してURLの書き換えが可能なので複雑な処理が実施できます。
例えば、httpヘッダーやタイムスタンプ、DBの情報を元にURLの書き換えができ、動的なURLを静的なURLへ変更もできます。

ユースケースでは、
ブラウザを元にアクセスを振り分けたり、
条件に合ったURLでアクセスが来た場合に、指定したURLにリダイレクトさせたりできます。

### 変更方法

- httpd.conf へ記載
	- サーバ単位でのリダイレクト処理が可能
	- .htaccessと比べると高速に処理が可能
	- root権限が必要(レンタルサーバでは難しいかも)
- .htaccess へ記載
	- ディレクトリ単位でのリダイレクト処理が可能
	- httpd.confと比べると処理が遅い
	- root権限がなくても使用可能

### mod_rewrite の記載の種類

記載の種類には以下のようなものがあります。

- RewriteEngine

mod_rewriteを有効もしくは無効にする宣言文で、
有効: `RewriteEngine on` / 無効: `RewriteEngine off` で有効無効を記載できます。

- RewriteBase

URL書き換える際に、ベースとなるディレクトリを明示的に指定するもので、
`RewriteBase /directory` と記載すると
/directory ディレクトリ配下のURLを変更することができます。

- RewriteCond

サーバ変数を参照して、正規表現のパターンに一致していれば次の条件を実施することが出来るようなものです。
例えばAndroidを条件とすれば `RewriteCond %{HTTP_USER_AGENT} Android` と記載することで
Androidに次に記載する条件を加えることができます。

- RewriteRule

URLを書き換えるためのもので、パターンにマッチした場合にURLの書き換えが行われます。
例えば、RewriteCondで条件を絞られたアクセスに対し、www.example.comで来てたものをexample.comでアクセスさせるために
`RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]` と記載します。

ちなみに `R=` とか `L` の意味に関しては、
`L` はルールの最終行(Last)を意味し、ルールが一致した場合それ以降のルールは処理されません。
`R` はリダイレクトを意味し、 リダイレクトを行う際HTTPステータスコードを指定できる。何も指定しない場合は通常302がデフォルトとである。

### やってみる

適当なwebサーバ立ててみました。
2ファイルを /var/www/html配下においています。
noredirect.html にアクセスをさせて、特定条件下では redirect.html にアクセスされるようにします。

```
# tree
.
├── noredirect.html → リダイレクトされないときに表示されるもの
└── redirect.html → リダイレクトされたときに表示されるもの
```

それぞれの中身は以下になります。

```
# cat noredirect.html
リダイレクトされないよ
```
```
# cat redirect.html
リダイレクトされるよ
```

- 変更前

`http://example.com/noredirect.html` へアクセス
何も設定されていないので、 noredirect.html の中身が見れる

![3Mozilla Firefox 2021-10-19 21.42.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/16e9b802-259a-54c0-657c-bb4eb75d74c2.png)



- httpd.confの設定変更

※今回の設定は.htaccessの挙動を見たいだけなので、以下のように全許可してますが
環境により適切に設定してください。

apacheはデフォルトで、.htaccessの設定を有効にしていないので、
許可する設定に書き換えます。

```
vi /etc/httpd/conf/httpd.conf
```

ファイルを置いてるのは `/var/www/html` なので、
設定の中の `AllowOverride None(上書きを許可しない設定)` を `All` に書き換えます。

```
<Directory "/var/www/html">
...
AllowOverride None
↓
AllowOverride All
...
</Directory>
```

apacheを再起動します。

```
service httpd restart
```

- 設定変更

変更したいディレクトリ配下(今回であれば /var/www/html) に.htaccess のファイルを作成して、中身を記述していきます。

```
vi .htaccess
```

中身に記載しているのは、
どのファイルへのアクセスが来ても(^.*$)、 redirect.html へリダイレクトする という風に書いています。

```
RewriteEngine on
RewriteRule ^.*$ redirect.html
```

- 変更後

変更前同様に `http://example.com/noredirect.html` へアクセスを行います。
すると表示が変わり、リダイレクトされたことがわかりました。

![4Mozilla Firefox 2021-10-19 21.43.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/cd9d9a94-b770-9ded-4c30-8837f0a01b86.png)


## 勉強後イメージ

初めて.htaccess触ったかも
実際に触ってみたらなんとなくイメージついた気がする
ほぼデフォルト設定でしか触ったことなかったから勉強になった

## 参考

- [mod rewrite](https://ysklog.net/mod-rewrite/)
- [URLを書き換える -Rewrite機能](https://rfs.jp/server/apache/02apache/url_rewrite.html)
- [mod_rewrite のインストールと設定、RewriteRule の書き方](https://memorva.jp/memo/linux/mod_rewrite.php)
Microsoft Wireless Display Adapter 接続時の躓きポイント

# 背景
出力自体は以下のように簡単なんですが、初期接続で詰まることがあったので備忘録

1. HDMI & USB 接続
1. Win + K で機器選択
1. Win + P で出力選択

無線機能の無いモニターに対して、簡単に出力できるので便利ですよね、これ
Fire TV Sticks といい、日本メーカーにもこういったガジェットをもっと開発してほしいな。

https://support.microsoft.com/ja-jp/surface/microsoft-wireless-display-adapter-%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B-e3c36815-74b2-b6fb-f09a-923ef28fd5fb#:~:text=Microsoft%20Wireless,Display%20Adapter%20%E3%81%AF%E3%80%81%E3%82%B3%E3%83%B3%E3%83%86%E3%83%B3%E3%83%84%E3%80%81%E5%86%99%E7%9C%9F%E3%80%81%E3%83%93%E3%83%87%E3%82%AA%E3%82%92%E5%A4%A7%E7%94%BB%E9%9D%A2%E3%81%AB%E6%8A%95%E5%BD%B1%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%E5%BC%B7%E5%8A%9B%E3%81%A7%E4%BF%A1%E9%A0%BC%E6%80%A7%E3%81%AE%E9%AB%98%E3%81%84%E6%96%B9%E6%B3%95%E3%81%A7%E3%81%99%E3%80%82

## 名称変更
ここで表示名称変更可能
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/4006e73e-e7c4-c383-f928-da35aca682e9.png)

:::note info
【セキュリティの設定】で、PIN 入れての切り替えなどにできます。
:::

## ファームウェアアップデート
1. 適当なモニターに HDMI 接続
1. アプリケーションを入れた PC へUSB 接続
1. Win + K で アダプターへ接続 <br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/6067b702-c272-4bd9-ab31-45c5a1a32637.png)
1. 更新実施<BR>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/5b229952-2484-d4c4-e281-f4561ac00f3a.png)


# 困ったときの記録

## プチプチ切れてアップデートまでいけない！
2.4GHzじゃないとアップデートとか出来ないという罠があります・・
> #### 解決策 8:デバイスのワイヤレス周波数帯域を変更する
> Microsoft Wireless Display Adapter は、2.4 GHz または 5 GHz のどちらでもデバイスと通信できますが、デバイスをアダプターとペアリングするときは、デバイスで 2.4 GHz 帯域が有効になっている必要があります。

https://support.microsoft.com/ja-jp/windows/microsoft-wireless-display-adapter-%E3%81%AE%E3%83%88%E3%83%A9%E3%83%96%E3%83%AB%E3%82%B7%E3%83%A5%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0-9d2369cf-ba4b-908c-69c0-d4e5f4117d35

## 見つからない
そもそも、画面を出力していないと、省エネで反応してくれません。
意外にはまります・・。特に設定時、既存の画面の空きHDMI端子に入れてると、画面切り替えを怠ってしまうので・・

Adapter の HDMI 端子の出力を行い、Adapter の待ち受け画面を見えるようにしてからにしましょう

## 画面の外周に映せない領域がある。
1. アダプターの設定
基本こっちはDefaultなので問題はないことの確認程度
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/89dcb343-784b-a2d1-a270-9942827c504f.png)

1. PCの設定
PC側のディスプレイ設定が影響している場合があります。
下図は、Intelの設定例で、100% にすると改善します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/702db71f-3dff-d159-0c4c-db50e6aeeff3.png)
【Java】二次元配列でドット絵を作ってみた

##作ろうと思ったきっかけ

→for文の演習問題中
→以下を実行せよ
▼▲▼
▼▲
▼
→これ応用したらドット絵作れるんじゃね？


##ドット絵を作ってみました

![kkk02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2064393/1535c15e-c10b-f035-a3ac-605525782349.png)
[星のカービィ](https://www.kirby.jp/)© Nintendo / HAL Laboratory, Inc.

![inu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2064393/7c62becd-0008-41b8-5dfd-9635dd8432c3.png)
[UNDERTALE](https://undertale.com/)©Toby Fox 2015-2021.

##開発環境
Windows10(32bit)
eclipse(4.9.0)
コマンドプロンプトで実行


```java:Dot_pic.java
class Dot_pic {
	public static void main(String[] args) {
		int[][] dotPic =
            {{0,0,0,0,0,0,1,1,1,1,1,0,1,1,0,0},
             {0,0,0,0,1,1,0,0,0,0,0,1,0,0,1,0},
             {0,0,0,1,0,0,0,1,0,1,0,0,1,0,0,1},
        /*------------------省略------------------*/
             {0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
             {0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,0}};

        for (int[] line : dotPic) {
            for (int dot : line) {
                if (dot == 1) {
                    System.out.print("■");
                } else {
                    System.out.print("　");
                }
            }
            System.out.println("");
		}
	}
}
```
二次元配列でキャンバスを作り、ドットにしたいところを1にします。
※[ドット絵を表示する - Java入門編 - Paiza](https://paiza.jp/works/java/primer/beginner-java5/5045) より引用



###ちなみに初期ドット絵はこちら
↓　↓　↓
![kkk.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2064393/fa4e84cf-b578-099e-95ba-b4ce00dc6d06.png)
笑
for文を使って自力でただひたすらに試行錯誤→微調整の繰り返し・・
0→1を頑張らずに、先人の知恵はとことん活用させて頂くことが賢明だと学びました。
【Rails】画像アップロードボタンのデザインをi18nで言語切り替えしたい！

<h1>状況</h1>

画像アップロードボタンをi18nで言語切り替えしたい...
と思ったのですがattachment fieldはデフォルトで日本語になっていて
言語の設定を変えたりすることができないようです。
(おそらく、インターネットブライザを英語に変えると英語になるのかも?!
試していないのであくまで予想ですが、言語を切り替えために
ブラウザの言語切り替えなんて非効率すぎますので...w)

![Screen Shot 2021-10-19 at 20.45.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1810522/773b96d7-c4e6-84b3-ae85-b8c2707853a4.png)

こいつはブラウザの言語によって日本語になったり
英語になるようなのですがi18nでの言語切り替えができない！

では、どうすれば...

<h2>CSSで被せるデザインを使えばOK</h2>

当初は、Javascriptで上を押したら下も押したことになる
Javascriptを書けばいいなどアドバイスをいただきましたが
CSSで解決できることが判明！！

『pointer-events: none』

このコードをcssで使用すれば、上にデザインを被せても
上のデザインは無効にして下をクリックできる！

という強者のコードなんです。

どんな風にコードを書くかについて説明しますね！

<h2>具体的なコードの解説</h2>

実際に私が作ったボタンのデザインはこれ。

Choose filesは元のattachment fieldの上にかぶさっているCSSになるので
自作したボタンということになります。

通常であれば、attachment fieldのようなボタンの上に
CSSを被せるとしたのボタンを押せなくなってしまうのですが...
poinster noneというcssを書くことで上に被せてもボタンを押せる様になるミラクルw

![Screen Shot 2021-10-19 at 21.00.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1810522/ee1a2a8e-5d4a-988b-6ba9-fc4deb1cd374.png)

まずは、コードをどぞ。


```php:examplehtmlcode

      <div class="field">
        <div class="col-sm-12 col-md-8 col-lg-6 px-5 px-sm-0 mx-auto mt-3">
          <label><%= t 'devise.registrations.new.profile_image' %></label>
          <br>
          <div class="attachment_relative">
            <%= f.attachment_field :profile_image, class:"mt-1 attachment_field" %>
            <div class="attachment-absolute"><%= t 'devise.registrations.new.button' %></div>
          </div>
        </div>  
      </div>

```

```php:examplecsscode

.attachment_relative{
    position:relative;
}    

.attachment-absolute{
    position:absolute;
    width: 135px;
    text-align: center;
    padding: 5px 0;
    pointer-events: none;
    top: 0;
    left: calc(-0.7%);
    background-color: #EEEEEE;
    border-radius:7px;
    // border: 1px solid;
}  


```

簡単に説明するとposition relativeで大きな囲いをつくり
そこにposition absoluteでボタンのデザインを作っています。

position absoluteのcssにpointer-events: none;をいれることで
下のボタンを押せる様にしているわけなのです！

![Screen Shot 2021-10-19 at 21.04.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1810522/e44bc35c-a662-5841-c03e-348b4194d83a.png)

上の図の右上にある言語切り替えのボタンをi18nで作ったはいいものの
attachment fieldの言語切り替えができない(泣)

となって苦戦したのですが、cssを上から被せてそこにi18nの
文字を書くことによってボタンの言語切り替えを無理やりできました！

<h2>まとめ</h2>

・refileを導入するとつかえるように　なる、attachment fieldはブラウザの言語によって言語が切り替わる。
・i18nなどの言語切り替えをサイトで行う場合はattachment fieldの言語は切り替わらないのでcssを使う
・pointer-event:noneを使うとデザインを被せつつ、下にあるボタンを押せる様になる。

pointer non eventは下記の記事を参考にしたので、よければみてくださいね＾＾

参考記事：
https://on-ze.com/archives/7174

それでは、次の記事でお会いしましょう！
チャオ♪