OmniAICreator/Qiita-1.07M huggingface dataset:
ノートPCのWiFiを交換したお話（AC8265→AX200）

# Intel(R) Dual Band Wireless-AC 8265をIntel(R) Wi-Fi 6 AX200に換装

## 部材・装置
-[Fujitsu LIFEBOOK WS1/B3（**SH90B3**）](http://www.fmworld.net/fmv/sh/1710/spec/)
-[Intel Dual Band Wireless-AC **8625**NGW](https://ark.intel.com/content/www/jp/ja/ark/products/94150/intel-dual-band-wireless-ac-8265.html)
-[Intel Wi-Fi 6 **AX200**NGW](https://ark.intel.com/content/www/jp/ja/ark/products/189347/intel-wi-fi-6-ax200-gig.html)

## 交換前のWiFi構成と通信速度
交換前のWiFiデバイス(Intel AC8265)
<img width="500" alt="Intel-AC8265.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404502/4581b76a-409b-1a3f-2e03-5c413aaa8d83.png">

交換前の通信速度(Intel AC8265)
<img width="600" alt="Intel-AC8265-speed-trim.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404502/bd41bae7-b421-2d17-c864-a0df2784e4a5.png">


交換後のWiFiデバイス(Intel AX200)
<img width="500" alt="Intel-WiFi6-AX200.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404502/e8ce8062-ab98-0e56-c215-2b98fa21eed7.png">

交換後の通信速度(Intel AX200)
<img width="500" alt="Intel-WiFi6-AX200-speed-trim.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404502/f1d04a55-5bb3-9d0f-9950-439b1a9a61db.png">

約150Mbps上昇しました。しかしながら手間暇考えると微妙…



デバイスの比較写真
![DSC_1195-trim.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404502/04f764c1-0835-4c59-c77a-6aa6488c05e4.jpeg)


換装後のノートPC写真
![DSC_1196-trim.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404502/6bdd8469-3db4-15e2-9433-7299fa93b6a8.jpeg)


※注意事項
速度が出ないときには以下の点に注意してください。
-アンテナ線がちゃんと装着されているか、左右が間違っていないか
-無線LANのアクセスポイントの**144チャネル**が**無効**になっているか

144チャネルを有効にしていたところ、通信速度が10Mbps程度までしか出なくなり、ちょっと焦りました。
Enumの設定ミス。なぜかEnum指定の列からデータが取れない…

###  <font color='lightblue'>発生した背景</font>
※備忘録として記録します（ネタ的にはしょぼいです…）
以下のようなモデルにEnum設定したとき、データが取り出せない。

```ruby:table.rb
class ColorManage < ApplicationRecord
  enum color_type: { single: 0, double: 1, graphic: 2 }
（省略）
````

（前提）singleというラジオボタンを押すと、0が入力されるようにする。

```erb:color-edit.html.erb
  <!--  カラータイプ、どの設定にするか。-->
  <%= color_manage_record.radio_button :color_type, :single ,class:"color-form__button" %>
  <%= color_manage_record.label :color_type, "single-color", {class: "color-form__tag"} %>
```

<font color="red">問題点> 画像のとおり、color_typeには"ゼロ"で入力されていますが、モデル抽出して、列値を取得しようとしてもnullで返ってくる</font>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647299/89a2c15d-375d-36b7-92dc-7201e1d6cc48.png)


###  <font color='lightblue'>環境</font>
| 項目              |               内容 | 
|:-----------------|:------------------:|
| OS.Catalina      |           v10.15.4 |      
| Ruby             |            v2.5.1 |  
| Ruby On Rails    |           v5.2.4.3 |   
| MySQL          |           V5.6|   


###  <font color='lightblue'>対応手順</font>

原因）テーブルの定義がstringだったので、enumを以下のように定義しなおしました。ポートフォリオなので、恥ずかしながら、設計側を変えた次第です。

```ruby:test.rb
  enum color_type: { single: "single", double: "double", graphic: "graphic" }
```
これで解決しました。

以上です。
aarch64 linux で C/C++ 浮動小数点例外周りのメモ

## 背景

* レイトレや機械学習のコードで, どうも NaN とかが出ているようで, 計算結果(e.g. ピクセル値)がおかしい
* 原因を突き止めるため, aarch64 C/C++ プログラムで, NaN とかが発生したら SIGFPE とか seg fault してほしい

### 結論

少なくとも, x86 のように例外が起きたらプログラムが自動で seg fault するとかシグナル出すのは, aarch64 では無理(大部分の(?) HW が未実装)なことがわかりました.
もしかしたら iOS(arm64) ではいけるかもしれません.

怪しいコードのところに明示的に FPU 例外ステータスチェックを入れての対応になります.
clang undefined behavior sanitizer で, ソフトウェア的に divide-by-zero と overflow は検出できます.

## 環境

* aarch64 linux(Ubuntu 18.04 + Jetson) を想定する
* glibc 環境
* gcc 7.5.0(apt で入る)
* clang 10.0(llvm.org などから手に入る prebuilt or apt パッケージ)

fenv.h は

`/usr/include/fenv.h`
`/usr/include/aarch64-linux-gnu/bits/fenv.h`

にあります.

## sNaN

aarch64 + gcc/clang では, NaN(sNaN) のシグナル検出はデフォルトでは有効にならない.

https://developer.arm.com/documentation/dui0491/i/Compiler-specific-Features/Predefined-macros

gcc/clang では `-fsignaling-nans` で有効にする.
ただし, これらはコンパイラでの扱いを変えるだけで, FPU の動作自体には影響はない(コメントありがとうございます!)
(`-fsignaling-nans` を指定しても aarch64 では NaN で浮動小数点数例外トラップは発生しない)

以下, 参考まで.

`__SUPPORT_SNAN__` が定義される.


```
/* NaN support.  */

#if (__GLIBC_USE (IEC_60559_BFP_EXT)    \
     && defined FE_INVALID      \
     && defined __SUPPORT_SNAN__)
# define FE_SNANS_ALWAYS_SIGNAL 1
#endif
```

`FE_SNANS_ALWAYS_SIGNAL` はそのままでは定義されない.
 
`_GNU_SOURCE` を定義することで有効になる.


```
#define _GNU_SOURCE
#include <fenv.h>
```

ソースコードで定義する場合は, 最初に `_GNU_SOURCE` を定義する必要がある.

```
// NG
#include <signal.h>
#define _GNU_SOURCE
#include <fenv.h>
```

などとするとうまくいかない.

## feenableexcept

例外トラップ指定 feenableexcept は aarch64 では利用できない. `-1` を返してしまう.

https://developer.arm.com/documentation/100073/0607/floating-point-support/controlling-the-arm-floating-point-environment/exception-trap-handling-by-signals

arm compiler でも aarch64 は例外トラップはサポートしないとあるので, aarch64 環境では浮動小数点例外トラップが使えないと考えてよいでしょう.

## Clang undefined behavior sanitizer

https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html

ゼロ除算は `-fsanitize=float-divide-by-zero` で検出できる.

ただし, `sqrtf(-1.0f)` のように NaN が生成されるのは検出できない.

## builtin

https://gcc.gnu.org/onlinedocs/gcc-6.2.0/gcc/AArch64-Built-in-Functions.html

__builtin_aarch64_set_fpcr で FP control register 指定.

https://docs.microsoft.com/ja-jp/cpp/build/arm64-windows-abi-conventions?view=vs-2019#floating-pointsimd-registers

例外ビットは定義されているが, 設定しても反映されない(コメントありがとうございます).


## 手動検出

C/C++ コードで, 怪しそうなところを feclearexcept と ftestexcept で囲い, 例外ビットが立っているか検出し, 自前で SIGFPE なり発行するしかない.

## gdb で NaN 検出

https://ro-che.info/articles/2020-01-11-gdb-break-on-nan

watch でいけるが, ただし変数の場所がわかっている必要がある.

## 参考文献

* https://stackoverflow.com/questions/12762418/how-to-enable-sigfpe-signal-on-division-by-zero-in-ios-app
* https://ro-che.info/articles/2020-01-11-gdb-break-on-nan
* https://docs.microsoft.com/ja-jp/cpp/build/arm64-windows-abi-conventions?view=vs-2019#floating-point-exceptions
【備忘録】お役立ちコマンド

#Windowsのジャンクションリンクリンク

##用途
静的コンテンツをプロジェクトフォルダの外で管理したい場合。WindowsのショートカットだとjQueryで参照できなかったので。
新しい環境で動くプログラムならシンボリックリンクでも大丈夫かもしれない。

```sh
mklink /j [リンク名] [リンク先]
```

#Windowsで多ノードを含むフォルダを素早く削除する。

##用途
node_modulesディレクトリなどはたくさんのディレクトリやファイルが作成される。
エクスプローラー上で削除しようとしても現実的でないぐらい時間がかかる。こういうフォルダを丸々消したいときに。
消したい**フォルダの中に入って**以下のコマンドを実行。これで**全階層のファイル**が消される。***場所は注意。***

```sh
DEL / F / Q / S * *> NUL
```
次のコマンドで残ったフォルダを全て削除する。**フォルダの外に出て実行する。**

```sh
RMDIR / Q / S [foldername]
```
Timeオブジェクトの次の値ってどうやってだすのが正しい？

## 概要

RubyでTimeオブジェクトを扱ってると境界問題にぶち当たる。
普通にやってるとRangeオブジェクトなりを使ってそこまで問題になることはないが、普通じゃないやり方をしていて躓いた。

## 環境

Ruby: 2.6.2
Rails: 5.1.2

## そもそもハマった問題

```ruby
Time.now.end_of_day
=> 2020-05-15 23:59:59 +0900
```

これの次の値を取りたい。
※ end_of_dayはわかりやすいから使ってるだけであって、とある日の先端、終端が欲しいわけではない。飽くまでもTimeオブジェクトの次の値

真っ先に思いついたのがこれ

```ruby
Time.now.end_of_day + 1
=> 2020-05-16 00:00:00 +0900
```

ただ、これは間違い

```ruby
(Time.now.end_of_day + 1).iso8601(3)
=> "2020-05-16T00:00:00.999+09:00"
```

`+ 1` は飽くまでも1秒加算であって、次の値に移行するわけではないので使えない。

Timeクラスを漁ってるとすごくそれっぽいメソッドを見つけた
https://docs.ruby-lang.org/ja/latest/method/Time/i/succ.html

```ruby
Time.now.end_of_day.succ
(pry):109: warning: Time#succ is obsolete; use time + 1
=> 2020-05-16 00:00:00 +0900
```

しかし、時代遅れだから使うなって怒られる上 `+ 1` と同じことしてるだけらしい。だめ。

## 解決方法

結局良さげな方法はわからなかったからゴリ押し


例の問題だと少数9桁までしか見ていない

```Ruby
(Time.now.end_of_day + 1).iso8601(10)
=> "2020-05-16T00:00:00.9999999990+09:00"
```

つまり、1ナノ秒加算してやればいいわけだ

```Ruby
(Time.now.end_of_day + 1/1000000000.0).iso8601(9)
=> "2020-05-16T00:00:00.000000000+09:00"
```

できた！


## おまけ

```Ruby
Time.now.iso8601(10)
=> "2020-05-15T19:56:55.4979370000+09:00"

Time.new(2020, 5, 16, 16, 59, 59.3).iso8601(9)
=> "2020-05-16T16:59:59.299999999+09:00"

Time.parse("2020-05-16T16:59:59.3+09:00").iso8601(9)
=> "2020-05-16T16:59:59.300000000+09:00"

Time.parse("2020-05-16T16:59:59.35555555555555555555+09:00").iso8601(20)
=> "2020-05-16T16:59:59.35555555555555555555+09:00"
```

だめだった

## 結論

- Timeオブジェクト内の小数秒の桁数は無限に持てる
- そのため次の値という概念がそもそも無い
- ただ、Timeオブジェクトの生成の仕方に依存するので、DBから引っ張ってくるならその有効桁数を考慮してやれば無理やり作れなくはない
- そもそも素直にRangeオブジェクトを使うなりして比較すべき
Nuxt.js(Vue)【Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: ""  found in】対処法


Nuxt.js(Vue)のprops関連で、下記のエラーが出た時の対処法です。

```
Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders.

Instead, use a data or computed property based on the prop's value. Prop being mutated: ""

found in

```
propsの値を直接v-modelすると起こるようです。

```vue

v-model="drawer"

 props: {
    drawer: {
      type: Boolean,
      default: false
    }
  }

```

↓watchを使います。

```vue
<template>
  <div class="sidebar">
    <v-navigation-drawer v-model="drawerState" fixed temporary>
    </v-navigation-drawer>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
  name: 'Sidebar',
  props: {
    drawer: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      drawerState: this.drawer
    }
  },
  watch: {
    drawer() {
      this.drawerState = !this.drawerState
    }
  }
})
</script>

