python リスト型操作関数による回転コマンドの作成

# まえがき
標準入出力とか意識してリスト型の操作でコマンド作成してみた。

# 参考文献

https://note.nkmk.me/python-unicode-escape/
https://qiita.com/motoki1990/items/d06fc7559546a8471392
https://qiita.com/masakielastic/items/2a04aee632c62536f82c
https://www.yoheim.net/blog.php?q=20150801
https://docs.python.org/ja/3/tutorial/datastructures.html

# 環境

```bash
$python --version
Python 3.7.4
$bash --version
GNU bash, バージョン 5.0.0(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2019 Free Software Foundation, Inc.
ライセンス GPLv3+: GNU GPL バージョン 3 またはそれ以降 <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
```

# スクリプト

## 1.left_stair.py

先頭要素取得して末尾要素に追加していくパターン。

```python
$cat left_stair.py
#!/usr/local/bin/python3.7
import sys

def usage():
    usage='''
Usage:
$echo \'\x5c\x5cU0001f4a\'{1..9} | xargs -n1 | ./left_stair.py 
$./left_stair.py \'\x5cU0001f4a\'{1..9}
'''
    print(usage)
    sys.exit(1)

def left_stair(rsv_args):
    for ind in range(len(rsv_args)):
        ele=rsv_args[0]
        del rsv_args[0]
        rsv_args.append(ele)
        print(rsv_args)

def main():
  try:
    if (len(sys.argv[1:]))==0:
      #パイプ経由引数の場合
      #改行を取り除く
      stdin=list(map(lambda x:x.strip(),sys.stdin.readlines()))
      #ユニコード文字列をバイト型に変換してユニコードを文字に変換
      init_args=list(map(lambda x:x.encode().decode('unicode-escape'),stdin))
      left_stair(init_args)
    else:
      #コマンドライン経由引数の場合
      #先頭要素のファイル名を除く
      stdin=sys.argv[1:]
      #ユニコード文字列をバイト型に変換してユニコードを文字に変換
      init_args=list(map(lambda x:x.encode().decode('unicode-escape'),stdin))
      left_stair(init_args)
  except KeyboardInterrupt:
    usage()

main()
```


先頭要素が次の対象行の末尾要素に追加されていく様子がわかる。

```bash
$./left_stair.py
^C
Usage:
$echo '\\U0001f4a'{1..9} | xargs -n1 | ./left_stair.py 
$./left_stair.py '\U0001f4a'{1..9}

$echo '\\U0001f4a'{1..9} | xargs -n1 | ./left_stair.py
['💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩', '💡']
['💣', '💤', '💥', '💦', '💧', '💨', '💩', '💡', '💢']
['💤', '💥', '💦', '💧', '💨', '💩', '💡', '💢', '💣']
['💥', '💦', '💧', '💨', '💩', '💡', '💢', '💣', '💤']
['💦', '💧', '💨', '💩', '💡', '💢', '💣', '💤', '💥']
['💧', '💨', '💩', '💡', '💢', '💣', '💤', '💥', '💦']
['💨', '💩', '💡', '💢', '💣', '💤', '💥', '💦', '💧']
['💩', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨']
['💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩']
$./left_stair.py '\U0001f4a'{1..9}
['💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩', '💡']
['💣', '💤', '💥', '💦', '💧', '💨', '💩', '💡', '💢']
['💤', '💥', '💦', '💧', '💨', '💩', '💡', '💢', '💣']
['💥', '💦', '💧', '💨', '💩', '💡', '💢', '💣', '💤']
['💦', '💧', '💨', '💩', '💡', '💢', '💣', '💤', '💥']
['💧', '💨', '💩', '💡', '💢', '💣', '💤', '💥', '💦']
['💨', '💩', '💡', '💢', '💣', '💤', '💥', '💦', '💧']
['💩', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨']
['💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩']
```

## 2.right_stair.py

末尾要素取得して先頭要素に追加していくパターン。

