OmniAICreator/Qiita-1.07M huggingface dataset:
[ruby,rails]gemのバージョンのdefault設定解除方法

# 1.エラーの例

```
$gem uninstall railties -v '6.0.2.1' #アンインストールコマンドです
~中略~
gem "railties" cannot be uninstalled because it is a default gem #エラー文
```

railsやその周辺のgemをダウングレードするべく、最新のgemに対し上記のアンインストールコマンドを打ったところその下のようにエラー文をだしました。そのエラー解決についてあまりネット上に記載がなかったので、解決方法を記載します
※railsなどのgemのバージョンを下げるには"インストールされている最新のgemのバージョン=反映させたいgemバージョン"とするため、必要なバージョン以上の全てのバージョンをアンインストールする必要があります


# 2.エラーの原因
コマンドの意味をよく調べずに`gem update --default`というコマンドを打ったところ、local( /Users/kontatomoya/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0)のgemの最新バージョンが一度にインストールされ、かつ最新バージョンがデフォルトに設定されてしまったのが原因でした

```
# （gem update --default コマンド入力後）
$ gem list #projectのGemfileにあるgemで使用可能な（もともとpcにinstallされている）gemのバージョンを調べるコマンドです。
　　　　　　　(localのどこで打っても同じものが出てきます)
〜前略〜
rails (default: 6.0.2.1, 5.2.4.1)  #このdefault:と付いているバージョンはdefault設定を解除しないとアンインストールすることができません
rails-controller-testing (1.0.4)
rails-dom-testing (2.0.3)
rails-html-sanitizer (1.3.0)
railties (default: 6.0.2.1, 5.2.4.1) #上記と同じです
〜後略〜
```

# 3.解決方法

下記の順にコマンドを打っていただければdefaultを解決できます

```
$ gem environment #gemのインストール先のパスを確認します
RubyGems Environment:
  - RUBYGEMS VERSION: 2.7.6
  - RUBY VERSION: 2.5.1 (2018-03-29 patchlevel 57) [x86_64-darwin18]
  - INSTALLATION DIRECTORY: /Users/kontatomoya/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0
　　#↑この行でgemのインストール先のパスを確認します
　〜後略〜

$ cd #ホームディレクトリへ移動
$ cd /Users/kontatomoya/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0 
　#上記で確認したパスに移動します（今回は筆者のディレクトリで記述します）
$ ls #中を確認します
build_info	doc	gems
cache	extensions	specifications ←この中にdefault設定が記述されています

$ rm -rf specifications/default/ 
　#specificationsのなかのdefaultディレクトリ削除します（これでdefaultが解除されます）

$ gem list #defaultが解除されているのを確認します
〜前略〜
rails (6.0.2.1, 5.2.4.1) #defaultが解除されているのが確認できます
rails-controller-testing (1.0.4)
rails-dom-testing (2.0.3)
rails-html-sanitizer (1.3.0)
railties (6.0.2.1, 5.2.4.1) #defaultが解除されているのが確認できます
〜後略〜
```

# 4.(補足)ダウングレード
1~3が終わった状態で下記のコマンドを打つことでダウングレードすることができます（当初の目的がダウングレードだったので忘れずに行いましょう）

```
$gem uninstall railties -v '6.0.2.1'
$gem uninstall rails -v '6.0.2.1'

$ gem list
〜前略〜
rails (5.2.4.1) #6.0.2.1が削除されているのが確認できます
rails-controller-testing (1.0.4)
rails-dom-testing (2.0.3)
rails-html-sanitizer (1.3.0)
railties (5.2.4.1) #6.0.2.1が削除されているのが確認できます
〜後略〜
```

# 5.注意点
default値を消すことができないことに焦って`gem uninstall -I -a -x --user-install --force`（クリーンアップ（強制削除））をしてしまわないようにしましょう。このコマンドでもdefault値は消せず、gemの最新バージョン以外の全てのバージョンと、初期から入っていない全てのgemが削除されます。筆者は焦ってこのコマンドを打ってしまい、macのタイムマシーンで元に戻すことにしました。バックアップしてない人は手詰まり（元のバージョンとすることができない状態。最新バージョンなら`gem install bundler`などで必要なものだけのインストールはできますが...）になってしまうので注意しましょう。

# 6.参考
bundled gem と default gem の違い
https://blog.n-z.jp/blog/2016-09-10-bundled-gem-and-default-gem.html
データベーススペシャリスト試験で絶対に正解してはいけない問題

データベーススペシャリスト試験でIPAの正解を正解だと覚えると実務で問題を起こす事例がある。
H28の午後１　問１　１

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163299/98f3cb38-8239-507a-5ce2-ac1989a8b0d3.png)
なので、緯度経度だけで施設が特定できると考えているのだろうが、施設は高度も関係してくるので、これは間違い。
施設名も重複の可能性があるので、「緯度経度、施設名、所要時間」でも候補キーとしてはいけない。


なお、施設IDと駐車場IDで候補キーとなる設計も一般的にはありえない。
施設名はかなりしょっちゅう変わる要素であるから、それが重複して存在する設計にするのは、かなりの初心者でもやらないだろう。
Android Studio:Kotlin グローバル変数

探してもJavaばっかりしかなかったので苦労しました。
誰かの役に立てばうれしいです。

まずグローバル変数を保存するクラス作ります

``` kotlin:MyApp.kt

package your_package_name
import android.app.Application
class MyApp :Application(){
    var QRResult: String? = null

    companion object {
        private var instance : MyApp? = null

        fun  getInstance(): MyApp {
            if (instance == null)
                instance = MyApp()

            return instance!!
        }
    }
}
```

MyAppCallerで呼び出し。
Activity間で変数をまたいで使えます。

```kotlin:MyAppCaller.kt
//instance呼び出し
val myApp = MyApp.getInstance()
//setter
myApp.QRResult = string
//getter
val QRResult = myApp.QRResult
```

間違いがあったら教えてくれると嬉しいです。
[Java8]streamを使ってint型の配列を降順ソートする

# 概要
- 勉強中にひっかかったところのメモ
- Integer型だと使えたけど、int型の降順だと、Comparatorが使えなかった。
- 結論は、boxedを使えばできるようだった。

# サンプルプログラム
- 「int型配列を使って、次の数字を降順に並び替えて出力しなさい」みたいな問題

```java
import java.util.Arrays;
import java.util.Comparator;

public class Main {
    public static void main(String[] args) throws Exception {
        
        // 入力
        int[] numArray = {4, 3, 2, 5, 6, 7, 3, 2, 1, 9, 7, 8, 10, 6, 4, 3, 5, 8, 9};

        Arrays.stream(numArray)
                .boxed()
                .sorted(Comparator.reverseOrder())
                .forEach(i -> System.out.print(i + " "));
    }
}

```

出力結果

```console
10 9 9 8 8 7 7 6 6 5 5 4 4 3 3 3 2 2 1 
```

filter や　distinct　を組み合わせれば、絞り込みや重複の削除もできる

```java
import java.util.Arrays;
import java.util.Comparator;

public class Main {
    public static void main(String[] args) throws Exception {
        
        // 入力
        int[] numArray = {4, 3, 2, 5, 6, 7, 3, 2, 1, 9, 7, 8, 10, 6, 4, 3, 5, 8, 9};

        Arrays.stream(numArray)
                .boxed()
                .distinct()
                .filter(x -> x >= 5)
                .sorted(Comparator.reverseOrder())
                .forEach(i -> System.out.print(i + " "));
    }
}

```

出力結果

```console
10 9 8 7 6 5 
```

配列自体を書きかえるならこんな感じみたいです

```java
import java.util.Arrays;
import java.util.Comparator;

public class Main {
    public static void main(String[] args) throws Exception {
        
        // 入力
        int[] numArray = {4, 3, 2, 5, 6, 7, 3, 2, 1, 9, 7, 8, 10, 6, 4, 3, 5, 8, 9};
                
        numArray = Arrays.stream(numArray)
            .boxed()
            .distinct()
            .filter(x -> x >= 5)
            .sorted(Comparator.reverseOrder())
            .mapToInt(Integer::intValue)
            .toArray();
        System.out.println(Arrays.toString(numArray));
    }
}
```

出力結果

```console
[10, 9, 8, 7, 6, 5]
```

# 参考
- https://stackoverflow.com/questions/880581/how-to-convert-int-to-integer-in-java
- https://teratail.com/questions/52847
【Python】joinの正しい使い方

## 学びたての認識

リストの要素(str)を連結・結合する際はjoinを使います。

```py
>>> v = ["Hello", "Python"]
>>> "".join(v)
'HelloPython'
```

要素はstr型でなければいけません。

任意の文字列で連結可能です。

```py
>>> s = ["A", "B", "C", "D"]
>>> "->".join(s)
'A->B->C->D'
```

## リストだけじゃない

`join`は引数として**iterableなオブジェクト(イテレータ)**を受け取ります。つまり、**for文で回せるようなもの**なら引数として受け取ることができます。

リストもiterable(イテレータ)の一種で、例は先ほどあげました。

iterableなオブジェクトはその他にもいろいろあります。

- tuple
- dict
- str
- ジェネレータ式
- mapオブジェクト
- fileオブジェクト
- その他さまざまな標準ライブラリの戻り値
- 独自iterableクラス