```
propsの値をwatchで監視して、dataに反映させることで解決できます。
デザイン４つの基礎原則

##　基礎原則

##1　近接
　・人間の心理で、近くに並べたものを無意識のうちにグループとしてみなす心理が働く。

　・同じ要素のグループは近くに配置し、距離をとることによりグループの境界が明白になり、ハッキリとしたデザインになります。

##2　整列
　・デザインの要素を整列させることにより、見た目が整いすっきりしたデザインになります。
　
　左右整列例 :　右揃え　中央揃え　左揃え
  上下整列例 :  上揃え　中央揃え　下揃え

　・仕事でPowerPointなどでプレゼンの資料作成時に
整列するだけでも見やすさが変わり印象がよくなるので活用していきましょう。
##3　強弱
　・デザインで強弱をつけることにより、見た人が瞬時に理解できる早さが変わり、目で直感的に伝わるデザインになります。

　例として新聞などでも大きく見出しがあり、見て直感的にどんな内容なのかがわかり、瞬時に伝わってきます。
##4　反復
　・視覚的要素を繰り返し用いることにより、一貫性や統一感が出てまとまりのあるデザインになります。





参考サイト：https://webdesign-trends.net/entry/7810
Anaconda3の環境導入手順

#1.ANACONDAをダウンロード
※Pythonには2.*と3.*と二つのバージョンが存在しますが3.*を取得するようにしてください

https://www.anaconda.com/download

#2.ANACOND Aをインストール

#3.ANACONDA起動
起動すると以下のような画面が起動されます。

![Anaconda.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669260/347c705d-85b2-89eb-11a9-da36dd13bd5e.png)

#4.Jupyterを起動
jupyter　NotebookのLaunchというところをクリック

こんな画面が表示されますが、起動できないので

![Anaconda1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669260/f582e5fa-d705-13f4-4bce-c31a7dc21d14.png)

ターミナルから網掛け部分をコピーしてブラウザのURLに貼り付け実行

![Anaconda2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669260/f0ed57a5-f1ae-4acc-b293-bc247164ac44.png)

以下のような画面が表示されればOK!!!

![Anaconda3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669260/e270d081-a54c-b33b-9a3c-f034c1052ef4.png)

#終わりに
次回はSCRAPYの導入手順について書いていこうと思います。
【大人のプログラミング入門】プログラミングを始めたい方へ【目次】

あなたはプログラミングを始めたいですか？
この記事を読まれる方はプログラミングに興味があるかと思います。
そんな方に向けてプログラミングについて解説していきたいとお思います。

# 対象読者
* パソコンに触った事がある
* WindowsとMicrosoft Officeを使った事がある。もしくは知っている
* 小学生で習う四則演算がわかる
* プログラミングに興味がある

#この記事の特徴
プログラミングの学習は大きく分けると以下の種類があります。

* プログラミング言語の文法
* プログラミング言語の命令の使い方
* プログラムを作る際の考え方
 
本記事ではプログラムを作る際の考え方について焦点を当て、プログラミング言語の文法とプログラミング言語の命令の使い方については本記事では扱いません。

#焦点の理由
まずプログラミング言語の文法については大きめの書店やインターネットで情報が得やすいためです。
またプログラミング言語の命令の使い方についてはプログラミング言語の文法を知っている事が前提の応用的な内容のためです。
その為あまり情報が多くないプログラムを作る際の考え方についてを取り上げさせていただきます。

#目次
[プログラミングとは何か？](https://qiita.com/rasclass/items/964021f3c9b99de51714)
命令する(準備中)
繰り返す(準備中)
判断する(準備中)
判断して繰り返す(準備中)
値を保存する(準備中)
処理をまとめる(準備中)
アルゴリズム(準備中)
終わりに(準備中)

##補足
目次については記事を追加した際に更新いたします。
AWSのCentOS8 AMI

# 公式イメージ

CentOS 8でEC2インスタンスを作成しようと、AWS MarketplaceからCentOS 8で検索すると、ずらずらっといくつかAMIが表示されるものの、公式イメージが出てきませんでした。

まだ、公式イメージは提供されてへんのかいな…と途方に暮れかけていたところ以下のページを発見。

https://wiki.centos.org/Cloud/AWS

AMIの画面からインスタンスを作成したいリージョンのAMI IDを入力して検索すると出てきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527863/0db6b1ea-6300-9b07-1c1b-2e094dc4d3dc.png)

例えば東京リージョンであれば、ap-northeast1なので、「ami-089a156ea4f52a0a3」で検索

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527863/0b705e85-0473-81c7-27fb-8366a1a1a08f.png)

出てきた。

ここから起動して、とりあえず使ってみよっと。
GAS を使ったGoogle Driveのファイルの移動についてハマったこと。

# この記事について
表題について少しはまったのでmemo。


# やりたかったこと。
フォルダAのスプレッドシートをフォルダBにコピー（copyFile）する。
コピーファイルのidをゲットして、いろいろSpreadsheetAppクラスのメソッドを使って操作したい。


# まず、Google Driveにおけるファイル操作は下記の2パターンある。

- DriveAppサービスを使う
- DriveAPIを使う
    - スクリプトのプロジェクトに下記のいづれかの方法で明示的に読み込み設定が必要。
        - マニフェストファイルに記述する
        - リソース＞Googleの拡張サービス＞Drive APIのチェックをonにする



# コピーの仕方にも色々あった。

## 前提

```javascript

