Python 言語の理解 その9

GPIO接続したスイッチ入力とLED出力を組み合わせてみる

LED 6個を順に光らせ、スイッチが押されたら反転させる

 

GPIO_inout_LED6.py

 

#Raspberry Pi3 GPIO 入出力

#ライブラリの読み込み
import RPi.GPIO as GPIO
from time import sleep

SW_PIN = 4
LEDNO = [23,24,25,16,20,21]

#初期化
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

#入力モードとして設定
GPIO.setup (SW_PIN,GPIO.IN,pull_up_down=GPIO.PUD_DOWN)
#出力モード設定
for LED_PIN in LEDNO:
GPIO.setup (LED_PIN,GPIO.OUT,initial = GPIO.LOW)


#出力設定
try:
    LED_PIN = 0
    LED_ADD = 1
    while True:
        GPIO.output (LEDNO[LED_PIN],GPIO.HIGH)
        sleep(0.3)
        GPIO.output (LEDNO[LED_PIN],GPIO.LOW)
        LED_PIN = LED_PIN + LED_ADD
        if (LED_PIN == 6):
            LED_PIN = 0
        if (LED_PIN == -1):
            LED_PIN = 5
        # スイッチが押されていたら反転
        if (GPIO.input(SW_PIN) == GPIO.HIGH) :
            print ( 'SW on :GPIO' + str(SW_PIN) + ' HIGH' )
            if (LED_ADD == 1) :
                LED_ADD = -1
                print ( 'LED_ADD = -1' )
            else :
                LED_ADD = 1
                print ( 'LED_ADD = 1' )
        else :
            print ( 'SW off:GPIO' + str(SW_PIN) + ' LOW' )

except KeyboardInterrupt:
    print ( 'CTRL + C' )
    pass

#GPIOリセット終了
GPIO.cleanup()

 

それなりに機能するのですが、スイッチの反応が悪くてなんかうまくいきません。
押されたトリガを捕まえられるとよいのですが、押された時に読み込まないと反応しないし、押されたままだと続けて反応してしまうので、ボタンを押したことがうまくLEDの光らせ順を変えるようには機能しない事が多いです。

で、押されたら話されるまで反転させないようにちょっとプログラムをいじってみました。

 

 

GPIO_inout-2_LED6.py

 

#Raspberry Pi3 GPIO 入出力

#ライブラリの読み込み
import RPi.GPIO as GPIO
from time import sleep

SW_PIN = 4
LEDNO = [23,24,25,16,20,21]

#初期化
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

#入力モードとして設定
GPIO.setup (SW_PIN,GPIO.IN,pull_up_down=GPIO.PUD_DOWN)
#出力モード設定
for LED_PIN in LEDNO:
    GPIO.setup (LED_PIN,GPIO.OUT,initial = GPIO.LOW)


#出力設定
try:
    SWC_CHK = 0
    LED_PIN = 0
    LED_ADD = 1
    while True:
        GPIO.output (LEDNO[LED_PIN],GPIO.HIGH)
        sleep(0.3)
        GPIO.output (LEDNO[LED_PIN],GPIO.LOW)
        LED_PIN = LED_PIN + LED_ADD
        if (LED_PIN == 6):
            LED_PIN = 0
        if (LED_PIN == -1):
            LED_PIN = 5
        if (GPIO.input(SW_PIN) == GPIO.HIGH) :
            print ( 'SW on :GPIO' + str(SW_PIN) + ' HIGH' )
            if (SWC_CHK == 0) :
                SWC_CHK = 1
                if (LED_ADD == 1) :
                    LED_ADD = -1
                    print ( 'LED_ADD = -1' )
                else :
                    LED_ADD = 1
                    print ( 'LED_ADD = 1' )
        else :
            print ( 'SW off:GPIO' + str(SW_PIN) + ' LOW' )
            SWC_CHK = 0