```python
$cat ./right_stair.py
#!/usr/local/bin/python3.7
import sys

def usage():
    usage='''
Usage:
$echo \'\x5c\x5cU0001f4a\'{1..9} | xargs -n1 | ./right_stair.py 
$./right_stair.py \'\x5cU0001f4a\'{1..9}
'''
    print(usage)
    sys.exit(1)

def right_stair(rsv_args):
    for ind in range(len(rsv_args)):
        ele=rsv_args[len(rsv_args)-1]
        del rsv_args[len(rsv_args)-1]
        rsv_args.insert(0,ele)
        print(rsv_args)

def main():
  try:
    if (len(sys.argv[1:]))==0:
      #パイプ経由引数の場合
      #改行を取り除く
      stdin=list(map(lambda x:x.strip(),sys.stdin.readlines()))
      #ユニコード文字列をバイト型に変換してユニコードを文字に変換
      init_args=list(map(lambda x:x.encode().decode('unicode-escape'),stdin))
      right_stair(init_args)
    else:
      #コマンドライン経由引数の場合
      #先頭要素のファイル名を除く
      stdin=sys.argv[1:]
      #ユニコード文字列をバイト型に変換してユニコードを文字に変換
      init_args=list(map(lambda x:x.encode().decode('unicode-escape'),stdin))
      right_stair(init_args)
  except KeyboardInterrupt:
    usage()

main()
```

末尾要素が先頭要素に追加されていく様子がわかる。

```bash
$./right_stair.py
^C
Usage:
$echo '\\U0001f4a'{1..9} | xargs -n1 | ./right_stair.py 
$./right_stair.py '\U0001f4a'{1..9}

$echo '\\U0001f4a'{1..9} | xargs -n1 | ./right_stair.py
['💩', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨']
['💨', '💩', '💡', '💢', '💣', '💤', '💥', '💦', '💧']
['💧', '💨', '💩', '💡', '💢', '💣', '💤', '💥', '💦']
['💦', '💧', '💨', '💩', '💡', '💢', '💣', '💤', '💥']
['💥', '💦', '💧', '💨', '💩', '💡', '💢', '💣', '💤']
['💤', '💥', '💦', '💧', '💨', '💩', '💡', '💢', '💣']
['💣', '💤', '💥', '💦', '💧', '💨', '💩', '💡', '💢']
['💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩', '💡']
['💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩']
$./right_stair.py '\U0001f4a'{1..9}
['💩', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨']
['💨', '💩', '💡', '💢', '💣', '💤', '💥', '💦', '💧']
['💧', '💨', '💩', '💡', '💢', '💣', '💤', '💥', '💦']
['💦', '💧', '💨', '💩', '💡', '💢', '💣', '💤', '💥']
['💥', '💦', '💧', '💨', '💩', '💡', '💢', '💣', '💤']
['💤', '💥', '💦', '💧', '💨', '💩', '💡', '💢', '💣']
['💣', '💤', '💥', '💦', '💧', '💨', '💩', '💡', '💢']
['💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩', '💡']
['💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩']

```

## 3.square.sh

上記スクリプトをそれぞれ左と右、右と左に並びて、与える引数を正順と逆順の2つにしたパターン。

```bash
$cat ./square.sh 
#!/bin/bash

usage(){
  cat <<EOF
Usage:
\$$0 '\\\\U0001f4a'{0..9}
EOF
}

chk_args(){
  declare -a argv=()
  local argv=($@)
  local argc="${#argv[@]}"
  [ "${argc}" -le 1 ] && usage && exit 1
}

circle(){
  paste -d' ' <(sed 's;^;\x5c\x5c;;s; ; \x5c\x5c;g;' <<<"$@" | xargs -n1 | ./left_stair.py) <(sed 's;^;\x5c\x5c;;s; ; \x5c\x5c;g;' <<<"$@" | xargs -n1 | tac | ./right_stair.py)
  paste -d' ' <(sed 's;^;\x5c\x5c;;s; ; \x5c\x5c;g;' <<<"$@" | xargs -n1 | ./right_stair.py) <(sed 's;^;\x5c\x5c;;s; ; \x5c\x5c;g;' <<<"$@" | xargs -n1 | tac | ./left_stair.py) 
}

main(){
  local init_args="$(cat -)";
  chk_args "${init_args}"
  while read ln;do circle ${ln};done <<<"${init_args}"
}

[ -p /dev/stdin ] && cat - | main
[ -p /dev/stdin ] || echo -ne "$@" | main
```

