OmniAICreator/Qiita-1.07M huggingface dataset:
画像処理の可逆性とその応用

# 画像は最も身近なファイル
画像を計算機上で扱うようになって何年経つのでしょうか。今では当たり前に、パソコン、スマートフォンで画像を見ています。テキストファイルよりも、ドキュメントファイルよりも、間違いなく最も身近なファイルは画像であることでしょう。一日に一回はスマートフォンのカメラを起動する、そんな時代になってきたのです。
画像ファイルが多く使われるようになって、益々その処理についての需要も大きくなっているということで、おそらく私のような画像処理を専門にする人よりも、そこらへんの女子高生のほうがスマートフォンでの画像処理に詳しいというのは想像に難くないわけです。
ということで、これほど身近になった画像というファイル形式について、その可能性は今まで以上に広がっても良いのではないかと思うのです。
ここでは画像処理の可逆性について触れ、私の運営するホームページにて用いられている技術を例に、その応用を探っていきます。

# 画像の可逆性
画像処理、例えば色変化、フィルタ、アフィン変換など、様々ありますが、それらは、可逆的なもの、不可逆的なものに大別できると考えます。
#### 可逆的なもの
- 単純な色変化
- 反転
- 90度の回転

など

#### 不可逆的なもの
- アフィン変換
- フィルタ
- モルフォロジ演算
- リサイズ

など

ここで、可逆、不可逆の定義をしなければなりません。
そもそも画像処理とは、画像全体の集合を$I$としたときの写像$f:I\longrightarrow I$ であると考えます。
可逆とは、その逆写像$f^{-1}$が容易に計算できるという写像$f$であり、不可逆とは$f^{-1}$が容易に計算できない、もしくは数学的に不可能であるというものであると、ここでは定義します。
さて、一次元、長さ3のメディアンフィルタ$f_{MF}$を例にしてみると、計算例は以下のようになります。

```math
\begin{align}
f_{MF}([3\ 2\ 9\ 0\ 2\ 6]) & = [3\ \mbox{med}(3, 2, 9)\ \mbox{med}(2, 9, 0)\ \mbox{med}(9, 0, 2)\ \mbox{med}(0, 2, 6)\ 6] \\
 & = [3\ 3\ 2\ 2\ 2\ 6]
\end{align}
```
ただし、$\mbox{med}(x, y, z) = y\ \ \ (\mbox{when}\ \ x\leq y\leq z)$

つまり、$[3\ 3\ 2\ 2\ 2\ 6]$から$[3\ 2\ 9\ 0\ 2\ 6]$が推測できれば可逆ということになろうかと思いますが、これは確実に推測不可能であるため、この例からもメディアンフィルタが不可逆な画像処理であるということが直感的にわかったのではないかと思います。
ただし、

```math
f_{MF}([3\ 3\ 3\ 3\ 3\ 3]) = [3\ 3\ 3\ 3\ 3\ 3]
```

のような場合は成り立ちません。すなわち恒等写像$f(a\in I) = a\in I$ではいけないということです。

# メディアンフィルタの実際
下の画像は私の書いたものですが、どちらかがオリジナル、どちらかがメディアンフィルタ適用のものです。さて、判別できるでしょうか。
<img width=200 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494500/21958ca7-52a3-64de-be7a-bffb995ec540.png">  <img width=200 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494500/9907bcec-90ec-69ef-d79b-88c52618297d.png">


書いた本人ですらわかりませんが、一応左がオリジナルです。
このように、メディアンフィルタの、実際の違いはほとんどわからないということなのです。
ほとんど同じに見えますが、ハッシュ値は以下のように異なります。
オリジナル: bbe27c5a63dac211d4d640ed878b5aad
メディアンフィルタ適用: 0990b70ffdc4dc0effa7991a806cc677

# 不可逆画像処理の応用
それでは、私の運営するホームページにおける、不可逆画像処理の応用例についてですが、まずそのホームページについての説明が必要でしょう。
ホームページは、簡単に言うとpixivの書作品バージョンのようなものです。ただし、アカウントを用いず、匿名で画像をアップロードできるようにしてあります。まだあまり利用されてませんが...
アカウントという形をとらないということで、問題になったのが画像の削除です。つまり間違って画像をアップロードしたとき、思い直して画像を消したくなったとき、本人だけがその画像を削除できるようにするにはどうしたらよいか。
そこで、以下のような仕組みを考えたわけです。

1. 画像がアップロードされたと同時に、画像ファイルのハッシュ値を計算し、データベースへ保存
2. 画像のEXIF情報を削除
3. 画像にメディアンフィルタ等の不可逆画像処理を適用、恒等写像でないか確認
4. 処理が適用された画像をホームページに載せる

ホームページにある画像のオリジナルの画像をアップロードすることで、ハッシュ値の比較により、アップロード者本人であることを確認でき、画像が削除されるというわけです。ホームページにある画像を使ってその画像を削除することはできない、ということです。
EXIF情報の削除だけでいいのでは、と思うかもしれませんが、そもそもEXIF情報のない画像がアップロードされる可能性もあり、このような手法をとっています。
欠点としては、オリジナルの画像ファイルをなくした場合、削除できないということです。
これはアカウントの認証等にも応用できる気がしますが、このオリジナルのファイルをなくしたときにどうしようもなくなるという欠点が大きすぎるため、現実的ではないかもしれません。このような限られた状況でのみうまくはたらくのでしょう。

# 主張
そもそも、本来はアカウントの不要なウェブサービスが多すぎる気がします。アカウントは個人情報の流出の危険と常に隣り合わせであり、私などはアカウント作成の段階で面倒になる人です。
当ホームページでは、画像のアップロード時にいちいちニックネームの入力を促していますが、その手間で安全性が担保されるのであれば、それは嬉しいことだと思っています。
colorboxのiframe可変

colorboxのiframeを表示コンテンツに応じた可変サイズにするテストです。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>test</title>
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="https://yarnpkg.com/en/package/normalize.css">
<link rel="stylesheet" href="colorbox.css">
<script src="http://code.jquery.com/jquery-3.1.1.js"></script>
<script src="jquery.colorbox-min.js"></script>
<script>
$(function(){
  $(".iframe").colorbox({
    iframe: true,
    innerWidth: 600,// 幅初期設定
    innerHeight: 400,// 高さ初期設定
    onComplete : function() {
      $('#cboxLoadedContent').children('iframe').on('load',function(){
        var $iframe = $(this);

        // bodyは特定の幅を持たないので、主要ブロックから最大幅を取得
        var W = Math.max.apply(null, $iframe.contents().find('body').find('div,header,footer,main,section').map(function (){
                  return $(this).outerWidth();
                }).get());
        // ドキュメント(body)の高さを取得
        var H = $iframe.get(0).contentWindow.document.body.clientHeight;

        // リサイズ
        $iframe.colorbox.resize({
          innerWidth: W,
          innerHeight: H,
        });
      });
    }
  });
});
</script>
</head>
<body>
<a href="modal.html" class="iframe">open iframe modal</a>
</body>
</html>
```

modal.html

```html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>modal</title>
<meta name="viewport" content="width=device-width">
<style>
  body {
    margin: 0;
  }
  main {
    display: block;
    width: 500px;
    margin: auto;
    padding: 20px;
    background-color: #ccc;
    box-sizing: border-box;
  }
</style>
</head>
<body>
  <main>
    <p>colorbox iframe test</p>
  </main>
</body>
```

## 参考

* https://codeday.me/jp/qa/20190402/505312.html
* https://highmoon-miyabi.net/blog/2016/04/21_000398.html
* http://chords.hatenablog.com/entry/2014/10/08/iframe%E3%81%A7%E5%9F%8B%E3%82%81%E8%BE%BC%E3%82%93%E3%81%A0%E3%83%9A%E3%83%BC%E3%82%B8%E3%81%AE%E5%B9%85%E3%83%BB%E9%AB%98%E3%81%95%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B
* https://codeday.me/jp/qa/20190109/99770.html
* https://codeday.me/jp/qa/20190614/1014584.html
* https://codeday.me/jp/qa/20181213/50445.html

以上、ありがとうございました。
DownloadHandlerTextureで取得した画像が解放されない

# TL;DR

`Destroy(texture)`または`Resources.UnloadUnusedAssets()`
またはシーン遷移

# DownloadHandlerTexture

`DownloadHandlerTexture`は画像をAssetBundleにしなくても使うことができます。
つまり、適当な`https://example.com/yukamaki.jpg`みたいなのを拾ってきてTexture2Dにまでしてくれるクラスです。
マニュアルを読む限り、textureプロパティにアクセスすることで追加のアロケーションは発生しないと書いてありますが、デコードはメインスレッドなのか、Rawなデータは破棄されているのかあたりが気になるところです。// 今度調べる
RawデータはHandlerのDisposeで消えそうな気がしますが…

AssetBundleで管理している場合は`AssetBundle.Unload`でOKです。

# Runtime生成Asset

ランタイム生成したAsset（`Object`）は基本的にこの扱いになり、`DownloadHandlerTexture.texture`はRuntime生成となるようです。
他にも、お馴染み`Instanciate(prefab)`や`new GameObject()`、`new RenderTexture()`などがこれに当たります。

# C#のオブジェクトがGCされたら一緒に解放

```csharp
class ManagedTexture2D : Texture2D
{
    public ManagedTexture2D(int width, int height) : base(width, height){}
    
    // GC時に呼ばれる
    ~ManagedTexture2D() => Destroy(this);
}
```