var sourceFolder = DriveApp.getFolderById(souceId); //ソースフォルダ
var destinationFolder = DriveApp.getFolderById(destId); //宛先フォルダ
var sourceFile = DriveApp.getFileById(fileId); //ソースファイル

var copyFile; //ここにコピーしたファイルを入れたい
```


## 方法1

```javascript
copyFile = destinationFolder.createFile(sourceFile.getBlob());
copyFileId = workingFile.getId();
doc = SpreadsheetApp.openById(copyFileId).getSheets()[0];
```

なぜか、PDFとしてコピーされるので、3行目でエラーになる。


## 方法2

```javascript
mimecode = "GOOGLE_SHEETS";
options = {
        title: sourceFile.getName(),
        mimeType: MimeType[mimecode],
        parents: [{ id: destinationFolder.getId() }]
    };
copyFile = Drive.Files.insert(options, sourceFile.getBlob());
copyFileId = copyFile.getId();
doc = SpreadsheetApp.openById(copyFileId).getSheets()[0];
```

なぜか、Google Document（.gdoc）としてコピーされるので、3行目でエラーになる。



## 方法3

```javascript
copyFile = destinationFolder.addFile(sourceFile);
copyFileId = copyFile.getId();
doc = SpreadsheetApp.openById(copyFileId).getSheets()[0];
```

戻り値がFileではなくFolderなので、保留。



## 方法4
```javascript
copyFile = sourceFile.makeCopy(sourceFile.getName(), destinationFolder);
copyFileId = copyFile.getId();
doc = SpreadsheetApp.openById(copyFileId).getSheets()[0];
```

求める結果になった。こちらを採用。


# さいごに
なぜ、PDFやGoogle Docになるのか、不明なままです。
②に関してはmimetypeの指定方法が違うのかも。
もし、何かわかる方がいらっしゃればコメントいただけると嬉しいです。

個人的にはGoogle製品のコピーは"方法4"、MS Office製品をGoogle形式に変換する場合は"方法2"で良いのかなと思います。
【大人のプログラミング入門】プログラミングとは何か？

皆さんはプログラミングと聞いて何を思い浮かべるでしょうか？
映画などでは黒い画面に向かって文字を入力しているイメージが強いかと思います。
ではあれは何を入力しているんでしょうか？
今回はプログラミングとは何かについて解説いたします。

#プログラミングとは何か
プログラミングとはざっくり言ってしまえば電子機器へ命令出す事です。
命令の種類は多種多様ですが、様々な命令を組み合わせる事がプログラミングです。
またプログラミングで作られた物のことをソフトウェア、またはプログラムと言います。
この記事をご覧になっている方はなんらかの電子機器を使って読んでいるかと思います。
その中でパソコンを例にとって解説いたします。

##パソコンの中で何が起こっているか？
皆さんパソコンのソフトでWindowsというソフトの名前は聞いた事があるでしょうか？
多くの方は仕事や自宅でWindowsを使っているかと思います。
このWindowsは少し特殊なソフトウェアで、パソコンを動かすために様々な命令を用意しているソフトウェアになります。
Windowsのような少し特殊なソフトウェアのことをOS(オペレーティング・システムの略)と言います。
OSはいくつか種類がありますが、基本的にはOSが入っていないパソコンは何もできません。
このOSが動くことで通常皆さんが使うパソコンの状態となります。
そして一般的にはOSが用意している命令を使ってプログラミングする事で、様々なソフトウェアが動作します。
例えばExcelはOSの命令を使ってプログラミングすることで皆さんが使えるようなプログラムになっています。

##補足
上記で登場したOSなど、プログラミングを行なっていると独特の用語が沢山登場します。
一つ一つの用語については解説いたしませんが、興味ある方はインターネットなどで調べると答えが見つかると思います。
またITの国家資格としてITパスポート試験という物があります。
少し大変ですが、ITパスポートを勉強すると満遍なくITの知識が学べます。

#プログラミング言語とは？
上記でプログラミングはパソコンに命令を出す事を学びました。
では実際にどうやってパソコンに命令を出すのでしょうか？

##0と1の世界
皆さんドラマや映画、またアニメなのでコンピュータの世界は0か1でできているというのを見た事はないでしょうか？
実際パソコンを使っていて0か1の世界を実感する事はないかと思います。
しかし実際はパソコンは0か1の信号でしか命令を理解できません。

##コンピュータと人間の橋渡し
上記で説明した0か1でコンピュータに命令を出すのは非常に大変です。
その為人間がパソコンに指示を出しやすい形で命令できるよう、パソコンと人間の間で橋渡しをするものがプログラミング言語になります。

##プログラミング言語の種類
ここでは詳細は解説致しませんが、プログラミング言語には用途に応じて様々なものがあります。
それぞれ一長一短があるので場面に応じて使い分ける事が多いです。
これだけ聞くと「様々なプログラミング言語を覚えなければならないのか？」と感じる方もいるかもしれませんが、大体一つのプログラミング言語をしっかりマスターできればその言語だけで仕事をする事も可能です。
プログラミング言語の入門本については書店でたくさん売っていますので、自分の作りたいものに応じて言語を選ぶと良いでしょう。

#プログラミング学習の効果
プログラミング学習には以下の効果があります。

##ITの世界で仕事ができる
論理的思考が身につく
パソコンを調子が悪い時に原因が探る事でできる
ITの世界で仕事ができる
プログラミングを学ぶ最大のメリットはIT業界でプログラマーとして働くことが出来ることです。
IT業界は慢性的に人手不足な為、今はプログラミングができれば未経験でも採用する企業もあります。
また世界規模で株価の時価総額を見ると上位にIT関係の会社がかなりの数入っています。
その為IT企業は儲かり、社員の給料も高いことが多いです。

##論理的思考が身につく
プログラミングを学ぶメリットに論理的思考が身につく、というものがあります。
パソコンは人間が命令した通りにしか動かない為、しっかり順序立てて命令を出す必要があります。
その為自然と論理的思考が身につきます。

##パソコンの調子が悪い時に原因を探る事ができる
皆さんはパソコンを使っていて「調子が悪い」と感じた事はないでしょうか？
そんな時はプログラムがどう動いているかがわかると原因を探れます。
原因がわかると自分で解決できる場合もあるので職場などでパソコンを直すことができます。

#まとめ
今回の記事ではプログラミングとは何か、またプログラミング言語についてとプログラミング学習の効果について触れてきました。
要点は以下の3点です。

プログラミングとはパソコンを動かすために必要なプログラムを作る事
プログラミング言語とは0と1のパソコンの世界と人間の世界の橋渡しをする物
プログラミングの学習効果はIT業界で働けたり論理的な思考が身に付く
次回の記事ではプログラミングの「命令する」について解説していきます。

なお各講座の目次については以下の記事より参照できますので、よろしくお願いします。
小売業における画像検索の動向とイノベーション

本ブログは英語版からの翻訳です。オリジナルは[こちら](https://www.alibabacloud.com/blog/trends-and-innovations-of-image-search-in-the-retail-industry_594468)からご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。

人工知能（AI）とビッグデータ技術の台頭は、小売業界のイノベーションを後押ししています。アリババクラウドの画像検索やAIのための機械学習プラットフォームなどの最先端の製品は、顧客の商品との関わり方や買い物の仕方を変えてきました。顧客は、もはや実店舗で行列に並ぶ必要はなく、簡単な画像検索を行うことで便利に商品を検索することができます。

しかし、画像検索技術の利用は、小売業界の電子商取引プラットフォーム上での単純な商品検索に限られていません。近年では、簡易画像検索サービスとの融合により、新たな顧客体験を提供する取り組みが増えてきています。これには、在庫管理単位（SKU）検索だけでなく、商品と素材やパターンのマッチングに画像検索を利用することも含まれます。

本記事では、eコマースプラットフォームの商品検索以外にも、画像検索技術がどのように活用できるのかを紹介します。

#モバイルバーチャルアシスタント
小売業界における画像検索技術の革新的な応用として、モバイル・バーチャルアシスタントの開発があります。このソリューションは、顧客がバーチャルアシスタントを使って適切な商品を選択できるようにし、人件費を削減し、在庫管理を最適化することを目的としています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/c0794d9c-9436-0ba6-ea18-c6c13d3cc497.png)

転売屋ショップの新商品のプロモーションには、必ず課題があります。例えば、ショップのアシスタントの数が足りない、ショップのアシスタントが最新の商品情報を持っていない、商品ラインナップの全ての商品に精通していないなどです。さらに、似たようなパッケージの商品があると、顧客や店員が商品を見極めるのが難しくなります。

これらの問題は、画像検索サービスと連携したシンプルなアプリで簡単に解決できます。例えば、会員制アプリやQRコードを利用したバーチャルアシスタントを提供することができます。アプリを通じて、顧客は商品の写真を撮影して、商品の特徴や価格、比較などの商品情報を取得したり、商品を選ぶ際のガイドラインを取得したりすることができます。

顧客がより多くの質問を持っている場合は、オンラインの顧客サービス（[チャットボット](https://www.alibabacloud.com/ja/product/bot)やサービスセンターなど）を統合し、パーソナライズされたサービスを提供することで顧客をサポートすることができます。このフローは、クーポンや商品のおすすめなど、他のフォローアッププロモーションに簡単にリンクさせることができます。さらに、このアプローチは、顧客がオンラインショップから購入できるようにすることで、O2O統合のためのチャネルの1つにすることができます。

#ターゲットを絞ったキャンペーン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/1e675fdd-e8d0-16a4-4feb-1fd01a492cae.png)

マーケティングの競争が激しくなるにつれ、プロモーションゲームはマーケティングイベントの人気戦略となっています。しかし、楽しい体験を提供するだけでは十分ではありません。組織にとって、これらのマーケティングキャンペーンの収益性は、これらの質問に依存しています。

- これらのキャンペーンを販促品としてリンクさせるにはどうすればいいのでしょうか？
- 小売店への来店を促し、ターゲットとなる商品を体験してもらうためにはどうすればいいのか？


画像検索技術はここで重要な役割を果たしています。例えば、オフラインの小売店への来店を促すために、画像検索やAR（拡張現実）アプリを使ってインセンティブを与えることができます。店頭で関連する商品を検索してスキャンすることで、顧客にクーポンを提供するゲームを開発することができます。このアプローチを利用することで、顧客体験を向上させるだけでなく、モバイルアプリを通じてターゲットとなる商品の売上アップにも貢献します。

#SKU検索
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/01f8c434-c574-98d8-9ba1-572f6b38bdb4.png)

社内スタッフや生産ラインのパートナー企業の在庫管理単位（SKU）検索を容易にするために、通常はキーワード検索ができるように商品にタグを付ける必要があります。データ量の増加と商品タグの複雑化により、標準化されていないため、社内業務の負担になっています。

また、キーワードだけでは簡単に説明できない、検索できない商品も多くあります。その中には、糸や縫い目のパターンが異なるジュエリーや洋服なども含まれているかもしれません。このような場合には、画像検索が有効な手段となる。商品のタグ付けやキーワード検索を完全に置き換えることはできませんが、検索結果を補完し、作業効率を向上させることができます。

#結論
小売業界は急速に進化しており、画像検索技術はデータテクノロジー（DT）時代の電子商取引に欠かせない要素となっています。タオバオなどの企業は、画像検索とビッグデータ技術を自社プラットフォームに統合することに成功し、2018年のアリババダブル11ショッピングフェスティバルの開催期間中、1日で308億ドル以上のGMVを達成することに貢献しました。

Alibaba Cloudでの画像検索の詳細については、[https://www.alibabacloud.com/product/imagesearch](https://www.alibabacloud.com/ja/product/imagesearch) をご覧ください。

[アリババクラウドは日本に２つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ](https://www.alibabacloud.com/ja)
SwiftUIとStoryBoardの共存時期の過ごし方 for watchOS

## そろそろSwiftUI使ってもいいよね？
iOS14betaも発表されて、そろそろエンタープライズアプリもiOS13対応が許される季節になってきましたが、皆様いかがお過ごしでしょうか？
と言っても、実際には過去のプロジェクトはStoryboardで沢山の画面が作られているわけで、むしろ僕の触ってるプロジェクトはそもそもObjective-Cだったりするんですが、利用現場の端末のバージョンも上がってきて、そろそろiOS13 / watchOS6の機能を使えるような空気が漂ってきました。

iOSでStoryboardとSwiftUIを混ぜる方法は [こちら](https://qiita.com/owen/items/73473cd2206afda3c5d4)の記事を参考にさせていただいて非常に助かりました。

ところが開発者の少ないwatchOS関連は探してもなかなか見つからないのです。そうですね。仕方ないからメモを残しておきます。
業務の終わりのタイミングで書いてるので本当にメモです。

## storyboardなInterfaceControllerからSwiftUIに遷移

既存のInterfaceControllerからSwiftUIを呼ぶには、**WKHostingController** を使います。
https://developer.apple.com/documentation/swiftui/wkhostingcontroller

WKHostingController　は InterfaceControllerを継承しているので、今までと同じ感覚でクラスを連携させれば呼べます。

まずは、今までのWKInterfaceControllerの代わりに WKHostingControllerでコントローラーclassを作ります。

```HomeViewInterfaceController.swift