引数も簡略化できていいかんじ。ただ、エスケープはくどいけど。必ず8桁ユニコード文字列でバックスラッシュ２つ重ねる必要があるようにした。難しい。

```bash
$echo ./square.sh '\\U0001f4a'{0..9}
./square.sh \\U0001f4a0 \\U0001f4a1 \\U0001f4a2 \\U0001f4a3 \\U0001f4a4 \\U0001f4a5 \\U0001f4a6 \\U0001f4a7 \\U0001f4a8 \\U0001f4a9
```

```bash
[sqlite💘ceacf3fb0808 (木 11月 14 02:44:10) ~/script_scratch/python]$./square.sh '\\U0001f4a'{0..9}
['💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩', '💠'] ['💠', '💩', '💨', '💧', '💦', '💥', '💤', '💣', '💢', '💡']
['💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩', '💠', '💡'] ['💡', '💠', '💩', '💨', '💧', '💦', '💥', '💤', '💣', '💢']
['💣', '💤', '💥', '💦', '💧', '💨', '💩', '💠', '💡', '💢'] ['💢', '💡', '💠', '💩', '💨', '💧', '💦', '💥', '💤', '💣']
['💤', '💥', '💦', '💧', '💨', '💩', '💠', '💡', '💢', '💣'] ['💣', '💢', '💡', '💠', '💩', '💨', '💧', '💦', '💥', '💤']
['💥', '💦', '💧', '💨', '💩', '💠', '💡', '💢', '💣', '💤'] ['💤', '💣', '💢', '💡', '💠', '💩', '💨', '💧', '💦', '💥']
['💦', '💧', '💨', '💩', '💠', '💡', '💢', '💣', '💤', '💥'] ['💥', '💤', '💣', '💢', '💡', '💠', '💩', '💨', '💧', '💦']
['💧', '💨', '💩', '💠', '💡', '💢', '💣', '💤', '💥', '💦'] ['💦', '💥', '💤', '💣', '💢', '💡', '💠', '💩', '💨', '💧']
['💨', '💩', '💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧'] ['💧', '💦', '💥', '💤', '💣', '💢', '💡', '💠', '💩', '💨']
['💩', '💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨'] ['💨', '💧', '💦', '💥', '💤', '💣', '💢', '💡', '💠', '💩']
['💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩'] ['💩', '💨', '💧', '💦', '💥', '💤', '💣', '💢', '💡', '💠']
['💩', '💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨'] ['💨', '💧', '💦', '💥', '💤', '💣', '💢', '💡', '💠', '💩']
['💨', '💩', '💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧'] ['💧', '💦', '💥', '💤', '💣', '💢', '💡', '💠', '💩', '💨']
['💧', '💨', '💩', '💠', '💡', '💢', '💣', '💤', '💥', '💦'] ['💦', '💥', '💤', '💣', '💢', '💡', '💠', '💩', '💨', '💧']
['💦', '💧', '💨', '💩', '💠', '💡', '💢', '💣', '💤', '💥'] ['💥', '💤', '💣', '💢', '💡', '💠', '💩', '💨', '💧', '💦']
['💥', '💦', '💧', '💨', '💩', '💠', '💡', '💢', '💣', '💤'] ['💤', '💣', '💢', '💡', '💠', '💩', '💨', '💧', '💦', '💥']
['💤', '💥', '💦', '💧', '💨', '💩', '💠', '💡', '💢', '💣'] ['💣', '💢', '💡', '💠', '💩', '💨', '💧', '💦', '💥', '💤']
['💣', '💤', '💥', '💦', '💧', '💨', '💩', '💠', '💡', '💢'] ['💢', '💡', '💠', '💩', '💨', '💧', '💦', '💥', '💤', '💣']
['💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩', '💠', '💡'] ['💡', '💠', '💩', '💨', '💧', '💦', '💥', '💤', '💣', '💢']
['💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩', '💠'] ['💠', '💩', '💨', '💧', '💦', '💥', '💤', '💣', '💢', '💡']
['💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩'] ['💩', '💨', '💧', '💦', '💥', '💤', '💣', '💢', '💡', '💠']
```