## tuple

```py
>>> " ".join(("やせいの","ポッポ","が","あらわれた！"))
'やせいの ポッポ が あらわれた！'
```

## dict

dictはfor文で回すとキーが取り出されます。
itemsメソッドは、キーと値がタプルで取り出されるのでそのままではjoinできません。

```py
>>> " ".join({"a": 2, "b": 3, "c": 5, "d": 7})
'a b c d'
```

## str

strもiterableなのでjoinできます。

```py
>>> "・".join("ひみつ")
'ひ・み・つ'
```

## ジェネレータ式

```py
>>> "".join(str(c) for i in [0,90,1234,5678])
'09012345678'
```

たまにjoinにわざわざリスト内包表記を渡す人がいますが、ジェネレータ式が返すものはiterableなのでその必要はありません。
ジェネレータ式を使う方法は、リストに変換する処理が省かれるので、速度的にもメモリ的にも効率的です。

## mapオブジェクト

```py
>>> "".join(map(str, [0,90,1234,5678]))
'09012345678'
```

map関数の戻り値は、リストではなくmapオブジェクトというiterableなオブジェクトです。
list型に変更する必要はありません。

## fileオブジェクト

open関数で生成されるfileオブジェクトはiterableです。for文で回すと一行ずつ取り出されます。

```:text.txt
函館
小樽
札幌
富良野
旭川
知床
```

```py
>>> print("からの".join(open("text.txt")))
函館
からの小樽
からの札幌
からの富良野
からの旭川
からの知床
```

## その他いろいろなイテレータ

- range
  - rangeは要素がintなのでjoinできません。
- filter関数の戻り値
- accumulate関数の戻り値

など。

---

joinのほかにもiterableを引数に受け取る関数はたくさんあります。

- filter
- sorted
- map
- sum

どの関数がiterableを受け取るのかわからないと思います。そういうときは公式サイトを見るか、
PyCharmなどのIDEを使っている場合は予測変換でiterableと出ると思います。
Salesforceの概念

引用：https://blog.csdn.net/weixin_30407613/article/details/101093843?depth_1-utm_source=distribute.wap_relevant.none-task&utm_source=distribute.wap_relevant.none-task
1. Organization
在学习salesforce，经常会看到Org这一名词，其实就是Organization（组织）。如果一家企业想要使用Salesfroce产品，首先得向Salesforce公司购买一个Org instance，其实就是给你一个用户名和密码，登录后，可以创建用户，配置业务逻辑以及二次开发等等。



存储空间
　　　　当购买Org instance后，它会限制存储空间外，主要分为Data Storage, File Storage以及Big Object Storage（如果不够用，可加钱扩展空间，类似国内的某些云盘）



License
　　　　每个Org都会配置制定数量的License，每创建一个User都需要消耗一个User License（一般创建用户时使用Salesforce License)



API Request
　　　　这里需要注意的是，除了Storage和License外，Salesforce还有API的数量限制，毕竟高请求意味着高并发，消耗的性能更多，所以这肯定是个卖点指标啦。正常情况下，API Request是够用的，但是如果设计大量数据的操作还是要关注的，防止请求数量被使用完。

PS: 当然，在Org的信息中，还有Language, Time Zone, Fiscal Year以及Currencies等相关概念，但这些相对简单，大家看一眼就明白，这里就不说了。

2. User
　　user，某个可登陆该Org的人，可以是developer, sales也可以是Partner。一般主要包含一下几个属性：personal, Security & Access, Locale

      

其中，最重要的概念是Role，User Liencese, Profile



PS: User一经创建便无法删除，只能去掉Active选项，该设计理念是为了方便查询某些历史记录。当然，inactive后，License 便会释放掉。

3. Profile
　　profile，其实就是一组settings和Permissions，用来决定该用户登录时可以见到什么，以及可以做些什么。

　　

PS: 每个User都归属于某一Profile，并且User与Profile是多对一的关系，详情请点击（https://www.cnblogs.com/cloudman-open/p/11552089.html）

4. Role
　　在私有或者混合模型中，Role层次结构允许更高级别的User继承了直系底层User的权限。比如：如果EMEA Sales Rep是某个case的owner，那么他的直系领导们(EMEA Sales Director, VP of Global Sales, CEO)都拥有访问这个case的权限，并且权限的继承是单项的。



    这里可能会有人疑问，什么是私有或者混合模型？那么就得提出sharing的概念。

5. Sharing
　　针对所有的sObjects，除了对该sObject schema的访问权限外（对该sObject具有增删改查权限），对其中的某条记录也有严格的控制。如上述的role中所说，EMEA Sales Rep是某个case的owner，那么在Case这个Object中，EMEA Sales Rep便有该条记录的访问权限，其他的case记录对他来说是不感知的。

　　那么问题来了，除了该条记录的owner之外，还有谁可以该条记录的增删该查权限呢？



 　 这里可以看出，针对每个sObject我们都可以设置访问权限：Private, Public Read Only, Public Read/Write。

private：只有该条记录的拥有者才拥有读写权限。
Public Read Only: 除了拥有者之外，其他人都是只读权限。
Public Read/Write：所有人都有读写权限。
PS: 当然，这里的设置只是默认的访问权限，除此之外，还有Role hierarchy，Sharing Rules，Team and Manual Sharing这几种方式来分享记录的访问权限。（具体的内容，会在后面的帖子中分享）

6. sObjects
　　sObjects(Salesforce Objects), 是Salesforce平台封装的对象，与传统的数据库table有异曲同工之妙。

　　sObject分为标准对象和自定义对象，标准对象是平台自动生成的对象例如：Account, Contact, Lead, Opportunity；而自定义对象可以按照各自业务需求自行设置，但是Salesforce为在API Name中自动加上“__c”这样的后缀（customize)。



　　每个对象都可以定义多个字段，并且每个字段可以是字符串，数字，公式，日期等类型。

　

　　针对每个字段，都可通过Field-Level Security设置访问权限。



　　当然，你可以设置Trigger，类似于数据库操作，before/after insert/update/del，例如：

trigger PairPtAttachToAccount on Pt_Attach__c (before insert) {
    for(Pt_Attach__c ptAttach: trigger.New) {
        List<Webex_Account__c> accounts = [select Id, Account_Id__c from Webex_Account__c];
        for(Webex_Account__c account: accounts) {
            if(ptAttach.Account_Id__c == account.Account_Id__c){
                ptAttach.Webex_Account__c = account.Id;
                break;
            }
        }
        ptAttach.Site_Name__c = ptAttach.Site_Name__c + '.webex.com';
    }
}
勾配降下法とは？？　〜機械学習の用語まとめ〜


#勾配って何？？
簡単に言えば、多変数関数における傾きのようなもので、１変数関数のようにスカラーではなく、ベクトルとなる。
勾配が示すベクトルは、各点において最も数が大きくなる方向と言える。(-をつければ、各点において最も数が小さくなる方向とも言える。)
実際に求める時には、全ての変数で偏微分し、ベクトルで表すと勾配になる。具体例を挙げてみてみよう。
$f(x,y) = x^{2} + y^{2}$をx,yで偏微分すると、それぞれ2x,2yとなる。
よって、点(0,0),(0,1),(1,0)の勾配は(0,0),(0,2),(2,0)となる。