import SwiftUI

class HomeViewInterfaceController : WKHostingController<HomeView> {
    override var body: HomeView {
        return HomeView()
    }
}
```

```HomeView.swift
import SwiftUI

struct Menu: Identifiable{
    var id: Int
    var name: String
    
    init(id: Int, name: String){
        self.id = id
        self.name = name
    }    
}

class MenuList: ObservableObject{
    @Published var list: [Menu]

    init(){
        self.list = [
            Menu(id: 1, name:"Apple"),
            Menu(id: 2, name:"Banana"),
            Menu(id: 3, name:"Cookie"),
            Menu(id: 4, name:"Donuts")]
    }    
}

struct HomeView: View {
    @ObservedObject var mymenu: MenuList = MenuList()
    
    var body: some View {
        List {
            ForEach(mymenu.list){ item in
                NavigationLink(destination: SecondView(id: item.id)) {
                    Text("\(item.name)")
                }
            }
        }
    }
}

```

storyboardにinterfaceControllerを追加して、参照先のclassをHomeViewInterfaceController.swift に Identifierを "HomeViewInterfaceController"にします。
![スクリーンショット 2020-07-09 17.43.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45591/f586b1f8-17e4-6bf4-ccaf-b757e0466d78.png)

InterfaceControllerから　SwiftUIを呼び出すには

``` InterfaceController.m
    [self pushControllerWithName:@"HomeViewInterfaceController" context:nil];

//rootViewとして呼び出すには
    [WKInterfaceController reloadRootPageControllersWithNames:@[@"HomeViewInterfaceController"] contexts:nil orientation:WKPageOrientationVertical pageIndex:0];
```

といつものようにIdentifierを指定してあげればOK。

HomeからSwiftUIで定義されているSecondViewを呼び出すには、上の

```
                NavigationLink(destination: SecondView(id: item.id)) {
                    Text("\(item.name)")
                }
```

で呼び出せます。


## SwiftUIからwatchKitのstoryboardのInterfaceControllerに遷移

    public init(destinationName: String, @ViewBuilder label: () -> Label)
を使います。

```
NavigationLink(destinationName: "second") {
　　　　Text("\(item.name)")
}
```

## SwiftUIからstoryboard のInterfaceControllerでrootViewsをリセット
```
            Button(action: {
                WKInterfaceController.reloadRootControllers(withNamesAndContexts: [(name: "second", context: [:] as AnyObject )])
            }){
                Text("second")
            }