# あとがき

便利なファンクションいっぱいあってpythonおもしろい。

以上、ありがとうございました。

# 20191114追記

コメント頂いた方の追記

事前にインストールが必要なもの

```bash
$pip install numpy
```

```python
[sqlite💘ceacf3fb0808 (木 11月 14 22:34:48) ~/script_scratch/python]$cat ./adusa1019さん.py
#!/usr/local/bin/python3.7

import numpy as np

def circle(rsv_args):
  for ind in range(len(rsv_args)):
    print(np.roll(rsv_args,ind))

circle(['💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩'])
```

```bash
$python ./adusa1019さん.py
['💠' '💡' '💢' '💣' '💤' '💥' '💦' '💧' '💨' '💩']
['💩' '💠' '💡' '💢' '💣' '💤' '💥' '💦' '💧' '💨']
['💨' '💩' '💠' '💡' '💢' '💣' '💤' '💥' '💦' '💧']
['💧' '💨' '💩' '💠' '💡' '💢' '💣' '💤' '💥' '💦']
['💦' '💧' '💨' '💩' '💠' '💡' '💢' '💣' '💤' '💥']
['💥' '💦' '💧' '💨' '💩' '💠' '💡' '💢' '💣' '💤']
['💤' '💥' '💦' '💧' '💨' '💩' '💠' '💡' '💢' '💣']
['💣' '💤' '💥' '💦' '💧' '💨' '💩' '💠' '💡' '💢']
['💢' '💣' '💤' '💥' '💦' '💧' '💨' '💩' '💠' '💡']
['💡' '💢' '💣' '💤' '💥' '💦' '💧' '💨' '💩' '💠']
```

逆回転

```python
[sqlite💘ceacf3fb0808 (木 11月 14 22:34:48) ~/script_scratch/python]$cat ./adusa1019さん.py
#!/usr/local/bin/python3.7

import numpy as np

def circle(rsv_args):
  for ind in range(len(rsv_args)):
    print(np.roll(rsv_args,-ind))

circle(['💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩'])
```


```bash
$python ./adusa1019さん.py
['💠' '💡' '💢' '💣' '💤' '💥' '💦' '💧' '💨' '💩']
['💡' '💢' '💣' '💤' '💥' '💦' '💧' '💨' '💩' '💠']
['💢' '💣' '💤' '💥' '💦' '💧' '💨' '💩' '💠' '💡']
['💣' '💤' '💥' '💦' '💧' '💨' '💩' '💠' '💡' '💢']
['💤' '💥' '💦' '💧' '💨' '💩' '💠' '💡' '💢' '💣']
['💥' '💦' '💧' '💨' '💩' '💠' '💡' '💢' '💣' '💤']
['💦' '💧' '💨' '💩' '💠' '💡' '💢' '💣' '💤' '💥']
['💧' '💨' '💩' '💠' '💡' '💢' '💣' '💤' '💥' '💦']
['💨' '💩' '💠' '💡' '💢' '💣' '💤' '💥' '💦' '💧']
['💩' '💠' '💡' '💢' '💣' '💤' '💥' '💦' '💧' '💨']
```