except KeyboardInterrupt:
    print ( 'CTRL + C' )
    pass

#GPIOリセット終了
GPIO.cleanup()

 

 

バッチリです!

ボタンを押すとLEDの光順が反転するようになりました。

Python 言語の理解 その8

if 文の不思議

今まで見てきたプログラム言語の制御文で、字下げが必須な言語は知りません!

pythonは初めて知った字下げが必要なプログラム言語!


test = 0
if test == 0 :
    print ("ifの中です")

もし、C言語ならこんな感じです。

test = 0
if ( test == 0) {
    print ("ifの中です\n") ;
}

見慣れているからか、C言語の方が見やすいです。

 

条件文は()でくくるし、その条件に合致した時に実行する文は{ }で囲んでました。

それが常識のように思ってました。
それが字下げで表現するなんて驚きです。でも見やすいような見づらいような。。

 

if (test == 0) { :
    print ("ifの中です")
}

SyntaxError: invalid syntax

 

if (test == 0) : {
    print ("ifの中です")
}

SyntaxError: invalid syntax

 

if (test == 0) :
{
    print ("ifの中です")
}

IndentationError: expected an indented block

いろいろ試してみましたが、駄目でした(>_<)

 

 

test = 0
if test == 0 :
    print ("if の then の中です tab")

else

        print ("if の else の中です tab*2")

 

これ else の後の字下げ幅が違うんですがエラーにならないし、ちゃんと機能しました。

うーん、慣れれば使いやすいのかもしれませんが、不思議な感じです。

 

 

Python 言語の理解 その7

すっきりしないプリント書式

画面に出力するときの print の書式の指定がなじめない。

c言語なら printf だけで様々なことが出来るのに、Pythonだとすっきりしない。

 

普通にプリントすると、ブランクで区切られて列挙されるだけ

>>> print (1,2,3)
1 2 3

 

オプションで区切り文字や行末文字を指定することはできる。

>>> print (1,2,3,sep=",")
1,2,3
>>> print (1,2,3,sep=",",end=" !\n")
1,2,3 !

 

文字列属性には、.formatメソッドで変数の展開が出来るらしい。変数名の指定順はどうでもいいらしい。変数がない場合も許される。

>>> print ("{name}の年齢は{age}歳です。".format(name="やまだ",age=15))
やまだの年齢は15歳です。

>>> print ("{name}の年齢は{age}歳です。".format(age=26,name="武田"))
武田の年齢は26歳です。

>>> print ("{}の年齢は{}歳です。".format("井上",30))
井上の年齢は30歳です。

 

既に設定済の変数を使う場合はこうすればいいらしい

>>> name="吉田"
>>> age=21
>>> print ("{}の年齢は{}歳です。".format(name,age))
吉田の年齢は21歳です。

 

書式文字列を変数に入れて共通で使うならは

>>> tfmt = "{}の年齢は{}歳です。"
>>> print (tfmt.format(name,age))
吉田の年齢は21歳です。


>>> print (tfmt.format("山田",19))
山田の年齢は19歳です。

 

python3.6 からは、f で書式設定ができるらしい

先に使ったこの一文を

>>> print ("{name}の年齢は{age}歳です。".format(name="田中",age=22))

こういう風に書くことが出来るらしい

>>> name="田中",age=22

>>> print (f"{name}の年齢は{age}歳です。")

 

ですが! ですが!

pi@raspberrypi:~/soc $ python3
Python 3.5.3 (default, Jan 19 2017, 14:11:04)
[GCC 6.3.0 20170124] on linux
Type "help", "copyright", "credits" or "license" for more information.

 

RaspberryPi の Raspbian に入っているのは Python 3.5.3でした(>_<)

駄目じゃん(笑)

Python 言語の理解 その6

モジュールを読み込む

 

>>> import random

 

使うときは モジュール名に .関数名 を付けて呼び出せます。

>>> random.randint(1,10)
9