```
macOS CatalinaにアップデートしたらCocoaPodsが動かなくなったときの対処

## pod installでエラー
```
$ pod install
-bash: /usr/local/bin/pod: /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/bin/ruby: bad interpreter: No such file or directory
```

`pod install` で上記エラーが発生するようになりました。タイトルにはCatalinaにアップデート後としましたが、本当にOSアップデートが原因かはわかっておりません。
このときの対処が

```
sudo gem install cocoapods -n /usr/local/bin
```

でパスを指定してCocoaPodsを再インストールして正常に動くようになりました。
参考:[[Xcode]Mac OS Catalinaにアップデートしたらpodコマンドが通らなくなった](https://www.yukiiworks.com/archives/385)

## ライブラリの追加がうまく動かない
このあとライブラリを新規に追加しようとすると

```
[!] Oh no, an error occurred.
```

というエラーが表示される（上下にも色々ありますが、詳細な原因はわからない）
調べたところレポジトリが壊れているようなので

```
rm -rf ~/.cocoapods/repos/trunk/
```

でリポジトリを削除します。
するとライブラリの追加も問題なくなりました。
参考：[pod install fails with json error on Mac OS X 10.15](https://github.com/CocoaPods/CocoaPods/issues/9260#issuecomment-542586026)
初学者用これだけは覚えておきたい gitコマンドまとめ

プログラミング初学者が、アウトプットのため気まぐれ更新。
アドバイス等あればご教示頂きたく、よろしくお願い致します。

今回は、最近使い始めたgitコマンドを備忘録的にまとめます。

##基本のコマンド

```
git branch
```

存在するgit branchを取得することができる
現在いるbranch名が米印・緑色で表示される

```
git add -A
```

全てのデータがステージングされる。



```
git commit -m "メッセージ"
```

ステージングされた変更をコミット（確定）する。
ダブルクォーテーションの中には、任意のメッセージを入れることができる

```
git push origin branch名
```

ブランチ名を指定して、リモートブランチへpushする


```
git pull origin branch名
```

指定したブランチをリモートからローカルへ保存する

##ブランチ系の処理

```
git checkout branch名
```

指定したブランチから抜ける


```
git checkout -b '新しいブランチ名' '元々のブランチ名'
```

今いるブランチから、抜けて、新しいブランチを設置する


##マージ系

```
git merge branch名
```

マージ先のブランチに所在を移しておく。

##デンジャー系

```
git branch --delete branch名
```

ローカルのbranchを削除する。
ローカルのbranchが削除されるだけで、リモートには存在する


----

初学者のため、認識違い等あれば、ご指摘頂きたく。


gitの尊さを実感しています。
随時更新予定。
Wordpressのアクセスログから、ログインに成功したログを検索する


## 前置き
関わったことのないWPシステムのログ調査を依頼されたのですが、
アクセスログが攻撃の無法地帯で、どこから手を付けてよいものか。。と悩んだ末、
まずはログインに成功したか否かの観点で調査を進めることにしました。

## ログイン成功のログを調査
どうやらログインに成功すると「302」失敗すると「200」のHttpStatusになるようなので、その線でgrepする。

```bash
 cat ssl_access.log* | grep "POST /wp-login.php HTTP/...\" 302
```

結果は伏せますが、13個ほどのIPのアクセスが、ログイン成功していました。

## 該当IPのログを調査

```bash
cat ssl_access.log* | grep 111.222.333.44
```

## 上記の結果、

- 大量のログイン失敗後に成功している（総当たり攻撃が成功している）
- ログイン後に怪しげな攻撃アクセスを行っている

といったログがあればアウト。

また、下記のようなアクセスは、正常ログイン時にも記録されるものなので無視でOKです。
### ログイン直後
- `"GET /wp-admin/ HTTP/2.0" 200`
- `"GET /wp-admin/load-scripts.php?c=1&lo......`
- `"GET /wp-admin/load-styles.php?c=1&dir=ltr&load%5Bchu.......`
- `"GET /wp-admin/admin-ajax.php?action=dashboard-widgets&widge.........`

### ダッシュボード等の画面表示中
- ` "POST /wp-cron.php?doing_wp_cron=1594281453.2171.........`
- `"POST /wp-admin/admin-ajax.php HTTP/2.0" 200`

## あとがき

ログイン成功時に`wp-settings-time`という文字がログに追記されるという記事もあったのですが、どうやら設定で省略されてしまった様子でした。

## 参考にさせていただきました。
https://www.orange-ss.com/column/0108.html
https://www.kdl.co.jp/special/img/otaku/whpaper_20161101.pdf
いつも忘れる Flask-Cognito

# CognitoのJWTで認証をしてAPIを実行する方法
githubの説明がわかりにくい...
cognitojwtモジュールのコードまで見に行かないといけなかった...
先駆者がいるありがた味がわかる。

## flask-cognitoのインストール
```
pip install flask-cognito
```

## JWKSの取得(サーバーがAWSにアクセスできない環境への対応用)
アクセスできるならなくてもよい。
あるとトラフィックが抑えられるかも。知らんけど。
https://cognito-idp.{リージョン}.amazonaws.com/{ユーザープールID}/.well-known/jwks.json

## flaskに各種設定
```
from flask_cognito import CognitoAuth, cognito_auth_required

app = Flask(__name__)
app.config['COGNITO_REGION'] = 'リージョン'
app.config['COGNITO_USERPOOL_ID'] = 'ユーザープールID'
app.config['COGNITO_APP_CLIENT_ID'] = 'クライアントID'
app.config['COGNITO_CHECK_TOKEN_EXPIRATION'] = True #"True"の場合、トークンの有効期限を無視する
app.config['COGNITO_JWT_HEADER_NAME'] = 'Authorization' # CognitoからのトークンならこのままでOK
app.config['COGNITO_JWT_HEADER_PREFIX'] = 'Bearer' # CognitoからのトークンならこのままでOK

# ここはflask-cognitoのための処理ではなく、congnitojwtモジュールのための処理 
# サーバーがインターネットに接続できない環境の場合、JWKSを配置することで認証が可能
# パスはサンプル。お好きなところにどうぞ。
# ちゃんと設定されたかの確認もお好みでどうぞ。
os.environ.setdefault('AWS_COGNITO_JWSK_PATH', 'cognito/jwks.json')

cogauth = CognitoAuth(app)

@app.route('/', methods=['GET'])
@cognito_auth_required # 認証をかけたいエンドポイントに追加するだけ
def page_index():
    return render_template('index.html')

```

どうせまた忘れる

#### ユーザーグループの対応
対して難しくないので、こちらはgithubのサンプルをどうぞ。
pyinstaller --onefile で固めた.exeで、実行時に動的にモジュールをimportする

Python公式では非推奨だが、成果物を人に渡す時に、以下のような *config.py* を、 *main.py* と同階層に置いて、*mian.py* でインポートしてそのまま使ったりすることがあった。

```config.py
width = 10
height = 10
count = 100
threshold = 50
```

```main.py
from config import *
```

今回pyinstallerで固めた.exeからも、動的に外部のパラメータをimportするようにしたかったのだが、ハマったのでTIPSをメモしておく。

まず、こちらの記事が非常に参考になった。
(参考) https://ja.coder.work/so/python/1422895

普通に.exeにしたものは、importlibを使えば動的にimportしてくれるのだが、 *--onefile* で固めると、config.pyも内部に取り込まれてハードコーディングされる模様。
この問題に関しては、(泥臭い方法だが)とりあえず.exe化するときに *config.py* を消しておくことで対応した。(おそらく *--hidden-import* とかを使って.specファイルを編集して～みたいなのが正しい手順)

あとは *main.py* 内で

```main.py
import os
import sys
import importlib

sys.path.append(os.path.join(os.path.dirname(__file__), '.'))

config = importlib.import_module('config')

width = config.width
height = config.height
count = config.count
threshold = config.threshold
```

としてカレントディレクトリをパスに加えてからimportしてやればOK。
Facebookの開発者アラートに対応する: [Action Required] Platform Not Selected

# FBからのメール
以下のような開発者アラートが届きました。

**1通目**
> [Action Required] Platform Not Selected
>  
>  
> To keep the Facebook platform and community safe, apps are periodically reviewed for compliance.
> 
> *** couldn't be reviewed because it does not have a platform selected.
> 
> To keep your app functioning without interruption, update the app Settings to include all of the platforms it uses. If this isn't updated, your app will be restricted in accordance with Platform Policy 7.9.
> 
> A confirmation alert will be sent as soon as you update this setting.
> 
> For help, see Specify Platforms in the App Setup documentation.

**2通目**
> To keep the Facebook platform and community safe, apps are periodically reviewed for compliance.
> 
> *** couldn't be reviewed because it does not have a platform selected.
> 
> To keep your app functioning without interruption, update the app Settings to include all of the platforms it uses. If this isn't updated, your app will be restricted in accordance with Platform Policy 7.9.
> 
> A confirmation alert will be sent as soon as you update this setting.
> 
> For help, see Specify Platforms in the App Setup documentation.

# 対応
以下の手順で対応できます。

1. Facebook Appの設定>ベーシックを開く
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50056/35eda770-8bf1-8c51-0618-0f16c25d2068.png)
1. 画面一番下の **プラットフォームを追加** から、FBの機能を利用しているプロダクトの情報を登録。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50056/75d31a1c-30f3-79a4-acb8-dfde1c4af0a2.png)
1. 画面上部のトグルで、アプリが **開発中** になっている場合はライブモードに変更する。
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50056/c96eb00d-55c5-1ee7-5d63-f75aaa3a30cd.png)
Nuxt.jsでのレンダリングエラーの修正について