```python
$cat ./しらかみゅさん.sh
#!/usr/local/bin/python3.7

import sys

def left_stair1(rsv_args):
  for ind in range(len(rsv_args)):
    print(rsv_args[:ind]);

left_stair1(['💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩'])

def left_stair2(rsv_args):
  for ind in range(len(rsv_args)):
    print(rsv_args[ind:]);

left_stair2(['💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩'])

def left_stair3(rsv_args):
  for ind in range(len(rsv_args)):
    print(rsv_args[ind:]+rsv_args[:ind]);

left_stair3(['💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩'])

def right_stair1(rsv_args):
  for ind in range(len(rsv_args)):
    print(rsv_args[:-ind]);

right_stair1(['💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩'])

def right_stair2(rsv_args):
  for ind in range(len(rsv_args)):
    print(rsv_args[-ind:]);

right_stair2(['💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩'])

def right_stair3(rsv_args):
  for ind in range(len(rsv_args)):
    print(rsv_args[-ind:]+rsv_args[:-ind]);

right_stair3(['💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩'])

```

実行結果


```bash
left_stair1
[]
['💠']
['💠', '💡']
['💠', '💡', '💢']
['💠', '💡', '💢', '💣']
['💠', '💡', '💢', '💣', '💤']
['💠', '💡', '💢', '💣', '💤', '💥']
['💠', '💡', '💢', '💣', '💤', '💥', '💦']
['💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧']
['💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨']
left_stair2
['💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩']
['💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩']
['💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩']
['💣', '💤', '💥', '💦', '💧', '💨', '💩']
['💤', '💥', '💦', '💧', '💨', '💩']
['💥', '💦', '💧', '💨', '💩']
['💦', '💧', '💨', '💩']
['💧', '💨', '💩']
['💨', '💩']
['💩']
left_stair3
['💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩']
['💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩', '💠']
['💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩', '💠', '💡']
['💣', '💤', '💥', '💦', '💧', '💨', '💩', '💠', '💡', '💢']
['💤', '💥', '💦', '💧', '💨', '💩', '💠', '💡', '💢', '💣']
['💥', '💦', '💧', '💨', '💩', '💠', '💡', '💢', '💣', '💤']
['💦', '💧', '💨', '💩', '💠', '💡', '💢', '💣', '💤', '💥']
['💧', '💨', '💩', '💠', '💡', '💢', '💣', '💤', '💥', '💦']
['💨', '💩', '💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧']
['💩', '💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨']
right_stair1
[]
['💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨']
['💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧']
['💠', '💡', '💢', '💣', '💤', '💥', '💦']
['💠', '💡', '💢', '💣', '💤', '💥']
['💠', '💡', '💢', '💣', '💤']
['💠', '💡', '💢', '💣']
['💠', '💡', '💢']
['💠', '💡']
['💠']
right_stair2
['💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩']
['💩']
['💨', '💩']
['💧', '💨', '💩']
['💦', '💧', '💨', '💩']
['💥', '💦', '💧', '💨', '💩']
['💤', '💥', '💦', '💧', '💨', '💩']
['💣', '💤', '💥', '💦', '💧', '💨', '💩']
['💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩']
['💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩']
right_stair3
['💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩']
['💩', '💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨']
['💨', '💩', '💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧']
['💧', '💨', '💩', '💠', '💡', '💢', '💣', '💤', '💥', '💦']
['💦', '💧', '💨', '💩', '💠', '💡', '💢', '💣', '💤', '💥']
['💥', '💦', '💧', '💨', '💩', '💠', '💡', '💢', '💣', '💤']
['💤', '💥', '💦', '💧', '💨', '💩', '💠', '💡', '💢', '💣']
['💣', '💤', '💥', '💦', '💧', '💨', '💩', '💠', '💡', '💢']
['💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩', '💠', '💡']
['💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩', '💠']
```

コメントありがとうございました。