`DownloadHandlerTexture`のように、自分でnewしていないときには成すすべ無いので微妙…
docker環境でお試しImageMagickをインストール

### コンテナ立て直すと消えますので注意です〜

DockerでOSを汚さずに試しにImageMagick使いたいな〜〜ってときに！
またはUbuntuにImageMagickインストールしたいときに！
コンテナたてるときにインストールしたいのであれば、下記記事を参考にしてください。
※Dockerイメージ`php:7.2-apache`の環境です＞＜
https://qiita.com/saya1001kirinn/items/dacf5ef6b1d66ced846a

## Ubuntu + Apacheの環境です。

#### ImageMagickのインストール(パッケージマネージャを使ったインストール)

```
$ apt-get update
$ apt-get install imagemagick
```

PECLはPHP拡張モジュールのリポジトリとのことなので使えるとは思いますが、PHPが入ってなければ、または下記コマンド叩いて`command not found`がでたら

```
$ pecl help
```

下記コマンドでpeclインストール

```
$ apt-get install php-pear
```

これでインターフェースであるImagckがインストール可能になる。

#### 必要ないのもあるかもです…

・ライブラリ共通インターフェース

```
$ apt-get install gcc
```

・Magick-Wand（ImageMagick C用のAPI)

```
$ apt-get install pkg-config
```

・ImageMagick関連のライブラリインストール

```
$ apt-get install libmagickwand-dev
```

#### Imagickのインストール(ImageMagickをインストールしてあることが前提)

```
$ pecl install imagick
```

#### php.ini にextension=imagick.so追加

※php.iniあるディレクトリ取得　 

```
php -i | grep php.ini
```

※ディレクトリ先移動

```
cd /usr/local/etc/php  
```
※php.iniファイルがなければ作る 

```
cp php.ini-development php.ini 
```
※vimインストールしてなければイントール 

```
$ apt-get update 
$ apt-get install vim
```
#### php.ini のあるディレクトリで、vimでphp.iniを編集、extension=imagick.soを追加

```
vi php.ini
```

```
extension=imagick.so
```

i = 挿入（文字打てる）
:w = 内容保存
:q = 終了
esc = 文字打つのもうやめたい（インサートモードを終了し、コマンドモードに移行する）
:q! = わけわからんくなった辛い、とにかく終了したい（保存せず終了）

終了後、catコマンドで追記できてるか確認

```
cat php.ini
```

#### webサーバ再起動

```
service apache2 reload
```

PDFから画像に変換するために必要なライブラリGhostScriptをインストール（必要であれば）

```
$ apt install ghostscript
```

#### composerにパッケージ追加

```
$ composer require spatie/pdf-to-image
$ composer require spatie/pdf-to-text
```
※バージョン確認やパッケージの種類は下記パッケージリストを確認してください。
https://packagist.org/packages/spatie/pdf-to-imagehttps://packagist.org/packages/spatie/pdf-to-image


#### 終わりッッッ！！！！



## (念のため)インストールできているか確認
#### Imagick

```
$ imagick identify -version
```

#### ImageMagick

```
$ convert -version
```
GitHubのユーザー毎に使用するSSH鍵を切り替える(GitHub以外もいけるよ)

簡単3ステップでできます(メールアドレスとかユーザー名は適宜書き変えてね)
# 鍵作って(すでにある場合は不要)
```
ssh-keygen -t rsa -b 4096 -C "kasyuu@example.com" -f kasyuu
```

# ~/.ssh/configに設定
```
Host github-kasyuu
  User git
  Port 22
  HostName github.com
  IdentityFile ~/.ssh/kasyuu
  TCPKeepAlive yes
  IdentitiesOnly yes
```

# clone時にconfig設定を使用
ssh接続情報のhostをconfigに設定したものに書き換え

```
git clone git@github-kasyuu:kasyuu/project.git
```

これでOK。
cloneの時に指定しておけばローカルリポジトリのoriginにも同じ設定がセットされるので、今後は特に意識することなく使えます。
気になる方は

```
git remote -v
```

で確認してみてください。

# これどんな時に使うの?
フリーランスでいろんな現場にお邪魔してると、そこの現場のメールアドレスで開発で使用するサービスに登録することがままありまして、初めて現場のメールアドレスでGithubに登録することになったんですが、いつものようにPCにある公開鍵をコピペしてはっつけてみるとですね

<img width="1145" alt="スクリーンショット 2019-11-15 2.00.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236058/8889bad4-7c19-ad1c-2a44-9b9ae5984d55.png">

とこのようにその公開鍵は使用されてるよ!とエラーがでて登録されませんでした。
たしかに個人用のアカウントでこの鍵登録してますしね。
はえー、こりゃ賢い。
ダメと言われたら仕方ないですね。
そんな時に使いましょう。
【初学者向け】RailsのルーティングにおいてHTTPリクエストの設定で気をつける点

Railsを使ったアプリケーション開発で、routesファイルのルーティング設定において注意したい点を忘れないように記事を書いてみました。初投稿および初学者のため、表現や解釈に間違いがあるかもしれませんがご容赦ください。
#遭遇したエラー
###ActiveRecord::RecordNotFound in UsersController
Railsのconfig/routes.rbファイルでルーティングの設定をして、指定したURLにアクセスできないエラーが発生してしまいました。
この時routesファイルとコントローラとは次のように設定していました。

```ruby:config/routes.rb
 # usersコントローラ
      get "users/:id" => "users#show", as: "user"
      get "users/close" => "users#complete"
```

```ruby:users_controller.rb
class UsersController < ApplicationController

  def show
  	@user = EndUser.find(params[:id])
  end

  def complete
  end
end
```
今回はEndUserというモデルを用意しています。
この状態でブラウザからurlに
http://localhost:3000/users/close
と入力すると、下のようなエラーに遭遇しました。
<img width="1126" alt="スクリーンショット 2019-11-15 0.27.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505196/61d3fc7f-1827-cd42-7eb5-1e9856a1c1a0.png">
routesファイルに記述したHTTPリクエストが上の行から当てはめられることで、users/closeのURL上でusers/:idのリクエストが先に当てはめられてusersコントローラのshowアクションが呼び出されています。:id部分にURLで入力したusers/closeのcloseという文字列が代入されています。これによりshowアクションで設定したインスタンス変数に、EndUserテーブルの中からidに"close"という文字列を持つ存在しないレコードを探して渡そうとしていたことが原因でした。

```ruby:config/routes.rb
 # usersコントローラ
      get "users/:id" => "users#show", as: "user" #こっちから実行されるため
      get "users/close" => "users#complete"       #これが実行されていない
```
##解決策
そこで、以下のようにルーティングの順番を設定し直しました。

```ruby:config/routes.rb
 # usersコントローラ
      get "users/close" => "users#complete"      
      get "users/:id" => "users#show", as: "user" 
 ```
completeアクションに対応するviewファイルは次のように設定しています。

```ruby:users/complete.html.erb
<h1>退会が完了しました</h1>

 ```

もう一度ローカルサーバー上でusers/closeと入力すると、上のget "users/close"のリクエストが先に実行され、次のように正しくURLにアクセスすることができました。
<img width="1212" alt="スクリーンショット 2019-11-15 2.21.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505196/2223a26d-dc74-c0fc-efae-47b18f9df132.png">


#まとめ
routesファイル中でurlを設定するときは、
**users**/close
**users**/:id
のようにURLの階層が同じかつ上位の階層名が同じ場合は階層名や記述する順番に気をつけることでエラーの予防や解消に繋がりそうです。
フォロー機能　User.rbとRelationship.rb

```Rails:Relationship.rb
class Relationship < ApplicationRecord
	belongs_to :follower, class_name: "User"
	belongs_to :followed, class_name: "User"
end
```

Relationshipモデル(中間モデル)には、
:boy:follower (フォローする人)
:two_women_holding_hands:followed(フォローされる人)
が存在している。


```Rails:user.rb
  has_many :follower, class_name: "Relationship", foreign_key: "follower_id", dependent: :destroy
  # フォロー取得。Relationshipモデルのfollower_idにuser_idを格納

  has_many :followed, class_name: "Relationship", foreign_key: "followed_id", dependent: :destroy
  # フォロワー取得。followed_idにuser_idを格納

```
上２行は、user主体で得る情報。
特定のアクションが起きた際、user_idが格納される場所をforeign_keyで指定することで、follower_id および followed_id　の適切な方にuser_idを格納。


また、フォロー数等のときは、ユーザ情報の中身を必要としないので

<% current_user.follower.each do |user| %>
<%= user.count %>
<% end %>

のように、followerをとってよい(フォロー数取得)。

(フォロワー数を取得する場合は、followed)



```Rails:user.rb

  has_many :following_user, through: :follower, source: :followed
  #following_userを命名。自分がフォローしているユーザ情報を取得。

  has_many :follower_user, through: :followed, source: :follower
  #自分をフォローしているユーザ情報を取得。
```

ユーザ情報を詳しく必要とする場合は、こちら(emailなど)。

<% current_user.following_user.each do |user| %>
<%= user.email %>
<% end %>

following_userで、followerテーブルを通じて、followedテーブルを参照。
PythonでNewsAPIから世界５４ヵ国のニュースヘッドラインを見る

## [NewsAPI](https://newsapi.org/) とは
世界中のトップニュースをJSON形式で取得出来るAPIです。

そこで今回はクリック１つで世界中のニュースヘッドラインをカテゴリ別に見る事が出来るリストを作ってみました。
以下の様にbusiness、technologyとカテゴリ別に世界のニュースをリストします。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348536/83d41503-8b6a-cd3d-a6c9-f4e2ae1d76d9.png)