## 今回発生した挙動
nuxt で作成したサイトを`npm run generate`して
ホスティングした際に遷移がうまくいかない。

n-linkで遷移しようとしてもURLは変更できるものの
ページはリロードされないと表示されない状況。

## 原因
レンダリングでエラーが発生している。
エラー分は下記になります。

![picture_pc_33ddf4c62d958e654c6dc8b4761909a6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199085/c39006c9-cc1e-e269-ddf6-67f42204824a.png)

```
[Vue warn]: The client-side rendered virtual DOM tree is not matching
server-rendered content. This is likely caused by incorrect HTML markup,
 for example nesting block-level elements inside <p>, or missing <tbody>.
Bailing hydration and performing full client-side render.
```

## 修正する
- ブロックレベルの要素を`<p>`の中に入れ子になっている場合は修正
- tableタグに`<tbody>`を追加する
- `<no-ssr/>`を追加する 対象のGithubのissue

今回の自分の環境ではpタグの中にブロック要素を追加してしまっていたので修正したところ解決しました。

## 今回の学び
レンダーエラーが具体的にどのような挙動に影響するのかを学べた。
Angular CLI を npm install しようとしたら、EEXIST: file already exists .... といったエラーが出た場合の対応

## 環境
- macOS 10.15.5
- node: 13.11.0
- npm: 6.13.7

## angular cli をインストールしようとした際に遭遇したエラー

```
% npm install -g @angular/cli
npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142
npm ERR! code EEXIST
npm ERR! syscall symlink
npm ERR! path ../lib/node_modules/@angular/cli/bin/ng
npm ERR! dest /usr/local/bin/ng
npm ERR! errno -17
npm ERR! EEXIST: file already exists, symlink '../lib/node_modules/@angular/cli/bin/ng' -> '/usr/local/bin/ng'
npm ERR! File exists: /usr/local/bin/ng
npm ERR! Remove the existing file and try again, or run npm
npm ERR! with --force to overwrite files recklessly.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/watashi/.npm/_logs/2020-07-09T08_20_01_508Z-debug.log
```

## 解決した方法

- エラーに表示されていた通り、 `File exists: /usr/local/bin/ng.` なので `Remove the existing file and try again, or run npm with --force to overwrite files recklessly.` します

```
% sudo rm -rf /usr/local/bin/ng
```

その後、通常通りインストールします

```
% npm install -g @angular/cli
```
【iOS】UIWebViewの削除のためにやったこと

## UIWebViewの廃止

iOSアプリからUIWebViewを2020年12月までに削除することが必須となりました。
[Updating Apps that Use Web Views](https://developer.apple.com/news/?id=12232019b)

そのために開発している古いアプリからUIWebViewを削除するためにやったことを書いていきます。当然これで対応が全てではない（どころかほんのちょっと）のでその点だけ注意してください。古いコードなのでObjective-Cのみ対応しました。

## どこでUIWebViewが使用されているのか
ここでプロジェクト内検索をかけました。

```sh
$ cd yourprojectpath
$ grep -r "UIWebView" .
```

これでUIWebViewが使われているところを検索しました
参考：[How to search for any UIWebView component usage inside a current project?
](https://stackoverflow.com/questions/58091231/how-to-search-for-any-uiwebview-component-usage-inside-a-current-project)

## 電話を掛けるときに利用していたUIWebViewの削除
知らなかったのですが、UIWebViewから電話を掛ける画面の表示が可能なようです。その実装を置き換えていきます。

### UIWebViewの場合
```objective_c
UIWebView *callWebview =[[UIWebView alloc] init];
NSURL *phoneNumberURL =[NSURL URLWithString:[NSString stringWithFormat:@"tel://%@", @"09011111111"]];
[callWebview loadRequest:[NSURLRequest requestWithURL:phoneNumberURL]];
[self.view addSubview:callWebview];
```

### UIWebViewを使わない場合

```objc
NSURL *telURL =[NSURL URLWithString:[NSString stringWithFormat:@"tel://%@", @"09011111111"]];
[[UIApplication sharedApplication] openURL: telURL];
```

## WKWebViewへのリプレイス
単純にWKWebViewに置き換えていきます。

```objective_c
#import <WebKit/WebKit.h>
```

```objc
-    UIWebView *web = [[UIWebView alloc]initWithFrame:CGRectMake(0,0,ScreenWidth, ScreenHeight)];
+    WKWebView *web = [[WKWebView alloc]initWithFrame:CGRectMake(0,0,ScreenWidth, ScreenHeight)];
```

### WEBページのアラートやpromptが表示されない
単純にWKWebViewに置き換えただけだとWEBページのalert、confirm、promptが表示されなくなります。WKUIDelegateのプロトコルに準拠する必要があります。
Alert等の表示は都度確認して表示するのかしないのか、またはカスタマイズして表示することが可能となります。

```objc
@interface HogeViewController () <WKUIDelegate>
```

```objc

// Alertの表示
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler 
{
}

// Confirmの表示
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler
{  
}

// Promptの表示
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler
{    
}

```

ここの実装はこちらの記事を参考にいたしました
参考：[WKWebViewでJavaScript(Alert,Confirm,Prompt)の処理](https://qiita.com/ShingoFukuyama/items/5d97e6c62e3813d1ae98)
単純に表示するのであればコピペで十分かと思います。

## その他ライブラリのアップデート
CocoaPods、Carthageで使用されているライブラリでUIWebViewを利用しているものがあったため、削除・アップデートを掛ける部分がありました。
以上で作業は完了です。
UiPath Orchestratorの認証API（/api/Account/Authenticate）が通らない問題

**UiPath Orchestrator v2020.4** で発生することを確認済みです。

# ユーザーもパスワードも間違ってないのに認証できない

UiPath Orchestrator APIの``/api/Account/Authenticate``で認証キーを取得しようとしたら、何度やっても

``` json
{
  "message": "Invalid credential, failed to login."
}
```

うーん・・・何故だ・・・

# Orchestratorの不具合だった

偶然古いパスワード入れたところ、なぜか認証が通って「は？:thinking:」となりました。

検証してみたところ、新しいユーザーを作成した際にパスワードを設定しますが、そのあと<font color="red">**「最初のログイン時にパスワードを再設定した場合」**</font>に発生する不具合のようです。

「新しいユーザーを作成した際に設定したパスワード」だと通ります。
「最初のログイン時の再設定したパスワード」だと弾かれます。

``` :例
初期パスワード：ABCD1234　　←APIはこっちが通る。UI(Web)ログインは弾かれる。
再設定パスワード：QWER5678　←UI(Web)ログインはこっちが通る。APIは弾かれる。
```

## 回避策

ユーザーのプロファイルページから、パスワードを再設定します。
（同じパスワードと、前回のパスワードに再設定はできません。）

## 既知の問題でした

偶然見つけた不具合でしたが、UiPathのコミュニティにも報告がありました。
https://forum.uipath.com/t/orchestrator-on-prem-api-authentication-not-working-with-new-password/230286/

認証通らなくて困ってたので、同じ現象に悩まされている方の助けになれば幸いです。
laravel7 マルチ認証でログアウト後にログインできなくなる

## 現象

管理者画面のログアウト後に違うアカウントでログインするとログインできないで「/login」にリダイレクトされる。

ちなみに認証は「laravel/ui 」を利用しています。

## 原因
ログアウト時にセッションがクリアされていないみたい。

## 対応

logout時にセッションをクリアするように修正。

```diff
--- a/app/Http/Controllers/Admin/Auth/LoginController.php
+++ b/app/Http/Controllers/Admin/Auth/LoginController.php
@@ -7,6 +7,7 @@ use App\Providers\RouteServiceProvider;
 use Illuminate\Foundation\Auth\AuthenticatesUsers;
 use Illuminate\Support\Facades\Request;
 use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Session;

 class LoginController extends Controller
 {
@@ -53,6 +54,7 @@ class LoginController extends Controller
     public function logout(Request $request)
     {
         Auth::guard('admin')->logout();
+        Session::flush();

         return $this->loggedOut($request);
     }

```
Django Channels のデプロイ時に注意すべきこと

#はじめに
今回はDjango Channelsを用いて作成した、websocketを用いてチャット等ができるDjangoアプリのデプロイ時に注意すべきことを紹介します。

#asgi.py
asgi.pyは以下のように変更しましょう。おそらく、チュートリアルの際に記述したコードと若干違うと思います。(`django.setup()`や`get_default_application()`など)

```python:asgi.py
import os
import django
from channels.routing import get_default_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")
django.setup()
application = get_default_application()
```

#サーバ
[こちら](https://channels.readthedocs.io/en/latest/deploying.html)を参考にして、好きな構成にしましょう。

#おわりに
デプロイ作業中に上記以外の気づきがあったらその都度追記していく予定です。
Ruby 二次元配列

## 二次元配列とは?

2次元配列とは、プログラムで利用される配列において、**配列の中に配列が入っている配列**のことである。


## ソースコード
```ruby
fruits_price = [["apple", [200, 250, 220]], ["orange", [100, 120, 80]], ["melon", [1200, 1500]]] # 配列Key 合計額算出

fruits_price.each do |fruit|
  sum = 0
  fruit[1].each do |price|
    sum += price
  end
  puts "#{fruit[0]}の合計金額は#{sum}円です"
end
```
## 結果
```
appleの合計金額は670円です
orangeの合計金額は300円です
melonの合計金額は2700円です
```

### 説明
### keyにフルーツの名前、valueにそのフルーツの値段が配列で複数

```
[["apple", [200, 250, 220]]
```

### Ruby each文
```
オブジェクト.each do |変数|
  実行する処理1
  実行する処理2
end
```
こちらで要素を一つづつ取り出しています。

```ruby
fruits_price.each do |fruit|
  sum = 0
  fruit[1].each do |price|
    sum += price
  end
```
ここで、配列の中の価格が入っている配列に対して要素を取り出し、
合計(sum)に格納します。

これで完成です。
TeXで素数判定

タイトル通りです．

```TeX
\usepackage[ドライバ]{xcolor}

% =============================================

\makeatletter
\def\Prime#1{\bgroup\def\numcolor{\textcolor{red}}%
  \@tempcnta#1\@tempcntb\tw@%
  \ifnum\@tempcnta=1
    \let\numcolor\relax%
  \else
    \@whilenum\@tempcntb<\@tempcnta\do{%
      \divide\@tempcnta\@tempcntb\multiply\@tempcnta\@tempcntb\relax
      \ifnum\@tempcnta=#1\let\numcolor\relax\fi
      \@tempcnta#1\advance\@tempcntb\@ne\relax
    }
  \fi\numcolor{#1}\egroup}
\makeatother

\Prime{5}
\Prime{334}
```
結果

><font color="Red">5</font> 334

自分もまだ勉強段階です．

[参考](http://0-chromosome.hatenablog.jp/entry/2015/12/07/000000)
Power Automate でテキスト形式のメールを転送する時に改行を保つ方法

#Power Automate を使用し受信したメールに一言添えて転送する
受信したメールを転送するだけ。
##Office365 Outlook のトリガーとアクションを使って簡単に設定できる；
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573860/8348e3a2-fb9f-f67f-e35c-ad59f6225776.png)
ところが、元の受信メールが「テキスト形式だった場合」転送されたメールで改行が崩れる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573860/ec11ede4-0009-65c9-40d6-1ba03c93f3fb.png)
参考：[「テキストメール」と「HTMLメール」、特徴と違いを理解する](https://www.innovation.co.jp/urumo/textmail_htmlmail/)

###「新しいメールが届いたとき(V3)」からOutput される文字列の例；
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573860/2329ea26-8de1-32d7-c774-48f36444c9d0.png)

黄色ハイライトの通り、
`\r\n`
が改行コードとして入っている。

と、言うことは、
1. テキスト形式のメールを受信した時には、[\r\n] が改行コードとして入っていた。
2. 転送をしようとしたら、転送メール自体はHTMLで書かれているので、「追加の一言」等は改行されている。
3. 転送メールに挿入した「テキスト形式の元メール」からは、メール送信の際には改行コードが消えている。

###「メールの送信（V2）」からOutput される文字列の例；
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573860/6adfec41-2486-3f8b-6577-7fbb3ed310b0.png)
改行コード `\r\n` が消えている。
#Power Automate で [\r\n] を [\<br>] に書き換える。
##以下の方法で出力（メールの送信をしてみる）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573860/4e181c41-d781-e27a-c8a3-2b7d7af80652.png)
(元々 動的コンテンツで [本文] だけを入れていてた、後述の [ちょっとした式] に変更した。メールを送信の本文中に [ちょっとした式] をそのまま挿入したら良い)

手を加えた方；
\<br> が改行したいところに入力されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573860/155e46a9-ff01-5048-534d-cda6f54e5586.png)
手を加えていない方；
\r\n も消えて、改行コードがなくなっている。※
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573860/a4e48422-772d-d664-b32b-a40de6448e4d.png)
※念の為に再確認しただけ。
##Power Automate でやったこと
以下のExpressions を使って、改行コード(\<br>) を挿入した（置換した）