>>> random.random()
0.5393296766294138
>>> random.random()
0.030883659185085177

モジュールの中の使う関数だけを限定で読み込むときは

>>> from random import randint
>>> randint(1,10)
2

読み込んでいない関数は使えません。
>>> random()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'module' object is not callable
>>> from random import random
>>> random()
0.46652281624641545

 

読み込めば当然使えます。(笑)

Python 言語の理解 その5

組み込み関数の不思議

 

組み込み関数はいろいろあると思いますが、書籍で最初に紹介されていた関数に驚きました。

>>> max(5,3)
5

これは良くある感じなんですが、パラメータが二つ以上でもいいんです。

 

>>> max(5,3,30)
30

どっちが大きいか、ではなく、どれが大きいか、なんですね。


>>> min(3,8,6,9)
3

小さいものを選ぶのも同じでした。

 

キャラクタ変換はアスキーコードじゃない!当たり前?

>>> chr (43)
'+'

>>> chr(12356)
'い'

utf-8コードなんですかね。

 

そしてその反対の関数もあります。
>>> ord ("1")
49
>>> ord ("あ")
12354

utf-8コードなんですかね。二文字指定するとだめでした。

 >>> ord("ad")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: ord() expected a character, but string of length 2 found

>>> ord("い")
12356

"あ" と "い" は連番ではない?? 真ん中のコードの文字は何?

 

>>> chr(12355)
'ぃ'

おー、小さい文字(笑)

 

 

キーボードからの文字入力はこんな感じで書けます。

>>> input("こんにちは:")
こんにちは:はい
'はい'

 

パラメータに何も書かないとプロンプトなし

>>> input("")
gh
'gh'

 

パラメータ省略も同じように動きます

>>> input()
fhg
'fhg'

 

これだけわかってくると何か書けそうな気もしてきますね~

Python 言語の理解 その4

今時の仕様 なの⁈

先日、複数行文字列を使ったコメントの書き方が面白いなと思いましたが、数値や文字列の操作も なかなか興味深いです(笑)。

僕はかなり昔にC言語を覚えただけで、それからは他の言語はほとんど習得してなかったからなんでしょうかねぇ。なんだか便利な感じを受けます。
これは今時の仕様なんでしょうかね。

 

進数表示と進数記述について

・10進数の10を 2進数で表示

 >>> bin(10)
 '0b1010'

・10進数の10を 8進数で表示
 >>> oct(10)
 '0o12'

・10進数の10を 16進数で表示
 >>> hex(10)
 '0xa'

・2進数の1010を 10進数で表示
 >>> 0b1010
 10

・8進数の12を 10進数で表示
 >>> 0o12
 10

・16進数のaを 10進数で表示
 >>> 0xa
 10

これらは、ありがちな事かもしれません。

 

変数の型表示はこのようにするとできるようです。以下整数の例。

>>> age = 10
>>> type (age)
<class 'int'>

 

これはプログラムで判定できるのか?そんな使い道はないか(笑)でも試すと、

>>> type (age) == "<class 'int'>"
False

➡できない!一致しない!

 

>>> type(age) == type(age)
True

➡これはできてる!

>>> type(age) == type(1)
True

➡もしやるなら、こちらかな

 

二重の比較判定が同時にできる⁈

>>> age = 10
>>> 5<age and age<20
True

これをまとめてこんな書き方ができる!これは超便利
>>> 5<age<20
True

 

複数行の文字列の書き方1

>>> poem1="""やま
... かぜ
... れんこん
... """
>>> poem1
'やま\nかぜ\nれんこん\n'

 

複数行の文字列の書き方2

>>> poem2="やま\nかぜ\nれんこん\n"
>>> poem2
'やま\nかぜ\nれんこん\n'

 

文字列の追加

数値の ⁺= はC言語でも使えるけど文字列には無かったような・・・