#勾配と損失関数
ニューラルネットワークの学習では、重みやバイアスといったパラメータを変化させ、以前説明した[損失関数](https://qiita.com/Becon147/items/988b637fb890b796d02e)を小さくしていく。
しかし一般的には損失関数は複雑で、どの方向にパラメータを動かせば良いかわからない。そこで勾配を用いると、簡単に損失関数が小さくなる方向がわかる。
しかしながら、必ずしも勾配は損失関数を最小値へと導くわけではない。
下図を見てみよう。(この場合は勾配というよりも傾きだが、、)
<img width="351" alt="スクリーンショット 2020-03-04 22.10.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/470838/5a2558e1-2415-0fdc-51c9-c4fe2baea56c.png">

仮にx=5から勾配に従っていくとx=3で勾配が０になり停滞する。しかしながら、x<0ではもっと値が小さくなる。このように勾配に従っているだけでは、極小値で停滞してしまい、最小値にたどり着かないことがある。

#勾配降下法って？
先ほど説明したように、必ず最小値にたどり着くわけではないが、損失関数を小さくすることができる。
勾配降下法とは、その点における勾配に従ってある一定距離進み、その進んだ先での勾配を求めて、またそこから勾配に従ってある一定距離進む..というのを繰り返す。
このようにして損失関数の値を小さくしていく方法が**勾配降下法**である。
ニューラルネットワーク以外でも、最適化の分野でよく使われる方法です。

実際の勾配降下法を式で表すと、
$$
x_n= x_{n-1} - \eta \frac{\partial f}{\partial x} \\\
y_n = y_{n-1} -  \eta \frac{\partial f}{\partial y}
$$
となる。なお、$f$は損失関数、$\eta$は学習率である。
学習率は、一回の学習でどれだけ値を更新するかを定めたパラメータで、事前に定める値である。

#実際の学習の流れ
①学習データの中から無作為に一部のデータを選ぶ。(このデータを**ミニバッチ**という。)
②ミニバッチを用いて、各パラメータの勾配を計算する。
③勾配降下法に従って、各パラメータを更新する。

上記の①〜③を繰り返し、パラメータを更新していく。
無作為にミニバッチを選ぶ勾配降下法を、**確率的勾配降下法(SGD)**という。

#まとめ
勾配降下法とは、損失関数を小さくするために、勾配を用いてパラメータを更新する手法であり、ニューラルネットワークの学習において使われる。
必ずしも、損失関数が最小になるとは限らないが、この方法を用いることで、損失関数を小さくすることができる。
基本情報技術者　テクノロジ系　第2章　機械語命令の読解

[基本情報技術者試験](https://qiita.com/savaniased/items/d3f94da4f087e178cb69)
こちらより

説明が長くなる上に、意味が少なめなので
最低限のことだけ書きます。

# 機械語命令の読解

ポイントとして

1,命令フォーマットを読み取る
2,有効アドレスの計算方法を図表から的確に把握しなければならない

## 基本攻略方法

1,命令後の形式を把握する
2,各表の理解(命令コードや実行アドレスの算出式など)
3,番地から命令内容をだすことを考える
4,細かい計算式をちょくちょく挟むので漏らさず行う。
　特に表の命令内容は漏らさないようにする。
【Spring】Unitテストで一部のテストでのみapplication.yamlの値を上書きする方法【Kotlin】

テストの時だけ`application.yaml`の値を変更して検証したいということがあったのでメモ。

# サンプルプログラム

```yaml:application.yaml
test:
    isMorning: true
```

```kotlin:SampleProperties.kt
@Component
@ConfigurationProperties(prefix = "test")
class SampleProperties {
    lateinit var isMorning: java.lang.Boolean
}
```

```kotlin:SampleService.kt
@Service
class SampleService(
    private val properties: SampleProperties
) {
    fun getGreeting(): String {
        return if (properties.execution.booleanValue()) {
            "Good Morning!"
        } else {
            "Good Afternoon!"
        }
    }
}
```

`application.yaml`の値を`@ConfigurationProperties`で取得して、その値に応じて分岐するというだけの簡単な処理です。

これをテストする場合`@SpringBootTest(properties = ["test.isMorning=false"])`や`@PropertySource`などを使用することでテストクラスごとに値を変えることはできますが、一つのテストクラス内でテストメソッドごとにプロパティの値を変更することはできません。

そこで今回は`ReflectionTestUtils.setField()`を使用してメンバ変数（フィールド）を直接上書きします。

# テストを書いてみる

```kotlin:SampleServiceTests.kt
@EnableAutoConfiguration
@SpringBootTest
class SampleServiceTests {

    @Autowired
    lateinit var sampleService: SampleService

    @Autowired
    lateinit var sampleProperties: SmapleProperties

    @Test
    fun `isMorningがtrueの場合`() {
        val result = sampleService.getGreeting()
        Assertions.assertEquals("Good Morning!", result)
    }

    @Test
    fun `isMorningがfalseの場合`() {
        ReflectionTestUtils.setField(sampleProperties, "isMorning", false as java.lang.Boolean)

        val result = sampleService.getGreeting()
        Assertions.assertEquals("Good Afternoon!", result)
    }
}
```

ちなみにこれ以外にも`ReflectionTestUtils.setField`は`private`なメンバ変数でも値を上書きすることができます。

### 参考文献
[SpringBootTestでapplication.propertiesの値をどうにかして使いたかった話](https://qiita.com/juhn/items/b8c2999051e60ca239d9)
[Mockitoでprivateメソッドのテストっぽいこと](https://k-sasaki.net/2019/10/502/)
[単体テストのためのReflectionTestUtilsへのガイド](https://www.codeflow.site/ja/article/spring-reflection-test-utils)
アルゴリズムと計算量

アルゴリズムとは、問題や課題を解決するための処理手順をもれなく表現した考え方のこと。
プログラムにおけるアルゴリズムの代表的なものとして、__ソート__（並び替え）と__探索__がある。


##アルゴリズムと計算量
アルゴリズムには結果が出るまでにかかる時間の特徴を表す計算量という考え方がある。
計算量は__O記法__という表し方をする。

- __O(1)__
    - データ数nにかかわらず一定、nが増えても計算量は等しい。
- __O(n)__
    - 比例なので、データ量が２倍増えると、計算量も２倍増える。
- __O(log n)__
    - 計算量を求める場合は底を２として考える。nが２倍、３倍と増えても、計算量は１、２と増える程度なので、データ量が多い場合に有用。
- __O（n log n）__
    - 先述のO(n log)にnの計算量がかけられたもの。
    - nが２倍になると、計算量は約２．５倍、１０倍になると２０倍、１００倍になると３００倍になる。
- __O(n^2)__
    - ｎ個の要素を用いた総当りの組み合わせを求める場合がこのパターンに当てはまる。大きなデータを扱うと莫大な処理時間になるので、実用的ではない。


##ソートアルゴリズム
###バブルソート
隣り合う要素の大小を比較して整列させる。
昇順に並び替えるときは、基準となる要素と隣の要素を比較して、基準の要素のほうが大きれば入れ替え、そうでない場合は入れ替えず、基準となる要素をひとつとなりにずらす。
これを繰り返し最終的に正しい順序に並び替える。
総当りで比較していくので、__O(n^2)__。



###挿入ソート
まず１番目と２番目の要素を比較し、要素の順番が逆なら入れ替え、正しければそのままにする。
次に３番目の要素を正しく並んでいる１番目、２番目の要素と比較し、正しい位置に挿入する。
以降の要素もひとつずつ既に並び替えた整列と比較し、正しい順に並ぶように挿入することを繰り返す。
総当りさせるので__O(n^2)__。


###マージソート
並び順がばらばらになっている要素を繰り返し２つに切り分け、要素数が１になるまで分解する。
分解した配列ごとに大小を比較し、並び替えたものを合併していく。小さく切り分けたソート済の要素を次々に合併して、すべての要素を正しい順番に並び替える。
並び替えの際に合併するので、マージソートという。
計算量は、はじめに分割する際に２つに切り分けていくので__O(log n)__、並び替えの際に要素の数だけ比較をするので__O(n)__かかる。よって、__O(n log n)__となる。

##探索アルゴリズム
探索とは、特定の条件に当てはまるデータを探し出すこと。求める要素と一致する要素が見つかるまで探索をします。

###リニアサーチ（線形探索）
一直線に並べたリストを先頭から順に目的の要素かどうか確認していく。一致する要素がでれば探索終了。
最もシンプルな探索アルゴリズム。
計算量は__O(n)__。

###バイナリサーチ（二分探索）
予め対象のデータを昇順に並べておく必要あり、
探したいデータと、探したい配列の中央の要素を比較し、それより大きいのか、小さいのかによって、次回探す範囲を絞り込みます。例えば、目的の要素が中央の要素より大きれば、大きい方の半分のリストを対象に再度中央の要素を確認し、目的の要素と比較します。
このように半分ずつ絞り込んで目的の要素を見つける。
中央の要素が探したいデータと一致したときに終了。
一回の比較を行うごとに探索の要素が半分になるので、計算量は__O(log n)__。



###参考

開発新卒に捧ぐ、基本のアルゴリズムと計算量 | TECHSCORE BLOG
https://www.techscore.com/blog/2016/08/08/%e9%96%8b%e7%99%ba%e6%96%b0%e5%8d%92%e3%81%ab%e6%8d%a7%e3%81%90%e3%80%81%e5%9f%ba%e6%9c%ac%e3%81%ae%e3%82%a2%e3%83%ab%e3%82%b4%e3%83%aa%e3%82%ba%e3%83%a0%e3%81%a8%e8%a8%88%e7%ae%97%e9%87%8f/
javascript で文字列を date オブジェクトに変換するときのメモ

下記のいずれかではいけるようです。

```str_to_date.js
var str = "YYYY/MM/DD HH:mm:ss";
var d = new Date(str);
```

```str_to_date2.js
var str = "YYYY/MM/DD HH:mm:ss";
var d = Date.parse(str);
```

perse はブラウザによって、Date オブジェクトではなく、1970/01/01 からの経過時間を数値でかえしてくることがあるようです。

str は例えば `"2020/02/29 12:34:56"` とかです。区切り文字がハイフンだと(例えば `"2020-02-29 12:34:56"`)、ブラウザによって時差の分だけズレが生じることがあるようです。ハイフンを `/` に直してから `new Date()` すれば良いようです。

```replaced.js
var str = "YYYY-MM-DD HH:mm:ss";
var d = new Date(str.replace(/-/g, '/'));
```

Date オブジェクト間の差分は、二つの時刻の間の差をミリ秒で表した数値になるようです。

```date_sub.js
> new Date("2020/02/29 10:00:00") - new Date("2020/02/29 09:59:00");
// 60000
```

# 参考

https://qiita.com/labocho/items/5fbaa0491b67221419b4
むしろここを見るべき。
【JavaScript】Moment Timezone

Moment Timezoneは日付の操作などの機能を提供するライブラリです。
早速インストールして使っていきます。

```
npm i --save moment-timezone
```

##基本的な使い方

moment()メソッドを使います。
引数なしの場合、現在時刻が返されます。

```javascript
const now = moment()
console.log(now)//2020-03-01T17:22:39+09:00

```
色々な形式で取得することが可能です。

```javascript

const now = moment().toDate() //Date型を返す。Sun Mar 01 2020 17:28:10 GMT+0900 (GMT+09:00) {}
const now = moment().unix() //unixのタイムスタンプを返す。1583051420
const now = moment().toDate() // ISO 形式 (ISO 8601) の文字列を返す。2020-03-01T08:31:45.639Z
```

##日時の加減
addメソッドとsubstractメソッドを使用します。
第一引数には加減する値、第二引数には単位を渡します。

```javascript
moment(now).add(10,"year").format() //2030-03-01T17:31:45+09:00
moment(now).subtract(10,"year").format() //2010-03-01T17:31:45+09:00
```

第二引数に渡す単位は省略形でも構いません。
年　「'year' or 'y'」
月　「'month' or 'M'」
週　「'week' or 'w'」
日　「'day' or 'd'」
時　「'hour' or 'h'」
分　「'minutes' or 'm'」
秒　「'second' or 's'」

##日時の始まり・終わり
startOfメソッドとendOfメソッドで指定した単位の始まりと終わりを取得できます。

```javascript
moment(now).startOf("year").format() //2020-01-01T00:00:00+09:00
moment(now).endOf("year").format() //2020-12-31T23:59:59+09:00
```

##コピー

元の日時を変更させたくない場合、cloneメソッド でコピーを作成します。

```javascript
  const now2 = moment('1900-01-01 01:01:01')
  const clone = now2.clone()
  clone.add(1000,'year').format()// 2900-01-01T01:01:01+09:00
  clone.format()// 2900-01-01T01:01:01+09:00
  now2.format()// 1900-01-01T01:01:01+09:00
```

##差分
diffメソッドで渡したデータとの差分を返します。
第二引数には差分を出す単位を渡します。
何も渡さない場合はミリ秒が返されます。

```javascript
  const toData = ('2000-01-01 00:00:00')
  const fromData = ('2020-01-01 00:00:00')
  moment(fromData).diff(toData)// 631152000000
  moment(fromData).diff((toData),'year')// 20
```

##比較
渡した日時と比較をし、真偽値が返されます。
isAfterメソッドでaはbより後かの比較
isBeforeメソッドでaはbより前かの比較
isAfterメソッドでaはbと同じもしくは後かの比較
isBeforeメソッドでaはbと同じもしくは前かの比較
isBetweenメソッドでaはbの範囲内かの比較

```javascript
  a.isAfter(b)// false
  b.isAfter(a)// true
  a.isBefore(b)// true
  b.isBefore(a)// false
  a.isSameOrAfter(b)// false
  b.isSameOrAfter(a)// true
  a.isSameOrBefore(b)// true
  b.isSameOrBefore(a)// false
  a.isBetween(b)// false
  b.isBetween(a)// true

```

##format

formatメソッドで日時の表示形式を変更することができます。

```javascript
  c.format('M') //01
  c.format('MM') //01
  c.format('MMM') //Jan
  c.format('MMMM') //January

  c.format('d') //3
  c.format('dd') //we
  c.format('ddd') //wed
  c.format('dddd') //wednesday
```
localeメソッドで日本を指定すると日本語形式で返されます。

```javascript

moment.locale('ja')
gcp asset exportをbigqueryに対してする際のエラー対処方法

gcpのassetをBigQueryに出力する際に
assetを取得するプロジェクトと、出力先のBigQueryのプロジェクトが異なるとエラーが起きて、export出来ない

```
gcloud  asset export --project="プロジェクトA" --bigquery-table="projects/プロジェクトB/datasets/データセット名/tables/テーブル名" --content-type=resource

#以下のようなエラーが出る
ERROR: (gcloud.beta.asset.export) User [xxxxx@xxxxx] does not have permission to access project [プロジェクトA:exportAssets] (or it may not exist): The caller does not have permission
```

解決方法はこちらに書いてあった
https://cloud.google.com/asset-inventory/docs/faq#how_do_i_export_assets_to_tables_that_dont_belong_to_the_current_project

assetのexportをする際はassetのサービスアカウント(service-PROJECT_A_NUMBER@gcp-sa-cloudasset.iam.gserviceaccount.com)がBQのテーブルを作りに行く
そのため、プロジェクトAのassetのサービスアカウントにプロジェクトBのBigQueryのユーザ権限とデータ編集者権限をつけないといけない
自動更新機能

console.log()使い方　複数記述し一度にたくさん確認できる

message.js
var html =の記述
段落を間違えるだけでメッセージの形が崩れる

// id:(last_id:にしていた)の記述を間違えたせいでコントーローラーにとんでいるがキャッチできずに全部のメッセージを拾っていた
 data: {id: last_message_id}
赤くテストのリファクタリング

*この文書は[TotT: Refactoring Tests in the Red](https://testing.googleblog.com/2007/04/tott-refactoring-tests-in-red.html)の翻訳です。*


いいテストのセットが適切にあれば、コードのリファクタリングは簡単になる。リファクタリング後にテストを走らせ、コードがパスすることを確認することで、素早く多くの確信を得ることができる。

一連のテストが大きくなるにつれ、重複が現れ始めるのは普通だ。コードと同様に、テストも分かりやすくメンテナンスしやすい状態を維持するのが理想的である。そこで、**テストもリファクタリング**したくなるだろう。


**しかしながら、テストのリファクタリングは難しい。だって、テストのテストは用意していないだろう？**

どのようにしてテストのリファクタリングが安全であり、間違ってアサーションの一つを消してしまっていないかを知るのだろうか？

**意図的にテスト対象のコードを壊せば**、テストが失敗し、アサーションが依然として働いていることが分かる。例えば、`CombineHarvesterTest`のメソッドをリファクタリングしているとして、`CombineHarvester`に手を入れ、返り値が間違ったものにすればよい。

テストが失敗する理由が期待通りアサーションが失敗しているからかどうかを確認しよう。そうであれば（注意深く）失敗しているテストをリファクタリングできる。もし、あるときテストがパスし始めたら、テストが壊れているということがすぐに分かる。やり直そう！リファクタリングが終わったら、テスト対象のコードをもとに戻し、再びテストがパスするかどうかを確認しよう。

(`revert`が助けになる。**テストはrevertしないように！**）[^1]

大事な点を再確認しよう：

**リファクタリングが終わったら… テスト対象のコードをもとに戻すのを忘れないこと！**

## まとめ

- **プロダクト**コードをテストを**通し**ながらリファクタリングする。そうすることで、プロダクトコードが意図通りに動作しているかどうかを判別できる。

- **テスト**コードをテストを**失敗**させながらリファクタリングする。そうすることで、テストコードが意図通りに動作しているかどうかを判別できる。


[^1]: 最近のことは分かりませんが、この当時のGoogleはPerforceじゃないかな[^2]。 Gitだとcheckoutでしょうか。
[^2]: [Why Did Google Choose a Central Repository](https://www.perforce.com/blog/vcs/why-did-google-choose-centralized-repository)
プロトコルとポートとURLの関係 （初学者向け）




| port      |        protocol |    URL    |
|:-----------------:|:------------------:|:------------------|
| 80           |     http    |        http://example.com        |
| 443          |     https    |       https://qiita.com/takaahi/items/b31d4bd67d5fc4f5df80       |
| 6379         |     tcp    |        tcp://redis-connection        |
| 6380         |     tls    |        tls://redis-ssl-connection       |
| 389          |     ldap    |       ldap://ad-ldap-connection       |
| 686          |     ldaps    |      ldaps://ad-ldap-ssl-connection      |

必ずしもhttpだから80という訳ではないのですが、初学者が理解しやすいようにまとめてみました。
<プロトコル>://<アクセス先>:<ポート>となる訳ですが、このことを理解するのに時間が掛かった気がする。。

最近だとdockerのおかげでポートのイメージはつきやすいかも。
最近の開発だとセッションの永続化や外部認証との連携はよくあることなので記載しました。



一応元の画像も添付しておきます。（自分で作ったものです。）
<img width="632" alt="スクリーンショット 2020-03-04 22.20.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222041/770c2bc2-3440-b5b6-24c1-99f4752e59ee.png">
[UE4] エンジンコードマージの注意点（パッケージバージョン編）

# 追記
この記事の内容は、誤った改造を行ったことによって、プロジェクトコンテンツとエンジンコンテンツのオブジェクトバージョンが uasset の構造が異なるにもかかわらず、同じ値となりロード処理が失敗するようになってしまった。

正しくは以下の記事を参照
https://qiita.com/Takezoh/items/0b95633e251c965b4f71


# 元記事

パッケージに格納するデータを拡張する場合、パッケージバージョンを追加する必要がある。
エンジンコードをアップデートの際にエンジン側でパッケージバージョンが追加されていた場合、自動マージではコンフリクトも起きず不整合な状態でマージされてしまう可能性が高い。

正しくマージするには、以下のようにすると良い。（エンジンアップデートの際には要注意）

パッケージバージョンは次のファイルに定義されている。
`Engine/Source/Runtime/Core/Public/UObject/ObjectVersion.h`
`enum EUnrealEngineObjectUE4Version`


過去にパッケージを拡張するため以下の修正を行った。

```diff
	// LocalizationId has been added to the package summary (editor-only)
	VER_UE4_ADDED_PACKAGE_SUMMARY_LOCALIZATION_ID,
	// Fixed case insensitive hashes of wide strings containing character values from 128-255
	VER_UE4_FIX_WIDE_STRING_CRC,

	// -----<new versions can be added before this line>-------------------------------------------------
	// - this needs to be the last line (see note below)
+	VER_UE4_YOMUNECO_CUSTOM,

	VER_UE4_AUTOMATIC_VERSION_PLUS_ONE,
	VER_UE4_AUTOMATIC_VERSION = VER_UE4_AUTOMATIC_VERSION_PLUS_ONE - 1
```
`VER_UE4_YOMUNECO_CUSTOM` と `VER_UE4_AUTOMATIC_VERSION` は同じ値となり、パッケージには `VER_UE4_AUTOMATIC_VERSION` が格納される。

4.24 へのアップデートを行い、自動マージにより `VER_UE4_ADDED_PACKAGE_OWNER` が追加された。

```diff

	// LocalizationId has been added to the package summary (editor-only)
	VER_UE4_ADDED_PACKAGE_SUMMARY_LOCALIZATION_ID,
	// Fixed case insensitive hashes of wide strings containing character values from 128-255
	VER_UE4_FIX_WIDE_STRING_CRC,
+	// Added package owner to allow private references
+	VER_UE4_ADDED_PACKAGE_OWNER,

	// -----<new versions can be added before this line>-------------------------------------------------
	// - this needs to be the last line (see note below)
	VER_UE4_YOMUNECO_CUSTOM,

	VER_UE4_AUTOMATIC_VERSION_PLUS_ONE,
	VER_UE4_AUTOMATIC_VERSION = VER_UE4_AUTOMATIC_VERSION_PLUS_ONE - 1
```

この場合、以前のバージョンで作成・更新したパッケージのバージョン番号と、マージ後エンジンの `VER_UE4_ADDED_PACKAGE_OWNER` が同じ値となり、パッケージのロード処理に不整合が起きる。

正しくマージするには次のようにする。

```diff

	// LocalizationId has been added to the package summary (editor-only)
	VER_UE4_ADDED_PACKAGE_SUMMARY_LOCALIZATION_ID,
	// Fixed case insensitive hashes of wide strings containing character values from 128-255
	VER_UE4_FIX_WIDE_STRING_CRC,
+	// Yomuneco custom version
+	VER_UE4_YOMUNECO_CUSTOM,
+	// Added package owner to allow private references
+	VER_UE4_ADDED_PACKAGE_OWNER,

	// -----<new versions can be added before this line>-------------------------------------------------
	// - this needs to be the last line (see note below)
-	VER_UE4_YOMUNECO_CUSTOM,

	VER_UE4_AUTOMATIC_VERSION_PLUS_ONE,
	VER_UE4_AUTOMATIC_VERSION = VER_UE4_AUTOMATIC_VERSION_PLUS_ONE - 1
```

これによりロード処理に不整合が起きず、新エンジンで作成・更新したパッケージのバージョン番号はインクリメントされ `VER_UE4_ADDED_PACKAGE_OWNER` となる。
GCPのサービスアカウントがどんな権限を持っているか確認する方法

iamに付いている権限を確認出来るSearching Cloud IAM policiesという機能があるので、これを使う

https://cloud.google.com/asset-inventory/docs/searching-iam-policies


サービスアカウントの権限知りたい場合は以下のようにするとわかる

```
gcloud beta asset search-all-iam-policies --scope='projects/123456'  --query='policy : "serviceAccount:サービスアカウント"'
```
リリースできなかったiOSアプリのソースを公開して供養する 🙏

アプリはこんな感じ

<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7694/70af21b6-09c2-7757-4522-e730336aced4.gif" />

ソースコードはこちら
https://github.com/abeyuya/Twibu-ios

## どんなアプリか

- ニュースアプリ
- **Twitter as a はてなブックマーク(コメント)** 的なサービスで、話題の記事 + Twitter上でのコメントをセットで読めるアプリ
  - データはバックエンド側で用意しており、そのビューアアプリ
- UIもかなりはてなブックマークを参考にしました
  - はてぶ大好き！

## なぜリリースできなかったか

- [デベロッパーが最も怖れる最恐のリジェクト「4.2 Minimum Functionality」とは](https://kanasys.com/tech/669)
  - 完全にこれだった
  - シンプルなニュース閲覧アプリで機能として不足していた
- リジェクト応酬に心が折れ、モチベーションがなくなってしまった

## iOSアプリエンジニア的な見どころ

- carthageオンリーでfirebase周りのライブラリを導入した
  - ググってもあまり情報がなくまあまあ大変だった記憶
- github actions + fastlane + firebase distributionによるアプリの自動配布設定
- TwitterKit → Swifterへの移行
  - twitterログイン機能でTwitterKitを使っていたが、すでにサポートが切れている
  - [Swifter](https://github.com/mattdonnelly/Swifter)というライブラリに移行した

## その他技術的な解説

- ReSwiftを導入した
    - redux大好きなので入れた
    - 個人的には良かったけどチーム開発だとメンバーの同意得るのしんどそうだなとちょっと思う
- TodayExtensionとfirebase
    - TodayExtensionとfirebaseが非常に相性が悪く、TodayExtensionでfirebase使うのを諦めた
        - 具体的にはTodayExtensionのメモリ制限が厳しく、firebaseを使おうとするとあっという間にメモリ食いつぶして落ちるという感じだった
        - (今思えばfirestoreのローカルキャッシュのサイズのせいだったかも :thinking: )



## 技術じゃなくてサービスの話

- コンセプトととしては今でも結構好き
    - 「はてブはやってないけどTwitter上では記事に対してコメントしている」という人のコメントがまとめて読めたら面白いよねという発想
    - 自分がほしいと思ったアプリで、作っていて楽しかった
    - 実際かなりヘビーユーズしていた
- 課題
    - 単にリンクをシェアしているだけのツイートを見ても面白くないので、コメント付きのツイートを集める必要があるのだが、その辺の精度が甘々で結構ノイジーなコメント欄になってしまった
        - これはバックエンド側の技術的な課題
    - コメント欄がつまらないことが多い
        - はてブのコメントに比べると全体的につまらないコメントが多い印象で、コンテンツ的に弱い感はあった
        - 一言で斬ると民度が低いという感じで、特に政治の記事とかのコメント欄は地獄になりがちだった
        - この辺もニュースの選定・コメントの重み付けのアルゴリズムの調整とかバックエンド側で工夫する余地はまだある
            - 今は単にファボ数、RT数の多いもの順に表示していた
    - 上記2点の課題 + リジェクトでモチベーションが切れ、結局はてブをまた見るようになってしまった
    - 話題の記事を集めるのが意外と大変
- 可能性/展望
    - 上記の課題をそれなりにクリアすれば、私のはてブ利用時間を50%奪うくらいのアプリにはなりそう
    - Twitterがデータソースなので、そのまま海外展開させることができる
        - githubの話題のリポジトリとかのコメント欄を見ると、ほとんど外国語ばかりだったりしていた
        - ニーズがあるのか不明だけどマーケットはでかそう


どなたか代わりに作ってくれてもいいんだよ！！
【PHP】連想配列の配列の書き方

jsonで連想配列の配列を送信しようとしたのだけど、どう書けばいいか分からず半日くらい詰まったのでメモ。
[20200307]うろ覚えで書いたら盛大に間違っていたのでコードを修正しました

```php:連想配列の配列.php
$arr = array(
        '表題' => '名簿',
        'リスト' => array([
            '名前' => '佐藤',
            '年齢' => 21,
            '出身' => '兵庫県',
            ],[
            '名前' => '高橋',
            '年齢' => 22,
            '出身' => '京都府',
            ],[
            '名前' => '鈴木',
            '年齢' => 25,
            '出身' => '愛知県',
        ]),
);
echo json_encode($arr, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT );
```

echoの内容

```
{
    "表題": "名簿",
    "requestList": [
        {
            "名前": "佐藤",
            "年齢": 21,
            "出身": "兵庫県"
        },
        {
            "名前": "高橋",
            "年齢": 22,
            "出身": "京都府"
        },
        {
            "名前": "鈴木",
            "年齢": 25,
            "出身": "愛知県"
        }
    ]
}
```

C言語では配列初期化が{}なので[]は違和感が凄いです。
Wheneverを使用したタイムセール機能の実装（開発環境）

## はじめに
本記事は自分自身の備忘録として書いていますが、同じような実装を考えている方々の参考になればと思います。
また、私と同様、プログラミングを初めたばかりの方々向けに投稿していますので、できるかぎりシンプルに記載していきます！

※ runner以外のコマンドや crontab などの説明は本記事では割愛しています。


## 開発環境
Ruby : 2.5.1
Rails : 5.0.7.2
Whenever : 1.0.0

## 実現したいこと
ネットショップなどを想定して、出品中の商品全品を定期的に値下げしたい。
また、処理を自動で行いたい。

具体的に以下の1, 2を繰り返し実行したい。

1. 毎週末（土日）に全商品が10％オフになる
2. 毎月曜日に元値に戻す

## 実装の流れ
よくある、「週末は10%オフのセール！」みたいなやつを Whenever を使用して実装していきます。

### 前置き
まず、定期実行をする際に重宝するのが Whenever という Gem です。
タスクに登録して好きなタイミングで自動実行してくれます。
学習コストが低く、私のような初心者でも取っつきやすいのが特徴です！
[Github: javan/whenever](https://github.com/javan/whenever)

### 本題

**[1] タスクを作成する**

必要なメソッドを備えた class や module が何処かにあれば良いと思いますが、今回は分かりやすく「lib/tasks」直下に「lib/tasks/product_task」ファイルを作成します。
また、このファイルに実行したい処理を記述します。

```ruby
(lib/tasks/product_task.rb)
class Tasks::Product_task
  # 10%オフを実行するメソッド
  def self.set_time_sale
    Product.update_all("price =  price * 0.9")
  end

  # 10%オンを実行するメソッド
  def self.end_time_sale
    Product.update_all("price =  price / 0.9")
  end
end 
```

**[2] タスクのパスをオートロードにする**

Whenever から「lib/tasks」を呼び出せるようにパスを通す必要があります。
開発環境では config.autoload_paths 、本番環境では config.eager_load_paths が必要となります。

```ruby
(config/application.rb)
module [アプリ名]
  class Application < Rails::Application

　　（省略）

    config.autoload_paths   += Dir["#{config.root}/lib/**/"]
    config.eager_load_paths += Dir["#{config.root}/lib/**/"]
  end
end
```

**[3] 手動で確認**

ここで一度、設定ができているか確認をします。

```ruby
(ターミナル)
$ bundle exec rails runner Tasks::Product_task.set_time_sale
```
動作問題なければタスクの設定は完了です！

**[4] Whenever の導入**

Gemfile に記述し、bundle install します。

```ruby
(Gemfile)
gem 'whenever', :require => false
```

**[5] Whenever の設定ファイルを作成**

下記コマンドを打つと、「config/schedule.rb」が作成されます。
これがcrontabの元になり、「○曜日にxxを実行」みたいな処理をこのファイルに記述していきます。

```ruby
(ターミナル)
$ bundle exec wheneverize
```

**[6] schedule.rbの編集**

先ほど作ったタスクを登録する為、以下のように記述します。

```ruby
(config/schedule.rb)
require File.expand_path(File.dirname(__FILE__) + "/environment")

rails_env  = Rails.env.to_sym
rails_root = Rails.root.to_s

# デフォルトは本番環境になる為、明示的に開発環境を指定する
set :environment, rails_env
set :output, "#{rails_root}/log/cron.log"

# 毎週末にタスクで定義した set_time_sale を実行する
every :weekend do
  runner 'Tasks::Product_task.set_time_sale'
end

# 毎週月曜日にタスクで定義した end_time_sale を実行する
every :monday do
  runner 'Tasks::Product_task.end_time_sale'
end 
```

**[7] crontabへ反映させる**

```ruby
(ターミナル)
$ bundle exec wheneverize
```

[write] crontab file updated がターミナル上に出てくれば登録完了です！

お疲れさまでした！


## 補足
今回の実装コードはあくまで、開発環境でのみ機能する仕様です。
本番環境は別途対応が必要になりますので、以下の記事などを参考にしてください。
一つ注意点としては、Herokuはサポートされていないみたいです。
もしHerokuで定期実行したいタスクがあるのなら「Heroku Scheduler」を活用しましょう。

[Railsでwheneverを使ってcronを設定する](https://qiita.com/Esfahan/items/e7a924f7078faf3294f2)

また、本実装はこのままでは問題点があります。。
月曜日に出品した商品は10％オンした状態になる為、修正が必要です。
内容については、実現したいことに合わせて書き換えてご活用ください。

## 参考記事
- [【Rails】バッチ処理を実装したいけどActiveRecordを中で使ったりもしたいし](https://altarf.net/computer/rails/2493)
- [Wheneverは導入が超簡単なcrontab管理ライブラリGemです！[Rails 4.2 x Ruby 2.3]](https://morizyun.github.io/blog/whenever-gem-rails-ruby-capistrano/index.html)
WSHで複数あるファイル名の末尾に特定の文字を追加する

##はじめに
複数あるファイルのファイル名の末尾に一括して特定の文字を追加したいことがありました。例えば、複数の報告書があり、完成したものについてファイル名末尾に"_DONE"を追加しておき、完成したかどうかが視覚的にわかるようにしておく場合などです。

ファイルが１つや２つであれば別に良いのですが、１０個とかあると結構大変です。そこで、WSHで自動化を考えました。

##コード
###JavaScript
まず、勉強がてらJavaScriptで記述してみました。

```sample.js
var fso = new ActiveXObject("Scripting.FileSystemObject");

var args = WScript.Arguments;

for (var i=0; i<args.length; i++) {
    var baseName = fso.GetBaseName(args(i));
    var ext = fso.GetExtensionName(args(i));
    var file = fso.GetFile(args(i));
    baseName += "_DONE";
    file.Name = baseName + "." + ext;
}

WScript.Echo("Complete");
```

###VBScript
続いて、慣れ親しんだVBScriptです。

```vb:sample.vbs

Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")

Dim args
Set args = WScript.Arguments

Dim i
Dim baseName
Dim ext
Dim file

For i = 0 To args.Count - 1
    baseName = fso.GetBaseName(args(i))
    ext = fso.GetExtensionName(args(i))
    Set file = fso.GetFile(args(i))
    baseName = baseName & "_DONE"
    file.Name = baseName & "." & ext
Next

WScript.Echo("Complete")
```

##まとめ
ファイル名を変更したいファイル群を選択し、コードを記述したファイルにドラッグ&ドロップするだけでファイル名の末尾に_DONEを追加することができました。一件落着。
拡張性の高いゲームを考えてみた

#ここ数年拡張性の高いゲームが求められている。よく改造マリオ等がニコニコでも受け入れられた
RustLanguageGameApp(ゲーム本編/最適化された共有ライブラリ(3D計算等重い処理やキャラクターの共通の処理))->InstallUserApp(拡張機能)
速度C++の0.95倍を目標、ファイルサイズCPU使用量は0.85倍以内目標
Python-(1度目のJITコンパイル必要な部分の静的型確保)->IL(.NetAsm)-(.Netライブラリリンク可+2度目のJIT)->#T(ObjectCode(マシン語)+共有ライブラリ)
速度、ファイルサイズ、CPU使用量はC++の5倍以内を目標
Toml-(パーサ/画面の装飾、敵のサイズ等のデータの情報を保持)->値を#Tに渡す
ユーザー画面からはどのような画面にするかや最適化された共有ライブラリや既に存在する拡張機能を利用して敵をどの様に動かすかを、スクリプトやTomlをいじらなくて済むようにオブジェクトの配置を画面で行い、高度なことを行う場合、ブループリント並みに汎用性の高いグラフィカルな絵算(Visual Print/VP)のみで済むように設計される。VP自体はオブジェクト毎に作られる。関連物毎に名前空間が割り振られそれがファイル名になる。全体を仕切るファイルにTomlファイルが、プロトコルにmarkdownファイルが利用される。そうすることで、ゲームツクールシリーズより容易に、他のゲームよりパワフルに行うことができる。

```ファイル構造(赤いゾンビプロジェクト)
                「-ZombiMove.py
赤いゾンビ.toml  |-ZombiFlging.py
📁赤いゾンビ　  -|-ZombiStyle.toml
                 |-ZombiStyle.py
                 L-赤いゾンビ.md(プロトコルファイル/説明書、識別、バージョン管理等)

赤いゾンビ.toml 「-ZombiStyle.toml
📁赤いゾンビ    ---赤いゾンビ.vak(*.ilアセンブリ一式)
                 L-赤いゾンビ.md(プロトコルファイル/説明書、識別、バージョン管理等)
```

```赤いゾンビ.md
#赤いゾンビ
@protocol T.es
\```EmilyScript:T.es
sec = SeCulity "../*";
sec.vis;
wait sec.chaim;
sec = sec.okorno;
if sec=sec.ok
   exit 0;
/
else
   log.set "続行しますか","YES_OR_NO";
   if log.get=log.no
       exit 1;
   /
   do T.es
/
\```
## Var
  0.0.2
## 説明書
1. ~~
2. ~~
3. ~~
```

VakMartに赤いゾンビで登録。
markdown://赤いゾンビ.tomlでファイルが登録される。他のユーザーからはVakMartにて"赤いゾンビ"で拡張機能が発見される。
※toml,markdown,フォルダの名前は変更禁止。
特殊事情でプロトコルファイルをhtmlにした時
html://赤いゾンビ.tomlで登録される。markdownと2つ作成されていた時プラットフォームを初見し、それで等しい場合、markdownが優先される。例外を作りたい場合は更に\*.mdに追加事項を作成しておくこと。\*.vakファイル(1回目コンパイル済み)があった場合後の場合優先的にそちらを参照する。

###実はこの仕組みwebをある程度参考にしてモデルを組みました(以下は比較である)

|比較|**web**|**game**|
|----|----|----|
|必要なもの|ブラウザ|ゲーム本体|
|アセンブリ|webアセンブリ|ILアセンブリ|
|2度目のコンパイラ|webアセンブリコンパイラ|.NetCore|
|スクリプト|JavaScript|C#スクリプトやPython|
|プロトコル|httpやhttps|markdownやhtml|
|画面描画|ブラウザ|ゲーム本体+スクリプト|
|画面描画設定|html,css|toml|
|追加ライブラリ|特になし|共有ライブラリ|
|高機能スクリプト機能|WebGL|OpenTKやOpenCVのラッパー|
|オフラインで使えるか|いいえ|ダウンロードさえ済めば|

###VPはゲームエンジンを参考にしました。
VPはゲームエンジンを参考に、オブジェクト配置はマリメ等を参考に作りました。

#コメント
拡張機能の作成者に対しコメントとお気に入り登録、著者ストリーミングができる。著者ストリーミングをするとその開発者が拡張機能を発表した後にゲームを立ち上げた時、インポートしますか?が出現し、それにOKをすると拡張機能のインポートが始まる。コメントは拡張機能開発者に感謝等を伝えることができる。設定をすれば、特定の環境下のみ拡張機能を動作させることもできる。
Rubyで小数点以下の計算をする時に気をつける事


忘れがちなのでメモ

## 問題だったところ

ふと全国の小学生の中からタレントって何人くらいいるだろうなって思ってRubyで計算してみたところ０が結果として出力されたのでちょっと期待と違うなーって思った。

```
~  irb                                                     17.8m  Wed Mar  4 21:49:20 2020
irb(main):001:0> 405/644900
=> 0
```

## 解決策

なんでかなと思ったがRubyには便利なClassオフジェクトがあるので一度確認をしてみる

```
irb(main):003:0> (405/644900).class
=> Integer
```

想定していたみたいに、小数点以下の割り算をする場合はデータ型をFloatにしてあげないといけないのんでこのように変更

```
irb(main):005:0> 405/644900.to_f
=> 0.0006280043417584122
```

こうする事で浮動小終点の計算ができる

### おまけ

でも調べたいのはおよそ何パーセントいるんだよって事なので、こんなに細かい数字はいらない。。。

なので余計な部分はfloor関数を使って下の部分をカットすることにした。

```
irb(main):008:0> (405/644900.to_f).floor(5)
=> 0.00062
```
このくらいになると割と現実的に使えそうな数字になってきたんのでいいのではないだろうか

ちなみに全国の０〜１３歳でタレントになっている確率はおおよそ０.０６％なのでSSRを１００ガチャで当てるよりもレアだぞ！

```
irb(main):009:0> (405/644900.to_f * 100).floor(2)
=> 0.06
```
AtCoder用にVim Snippetをインスコしたけど動かなかった話

#始めに
Visual Studio Codeみたいな補完機能をVimでも使いたいなーとか前々から思ってたら、Snippetという機能がありました。ちょうどAtCoderの精進を始めた頃に[Snippetの記事](https://qiita.com/xryuseix/items/7e9b4c6f12d001a0c0db)見つけて「お、これいいやん」となったわけです。
で、早速インスコしたわけですが、`:NeoBundleInstall`叩いてもVimのSnippetが機能しないんですね、何度`inc`と叩いても`#include <library>`が予測変換で出ない。なぜだ。
#解決法
はい、[Vimテクニックバイブル](https://books.google.co.jp/books?id=QZSWbc83LfQC&pg=PA340&lpg=PA340&dq=vim+snippet+%E4%BD%BF%E3%81%88%E3%81%AA%E3%81%84&source=bl&ots=i6Giq0sgVS&sig=ACfU3U1FI3gdMh3QgvkAjFi3HQb0XM60DQ&hl=ja&sa=X&ved=2ahUKEwjJxKyZ7YDoAhUoBKYKHYyBDXI4ChDoATACegQIChAB#v=onepage&q=vim%20snippet%20%E4%BD%BF%E3%81%88%E3%81%AA%E3%81%84&f=false)と[こちらの記事](http://gg-hogehoge.hatenablog.com/entry/2014/04/05/230043)に書いてました。`NeoBundleinstall`でインスコした後に.vimrcに

```vimscript:.vimrc
" Vim起動時にスニペットを利用可能にする
let g:neocomplcache_enable_at_startup = 1

" Plugin key-mappings.  " <C-k>でsnippetの展開
imap <C-k> <Plug>(neosnippet_expand_or_jump)
smap <C-k> <Plug>(neosnippet_expand_or_jump)
```

を入れないと使えないらしいですね。無事動きました!解散!

#参考
Vimのneosnippetで自分用snippetファイルを追加したい
http://gg-hogehoge.hatenablog.com/entry/2014/04/05/230043

Vim テクニックバイブル
https://books.google.co.jp/books?id=QZSWbc83LfQC&pg=PA340&lpg=PA340&dq=vim+snippet+%E4%BD%BF%E3%81%88%E3%81%AA%E3%81%84&source=bl&ots=i6Giq0sgVS&sig=ACfU3U1FI3gdMh3QgvkAjFi3HQb0XM60DQ&hl=ja&sa=X&ved=2ahUKEwjJxKyZ7YDoAhUoBKYKHYyBDXI4ChDoATACegQIChAB#v=onepage&q=vim%20snippet%20%E4%BD%BF%E3%81%88%E3%81%AA%E3%81%84&f=false

【競プロ】AtCoder早解きテクニック10選 (灰 ~ 緑コーダー向け)
https://qiita.com/xryuseix/items/7e9b4c6f12d001a0c0db
MCCに対応しているPICマイコンを調べる方法

# きっかけ
自分の買ったPICマイコン(PIC16F648A)がMCC(MPLAB Code Configurator)に対応していないことに（設定が面倒すぎて）絶望しました。
これからは事前にMCCに対応しているか調べたいと思ったのですが、思いの外すぐには見つからなかったので、MCCに対応しているPICマイコンを調べる方法を共有したいと思いました。

# やり方
まず[MCCのサイト](https://www.microchip.com/mplab/mplab-code-configurator)に行きます。
<img width="1440" alt="スクリーンショット 2020-03-04 21.53.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299406/a648514d-d450-4cdf-af1c-ddb188919865.png">

次に下の方の　「CurrentDownload」のタブを選択します。
<img width="1440" alt="スクリーンショット 2020-03-04 21.53.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299406/89460883-7c96-47d4-dee8-52817e607063.png">

そしてDevice Librariesの項目の中から自分が使いたいマイコンの種類の「Releace Note」を開きます。
<img width="1440" alt="スクリーンショット 2020-03-04 21.57.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299406/9cf65436-23dd-12f9-b8c1-8d8d09eb4bab.png">

そのPDFファイルの 「Appendix: Supported Devices」の項目にMCCに対応しているマイコンの一覧があります。その中に書いていないものは対応していません。
<img width="1440" alt="スクリーンショット 2020-03-04 21.59.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299406/6ee8df1d-d149-c238-c538-dc2f68ae0055.png">


# 最後に
マイコンを買うときは事前によく調べてから買おうと思いました。
もし何か間違いなどがありましたらコメントや編集リクエストで教えてください。
ありがとうございました。

# 参考
[https://www.microchip.com/forums/m903412.aspx](https://www.microchip.com/forums/m903412.aspx)
これに書いてあることほぼそのままな感じですが、日本語にするという意味では価値があるかと思い記事にしました。
Julia、Dockerで実行

# Dockerで実行
Docker Hub：<a href="https://hub.docker.com/_/julia">https://hub.docker.com/_/julia</a>

## イメージ取得

```shell
docker pull julia
```

## 実行
カレントディレクトリを/homeにマウント

```shell
docker run -v ${PWD}:/home --rm --privileged -it --name juliarun julia /bin/bash
```

## julia起動

```shell
root@0b1df7d9ec96:/# julia
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.3.1 (2019-12-30)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

julia> 
```
Chatwork 主な部分の色を元に戻す(ブラウザ限定)

## 更新
2020/3/26 CSSクラスの変更を行い、最新に対応しました
2020/3/18 CSSクラスの変更を行い、最新に対応しました
2020/3/12 CSSクラスの変更を行い、最新に対応しました

## Chatworkアップデート

色が変わりましたね
スキンも設定できるようになりました
ですが、自分宛てのメッセージが見えづらいと感じる方もいらっしゃるのでは

## 主な部分の色を元に戻すブックマークレット

結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350704/4d18a39e-625a-c948-4bc9-4c7886ba5ff3.png)
ほんの一部分で申し訳ありません・・
背景色から青みが消えているのはわかりますでしょうか
チャット背景色、チャットルーム背景色のみ元に戻しています

以下のコードをブックマークレットとして登録、チャットワーク起動後ライトスキンモードで実行してください

```
javascript:function getRuleBySelector(c){var b,a,e=null;var f=document.styleSheets;for(b=0;b<f.length;b++){var d=f[b].cssRules;for(a=0;a<d.length;a++)if(c===d[a].selectorText){e=d[a];break}}return e}function cssBgColor(c,b){c.forEach(function(a){if(a=getRuleBySelector(a))a.style.background=b})}cssBgColor([".eKutWW"],"rgb(255, 255, 255)");cssBgColor([".hfVMAh","body.light .roomInformationContentContainer"],"rgb(227, 228, 225)");
```

ブックマークレットの登録方法
https://qiita.com/aqril_1132/items/b5f9040ccb8cbc705d04

チャットワークを新規に開く度に起動せねばならないので、ブックマークバーにおきました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350704/1cd3ec88-9286-fabe-1990-58b430b44cc0.png)

## カスタマイズ

### 色の変更

コードの以下の部分を変えてください

- チャット背景色
  
```
"rgb(255, 255, 255)"
```

- チャットルーム背景色

```
"rgb(227, 228, 225)"
```

## 色がかわらない
- 以下のCSSクラスについて変更しています
    - Chatworkの更新で変わってしまうでしょう
    - この記事も更新するようにします

- チャット背景色

```
[".mPcFJ"]
``` 

- チャットルーム背景色

```
[".eKutWW"]
```

## GitHub Gist
- https://gist.github.com/itouh2-i0plus/04de2e40572a74e2c3294e20b866d981

## 参考にした記事
https://qiita.com/life5618/items/950558e4b72c038333f8
maxlengthオプション

##maxlengthオプション
text_fieldにつけることができるオプションです。ユーザー登録のニックネームなど入力できる最大文字数を指定することができます。

【例】

```
<div class="XXXX">
  <%= f.text_field :nickname, autofocus: true, maxlength: "8" %>
</div>
```
上記の場合だと最大文字数が8文字までと指定できます。
【プログラミング初心者】Rails6をダウングレードしたい

★実現したいこと

2020年3月現在、Macのローカル環境で【rails -v】を行うと
【rails '6.0.2.1'】がデフォルトとなっています。

アプリケーション作成の都合上、上記を【rails '5.2.1'】にダウングレードする必要がありました。

★試したがうまくいかなかったこと
①gem uninstall rails  
②gem uninstall railties -v '6.0.2.1'

①→②の順番で行うも、rails -vするとまだ'6.0.2.1'のまま・・・

★解決策
sudo gem uninstall railties -v '6.0.2.1' --force

上記コマンドを実行したところ、無事Rails６がアンインストールできました。
あとはこれまでと同様の方法で、Rails のバージョンを指定し、インストールするのみです。
Error importing xmlsec: null argument to internal routine エラーが出た場合

# Linuxにて xmlsec が必要になってインストールしたが以下のエラーが出た場合

```
Error importing xmlsec: null argument to internal routine
```

- `xmlsec1-openssl` もインストールしてみましょう

sentry(self host版)を最小構成で入れようとした時に発生。
他とは違い、解決方法がわかりづらかったので残しておきます。

私はこれで解決したのですが、無理なら別の理由という事で何卒・・
PowerPointで完結する字幕付きデモ動画作成

完全備忘録です。
たどり着くまでは、久しぶりにGoogle先生迷子になりました。

## 画面録画を行う

挿入＞メディア＞画面録画を選択

<img width="958" alt="1583321259099.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542997/83445e86-a359-8bc8-6755-410f7cefe670.png">

オーディオ選択を外し、領域の選択をクリックし、領域選択後、録画をクリック

<img width="258" alt="1583321364718.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542997/a28f0ae2-e5bf-40d4-bafe-4ffe5c9a1f64.png">

## 画面録画を字幕区切りで分割する

・画面録画全データスライドを1番上に

・字幕ごとにスライドを区切り、各スライド内に画面録画をトリミングしたデータを用意
　テキストボックスを字幕代わりにする

トリミング方法はこちらを参照
<https://www.crie.co.jp/chokotech/detail/279/>

![1583322638383.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542997/872b82f3-45b6-f0a9-786e-0c311da1fb3e.png)


・各スライドのビデオを選択し、開始:　を自動に設定

<img width="275" alt="1583322515443.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542997/c3dc9dc1-203e-50f6-3a48-64f30dc8b704.png">

・画面切り替えタブをクリックし、画面切り替えのタイミングを自動的に切り替えにチェックをいれ、すべてに適用をクリック

<img width="772" alt="1583322561139.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542997/d7c53ca5-ad0c-a784-3f43-03dbf2568ebb.png">


・1スライド目(画面録画全データスライド)を削除

・スライドショー＞最初から　でうまくいくか確認

<img width="349" alt="1583322804924.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542997/85d76769-b517-6527-83c7-7fb8071ac5b3.png">


・パワポファイルを動画形式(MP4)等で保存
【プログラミング初心者】Macのローカル環境でRails5のサーバーが起動しないエラーを解消

★当方環境
MacBookAir
Visual Studio CodeとiTerm2を使用。

★課題
iTerm2上で【rails s】でサーバー起動しても、エラーが発生する。

★解決策
bundle exec pumactl start
を行うことでpumaが起動し、サーバーが立ち上がりました。
Pythonを利用したデータクリーニング

# 概要
* データ処理の下準備として、csvファイルのデータクリーニングをする
* 空白、記号、数字、単語の削除、単語の切り出し、特定のデータ要素への書き込み、csv出力
* Python 3.x系, Pandas, reを利用
* メモ代わりに書き出してみたものです: テクニカルタームの誤り、説明不十分な点が多いと思いますので、随時修正します

# 実際のコード
## 0. ライブラリの読み込み
今回は```pandas```と```re```（正規表現利用のためのモジュール）を利用する

```
import pandas as pd
import re
```

## 1. データの読み込み

```
df = pd.read_csv("filename.csv")
```

## 2. いらない要素（空白、記号、数字、単語）の削除
列全体を対象とし、いらない要素の削除を行う

```
df['列名'] = df['列名'].str.replace(r'(\d)', '') # 数字を削除
df['列名'] = df['列名'].str.replace('-', '') # 記号を削除
df['列名'] = df['列名'].str.replace('word', '') # 単語を削除
df['列名'] = df['列名'].str.strip() # 冒頭・末尾の空白を削除
df['列名'] = df['列名'].str.replace(r'(\d)', '').str.replace('-', '').str.replace('あ', '').str.strip()
# これらは同時に実行することもできる
```

## 3. 単語の切り出し
### やりたいこと
```name``` という列に、複数の単語からなる要素がそれぞれ存在するとする
例: 

```
df['name'][0] = "I have a pen."
df['name'][1] = "She has a pen."
```

これに対し、はじめの単語を抜き出し、```subject``` という新しい列にリストとして格納する
例: 

```
df['subject'][0] = "I"
df['subject'][1] = "She"
```

### コード

```
temp = df['name'].str.split() # 単語に分解
subject = [] # 切り出した単語を格納するための空のリストを作成
for item in temp: 
    subject.append(item[0]) # 各行の最初の単語をリストに格納
df['subject'] = subject # subjectという列名でもとのデータフレームに追加
```

## 4. 特定のデータ要素に書き込む
```.at[]``` を使うことで特定のデータにアクセスすることができる

```
df.at['行名','列名'] = "これはテストです"
df.at[行番号,'列名'] = "これはテストです"
```

## 5. csv出力
最後に、編集したデータフレームをcsvに出力する。```encoding='utf_8_sig'```を付加することで、文字化けを防ぐことができる。

```
df.to_csv("filename_v2.csv", encoding='utf_8_sig')
```
[numpy] 多次元の時系列データから移動窓行列を作成

# 元ネタ
[\[numpy\] 時系列データから移動窓行列を作成 - Qiita](https://qiita.com/bauer/items/48ef4a57ff77b45244b6)
これを多次元データに拡張してみました。

# やりたいこと
ndarray ``x`` が与えられたときに、最後の次元を時刻と見なして、幅$w$の移動窓の中に入っているデータを並べたndarray ``y`` を作成します。

``x``が1次元のとき

```math
x = 
\begin{pmatrix}
x_0 & x_1 & \cdots & x_{n-1}
\end{pmatrix}
```

ならば

```math
y = 
\begin{pmatrix}
x_0 & x_1 & \cdots & x_{n-w} \\
x_1 & x_2 & \cdots & x_{n-w+1} \\
\vdots & \vdots & & \vdots \\
x_{w-1} & x_w & \cdots & x_{n-1} \\
\end{pmatrix}
```

となります。また``x``が2次元のとき

```math
x = 
\begin{pmatrix}
x_{0,0} & x_{0,1} & \cdots & x_{0,n-1} \\
\vdots & \vdots & & \vdots \\
x_{m-1,0} & x_{m-1,1} & \cdots & x_{m-1,n-1}
\end{pmatrix}
```

ならば、3次元目でスライスしたとき

```math
y_{:,:,t} = 
\begin{pmatrix}
x_{0,t} & x_{0,t+1} & \cdots & x_{0,t+w-1} \\
\vdots & \vdots & & \vdots \\
x_{m-1,t} & x_{m-1,t+1} & \cdots & x_{m-1,t+w-1}
\end{pmatrix}
```

となるようなndarray ``y`` を作成します。もっと次元が増えても同じです。

# コード

```python
import numpy as np

def moving_window_matrix(x, window_size):
    n = x.shape[-1]
    new_shape = tuple(x.shape[0:-1]) + (window_size, n-window_size+1)
    stride = x.strides[-1]
    return np.lib.stride_tricks.as_strided(
        x,
        shape=new_shape,
        strides=x.strides + (stride,)).copy()

x = np.arange(30).reshape((3,10))
print(x)
window_size = 3
y = moving_window_matrix(x, window_size)
print(y[:, :, 0])
print(y[:, :, 1])
print(y[:, :, 2])
print(y[:, :, 7])
```