```
何となく見やすい書き方
uriComponentToString(
  replace(
    uriComponent(
      triggerBody()?['Body']
      ), 
    '%0D%0A', 
    '<br>'
  )
)
```

```
Power Automate で使う用の書き方
uriComponentToString(replace(uriComponent(triggerBody()?['Body']), '%0D%0A', '<br>'))
```
####各項目の説明（自分の理解なので間違っているかも）
|項目|説明|参考|
|:---|:-----------------------|:--------------------|
|uriComponentToString|URIエンコード文字列をデコード|https://docs.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference#uriComponentToString|
|replace|[Body] の [%0D%0A] を [\<br>] に置換|
|uriComponent|URL の安全でない文字がエスケープ文字に置き換えられた、文字列の URIエンコード バージョンにする。<br>※ 要は[\r\n] を[%0D%0A] と表記する|https://docs.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference#uriComponent|
|triggerBody()?['Body']|Input となるメールのBody 部分を引用||
|%0D%0A|\r\n の16進数で表記（ここ大事）|http://seclan.dll.jp/cccrlf.htm , https://qiita.com/uhooi/items/dc74ff3434aecb17faa2|
|\<br>|HTML 改行コード||

##結局のところ
上述のExpressions を使えば ***テキスト形式のメールも改行が出来る*** ということでした。
これは、メールの転送以外にもTeams への投稿などでも使う機会がありそうです。
Dockerとは何か？[入門編]

#Dockerについて
> コンテナ仮想化を用いてアプリケーションを開発・配置・実行するためのオープンソフトウェアあるいはオープンプラットフォームである。（wikipediaより）

コンテナ？仮想化？何それ状態だと思います。次にそれらについて解説します。

##コンテナとは
OS上に区画を作り、アプリケーションを動作させるために必要なライブラリやアプリケーションなどを一つにまとめたものである。

##仮想化とは
コンピュータリソースを抽象化することである。
コンピュータそのものをハードウェアからソフトウェア化することを目指す。

##Dockerのメリット
まずよく比較されるサービスとして**VMware**や**VirtualBox**などの仮想マシンがあります。
こちらがメリットです。

1. 簡単に環境開発
2. 軽量でスピーディーな開発
3. ハードウェアの資源削減
4. 共有化されたシステム
5. イミュータブル・インフラストラクチャである点
6. 物理サーバの考慮を後回しにできる点
7. モダンなエコシステム


###Dockerのデメリット
1. 同一のOSを利用しなければならない
2. 提供できるホストの種類が少ない
3. Windowsでの利用ハードルの高さ

##仮想マシン(VMware・VirtualBox)について

ここからしばらくDockerから少し離れるので気になる方以外は飛ばしてください。

###仮想マシン
仮想マシン技術による仮想化の方式として**ホストOS型****ハイパーバイザー型**があります。

####ホストOS型
本来入っているOS（WindowsやMac・Linux）上で仮想化ソフトを使い、その上で仮想マシンを立ち上げる方法。

#####メリット
・ホストOSが対応していれば、ハードウェア環境にほぼ依存しない。
・管理マシンを必要としない。
・ハイパーバイザー型と比べて手軽に環境構築が可能。

#####デメリット
・ホストOSが必要な点
・物理リソースが必要な点

####ハイパーバイザー型
サーバへ直接インストールし仮想マシンを稼働させる方法

#####メリット
・ リソースを有効活用できる点
・システムにかかるコストを削減

#####デメリット
・ 運用コストが割高になる可能性
・ 種類によっては知識や技術が必要な点
  (高度な管理を実現するためのツールが標準装備されていない可能性があるため。)



#####デメリット

見にくいと思うので、表にしてまとめてみます。

|       |       仮想マシン |    コンテナ技術    |
|:-----------------|------------------:|:------------------:|
| 起動             |     遅い（パフォーマンスによる） |        早い        |
|　OS           |            各仮想マシンに付き一つ |       一つで複数稼働可能      |
| コスト             |              大きい |        小さい       |
| 構成               |                ハードウェアに依存 |         ハードウェアに依存しない       |
|メモリ消費|大きい|小さい|



続けてDockerでよく使われる言葉について説明します。

##Dockerでよく使われるワード