>>> poem2
'やま\nかぜ\nれんこん\n'
>>> poem2 += "いちご"
>>> poem2
'やま\nかぜ\nれんこん\nいちご'

 

文字列の繰り返しも出来る!

>>> moji = "うまい"
>>> moji * 3
'うまいうまいうまい'

>>> moji3 = "うまい" * 3
>>> moji3
'うまいうまいうまい'

 

文字列の部分取り出し

>>> id1 = "abcdefghijklmn"
>>> id2 = "ABCDEFGHIJKLMN"
>>> id1
'abcdefghijklmn'
>>> id2
'ABCDEFGHIJKLMN'

 

文字列から3文字目の取り出し
>>> id1[2]
'c'
>>> id2[2]
'C'
>>> id1[6]
'g'
>>> id2[6]
'G'

半角も全角も同じ添え字で可能みたいです!これは凄い!

 

7文字目から4文字目まで・・逆方向に指定するとなにも取り出せない

>>> id1[6:3]
''

 

7文字目から10文字目までを取り出す。

>>> id1[6:9]
'ghi'

解りやすいように、+3 と取り出す文字数を指定するとよいかも。

>>> id1[6:6+3]
'ghi'

 

全角でもやり方は同じ。
>>> id2[6:6+3]
'GHI'

 

6文字目から最後まで

>>> id1[5:]
'fghijklmn'

>>> id2[5:]
'FGHIJKLMN'
 

先頭から4文字目まで
>>> id1[:3]
'abc'
>>> id2[:3]
'ABC'

 

先頭から4文字目まで1文字おきに
>>> id1[:3:2]
'ac'
>>> id2[:3:2]
'AC'

 

頭から1文字おきに取り出すならこうなる。
>>> id1[::2]
'acegikm'
>>> id2[::2]
'ACEGIKM'

 

4文字目から1文字おきに取り出す、これは面白いかも。
>>> id1[3::2]
'dfhjln'
>>> id2[3::2]
'DFHJLN'

 

最後から逆順に取り出す。こんなことが出来るの?
>>> id1[::-1]
'nmlkjihgfedcba'
>>> id2[::-1]
'NMLKJIHGFEDCBA'

 

文字列の一部を置換することはできない。これは不便。

>>> id1
'abcdefghijklmn'
>>> id1[3]
'd'

4文字目は d でした。それを s に置換してみる
>>> id1[3]="s"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment

 

文字なのでシングルクオートで括ってみたが結果は同じ。
>>> id1[3]='s'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment

前半と、後半を取り出して合成するとできなくはないけど。。

>>> id1 = id1[:2] + 's' + id1[4:]

 

そのやり方は以下に書いてありました。

 

# 文字列からリストへ変換し、4文字目を置換
>>> str_list = list(id1)
>>> str_list[3] = 's'

# リストから文字列へ戻す
>>> id1 = "".join(str_list)
>>> print(id1)

'abcsefghijklmn'

 

出来てる!

最後のリストから文字列へ戻すやり方の "". これはどういう意味?

そこを外すとどうなるか

 

>>> id1=join(str_list)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'join' is not defined

 

なぜ怒られているのか理解できない。(笑)
それも外すと。。。

>>> id1=str_list
>>> id1
['a', 'b', 'c', 's', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n']

 

なにがなんだか(;^ω^)

Python 言語の理解 その3

サンプルプログラムなどで一番便利に使うのは画面への文字出力じゃないかな。

Pythonでも多言語にありがちな print です。ですが、そのオプションに驚きが!

基本はかなり普通です。

 

print ( 値1,値2,値3,・・・)

 

驚きは以下のような不思議なオプション。

print ( 値1,値2,値3,・・・,sep="区切り文字",end="行末文字")

 

値の間の区切りに使う文字、改行に使う文字を指定することが出来ます。
なんだか不思議です。

C言語のように、もっと簡単に書式設定ができればいいのに(笑)