###取得方法
先ず最初にAPIキーを取得する必要があります。
NewsAPIの仕様と使用方法は[Get started](https://newsapi.org/docs/get-started)を参照して下さい。

1.スクレイピング
基本的なRequestsを使う方法

```python
import requests
import json

url = ('https://newsapi.org/v2/top-headlines?'
    'country=us&'
    'apiKey=****************')
    
response = requests.get(url)
json_data=json.loads(response.text)

for k in range(len(data["articles"])):
    dic_data = json_data["articles"][k]["source"]["name"]
    print(dic_data)
```

２．APIClientを使う方法
どうせなら提供されてるAPIClientを使いましょう。

```python
from newsapi import NewsApiClient

newsapi = NewsApiClient(api_key='******************') #キーはマスクしてます
sources = newsapi.get_sources()

def pr_src(para):
    print(para)
 
def main():
    # カテゴリのリストを作る
    src_list = ["business","technology","sports"]
    for list in src_list:
        for i in range(len(sources["sources"])):
            dic_data = sources["sources"][i]["category"]
            if dic_data == list:
                pr_src(sources["sources"][i]["country"]+"\n"
                     + sources["sources"][i]["name"]+"\n"
                     + sources["sources"][i]["category"]+"\n"
                     + sources["sources"][i]["url"] +"\n"
                     + sources["sources"][i]["description"]+"\n")
               
if __name__=='__main__':
    main()
```
今回は触れませんでしたがdjangoに組み込んでニュース纏めサイトをアップしておくと何時でもどこでもスマホなんかで見れて良いですね。
(和訳) Code Health: 丁寧なコメント == 有用なコメント

Google Testing Blog の [Code Health: Respectful Reviews == Useful Reviews](https://testing.googleblog.com/2019/11/code-health-respectful-reviews-useful.html) のざっくり和訳です。

**コードレビューのコメントを丁寧に解決していくため、これらの tips を活用しましょう。**

## レビュワーやオーサー（コードを書いた人）として

**DO: 相手に能力があると想定しよう。**オーサーの実装や、レビュワーのコメントは、あなたの知らない事情を考慮したものかもしれません。まずは経緯を理解するために質問しましょう。

**DO: 根拠や文脈を示そう。**ベストプラクティスのドキュメントや、スタイルガイド、設計資料などのことです。これらは理解の助けになったり、学びもあります。

**DO: コメントがどう受け取られるかを考えよう。**誇張、ジョーク、絵文字の受け取り方は人によって違うことを意識しましょう。

| Author Don't     | Author Do          |
|:-----------------|:-------------------|
|短い名前がいいと思うので、やれと言われない限りは変えたくありません :)|自明、総称的な言葉は省くことが、ベストプラクティスで提案されています。この提案と、もらったコメントとの落とし所がちょっと思いつきません。|

**DON'T: 人を批判しないようにしよう。**代わりに、*コード*について議論しましょう。意味的に人を対象にしたコメントであっても、コードの質を上げるという本来のゴールから、"あなた" や "あなたの" といった言葉遣いによって話題がそれないようにしましょう。（訳注：日本語ではあなたといった言葉をあまり使わないので起こりにくい話です）

| Author Don't     | Author Do          |
|:-----------------|:-------------------|
|あなたはなぜこの方法を使っているのですか？あなたは必要以上に複雑にしています。|この並行モデルによって、目に見えたパフォーマンス改善がない割にシステムが複雑になっています。|

**DON'T: 厳しい言葉を避けよう。**ネガティブなトーンのレビューコメントは、有益ではない傾向があります。例えば、[ある研究](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/bosu2015useful.pdf)ではとてもネガティブなコメントがを有益だと受け取ったオーサーは 57% だったのに対し、より中立的なコメントだと 79%  でした。

## レビュアーとして

**DO: 具体的で、アクション可能なフィードバックをしよう。**具体的なアドバイスがない場合、どうしてオーサーがそのような書き方をしたのか尋ねるといいかもしれません。

| Reviewer Don't     | Reviewer Do          |
|:-----------------|:-------------------|
|これは分かりません。|これが最適化だとしたら、コメントを足してくれませんか？|

**DO: 些細な指摘や、オプショナルなコメントは、そうだと分かるように書こう。**'Nit' や 'Optional' といった言葉をつけたりすることで、レビュアーの感覚がオーサーに伝わりやすくなります。（訳注：Nit (nits) については[プルリク時のコメント略語](https://qiita.com/kuniyon-com/items/2ed8c48ff349e6add45b)が参考になります）

## オーサーとして

**DO: コードについてはっきり説明したり、レビュアーのコメントに答えよう。**レビュワーからのフィードバックに答えるときのコツです。これができないと、コードの改善に対する受容性の欠如を引き起こすかもしれません。

| Author Don't     | Author Do          |
|:-----------------|:-------------------|
|それがいい場合もありますが、ここでは違いますね。|このように実装した理由をコメントに書きました。|

**DO: フィードバックに反対するときは、あなたのアプローチの長所を説明しましょう。**合意に至れないときは、Google が出しているコードレビューにおける[衝突を解決する方法](https://google.github.io/eng-practices/review/reviewer/standard.html#conflicts)を参考にしましょう。
Nintendo Switch が認識されるけど充電されないので修理した

# はじめに
ポケモン新作が発売されるとのことで今まで買っていなかったNintendo Switchを購入したのですが、片方のジョイコンが携帯モードでは使用できるが、TVモードやテーブルモードでは使用できないという問題が生じていました。
公式のサポートページには同じ現象は記載されていませんでしたが、似たような問題が知恵袋では散見されています。
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q13200212048
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q12206272232

初期不良なので任天堂さんに送り返して修理してもらってもよかったのですが、せっかくなので分解して修理してみました。

# 準備したもの
[1.6mmY字ドライバ](https://www.amazon.co.jp/gp/product/B000AQOESS/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1)

# 症状
- ジョイコンを本体に接続すると「カシャーン！」という気持ちい音が本体から鳴る
- 充電はされない
- 本体に繋いでいる時のみ操作が有効になる
![IMG_2504.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340630/9e8da20b-3576-d0e6-f3b9-9af3bd77e16d.jpeg)


# 手順
とりあえずダメ元で本体再起動&ジョイコンのシンクロボタン長押しをしましたが，症状に変化はありませんでした．
本体側でジョイコンとして認識しているので、ジョイコンの基盤自体の問題ではなく、充電やバッテリーあたりが怪しいですね……
Y字ドライバで裏面のネジを外して，中を見てみました。
![名称未設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340630/1d59f160-caed-7145-4324-5be4d49733f6.png)

バッテリー関係のケーブルは赤と黒の配線部分ですが……なんと基盤と接続されているコネクタ(画像赤丸部分)がちょっとだけ浮いていました。
ドライバで軽く押してあげると、カチッという音とともにはまった感じがしました。
ん？もしかしてこれが原因？
ケースを元に戻して本体に再びはめると……
![IMG_2506.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340630/669dcf57-9d15-ab97-3db6-dac573b9bccc.jpeg)

ちゃんと認識しましたとさ。（そもそも新品なので充電も満タン）
TVモードやテーブルモードでも問題なく使えました。
めでたしめでたし。

# おまけ
今回問題になったコネクタは上からカポッとはめるタイプのコネクタでした。
一回はめると外すの大変だったので製造段階でちゃんとはまってなかったんだなと思いました。
人間がやってるのか機械がやってるのか気になるところ。
![IMG_2502.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340630/4edd5db0-e30a-66b3-fd0b-e3c8f219a2b5.jpeg)
アニメーションライブラリ Lottie

**Lottie(ロッティー)** は、**Airbnb 社**が開発したアニメーションライブラリで、2017年2月頃に発表されたものです。
これがとても面白かったので、メモとして残します。

# Lottie の特徴
- Lottie で使用するデータは、Bodymovin というオープンソースライブラリで作成します。
- 作成したアニメーションデータを Adobe After Effects で json 形式に変換し、javascript 内で指定の形式で記述すれば、そのアニメーションを表示できます。
- 通常の html, css, javascript でプログラミングした場合よりも、デザイナーの方が考えたアニメーションを再現できます。

# Lottie を使用するメリット
アニメーションデータが json 形式なので、画像や動画などの多数の、容量が大きなデータを保持する必要がなくなります。
なので、システム上の**ディスク使用率をかなり節約**できます。

# Lottie を使用するデメリット

Lottie の Web サイトのサポート機能一覧にあるように、現状実現できない動作はあるようです。

　参考：[Supported Features](https://airbnb.io/lottie/#/supported-features)

# Lottie でできないこと
事前に作成したアニメーションデータを json 形式に変換しているので、実行速度を可変にすることはできないようです。

# 環境の構成方法

1. Adobe After Effects を導入します。

2. ZXP Installter をダウンロードします。

3. Bodymovin をダウンロードし、ZXP Installter を使用してインストールします。

# アニメーションデータ作成方法

1. アニメーションの元となる素材を作成します。

2. Adobe After Effects でアニメーションを作成します。

3. Adobe After Effects で Bodymovin プラグインを立ち上げます。

4. 2 で作成したデータを json 形式のデータに変換します。

# 実装方法

使用するファイルは次の 3 つです。

- index.html
- main.js
- animation.json

```index.html
<html>
<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.5.9/lottie.js" type="text/javascript"></script>
</head>
<body>
    <div id="lottie"></div>
    <script src="main.js" type="text/javascript"></script>
</body>
</html>
```
[lottie の js ファイルの URL](https://cdnjs.com/libraries/bodymovin)を参考に、lottie.js を読み込んでいます。
ちなみに、[Github](https://github.com/airbnb/lottie-web/tree/master/build/player) にファイルもあります。


```main.js(アニメーション設定)
var ani = lottie.loadAnimation({
    container: document.getElementById("lottie"),
    renderer: "svg",
    loop: true,
    autoplay: true,
    path: "animation.json"
});
```

animation.json については、多数のサンプルがある [LottieFiles](https://lottiefiles.com) からお借りしました。

### 注意事項
Chrome ではローカルのファイル読み込みでエラーが出力されますので、Chrome のアイコンを右クリック->プロパティから、リンク先に記載のプログラム名の後に以下を記載するとローカルで読み込み可能になります。

```
--user-data-dir="<ファイルが配置されているフォルダ(フルパス)>" --disable-web-security
```
参考：[ChromeにてAjaxでローカルファイルにアクセス](https://qiita.com/cigalecigales/items/33afaa42f91542ffa62e)

# 所感

アニメーションが小容量のデータで実現できるので、PWA (Progressive Web Apps) との親和性もあると思いました。
オフラインでも問題なく実行できそうな気がします。

# 参考
Lottie の使い方等について、参考にさせていただきました。

- [AirbnbのアニメーションライブラリLottie(ロッティー)の使い方](https://qiita.com/17genai/items/37e988d0f68ffe6b44ef)
- [Web上でアニメーションを表示するなら「Lottie」がおすすめ！特徴や使い方など](https://webdesign-trends.net//entry/10360)
- [Lottieでアプリにアニメーションを組み込む話（デザイナー編）](https://kudakurage.hatenadiary.com/entry/2018/06/02/180828)
- [SwiftでLottieを使ってアニメーションを実装する](https://techblog.zozo.com/entry/swift-lottie)
- [Lottieで作ったアニメーションをWebサイトで実装（レスポンシブ対応）](https://tivel.jp/archives/11062)
- [アニメーションライブラリ「Lottie」を使って、超軽量Webアニメーションを実装する方法](https://alaki.co.jp/blog/?p=3057)
- [After Effectsでアニメーションをつくるチュートリアル](https://liginc.co.jp/455552)
- [アニメーション実装の選択肢のひとつになると思う。Lottieを試してみた。](https://liginc.co.jp/445055)
【Vue.js】Vueのナレッジ

# **Vueのナレッジ**

1. [オブジェクトのプロパティを子コンポーネントに渡す](#オブジェクトのプロパティを子コンポーネントに渡す)
2. [子コンポーネントに渡したデータの変更を親コンポーネントに反映する](#子コンポーネントに渡したデータの変更を親コンポーネントに反映する)


# オブジェクトのプロパティを子コンポーネントに渡す

下記のようなオブジェクトのデータを子コンポーネントに渡す時、方法はおおよそ２パターン！



`board`の`boardTitle`を子コンポーネントで表示させたい:writing_hand:

```json
"board": {
  "boardTitle": "11/12 TODO",
  "todos": []
}
```

## パターン①　オブジェクトを省略記法を使って渡す

### 親コンポーネント

```vuejs
<board-index v-bind="board"/>
```


### 子コンポーネント(BoardIndex.vue)

```vue
<template>
  <div>{{ boardTitle }}</div>
</template>

<script>
export default {
  props: {
    boardTitle: {
      type: String,
      required: true
    },
    todos: {
      type: Array
    }
  }
}
</script>
```


## パターン②　オブジェクトをそのまま渡す

### 親コンポーネント

```vuejs
<board-index :board="board"/>
```


### 子コンポーネント(BoardIndex.vue)

```vue
<template>
  <div>{{ board.boardTitle }}</div>
</template>

<script>
export default {
  props: {
    board: {
      type: Object,
      default: () => ({
        boardTitle: '',
        todos: []
      }),
      required: true
    }
  }
}
</script>
```

別にオブジェクトのプロパティを個々にバインドさせる方法もあります。
場面によって使い分けることができそうです。



話が少し逸れますが、パターン②で`board`の`default`を関数で返しています。
これは、
**propsのデフォルト値に指定したオブジェクトや配列は、参照が共有される**
ことを防ぐためです。

参照が共有されてしまうと、複数のvueインスタンスが同一のオブジェクトを参照し、同一のオブジェクトに変更を加えてしまう状況が発生します。




# 子コンポーネントに渡したデータの変更を親コンポーネントに反映する

親から子へpropsでデータを渡したとき、
子側でそのpropsデータを直接変えようとするとvueに怒られてしまいます。

では、どうすればいいか、備忘録でまとめておきます。

### 親コンポーネント
```vue
<child-component v-model="parentData"/>
```

### 子コンポーネント(ChildComponent.vue)

```vue
<script>
export default {
  props: {
    parentData: {
      type: String,
      default: ''
    }
  },
  computed: {
    inputData: {
      get() {
        return this.parentData
      },
      set(newVal) {
        this.$emit('input', newVal)
      }
    }
  }
}

</script>
```

親から受け取った`props`を`computed`を通して別名のプロパティ`inputData`として受け取り、子側で`inputData`に変更があった場合、`set`関数で新しい値を取得して親に返します。

`$emit`で`input`イベントを送ることで親の`v-model`の値にデータがバインドされます。


これができるのは、`v-model` (**=** `v-on:input`と`v-bind:value`)で双方向データバインディングを行っているためですね。
Xilinx もmodel zooに本気をだしてきたようだ。　- 深層学習をFPGAで実装する -

以下の記事は古くなっています。

https://github.com/Xilinx/Vitis-AI
上記のgithubを参照して、いまの状況を必要に応じて調査してください。


次のページには、modelzooにある各種モデルの種類とAMD(旧Xilinx)のFPGAデバイスでのfpsやレイテンシの値が記述されています。

https://xilinx.github.io/Vitis-AI/docs/reference/ModelZoo_VAI3.0_Github_web.htm

---

IntelがOpenVinoで各種model zoo を公開し、だれでもが簡単に学習済みの結果を使えるようにしてきた。

その状況にXilinxが手をこまねいてだまってみているわけもなく、誰でもがすぐに学習済みの結果をXilinxのFPGAで実行できる状況を作ってきた。


https://github.com/Xilinx/Edge-AI-Platform-Tutorials/tree/master/docs/AI-Model-Zoo


![](https://raw.githubusercontent.com/Xilinx/Edge-AI-Platform-Tutorials/master/docs/AI-Model-Zoo/images/xlnx_model_zoo.png)


どういったモデルが、どれくらいのlatency とthroughput でFPGAで実行できるのかが詳細に書いてある。


----
モデル性能

Model Zooのすべてのモデルは、DNNDK™（ディープニューラルネットワーク開発キット）およびザイリンクスAI SDKを備えたザイリンクスハードウェアに配置されています。さまざまなDPU構成のさまざまなボード上の各モデルのエンドツーエンドのスループットとレイテンシを含むパフォーマンスの数値は、次のセクションにリストされています。

DPUの詳細については、DPU IP製品ガイドを参照してください。

注：次のセクションにリストされているモデルパフォーマンス番号は、DNNDK v3.1およびXilinx AI SDK v2.0.xで生成されます。ボードごとに、異なるDPU構成が使用されます。 DNNDKおよびザイリンクスAI SDKは、https：//www.xilinx.com/products/design-tools/ai-inference/ai-developer-hub.htmlから無料でダウンロードできます。


## また以下の場所を読むとYoloV3などをFPGAに実装する手順が書かれている。

https://github.com/Xilinx/Edge-AI-Platform-Tutorials/tree/master/docs/Darknet-Caffe-Conversion

----
github 上にもXilinxの他のリポジトリがある。
- https://github.com/Xilinx/PYNQ
- https://github.com/Xilinx/Vitis_Libraries
- https://github.com/Xilinx/BNN-PYNQ
----
関連記事

http://lp6m.hatenablog.com/entry/2019/08/17/013229
用解説語：インターフェースについて

【インターフェース/interface】とは
　・境界面、接点、連絡役、橋渡し、などの意味を持つ
　・何かと何かが接する部分、もしくはその間
　・クラスに含まれるメソッドのひとつ
　・メソッドの型と変数のみを定義している
　・メソッドの具体的な処理内容は記述していない
　・メソッドを利用する直前で処理内容を記述することが可能
　・複数のインターフェースを継承し、新しいインターフェースを作ることも可能（多重継承というらしい）


（例）インターフェースの宣言/実装
-------------------------------

『宣言』
→　interface インターフェース名 {}

『実装』
→　class クラス名 implements インターフェース名{}

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


【抽象クラス/abstract】とは
 　・abstract：抽象、の意
　・抽象メソッドを１つ以上持つクラスのこと
　・定義のみを宣言するメソッド（メソッド名・引数など）
　・具体的な処理内容を記述しないメソッド
　・メソッドのオーバーライドが可能
　　※オーバーライド：親クラスのメソッドをサブクラスで書き換え（上書き）すること
　・直接のインスタンス化が不可
　・多重継承が不可

（例）抽象クラス/抽象メソッドの宣言
-------------------------------
『抽象クラス』
→　abstract class クラス名{}

『抽象メソッド』
→　abstract 戻り値の型　メソッド名（引数の型　引数名）;
-------------------------------


抽象クラスのメリットとして、

”抽象メソッドのオーバーライドによって、実装時に『挿入場所は決まっていないがいずれ必要になるメソッド』を予め宣言する。詳細の定義は後のクラスで定義する。という実装が可能”

・・・だそうだ。言葉だけだとふんわりとしか想像できないので、一旦この辺は課題とする。
ユーザ一覧で"フォローする"ボタンを押したときの挙動　備忘録

```Rails:user/index/html.erb

      <% if user != current_user %>

        <% if current_user.following?(user) %>
            <%= link_to 'フォロー解除', unfollows_path(user.id), method: :POST %>
        <% else %>
            <%= link_to 'フォローする', follows_path(user.id), method: :POST %>
        <% end %>

      <% end %>
```
上の 'フォローする' ボタンを押すと、follows_path が読み込まれる

follows_pathは

```Rails:routes.rb

post 'follows/:id' => 'relationships#follows', as: "follows" # フォローする。follows_pathの作成。
```
上の as "follows"で名前付きパスをつけたもの。
follows_path が呼び出されると、
relationships#follows（relationshipsコントローラのfollowsアクション)
が呼び出される

```Rails:relationships.controller.rb
  # ユーザーをフォローする
  def follows(user_id)
    follower.create(followed_id: user_id)
  end
```
フォロー完了。
【rails】jQueryでページカレントをつけようとして読み込み問題でハマった話

#まずは完成図gif
![a7abc847458f31a52675d3b296bed1fc.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480700/7c7a3e10-0ba6-d13c-f2df-f618c1878adf.gif)
なんの変哲もなく、しっかりとページカレントできています。

#書き加えたコードはこれ

``` sidebar.js
$(window).load(function () { //.loadでページが完全に読み込まれたら実行されるようにする

  var href = $(".main-header__left-box__current-group").data("group-id")
  $(".group").each(function (i, ele) {
    if ($(ele).data("group-id") === href) { //group__side_currentが色の変わるclass
      $(this).addClass("group__side_current") //data-id一致でclassをつける
    } else {
      $(this).removeClass("group__side_current")//data-id一致しなければclass削除
    }
  });

});
```
上記のjqueryの動きを図解？するとこんな感じです。
タイトル部分にお勉強中にdata-idをグループ名部分につけるくだりがあり、再利用しました。
<img width="794" alt="5b43aaaf86bab5bfb706ea37c9f932a8.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480700/abebe2d5-11c1-31a7-d7aa-f57dff6097b6.png">

#問題はこのコード
``` application.js
//= require turbolinks
```
このコードがあることによって、
な　ぜ　か　挙動が不安定になりました。
その時のgifがこちら

![f8291d5fd08a791fb8e71e374fa32a08.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480700/ab1c0fd8-765f-11f3-7e2f-58109411168e.gif)

- クリックすると何もおこらない
- リロードするとなぜかカレントがつく

この時コンソールに入れて確認しましたが、これは普通に動作しました。

>turbolinks = Ajaxによるページ遷移の高速化のためのライブラリ
> ~中略~
>遷移にあたって今のページと共有するリソース(css/img/js)の再読込が不要となるため、読み込みが速くなる。
なお、フックイベントを使って遷移をキャンセルできる。
>[turbolinksチートシート](https://qiita.com/morrr/items/54f4be21032a45fd4fe9)より抜粋

再読み込みを不要にしてるため、ページが変わったことによるcssの付与やjsの再試行が行われてなく、うまく動作してないみたいですね。

>turbolinksにおいて、リンクがクリックからページ表示までの一連の流れをVisitと呼ぶ。
>Visitは大きく二種類:
>Application Visits = リンククリックによるページ遷移
>Restoration Visits = ブラウザの戻る/進むボタンによるページ遷移
>[turbolinksチートシート](https://qiita.com/morrr/items/54f4be21032a45fd4fe9)より抜粋

リロードすると動作しているのは、「turbolinks」を通したブラウザの動作でないため、
読み込みの挙動は通常通りに行われている。だからカレントがついたわけなんですね。

うわぁ。なんてことだ。
犯人確定の証言記事じゃないか...たまげたな。

#今後の開発で気をつけようと思った点
現時点では「turbolinks」を削除しても動作に問題はない。
世に出回るサービスのように複雑でないし、アクセスがたくさんあるわけでもない、画像もあまり表示されていない。
大したことしてないから「速い」ので「turbolinks」の恩恵が正直わかりませんでした。

しかしサービスを作るとなると、素早くスムーズに動くことは必須なので、
プロジェクトで「これを使おう！」ってなった際には、個別に読み込みさせて影響範囲を絞ってあげることが必要かと思いました。

Railsで、任意のJavaScriptやCSSだけを読み込む
https://qiita.com/Oakbow/items/2e712e05bb4bbf68faf5

↑こういうのとかで

#参考記事
ナビゲーションをカレント表示する方法まとめ【jQueryとかWordPress】
https://webkcampus.com/201904/1598/

【jQuery】「$(document).ready()」と「$(window).load()」の違いを極める！
https://on-ze.com/archives/1851
ES2015以降で書かれたAngularJSコードのアノテーションminify対策

# まえがき
GruntでBabel+concat+uglifyしているJavaScriptコードをWebpack+Babelで対応できるようにする、
のだけれどもAngularJSアノテーションの対応が少し面倒だった備忘録。

# 結論
babel-plugin-angularjs-annotateを使う。
https://github.com/schmod/babel-plugin-angularjs-annotate

# AngularJSのアノテーション記法
AngularJSでは登録したモジュールを各コンポーネントで利用できる機能があり、
その指定で特有の記法がある。

```js
// aにmoduleA、bにmoduleBのインスタンスが代入される(=DI)
angular.controller('ctrl', ['moduleA', 'moduleB', (a, b) => { // （１）
  // いろいろ
}]);
```

この際、

```js
angular.controller('ctrl', (moduleA, moduleB) => { // （２）
``` 

と関数部分だけでも変数名によりDIされる。
しかしminifyすると変数名が変わってしまいDIできなくなるため、
（１）のようにモジュール名を入れたArray（=アノテーション）にすることで対策する。

# アノテーション付与をGruntでタスク化できるgrunt-ng-annotate

このminify対策を自動化するgrunt-ng-annotateというプラグインがあり、
Gruntのタスクで（２）を（１）のように書き換える事ができる。

しかしプラグインの更新が止まっており、
アロー関数やimport/exportを含んだコードがあるとタスクエラー（Ⅰ）となっていた。
なお既存ではng-annotateの前にBabelでES5にトランスパイルされており問題なく実行できていた。  

今回の場合はWebpackにBabelの処理も寄せたいが

* Webpack -> ng-annotateの場合はバンドルはされるが、minifyが先になってしまいDIできない
* ng-annotate -> Webpackの場合は（Ⅰ）のためエラー

のためすんなりとは行かなかった。
コード生成だけなら

1. Babelでトランスパイル
1. ngAnnotateアノテーション付与
1. Webpackでbundle+minify

でも出来たが、

* タスク順序に寄る（Grunt依存）
* Webpack時にimport -> requireとなっておりTree Shaking出来ない

のが後々面倒になりそうだったので試行錯誤。

# babel-plugin-angularjs-annotateで解決

色々調査した結果

* ng-annotate-webpack-plugin
* ng-annotate-loader
* babel-plugin-angularjs-annotate

があったが、前者二つはimport/exportに対応していないのかエラーとなった。
babel-plugin-angularjs-annotateは期待通りアノテーション付与+ES5+bundle+minifyできた。  

```json
{
  "presets": [
    [
      "@babel/preset-env",
      {
        ...
      }
    ]
  ],
  "plugins": ["angularjs-annotate"]
}
```

Webpackが入ったのでBower -> npmへの移行も見込みが立ったため頑張っていきたい所存。
dockerイメージphp:7.2-apacheでImageMagickをインストール

## インストールのイメージ
ImagicをインストールするためのImageMagickのインストールが必要。
まずPHPへImageMagicのインストールを行い(※Dockerfileへ記述)、その後、Imagicのライブラリをcomposerに追加する。

### インストール方法

php側でimagemagickとimagickのインストールが必要なため、Dockerfileに下記を追加。

```
 && apt-get update && apt-get install -y imagemagick libmagickwand-dev \
 && pecl install imagick \
 && docker-php-ext-enable imagick \
```

これでbuild後、`docker-compose up -d`！！！ッッッターーーーーン！！！！

Linux側で、下記コマンドを叩いてImagicのライブラリを追加。

```
$ composer require spatie/pdf-to-image
$ composer require spatie/pdf-to-text
```

※バージョン確認やパッケージの種類は下記パッケージリストを確認してください。
https://packagist.org/packages/spatie/pdf-to-image


すると、composer.jsonのrequireに下記が追加されてる。

```
        "spatie/pdf-to-image": "^1.8",
        "spatie/pdf-to-text": "^1.2"
```

#### ImageMagickを使えるようになったか下記コマンドで確認
```console
# convert -version
```

インストールできてたら下記表示されます。

```console
# convert -version
Version: ImageMagick 6.9.7-4 Q16 x86_64 20170114 http://www.imagemagick.org
Copyright: © 1999-2017 ImageMagick Studio LLC
License: http://www.imagemagick.org/script/license.php
Features: Cipher DPC Modules OpenMP
Delegates (built-in): bzlib djvu fftw fontconfig freetype jbig jng jp2 jpeg lcms lqr ltdl lzma openexr pangocairo png tiff wmf x xml zlib
```

ちなみに、Dockerfileに書いた

```
 && docker-php-ext-enable imagick \
```

は、extensionを有効にするため、 php.iniに `extension=imagick.so` を書く必要がなくなります。

もし書いていれば重複するため、下記エラーが。

```
PHP Warning:  Module 'imagick' already loaded in Unknown on line 0
```

以上です。
DSP FMラジオ RDA5807FP+ATTINY85+AQM0802A　その8　回路図

#はじめに
* 電池駆動DSPラジオのその8。全体回路図です。BSch3Vで作成してみました。
* とりあえず、この電池駆動DSPラジオの記事はここでおしまいにします。
* [前記事（その1～その7）や過去記事](https://qiita.com/dabodabo)も適宜ご参照ください。

#回路図について
* 初めてBSch3Vを使ったので、今一つな出来上がり。
* 電源（3.3V)とGroundラインは記号で書いています。電源ラインを書くと画面が煩雑になって見難いので。
* ATTINY85は右下を１番ピンにしています。
![RDA5807FP_BOX_RADIO.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482773/14628ded-b0a1-8814-1328-c19ffdf400fe.png)


#おまけ
* 備忘録もかねて記事を書いてみましたが、慣れていないせいか時間がかかりました。実物を先に作って後から記事を書いたので、忘れていることも多かったです。
* 今回のように実物を作ると、ハードウェアの製作と、ソフトウェアの作成の両方を組み合わせる必要があるので、作業していて楽しかったです。
Selenium WebDriverでServiceNowへ自動ログイン

# ◆概要

* WebのUIテスト自動化に使われるSelenium WebDriverを使い、ServiceNowのログイン操作を自動で行ってみた。

# ◆動作環境
* OS: Windows10
* Pythonバージョン: 3.8.0

# ◆準備

### ServiceNowのインスタンス作成

* [ServiceNow Developers](https://developer.servicenow.com)のページからアカウントを登録することで開発者用のインスタンスを作成することができる。
* 作成が完了するとインスタンスURLやadminアカウントの初期情報が表示されるので必ずメモをしておく。  
![instance.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181632/88e334e7-d381-54fc-c3fa-4ba1b5514d55.png)

### Pythonの実行環境準備
* [Pythonの公式サイト](https://www.python.org/)からインストーラをダウンロードしてインストールする。
    * 必ずpipが含まれているか確認する。

### Seleniumの準備
* pipでSeleniumをインストールする。
    * `> pip install selenium`
* [Seleniumの公式サイト](https://www.seleniumhq.org/download/)から動かしたいブラウザのドライバをダウンロードする。
    * 今回はGoogle Chrome上で動かすため、「Google Chrome Driver」をダウンロードする。
    * ダウンロードした「chromedriver.exe」を任意の場所に設置しておく。

# ◆ServiceNowを操作してみる

## ブラウザを起動
* ブラウザをGoogle Chromeに指定して起動させる。
    * ついでにウィンドウを最大化

```python
from selenium import webdriver

# Google Chromeを起動
driver = webdriver.Chrome(executable_path = 'Chrome Driverのパス')
# ウィンドウを最大化
driver.maximize_window()
```

## ServiceNowのログインページへアクセス
* インスタンスごとのURLを指定してアクセスする。

```python
# ServiceNowのログインページへアクセス
driver.get('https://<ServiceNowのインスタンス名>.service-now.com/')
driver.implicitly_wait(20)
```

## ログインフォームの要素取得
* ログインフォーム部分はiframe内にあるため、そのままid指定すると見つからずエラーが吐き出される。
    * 先にiframeの要素を取得し、switch_to_frameでフレーム移動を行う必要がある。
    * 操作が終わったらswitch_to.default_content()でiframe内から抜ける。

```python
# ログインフォームの含まれるiframeの要素を取得する
login_iframe = driver.find_element_by_xpath("//*[@id='gsft_main']")
# 指定したiframe内へ移動
driver.switch_to_frame(login_iframe)

# ユーザー名フォームの要素取得 & ユーザー名入力
user_name_form = driver.find_element_by_id('user_name')
user_name_form.send_keys("<ユーザー名>")

# パスワードフォームの要素取得 & パスワード入力
password_form = driver.find_element_by_id('user_password')
password_form.send_keys("<パスワード>")

# ログインボタンの要素取得 & ログインボタンクリック
login_button = driver.find_element_by_id('sysverb_login')
login_button.click()

driver.implicitly_wait(20)

# iframeから抜ける
driver.switch_to.default_content()
```

# ◆参考ページ
* [Python + Selenium で Chrome の自動操作を一通り](https://qiita.com/memakura/items/20a02161fa7e18d8a693)
* [Selenium webdriverよく使う操作メソッドまとめ](https://qiita.com/mochio/items/dc9935ee607895420186)
* [Seleniumでiframeに出入りしてみた](https://qiita.com/Tokyo/items/7e61ac57ffd79b5a1085)
MacでPowerShellを利用するとき使えば便利になるモジュール

MacでPowershellを利用し始めているけどiTermに比べたら色んなところでかゆいところに手が届きません。特にgitに関する操作がすごくめんどくさいから何か解決策があるかを調べていました。



1. [powershell-git-aliases](https://github.com/gluons/powershell-git-aliases)

   gitのAliasをまとめて追加するmoduleです。もとのPSコマンドのAliasと衝突したら自動的にそのAliasを消します。Oh My Zshのようにgitコマンドを入力できるようになりました。

2. [posh-git](https://github.com/dahlbyk/posh-git)

   iTermのようにコマンドの入力先にgitの情報（ブランチ、statusなど)を表示させます。

   そして、Tabで自動的にコマンドを補足する機能もあります！

3. 最後はPowershellからVSCodeを呼べる方法：

   もともとは自動的に`code` を打てたらVSCodeを呼ばれるはずだが、もし起動できない場合は以下のようにやれば大丈夫。

   1. VSCodeを起動して、Command Palette を起動します（Command + Shift + P :)

   2. ` Install shell in PATH` コマンドを実行すればOKです。
【Nuxt.js】 Jestを使ってコンポーネントのテスト書く

今までフロントエンドでテストケースを書いたことがありませんでしたが、とある案件で挑戦する機会があったのでやってみました

## やりたいこと
- 作成済みの Nuxt.jsアプリに、後から[Jest](https://jestjs.io/docs/ja/getting-started)を導入する
- コンポーネントにpropsで渡した値が表示されるか確認するのテストを用意して実行する

## 事前準備

### ライブラリのインストール
- NuxtアプリでJestを動かすために必要なライブラリが入っていない場合は導入する  
(警告を消すために色々と入れましたが、全部は必要ないかもです)

```bash
yarn add -D @babel/core @nuxt/babel-preset-app @vue/test-utils babel-core babel-jest babel-preset-env jest vue-jest vue-template-compiler
```

### 設定ファイルの用意

Nuxtアプリのルートディレクトリ直下に用意

```js:jest.config.js
module.exports = {
  transform: {
    '^.+\\.js$': 'babel-jest',
    '.*\\.(vue)$': 'vue-jest'
  },
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/$1',
    '^~/(.*)$': '<rootDir>/$1'
  },
  moduleFileExtensions: ['js', 'json', 'vue']
}
```

```json:.babelrc
{
  "presets": [
    ["env", {
      "modules": false
    }]
  ],
  "env": {
    "test": {
      "presets": [
        ["env", {
          "targets": {
            "node": "current"
          }
        }]
      ]
    }
  }
}

```

## コンポーネント作成

propsにtextを渡して、それを表示させるだけのシンプルなコンポーネントです

```vue:Button.vue
<template>
  <nuxt-link>
    {{ text }}
  </nuxt-link>
</template>

<script>
export default {
  props: {
    text: {
      type: String,
      required: true
    }
  }
}
</script>
```

## テストケース作成
```js:test/components/Button.spec.js
import { mount } from '@vue/test-utils'
import Button from '~/components/shared/Button'

describe('Button', () => {
  test('Display text', () => {
    const props = {
      text: '検索する'
    }
    const wrapper = mount(Button, {
      propsData: props
    })
    // propsに指定したデータが正しく表示されること
    expect(wrapper.props('text')).toBe(props.text)
  })
})

```

今回は簡単なpropsの表示テストだけですが、追って別記事でVuexのテストサンプルも作成する予定

## 参考
- [Wrapper | Vue Test Utils](https://vue-test-utils.vuejs.org/ja/api/wrapper/#props)
- [Nuxt.js + JestでTodoアプリと自動テストを作成 - Qiita](https://qiita.com/rhistoba/items/6e90e2c51e8ad1875ac0)
【Ruby】HTMLタグを表す正規表現と`gsub`メソッド内での活用例

## はじめに

先日、[【Ruby】HTTPClientとLINE Notifyを使ってターミナルから文字列を送るプログラム](https://qiita.com/terufumi1122/items/e554b529612a49d462c2)という記事を書きました。

その中で使用している`HTTPClient`の学習中に`<div>`や`</div>`など、HTMLタグを表す正規表現を見て**「便利！」**と感じたためまとめました！

どなたかの参考になれば幸いです。

## この記事が役に立つ方
- HTMLタグが邪魔で除去したい
- 正規表現初心者

## この記事のメリット
- HTMLタグを表す正規表現を理解し、活用が出来る
- ついでにRubyの `gsub`メソッドの使い方が分かる

## 環境
- シェル：zsh
- Ruby 2.6.3

## 参考にしたサイト
`HTTPClient`チュートリアルサイトにて。
`get_content`メソッドの使用例の中で見かけました。

以下リンクの「The get_content function」の中に書いてあったものです。
[Ruby HTTPClient tutorial](http://zetcode.com/web/rubyhttpclient/)（英語）

## HTMLタグを表す正規表現
こちらがHTMLタグを表す正規表現です。

```
%r{</?[^>]+?>}
```

このコードを順に読み解いていきます。

↓参照したリファレンスはこちら
[正規表現 (Ruby 2.6.0)](https://docs.ruby-lang.org/ja/latest/doc/spec=2fregexp.html)

---
### `%r{正規表現を記載}`
`{}`内は`/`などをエスケープして記述する必要がない。

HTMLタグは閉じタグに`/`が必ず使われているので、通常の`/正規表現/`というでいちいちエスケープする必要がなくなる`%r{}`のほうが便利です。

---
### `<`
そのまま`<`を表す。

---
### `/?`
`/`が１つあるか、ないか。

---
### `[^>]`
`^`を付けた文字は除外される。
つまり、`>`以外の１文字を表します。

---
### `[^>]+?`
`+?`は直前に書いたパターンが「1個以上」という意味です。
 `>`以外の文字が1個以上ということですね。

※2019/11/15追記
この記法は**「最小量指定子(reluctant quantifier)」**といい、マッチが成功する、**最短の文字列**にマッチします。
今回のHTMLタグを表すケースでは`[^>]+`としても同様の挙動を示します。
@scivola さん、いつもありがとうございます！

---
### (もう一度)`%r{</?[^>]+?>}`とは

**「`<`から始まって`/`があってもなくてもよくて、最後の`>`までの間に`>`以外の文字がいくつかある」**
ということになりますね。

つまり、`<任意の文字列>`か`</任意の文字列>`ということ！
まさにHTMLタグのことです。:thumbsup:

## 【活用例】`gsub`メソッドでHTMLタグを除去する
```
(何らかのHTML).gsub(%r{</?[^>]+?>},'')
```

Rubyで`gsub`メソッドは、文字列の置換をするメソッドです。

上記コードでは
`<任意の文字列>`か`</任意の文字列>`を`''`に置換（削除）
しています。

例えば、HTMLドキュメントからHTMLタグを除去して**可読性を向上**する際に使えます。（以下参照）

【Before】

```shell
<html><head><title>Something.</title></head>
<body>Something.</body>
</html>
```

【After】

```shell
Something. # <title>タグ内のもの
Something. # <body>タグ内のもの
```


## おわりに
正規表現はパッと見てもわからない、でも読み解くと必ず分かるのがいいですね。:relaxed:

よく使いそうな正規表現をリスト化しておき、必要に応じて参照出来るようにしておくと作業効率上がりそう。:thinking:

## 参考にさせて頂いたサイト（いつもありがとうございます）
[Ruby HTTPClient tutorial](http://zetcode.com/web/rubyhttpclient/)
【Kotlin】乱数のシーケンスを作る方法

すぐに思いつくのはこれ。

```Kotlin
    (0 until 100)
        .asSequence()
        .map { Random.nextInt() }
```

しかしこれだと余計な `0` が現れるし、
`map` で「変換する」というのも本来やりたいこととは関係ない。

次のようにすると、意図とコードが一致する。

```Kotlin
    generateSequence {
        Random.nextInt()
    }.take(100)
```

ちなみに `Random` インスタンスを新しく1つ用意して使いたい場合は次のようにすればよい。

```Kotlin
    Random(0).let { random ->
        generateSequence {
            random.nextInt()
        }
    }.take(100)
```

---

関連記事：[【Kotlin】Sequenceオブジェクト生成方法7種](https://qiita.com/sdkei/items/cc3d7846b09c87603718)
iPhoneのSafariで横向きにしたときに文字が一部拡大してしまう

[【CSS3】iOSのサファリで縦画面から横画面にすると文字が大きくなるのを防ぐ設定](https://www.webdlab.com/labs/iphone-font-size/)

iPhone Safari 横
<img width="306" alt="24007581-BA54-4D6D-BB66-639D5167D9E0.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111089/8c8f0295-7c95-7b42-deb5-153409034e97.jpeg">
iPhone Safari 縦
<img width="157" alt="853E5CD4-3F1A-441B-B4A4-3BE7FFE7EEC6.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111089/588d3d24-e855-c347-69ac-d063ee37e1a3.jpeg">

横にすると、※1が拡大されてしまう。
おそらくiPhoneのSafariのみ。
なので、
[text-size-adjust](https://developer.mozilla.org/ja/docs/Web/CSS/text-size-adjust)
これでテキストの自動拡大アルゴリズムを制御する。

```sass
    body {
    	//iPhoneのSafariでで横向きにした際に一部文字が拡大されてしまうための対応
      -webkit-text-size-adjust: 100%;
    }
```
これで出来る。
[Can I use... Support tables for HTML5, CSS3, etc](https://caniuse.com/#search=text-size-adjust)
iOSのSafariではprefixが必要なので、`-webkit-`をつける。

ただ`none`は指定してはいけない。
[[備忘録]「-webkit-text-size-adjust」は指定しておこう、今のところは！ | ultimate-ez.com](https://ultimate-ez.com/2014/03/29/3572/)

PCでのユーザビリティに影響するらしい。
TensorFlow World Extended Tokyo 2019 @Google渋谷オフィスへ参加してきて感じたTensorFlow2.0の進化

# はじめに
TensorFlow Worldの日本版に行ってきたので簡単にレポートします。

[TensorFlow World](https://conferences.oreilly.com/tensorflow/tf-ca/public/schedule/full/public)は2019年10月28日〜31日にカリフォルニアで開催された、O'Reilly主催の初のTensorFlowに関するカンファレンスです。

今回はその日本版ということで、TensorFlow User GroupとGoogleさんの協力で開催されたようです。日本でもこういう会を設けてくれるのはとてもありがたい。
Connpass上で募集を見かけ、応募したところ参加枠108人に対し216人が応募。最初の抽選に落ちたものの、前日に再度確認すると繰り上げ当選しました。当日も2, 3割が空席のようでした。

Connpassのイベントページ
https://tfug-tokyo.connpass.com/event/152615/

Slido.comの当日質問ページ
```#TFUG191114```

今回は折角参加できたので、感想&簡単なメモを共有させていただきます！

# 感想
- オープンなプロジェクトにContributeしてみたいなあ
- Eager Executionって何だ？？？

## 気になったキーワード
- Commuinty / Open Source
- SIG
- Mobile BERT

## わからんワード
- Eager Excution
- RFC
- What-If

# 以下はメモ。当日のスライドは後日運営の方がUPしてくださるらしいです。

# TensorFlow のエコシステムとTensorFlow
ohtamanさん(Twitter:@ohtaman)

## TensorFlow2.0の開発体制
1.xまではGoogleで開発していた。
一方、2.0は11のSIGS(Special Interest Group)で開発している。
SIGの一例として、SIG Addonsがある。2.0でディスコンになった機能をサポートするためのSIG。
Docs Translation 11/18にTensorFlowのドキュメントを翻訳しつつ勉強する会。

## TensorFlow Hub
https://tfhub.dev
学習済モデルが公開されている。.pyのソースでURLを指定するだけで、学習済モデルが使える。
Google, Microsoft, Nvidiaなどのモデルが一同に会している。


## TensorFlow Enterprise
従来サポートが弱かった、Tensorflowをビジネス向けに適用するためのサービスを追加する。
フレームワークではな、あくまでサービスの総称。Google Cloudでサポートするとのこと。
最大過去3年間のバグフィックスをサポートするなど手厚いので、ビジネス利用が促進されることを期待したい。


# TensorFlow Lite のアップデート
Le Viet Gia Khanhさん(TensorFlow Developer Engineer at Google)

TensorFlow Liteというエッジコンピューティング用システムがある。
エッジでの機械学習は低レイテンシの実現・ネットワークが繋げられない・セキュリティセンシティブなケースで有用。
BERTという自然言語処理モデルがあることを知ったのですが非常に精度の高いモデルのようですね。


# TensorFlow Lite Micro
proppyさん(Developer Programs Engineer at Google)
TFLite microというデバイスで学習データを入力、PCで学習、モデルをANSI Cなどのバイナリとして出力することができる。


# TensorFlow2.0とTensorBoard.dev
## TensorFlow2.0の変更点
- APIの整理
- Eager Executionがデフォルトに
- tf.Variable()の管理方法が簡略化
- Eagermodeの副作用として自作関数のパフォーマンスが低下する。tf.functionでwrapすることで最適化する。

## TensorBoard
Logはtf.kerasのcallbackを用いる。

```
tb_cb = tf.keras.callbacks.TensorBoard(...) # これでカバーできないものもある。
model.fit(..., callbacks=[tb_cb])
```
GANの学習中など、デフォルトのcallback関数で機能が不足する場合は自作のcallback関数を渡すことになる。
二分探索木を理解するために

# 二分探索木を理解するために
## 二分探索木とは
探索を目的としたデータ構造である。

各ノード持つデータに制約を持たせる（親子間の大小関係）ことで、平均演算時間が$O(\log n)$となり、線形探索よりも高速な探索が可能となる。

二分木の一種であるため、二分木のデータ構造をもつ。

## 目的
* 二分探索木を学ぶことで、データ構造とアルゴリズムに対する理解を深めたい。
* 単に二分探索を実装するだけではなく背景になっているデータ構造の考え方を理解する。

## 内容
* 下記項目について、リンク先の記事で解説する。
  * 二分探索木にとりかかる前に二分木データ構造について学んだ。
  * データ構造の考え方に馴染むために、一般木についても学んだ。
  * 二分探索木を実装し、データ構造と解決できる問題について学んだ。


* [[入門]二分木を理解するために解説しながら自力実装してみた](https://qiita.com/tagtagtag/items/c5c460633e1ac864937a)
* [[入門]一般木入門](https://qiita.com/tagtagtag/items/04d5cbe58686c1aebfee)
* [[入門]二分探索木](https://qiita.com/tagtagtag/items/12bc86bc742df280e8da)
用語解説：アクセサ / アクセサメソッド、カプセル化

アクセサメソッドに入る前の補足

【カプセル化/ encapsulation】とは

　・オブジェクト指向言語の特徴の一つ
　・関連性のあるデータやプログラムを容器の中に収納すること
　・容器　＝　オブジェクト
　　（※容器の名前はオブジェクト、と記載していました。修正いたします。）

　・フィールド、メソッドを収容する
　・収容したものは、クラスの外から干渉できない
　　（※干渉できるものもあるようです。ご指摘ありがとうございます。）

　・オブジェクトの中に収容したフィールドやメソッドは、外から干渉できないように保護されている
　・オブジェクトに入れて他から触れなくすることをカプセル化という（みんな箱入り娘？）

　
【アクセサ/アクセサメソッド】とは

　・フィールドのアクセスを仲介する目的で用意されるメソッド
　・フィールドの値の更新や取り出しは、そのオブジェクト（容器）のメソッドを経由する
　・全てのフィールド値は『set○○』『get○○』というメソッドがないとアクセスできない
　・この『set○○』『get○○』のことをアクセサという


【フィールド】とは
　・classの構成要素の一つ
　　※classはフィールドとメソッドで成り立つ
　・クラスフィールドとインスタンスフィールドの二つ
　・staticあり：インスタンスフィールド。いくつインスタンスを生成しても１つしか作成されない
　・staticなし：クラスフィールド。インスタンス生成毎に別途作成される


【クラス】について
　・フィールドとメソッドによって構成される
（例）

```java
public class test{

 int a;         //　フィールド
 String b;       //　フィールド

 public int getA{    // メソッド
  return x;
 }

 public void setB(String b){    // メソッド
  this.b = b;
 }
}
```
Linuxについて

SQLと扱いが混乱してきたので
少し備忘録を書きます。

# Linuxとは

OSの一種、MacやWindowsと同じ枠組みです。
主にサーバー用として使うOSです。
ちなみにLinux自身にも色々種類があります。
Linuxカーネルを基本にして
様々な企業・団体が独自のLinuxディストリビューション(改造Linux)を再配布しています。

## 利点
* スペックの低いPCでも使える
* 基本無料である

# Linux用語

## Linuxカーネル（カーネル）
リーナス・トーバルズ氏が開発したLinuxのこと。
基本構成は下記の通り

* プロセス管理
* プロセス間通信
* メモリ管理
* ファイルシステム
* ネットワーク
* カーネルプリミティブ

## パッケージ
Linuxが採用しているアプリケーションの配布形態です。
インストールは色々存在し

RPM（RPM Package Manager）
Yum（Yellowdog Updater Modified）
Apt（Advanced Package Tool）
DNF（Dandified Yum）
などと呼ばれるパッケージ管理ツールを使用して、パッケージをダウンロードしてインストールします。
rpmコマンドでパッケージをインストールしたい場合は以下のようなコマンドです。

 ```bash:
$ rpm -ivh 「パッケージ名」
```

## ディレクトリ
フォルダのこと

## シェル
シェルは、Linuxへの命令文を入力するためのアプリケーションの総称です。
Linuxの代表的なシェルはbashであり
sh、ksh、zsh、csh、tcshなどもシェルです。

## コマンド
実行命令文のこと主な一覧はこちら

* cd：ディレクトリの移動
* cp：ファイル・ディレクトリのコピー
* rm：ファイル・ディレクトリの削除
* vi：エディタの起動・ファイルの作成
* rpm：パッケージのインストール
* make：ソースファイルのコンパイル

## サービス
Linuxが起動するときに自動的に起動するプログラムのこと

Apache
Webサーバとして動作するサービス

Samba
Linuxで、Windowsのファイルサーバやプリントサービス、ドメインコントローラ機能、ドメイン参加機能を提供するサービス

BIND
DNS（Domain Name Service）サーバの機能を提供するサービス

## ライブラリ
よく使われるプログラムの共通部分を、他のプログラムから利用できるようにしたものです

OpenSSL
インターネット上で標準的に利用される暗号通信プロトコルであるSSLおよびTLSの機能を実装した、オープンソースのライブラリ

NSS（Network Security Services）
セキュア通信を用いるソフトウェアの開発のためのクロスプラットフォームライブラリ
SQLについて


少しSQLについて投稿しようと思います。
DMLとDDLといった種類がありますが基本から説明します。

# SQLとは

データベース(リレーショナルデータベース (RDB))を操作するプログラム言語です。
大量データが登録されたデータを効率的に取得・更新・削除・追加することができます。

## 凡庸性
国際標準化されているので
MySQLやOracleなどのデータベースが変わったとしても
同じSQLで操作することが可能です。

そのためどのプログラミング言語でも組み合わせて利用することができます。

# 基本操作例

イメージを掴むために簡単な使用例を書きます。

```bash:使用例

SELECT カラム名 FROM テーブル名 WHERE カラム名 = 2

例
SELECT name FROM 人間テーブル WHERE id = 2

これで下記の図からueが出力されます。
```
人間テーブル

| id | name | age |
|:-:|:-:|:-:|
|  1 | ai   | 22  |
|  2 |  ue  | 33  |
|  3 |  oka | 44  |
|  4 | kiku | 55  |

次にDDLとDMLについて説明します。

# DDL

データを定義する意味
DDL（Data Definition Language)
SQLのうちデータベースやデータベースのテーブルを作成や定義する文法のこと

| 命令 | 機能 |
|:-:|:-:|
| CREATE | データベースやテーブルの作成 |
| ALTER | データベースやテーブルの更新 |
| DROP | データベースやテーブルの削除 |

```bash:使用例

CREATE TABLE テーブル名(カラム名 データ型や形式, ~~繰り返し);

例
CREATE TABLE member(member_id int, name varchar(20), sex char(1));

```



# DML
データを操作する意味
DML（Data Manipulation Language）
登録、更新など行う文法のこと

| 命令 | 機能 |
|:--|:--|
| INSERT | データの登録 |
| UPDATE | データの更新 |
| DELETE | データの削除 |
| SELECT | データの検索 |
swift⇄objective-cのファイル間での連携

Swift⇄objective-cのファイル間でのやりとりの方法を稀に忘れてしまうので備忘録としてここに記す。

#objective-cからSwiftを呼び出す方法

### Swiftのクラス名に@objcを書きNSobjectを継承させる
```swift

@objc class test: NSObject {
    func test1() {
        print("テスト")
    }
}
```

###呼び出したいメソッドに@objcを書く

```swift

@objc class test: NSObject {
    @objc func test1() {
        print("テスト")
    }
}
```

ちなみにクラスの頭に@objcMembersを書くとクラス全体に対して一括して@objcとして設定することが可能

```swift

@objcMembers
class test: NSObject {
    func test1() {
        print("テスト")
    }
}
```

#Swiftからobjective-cを呼び出す方法

###<プロジェクト名>-Bridging-Header.h
<プロジェクト名>-Bridging-Header.hに呼び出すobjective-cのヘッダーファイルを記載してあげる

```swift

#import "ObjcTest.h"
```
###objective-cの.m実装ファイル側でimportする
```swift

#import "名前-swift"
```

###objective-cのヘッダーファイルに参照するメソッドを書く
```swift
- (int)test;
```

#締め
必ずビルトかけてから参照しよう！
漏れがあるかもしれないのでほかあれば教えてください。
constっぽい処理。

先日やたらレガシーな案件で、スポットのお手伝いとしてJSを書きました。
その時constの代わりが欲しくなって変わりの処理を書いたので一応メモ書き。

``` js
/** GlobalRegistor CLASS */ (function () {

  "use strict";

  // constructor

  function GlobalRegistor () {}

  // static accessor

  Object.defineProperty(GlobalRegistor, 'global', {
      /**
       * @return {Object} global object
       */
      get: function() {
          return new Function('return this')();
      }
  });

  // static

  Object.defineProperty(GlobalRegistor, 'readOnly', { writable: false,
      /**
       * @param  {String} name
       * @param  {Any}    value
       * @return {Void}
       */
      value: (function readOnly (name, value) {
          if (GlobalRegistor.global[name] === void 0) {
              Object.defineProperty(GlobalRegistor.global, name, { writable: false, value: value });
          } else {
              throw new Error(name + ' is Declare Property');
          }
      })
  });

  GlobalRegistor.readOnly('GlobalRegistor', GlobalRegistor);

})();
```

## 使い方

```　.js
GlobalRegistor.readOnly('globalModules', {});
window.globalModules.fn  = function () { console.log('success!'); };
window.globalModules     = null;
window.globalModules.fn(); // success!
widnow.globalModules.foo = 1;
widnow.globalModules.foo = 2;
console.log(widnow.globalModules.foo); // 2

GlobalRegistor.readOnly('foo', 1);
console.log(widnow.foo); // 1
widnow.foo = 999;
console.log(widnow.foo); // 1
GlobalRegistor.readOnly('foo', 999); // error
```