###Dockerイメージ
OSやアプリケーションを含んだテンプレートのベースイメージ。読み取り専用。
構築（build）コンポーネント

###Dockerコンテナ
分離された名前空間とアプリケーションの実行環境
実行(run)コンポーネント

###DockerHub（Dockerレジストリ）
公開されているDockerイメージを提供しているプラットフォーム
配布(distribution)コンポーネント

###Dockerクライアント
ユーザがコマンドを反抗し、Dockerデーモンと通信を行う

###Dockerデーモン
ホストマシン上で動いている。直接ユーザとはやりとりはしない。管理者的な役割を果たす。


次回は実際にDockerを動かしていきます。
deeplinkのstateパラメーターについて

今回はdeeplinkにおけるstateパラメーターのチェックについてお話します。

OAuth周りでstateパラメーターのチェックをすることがあります。
stateについては以下を参照してください。

[OAuthやOpenID Connectで使われるstateパラメーターについて]
https://tech-lab.sios.jp/archives/8492

リダイレクトする際に注意することも多いと思いますが、アプリのdeeplinkでauth_codeとか送る際にも同様のことが言えます。

```
hoge://success?auth_code=XXX
```

みたいにauth_codeのみdeeplinkで送っていた場合、攻撃者が自分のauth_codeをdeeplinkで送り込んだりできてしまうためです。
そのため、deeplinkでもstateを送り

```
hoge://success?auth_code=XXX&state=YYY
```

アプリ内部で発行したstateと一致することチェックすることで攻撃者が自分のauth_codeをdeeplinkで送ることを防げます
【概要】NoSQL

# NoSQL
## 概要

 - Not only SQL
 - 非RDBMSを指すおおまかな分類語
 - 非RDBMSの利用・発展を促進する運動の標語
 - 1970年～1990年はビジネスフィールドへのITシステム導入が急速に進んだ
 - この時代ではまだ世の中はパソコン/インターネット時代には到達しておらず、情報管理を旨とするITの中心は正にデータベースにあった
 - 最初期では業務処理のため、メインフレームと呼ばれる巨大な専用機をITシステムの中核に採用していた
 - 現在ではIAサーバと総称される汎用サーバを並べ、クラスタシステムを構成することでITシステム全体としての性能向上を図る
 - 大量データ処理においてもクラスタシステムを構成し分散処理を行う
 - ネットワークとストレージのボトルネック
 -  データローカリティ
 -  Google File System (GFS) , Hadoop Distributed File System(HDFS) : 分散ファイルシステム
 -  Hadoop : 分散処理フレームワーク
 -  NoSQL : 分散データベース

## 詳細
 - どのような形でデータを持つか(データモデル)
 - どのように分散してデータを持つか(アーキテクチャ)
 - データ型の定義が必要ない
 - データ同士の関連は表現できない
 - 堅牢なトランザクションは、サポートしていないものが多い
 - 高速
 - SQLが使えないため条件を指定した検索などに苦労する
 - シンプルなデータ構造で、スキーマレスのものも多く自由に拡張できる
 - データの一貫性を一部犠牲にしているので分散させることができる

## まとめ

- NoSQLは分散データベース
- 複数台のPCで大量のデータを分散処理するためにNoSQLが生まれた
- 必要となるデータ量が増えたことが時代背景にある
- NoSQLの売りは「スピードと柔軟性」
- RDBMSの売りは「データの一貫性」


## 豆知識

- 1977年にOracleが世界初の商用RDBMSであるOracle v2を発売した
- 1989年 PostgreSQL (OSS)
- 1995年 MySQL (OSS)
- ムーアの法則 : ゴードン・ムーアが1965年に発表した半導体の成長に関する経験則


# mongoDB
## 概要
- humongousは英語で「ばかでかい」という意味で、MongoDBのmongoはこの単語が由来である
- オープンソースのドキュメント指向型データベース
- 自由度の高いドキュメントという形式でデータを格納する
- 1ドキュメント1件
- ドキュメントのフォーマットに定義はないので、その都度異なるデータ構造で書き込むことができ、スキーマレスである
- スケールアウトが可能
- インメモリで動作するため処理速度が速い
- 後からドキュメントの構造を変更することが容易

## 豆知識

- インメモリ型データベース
    - メモリ上でデータアクセスを行う


# 参考
[MongoDBの特徴と使い方を徹底解説！使いどころや導入のメリットは？MySQLとの違いや連携・移行方法もチェックしよう](https://agency-star.co.jp/column/mongodb/)
AI素人が日英のAI翻訳モデルをGoogle Colaboratoryで作成・評価してみた。

あんまり知られてないみたいですが、ヨーロッパでは評判がよいオープンソースの **ModernMT**（Fairseq Transformer Model）ツールを利用して**Google Colaboratory**で下記の手順で学習して翻訳を試してみた。

**ModernMT**は下記の特徴や翻訳APIが実装されているのですごく便利で開発中の英語学習アプリに使えそうだ。
>
・各文に対してより良い翻訳を予測するため、文書全体のコンテキストを使用。
・モデルは翻訳者による各修正からリアルタイムで学習。

 [GitHubのModernMTコード](https://github.com/ModernMT/MMT)

#####１．学習する対訳コーパスを事前に準備する。
今回無料と有料コーパス合わせて１００万文近くのデータを使って学習した。
**無料コーパス**
① [GlobalVoice (news)](http://opus.nlpl.eu/GlobalVoices.php)
② [日英基本対訳コーパス](http://nlp.ist.i.kyoto-u.ac.jp/index.php?日英中基本文データ)
>
   日本語基本文データの著作権は京都大学黒橋・河原研究室にあり、英語中国語基本文データの著作権はNICTマスタープロジェクト多言語翻訳研究室にある。両者は、Creative Commons Attribution 3.0 Unportedで利用可能である。

③ [日英法令対訳コーパス](http://www.phontron.com/jaen-law/index-ja.html)
④ [田中コーパス](http://www.edrdg.org/wiki/index.php/Tanaka_Corpus)

**有料対訳コーパス**
　[マジックスープAI翻訳](https://mingkeestudio.wixsite.com/magicsoup)
　[対訳コーパス購入](https://mingkeedata.stores.jp/?category_id=5ed4ac0934ef0160882a91b4)

#####２．学習するコーパスを自分アカウントのGoogle Driveにアップしておく。

#####３．Google Colaboratoryでノートブックを新規作成。

#####４．Google Driveをマウントする。
```
from google.colab import drive
drive.mount('/content/drive')
```
#####５．JAVAやPythonをインストール
```
!apt install -y openjdk-8-jdk python3 python3-pip
!update-alternatives --set java /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java
!java -version
```
#####６．GitHubからModernMTをダウンロード・インストール
```
!wget https://github.com/modernmt/modernmt/releases/download/v4.5.4/mmt-4.5.4-ubuntu.tar.gz
!tar xvfz mmt-4.5.4-ubuntu.tar.gz
!cd mmt; pip3 install -r requirements.txt
```
#####７．Googleドライブから対訳コーパスをコピーする。

![7CAP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664436/caaa0b36-7fa3-60f6-cc43-ab333058c81a.png)

#####８．日英モデルを学習する。Defaultコマンドで学習回数のみ設定

 エンジン名：mmt45_base_ja-en
 言語方向：ja en

```
!mmt/mmt create ja en -e mmt45_base_ja-en mmt/corpus/ --train-steps 1000
```
![8CAP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664436/9ffc938c-a6fd-142a-e310-572964e20f77.png)
1から4までのStepで翻訳モデルをModernMTで使える形にパッケージングしてくれる。
止めても --resume オプションで続けて学習できるのですごく便利。

```
!mmt/mmt create ja en -e mmt45_base_ja-en mmt/corpus/ --train-steps 30000 --resume
```

[ModernMTのCLIドキュメント](https://github.com/modernmt/modernmt/wiki/CLI-Documentation)

#####９．翻訳エンジンを起動
```
!mmt/mmt start -e mmt45_base_ja-en &
```
#####１０．翻訳
```
!mmt/mmt translate -e base0_ja-en "強盗殺人ではなく、殺人と窃盗の罪にあたる」などとして、無期懲役が妥当だと主張していました。"
```
[ModernMTのREST APIドキュメント](https://github.com/modernmt/modernmt/wiki/API-Documentation)

#####１１．機械評価
Defaultの値で３万回学習して、評価コマンドでGoogleとの比較（BLEU）
BLEUの機械評価ではModernMTの方がかなりの差で勝ちました。

![EVAL.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664436/8728a19a-20df-d086-b11b-75a9daa6f411.png)

####感想
機械翻訳やAIに関して何もわからない素人でも対訳コーパスがあれば自分アプリにAI翻訳APIを利用することができるかと思います。