カテゴリー: プログラミング

  • GitHubの基礎から論文にコードを公開するまでの方法

    GitとGitHubの使い方に関する発表を行った時の資料を公開します。

    実際にGitHubを使ってどのように操作するのかから、プログラムコードを論文に載せるためにはどのような操作するのかを説明しています。

    論文データや解析プログラムの公開が現在よく求められています。
    それ以外にもGitHubを使ったプログラム管理は共同研究を行う上で重要な要素となってきています。

    [2024年1月15日更新] https://www.slideshare.net/slideshow/embed_code/key/vzfmHD9i6I15wI

    GitHubの基礎からプログラム管理、そしてプログラムコードを論文に公開するまでの手順 from Hayato Yamanouchi

    自身のサイトにも同様のものを載せています。

    山ノ内勇斗の個人サイト

  • MacでPythonの環境構築をVS Code(Visual Studio Code)で行う!![備忘録]

    MacでPythonの開発環境を作ろうとおもい、備忘録を残したいと思います。

    Visual Studio Code (VS Code)のインストール

    Visual Studio CodeのHPからアプリをインストール

    なんか、そのまま実行できるアプリがインストールされるので、Macのアプリケーションのフォルダにいれる。

    VS Codeの日本語化

    “Japanese Language Pack for Visual Studio Code”を入れます。

    左側のメニュー欄のExtension (拡張機能)を選び、“Japanese Language Pack for Visual Studio Code”と入力します。

    そのときに、一番上に出てきた同じ名前のパッケージをインストールします。

    その後、VS Codeを再起動し、日本語化されているかをみます。

    Pythonの拡張機能をインストール

    同様に、Pythonの拡張機能をインストールします。

    左側のメニュー欄の拡張機能を選びPythonと入力し、Pythonをインストールします。

    これによって、VS CodeでPythonのプログラムを書いたときに、jupyterを使えたり、文法を勝手に認識して色分けしれくれたり、Pythonの開発環境を作ってくれます。

    実際に動くかどうかの確認

    適当なディレクトリにtest.pyのファイルを作成します。

    新規ファイル作成で、テキストを選び、言語選択でPythonを指定します。

    その後、test.pyとし、プログラムには

    print(“Hello World!!”)

    と入力します。

    そして、右上の再生ボタンで実行します。

    すると、下のターミナルで、Hello World!!と表示されます。
    ここまでくれば、pythonの開発環境は一旦できました。

    Anacondaで仮想環境を作っている人は、右下のPythonの実行を選ぶところから、任意の環境を選択することができます。
    もしくは、ターミナルでcondaコマンドで仮想環境をアクティベートすることができます。

  • elifを使った条件分岐がうまくいかない!![Python]

    elifを使った条件分岐がうまくいかない!![Python]

    if文で複数条件で複数の条件分岐を行いたいときに、elifでやってみたらエラーは出ていないんだけど、なんか結果がうまくいかないという時ってないでしょうか。
    もしかしたら、下の事象が当てはまっているかもしれません。
    参考までに、僕が間違えてしまっていたので、メモ書きします。

    問題となるプログラム

    if、elifに二条件を記載して、elifを含むプログラムを作成した状況で問題が起こります。

    def trable(a, b):
        if a >= 10 & b >= 10:
            print("patern A")
        elif a >= 10 & b < 10:
            print("patern B")
        elif a < 10 & b >= 10:
            print("patern C")
        else:
            print("patern D")
    
    trable(11, 11)
    trable(11, 9)
    trable(9, 11)
    trable(9, 9)

    上記のプログラムを実行したときに、上から順にA, B, C, Dのパターンに分類分けされてほしいようにも思えますが、実際には下の出力になります。

    patern A
    patern B
    patern C
    patern B

    順序を入れ替えてみてはどうでしょうか。

    def trable(a, b):
        if a >= 10 & b >= 10:
            print("patern A")
        elif a < 10 & b < 10:
            print("patern B")
        elif a >= 10 & b >= 10:
            print("patern C")
        else:
            print("patern D")
    
    trable(11, 11)
    trable(9, 11)
    trable(11, 9)
    trable(9, 9)

    とやって、patern B, Cのプログラムを入れ替えて、A, B, C, Dと出力してほしいというプログラムを作ると、実際には下記の出力になります。

    patern A
    patern D
    patern D
    patern D

    elif自体は複数条件を定義したいときに下記のように使用します。

    if 条件式A:
      条件式Aが真(True)となった場合の処理
    elif 条件式B:
      条件式Aが偽(False)で、条件式Bが真(True)となった場合の処理
    else:
      条件式Aが偽(False)で、条件式Bも偽(False)となった場合の処理

    しかし、if文、elif文の条件式が二条件になると、上記のような問題が起こると想定されます。
    よって、目的の出力にならないことが起こります。

    これの厄介なところはエラーが排出されないので、実際に結果を見てみないとうまくいっているかどうかがわからないという点です。

    改善策

    複数条件で複数の条件式で分けたいときには、elif文で複数条件を指定しないようにします。

    def resolve(a, b):
        if a>= 10:
            if b >= 10:
                print("patern A")
            else:
                print("patern B")
    
        else:
            if b >= 10:
                print("patern C")
            else:
                print("patern D")
    
    resolve(11, 11)
    resolve(11, 9)
    resolve(9, 11)
    resolve(9, 9)

    煩わしくなりましたが、こうすることで思っている想定通りの出力を行うことができます。

    プログラムではこのような思わぬ落とし穴があるので、書いたプログラムはしっかり確認することの教訓になりますね。

    追記(2022年8月)

    ()で括っていないことが問題であったみたいです。

    def trable(a, b):
        if (a >= 10) & (b >= 10):
            print("patern A")
        elif (a < 10) & (b < 10):
            print("patern B")
        elif (a >= 10) & (b >= 10):
            print("patern C")
        else:
            print("patern D")

    とすると、うまく条件分岐できました。
    もしくは、&をandと表記することでも解決することができます。

    def trable(a, b):
        if a >= 10 and b >= 10:
            print("patern A")
        elif a < 10 and b < 10:
            print("patern B")
        elif a >= 10 and b >= 10:
            print("patern C")
        else:
            print("patern D")

    &とandって同じように思えますが、&には論理積という側面があり、元々のプログラムだと

    a >= 10 & b < 10

    これは a >= (10 & b) < 10 の意味になるようで、
    a=9, b=9だと不等式が
    9>=8<10となり、Trueとなってしまうそうです。

    難しいですね・・・。

  • PWM出力を使ってパルス波の周波数, Duty比を変更する [Arduino UNO]

    PWM出力を使ってパルス波の周波数, Duty比を変更する [Arduino UNO]

    PWM出力とは

    PWMとはpulse width modulationの略で、パルス幅変調と日本語では言います。
    波長のデューティー比(Duty cycle)を変えることによって、変調を行う方法です。

    詳しくは前回の記事で説明されています。

    ArduinoのPWM出力

    Arduino UNOではATmega328と呼ばれるMicrochip社のマイコンをメインチップとして使っています。
    Arduinoのプログラムを考える上で、深みにハマっていくとマイコンのデータシートを見ていかなければならなくなりますので、一回見てみると面白いかと思います。(事実今がそう)

    Arduinoには三つのタイマー(Timer/Counter)があります。
    このタイマーはArduinoプログラムの時間に関係しています。
    delay()やtone()などの関数はこのタイマーを使って計測されています。

    Timer/CounterPin番号ビット数役割PWM周波数
    Timer05, 68 bitArduinoの時間を管理
    delay(), millis(), micros()など
    977 Hz
    Timer19, 1016 bitServoライブラリなど490 Hz
    TImer23, 118 bittone()など490 Hz

    今回このタイマーをいじることでPWMの出力を変えるということをします。
    ちなみに、応用するとタイマーの根本を変えるので、delay()などの関数もいい感じに変えたりすることができたりするかも?(どちらかというと影響を受けて狂ったりすることの方が多そう)

    TImer0は基本的にシステム全体に関わることが多いので、TImer1を使用することをお勧めします。

    参考になるサイト集
    https://playground.arduino.cc/Main/TimerPWMCheatsheet/
    https://www.arduino.cc/en/Tutorial/SecretsOfArduinoPWM
    https://atooshi-note.com/arduino-1hz-pwm/
    http://blog.kts.jp.net/arduino-pwm-change-freq/
    http://garretlab.web.fc2.com/arduino/inside/hardware/arduino/avr/cores/arduino/wiring_analog.c/analogWrite.html

    プログラムの概要

     プログラムの全体の方針として、Arduinoのタイマーをレジスタの設定を変えることで自由にPWM出力の周波数を変更することができるようにします。

    目的としては、低い周波数を出力できるようにしたく、10 Hzを出力できるようなプログラムにします。

    今回は10番ピンにLEDを繋いで、その光の周波数、Duty比を自由に変更できるようにするプログラムを作成します。
    10番ピンなので、TImer1を使用します。

    プログラムコード

    //レジスタの設定を変えるためのもの
    #include <avr/io.h>
    int PWMPin = 10;
    
    //関数の定義
    //frq:周波数 (1Hz~指定できる)
    //duty:指定したいduty比
    void HzWrite(int frq, float duty) { 
    
        // モード指定
      TCCR1A = 0b00100001;
      TCCR1B = 0b00010100; //分周比256を用いる
    
      // TOP値指定
      OCR1A = (unsigned int)(31250 / frq);
    
      // Duty比指定
      OCR1B = (unsigned int)(31250 / frq * duty);
    }
    
    
    void setup() {
      pinMode(PWMPin, OUTPUT);
    }
    
    void loop() {
      HzWrite(10, 0.5);
      delay(5000);
      digitalWrite(PWMPin, LOW);
      delay(5000);
    
    }

    プログラムの説明

    まず、レジスタの設定を変えるために、<avr/io.h>をインクルードします。

    #include <avr/io.h>

    次に、delay()と一緒に使って、10 Hzの出力を5秒ごとに繰り返すという関数を作るため、HzWriteという関数を指定します。カッコ内には周波数、Duty比を指定できるようにします。

    void HzWrite(int frq, float duty) { 
    
    }

    次にモードの指定です、。
    今回使うレジスタはTCCR1A/TCCR1Bです。(TCCR: Timer/Counter Control Register)
    ここで1というのはTImer1を示しており、Timer2を使いたければTCCR2A/TCCR2Bを使います。

    PWM周波数を〇〇Hzとして設定するには、TOP値を自分で指定する必要があります。
    TOP値が大きければ大きいほど出力される周波数は低くなります。
    今回は10 Hzで例を取っているので、16MHzというシステムクロックと比べると非常に遅いので、大きなTOP値と分周を指定する必要がある。よって、なるべく大きいTimer1を使用します。


    Timer0, 2の8 bitではTOP値の最大値は255(2^8 – 1)であり、Timer1の16 bitでは65535(2^16 – 1)となる
    (最大値が-1となるのは、0~255もしくは0~65535となるため、数字の数が2^xになるが、最大値は-1しなければならない。)

    システム的には、TOP値までカウンタをインクリメント(0, 1, 2, と数えていく)し、OCRxA/OCRxB(xはカウンタ番号、カウンタについて2つの出力ピンA, Bが割り当てられている。)と一致した時にピンの出力を変化させる(LOW→HIGHのように)。そして、カウンタがTOP値まで到達すると今度は0までデクリメント(65535, 65534, 65533と上から数えていく)し、インクリメントの時と同様にOCRxA/OCRxBと一致した時にピンの出力を変化させます。

    Arduino UNOではこのカウンタのインクリメントするスピードは分周比の設定を変えることによって、ある程度変えることができます。(ある程度とは、1/8/64/256/1024 の中から選択できるということ)
    分周比は周波数を分周(周波数を1/n倍すること)するときの比(n)です。
    つまり、1000 Hzを分周比10で分周すると100 Hzになります。

    ちなみに、分周比1ではArduino UNO(ATmega328)のシステム動作クロックである16MHzで操作します。

    つまり、TOP値とOCRxA/OCRxBの値、分周比を変えることによって、自由に出力の変換点を変えることができます。

    今回は10Hzを指定したいので余裕を持って分周比256で行います。
    1カウントする時間は、Unoなら16MHzなので1 / 16MHz = 62.5ns(分周1)
    分周比を256にすると、TOPまでカウントした際には62.5ns x 256 x 65535 = 1.04856 secなので、1 Hzを指定できるようになる。

    今回このプログラムでは1 Hz ~ 31250 Hzまでの周波数を作り出すことができる。
    しかし、31250に近づくにつれてDuty比の指定ができなくなっていきます。
    Duty比を細かく設定したい際には300 Hz程度までしか作成することができません。

    このプログラムでは分周比の設定を変更することで、自分の使用用途にあった周波数帯を作れるようなプログラムを作ることができます。

    TCCRaA/TCCR1Bには何を指定するのかを書きます。
    ここら辺の細かいところはなんか難しいので、データシートを使って、なんとなく指定していきましょう。

    今回は2進数で示しているので、最初に0bがついています。TCCR1AではCOM1A1, COM1A0, COM1B, 無指定, 無指定, WGM11, WGM10 を 1 か 0 で設定します。
    TCCR1B には それぞれ、無指定(ICNC1), 無指定(ICES1), 無指定, WGM13, WGM12, CS12, CS11, CS10 を設定します。

    TCCR1Aの指定(ATmega328データシートより)
    TCCR1Bの指定(ATmega328データシートより)

    まず、今回はModeはPWMモードがPhase Correct and Frequency Correct であるMode9を指定する。
    今回TOP値OCR1Aに指定する。

    モードの指定(ATmega328データシートより)

    よって、WGM13 / WGM12 / WGM11 / WGM10 はそれぞれ、1,0,0,1 

    出力の指定(ATmega328データシートより)

    COM1B0 / COM1B0 は 0, 0 が 無出力、0, 1 が トグル動作 (一致時の出力を反転)、
    1, 0 は カウンタ がOCR1A/B – TOP間 にある場合 LOW、0 – OCR1A/B間 は HIGH となるよう出力、
    1, 1 は1, 0 の逆です。

    今回は周波数をOUTPUTのLEDをLOWとHIGHで変えるため、1B0 / COM1B0 は1, 0の値を指定します。

    スケッチを書く際にわかりやすいので 1, 0 を選択します。

    分周比の指定(ATmega328データシートより)

    今回分周比は256を指定するため、CS12/CS11/CS10は1, 0, 0を指定する。

    まとめると、以下のようになる。

    TCCR1A = 0b00100001;
    TCCR1B = 0b00010010;

    次にOCR1AとOCR1Bを設定し、周波数とDuty比を指定したもので出力してもらうように指定します。

      // TOP値指定
      OCR1A = (unsigned int)(31250 / frq);
    
      // Duty比指定
      OCR1B = (unsigned int)(31250 / frq * duty);

    今回Phase and Frequency Correct PWMを用いる際には、インクリメントしディクリメントすることから、出力される周波数は以下のように示すことができます。

    周波数frq = IC の動作周波数 / (分周比 * TOP値 * 2)

    逆にTOP値を指定するときは

    TOP値 = IC の動作周波数 / (分周比 x frq x 2)

    今回Arduino UNOで分周比256とした際には

    TOP値 = OCR1A = 16,000,000 / (256 x frq x 2) = 31250 / frq

    LOWとHIGHが入れ替わるタイミングはOCR1A/OCR1B = Duty比としたいため、

    OCR1B = 31250 / frq x duty

    オーバーフローを防ぐため、Unsigned intを指定している。

    出力のメインはこちら

    void setup() {
      pinMode(PWMPin, OUTPUT);
    }
    
    void loop() {
      HzWrite(10, 0.5);
      delay(5000);
      digitalWrite(PWMPin, LOW);
      delay(5000);
    
    }

    PWMPinつまり10ピンをOUTPUTで指定し、HzWrite()で周波数とDuty比を指定する。
    delay()でまった後に、digitalWrite(PWMPin, LOW)で出力をなくし、delay()する。

    以上がプログラムの全貌と解説です。

    後書き

    PWM出力の周波数を変更する方法のブログに関して、Arduinoで検索するよりも、AVRとか、ATmega328, 328Pなどのように検索した方が多く出てきました。

    今回はざっくりとしたブログでしたが、より深く知りたい人は調べてみてください。

  • Arduionoで連続パルス波を作成する方法

    Arduionoで連続パルス波を作成する方法

    はじめに

    Arduinoを使って、連続パルス波を出力したりしたくなる時があると思います。
    LEDを点滅させたり、音を出力したり、タイマーとして使ってみたり・・・

    何かと使うことが多く、そして簡単なようにも思えますが、調べていくと非常に奥深いことがわかります。

    今回は、Arduinoで連続パルス波を出力する方法をいくつか紹介していきます。

    Delayを使って時間を変える

    最もシンプルかつ、簡単な方法で、delay関数を使って出力のONとOFFを切り替える手法です。

    //pinはピン番号
    void loop(){
        digitalWrite(pin, HIGH);
        delay(1000);
        digitalWrite(pin, LOW);
        delay(1000);
    }

    上記のプログラムでは、出力がHIGHとLOWとで切り替えています。
    delayは単位はmsなので、delay(1000)では1秒間待つというプログラムになります。

    つまり、1Hzでついたり消えたりするプログラムになります。

    ただ、周波数の指定にdelay()関数を使うことは問題点が多いです。
    また、この方法では、60Hzの信号を5秒間出力といったように、出力の時間を変更するのが、for構文を使って指定する必要があり、そういった面で不便さがあります。

    ただ、シンプルが故、とりあえずやってみたいという時にはおすすめです。

    tone()を使って指定する

    tone()関数はブザー音などを作成するときによく使われる関数です。
    Arduino公式の解説

    この関数では、周波数、継続時間を指定することができます。
    なので、delayを使った時とは違い、周波数を計算せずとも直接指定することができます。

    //pinはピン番号
    void loop() {
         tone(pin,60);
    }

    tone(pin, frequency)や、tone(pin, frequency, duration) といったように指定することができます。

    durationはms単位で指定するため、delayと同様の記載方です。

    この関数の問題は、指定できる周波数が31Hz以下ではできないという点です。
    つまり、1Hzなどの出力を作ることができません。

    音などの31Hzより大きい周波数を指定する時には非常に簡単に周波数を指定できますし、delay関数を使う時よりも非常に短く、正く指定することができます。

    PWM出力を使って、PWM出力の周波数を変える

    PWM出力を使う方法は最も自由度が高く、そして奥深すぎる原因です。

    PWMとはpulse width modulationの略であり、日本語ではパルス幅変調です。
    詳しくはwikipediaより

    この言葉だけ聞いてもなんのことかよくわかりませんが、簡単にいうと、PWMとはデューティー(Duty)比を変更して色々変調する方法です。
    Arduino公式の説明はこちらから

    LEDの明るさを指定するときに、本来であれば電流値を変えることで明るくしたり、暗くしたりできます。
    しかし、電流値が一定だった時に、でもLEDの明るさを変えたいとなった際に、めっちゃ早い周波数で(人が点滅しているのがわからなくなるのが30~60Hzと呼ばれている)点滅させます。

    そして、ONとOFFが通常であれば1:1(Duty比が50%)となっていますが、これを4:1(Duty比が80%)とか1:4(Duty比が20%)とかにしてみるとどうでしょうか。
    前者では明るく見え、後者では暗く見えるでしょう。

    このようにして、パルスの幅を変えることで出力を変調するというのがPWMによる出力です。

    そして、Arduinoではこの出力ができるとともに、PWM出力の周波数を変えることもできます。
    レジスタ設定と呼ばれる、まあArduinoの元の部分を変えちゃえばPWMの出力周波数を変えることができるっしょっていう考えがこの方法です。
    ちなみにデフォルトでは出力周波数は490Hz、一部のピンでは980Hzです。

    今後の記事でやり方を詳しく説明します。
    「PWM Arduino 周波数 変更」で調べるとたくさん説明が出てきます。

    4回ぐらい読むとなんとなくわかるようになると思います。

    基本的にはこれらの方法で自分の目的にあったプログラムを探してみてはどうでしょうか。

  • macOSでCondaコマンドを使う

    macOSでCondaコマンドを使う

    MacOSでのAnacondaのインストール、ターミナルの環境設定を行いたいと思います。

    Anacondaのインストール

    Anacondaのホームページへと行き、下の方にスクロールするとダウンロードがあります。

    ここでは自分の環境にあったものをインストールしましょう。
    今回は、MacOSの説明なので、64-bit Graphical Installerを選択しましょう。

    インストーラーを起動し、指示に従ってインストールしましょう。

    Macでインストーラーが二つありますが、64-bit Graphical InstallerはGUIによってAnacondaをインストールする方法で、こちらの方が親しみが深く、何もなければこちらでAnacondaをインストールできます。

    64-bit Command Line Installerはダウンロードすると *.shのファイルがインストールされます。
    これはシェルスクリプトによるインストールで、ターミナルを使ってインストールする際に使用します。

    Linuxでのソフトのインストールがターミナルを用いたインストールが基本なので、Linuxに親しんでいる人はこちらの方がインストールしやすいんですかね。(多分)

    コマンドラインの環境設定

    MacOSでインストールすると、ソフト一覧にAnaconda-Navigaterが出てくるだけで、このままだとターミナルでAnacondaやPythonを使えません。

    ソフトのインストールなどで、condaコマンドを使用したい場合には、Anacondaを有効にしなければなりません。
    Anacondaを有効にするには(Conda コマンドを使えるようにするには)

    conda activate

    とする必要があります。
    これでcondaコマンドを使えるはずです。

    いちいちconda環境をアクティベートするのがめんどくさい方は、自動でconda環境を有効にすることもできます。
    その時にはターミナルで、

    ~/opt/anaconda3/bin/conda init シェル名

    とします。
    シェル名は自分の使用しているシェル名を使うのですが、なんだそれ、いじったことないぞという方はデフォルトのシェル(MacOSだとzsh)だと思うので、これをシェル名に代入しましょう。

    ~/opt/anaconda3/bin/conda init zsh

    これで、ターミナルを再起動すると、自動的にconda環境が有効になり、conda activateのコマンドを打たなくても良くなります。

    自動有効をオフにする場合には、

    conda config --set auto_activate_base false

    とターミナルで実行しましょう。

  • ファイルのバージョン管理をするための最強ツール”Git” 初心者向け解説

    ファイルのバージョン管理をするための最強ツール”Git” 初心者向け解説

    Gitとは

    皆さんGitよりもGitHubを先に知っているのではないでしょうか。
    参考にするプログラムや、ソフトを探すときに、よくGitHubのサイトがヒットし、よく使い方がわからないまま、とりあえずダウンロードしたという経験がある人も多いのではないのでしょうか。

    ただ、GitHubはプログラムの共有の場所ではあるが、ただの共有する場所ではなく、Gitとよばれるツールをオンラインで使うためのツールです。

    Gitとは、ファイルのバージョン管理を行うためのツールです。
    ファイルを変更し、その変更を記録することによって、いつでも記録した任意のバージョンへと戻ることができるツールです。

    発表原稿とかを誰かに添削してもらう際に、添削する前のファイル、添削し終わったファイル、添削をもとに修正したファイルなどをそれぞれ別のファイルとして保存すると思います。
    そのような変更をGitと呼ばれるツールを使うことによって、簡単に、そして一つのファイルで行うことができます。

    Gitのリンクはちらから

    Gitの三つの場所

    Gitを使った記録、およびその記録をするという操作を“コミット”と呼びます。

    そして、コミットを貯めていく場所を“レポジトリ”と呼びます。
    つまり、レポジトリは変更履歴を補完する場所とも言えます。
    リポジトリの保管庫は自分のパソコン上では“ローカルレポジトリ”GitHubなどのリモート上では“リモートレポジトリ”と呼びます。

    Gitでファイル管理を行おうとする際には、Gitでファイル管理を行うフォルダーを指定します。
    そしてそのフォルダ内には三つの場所があります。
    ワークツリー、ステージングエリア、Gitディレクトリです。

    ワークツリーはファイルを保持する場所であり、ここにあるファイルを変更しただけではまだ変更履歴をコミットとして保存できていません。

    ステージングエリアはコミットするファイルを登録するための場所です。
    個々のステージにあるファイルも同様に、まだ変更履歴は保存されていませんが、このファイルをコミットしますという宣言をする場所と思ってください。

    Gitディレクトリはコミットを保管する場所です。
    ここにコミットされたファイルは変更されることはないファイルとして格納されます。
    コミットによって記録された内容は、基本的にはあとから変更、消去することができないです。
    Gitディレクトリにコミットされることによって、変更履歴として記録されたこととなります。

    Gitの基礎的な使い方

    詳しい使い方は実際に調べていただくとして、ここでは実際の操作の大まかな説明をします。

    Gitは基本的には、WindowsではGit Bash(Gitをインストールしたときに一緒にインストールされる)、macOS. Linuxではターミナルを使って操作します。(ここでは両行ターミナルと呼びます。)

    皆さんが使い慣れているであろうGUIでの操作もありますが、慣れるとCUIでのGitの利用は非常に便利なので、最初からCUIを使うことをお勧めします。
    1時間で慣れると思います。

    まず、Gitで管理を始めるために、ローカルリポジトリを作成します。
    初めに、Gitで管理したいディレクトリに、ターミナル上で移動します。
    そして、

    git init

    と入力することによって、Gitでのバージョン管理をする準備ができます。

    次に、ステージングエリアに変更を記録するために、

    git add ファイルパスもしくはディレクトリパス

    を実行することで、ワークツリーの指定したファイルをステージングエリアに登録します。

    次に、

    git commit

    でワークツリー内のファイルをコミットします。

    今現在、どのファイルがどの状態であるかを確認するには

    git status

    を実行します。
    コミット履歴は

    git log

    を実行することで確認することができます。

    基本的には、git addして、git commitをすることで変更履歴を作成し、git satusで困ったときに状態を確認するという流れになります。

    下は参考文献です。
    初心者にも非常にわかりやすい本であり、こちらの記事の執筆の参考にもさせていただいています。
    より詳しく勉強したいという方はこちらの本をおすすめします。

  • データフレームにおける特定の値の抜き出し[Python]

    データフレームにおける特定の値の抜き出し[Python]

    Pythonのデータフレームに関して、ある特定の値を抜き出すことは意外にも難しいです。
    それは、Pythonのデータフレームはデータフレームの形式で扱うことが前提であり、ある行を抜き出したり、切り取ったり、追加したりは非常に簡単に行うことができます。

    ただ、値を抜き出そうとする時にはなぜか値として抜き出せず、データフレームの形のままだったり、問題がいろいろ発生します。

    ここでは、ある特定の条件を満たすデータフレームの値を抜き出す方法を記載します。
    他に多分いい方法とかあるのかもしれませんが、今現状僕の状態ではこれが限界です。

    まず、状況として、以下のデータフレームがあったときに、赤枠で囲った20の値を抜き出そうとします。

    ここで問題になるのは、上記のような単純なデータフレームであればインデックスがわかり、一発で抜き出すことができますが、大量のデータであったときにインデックス番号を確認してそれを使うことは非常に難しいです。

    大量にデータがあったときに、キーとなる列(顧客番号、idなど)を手がかりにデータを抜き出すことが効率的です。
    そこで、下のような状況で抜き出そうとします。

    つまり、Aの列でAichiの行のBの値を抜き出したいとします。
    その時には一度で抜き出すことはできず、二段階踏んで値を抜き出します。

    まず、上記と同様のデータフレームを作成します。

    import pandas as pd
    df = pd.DataFrame({ 'A' : ["Tokyo", "Aichi", "Osaka"],
                        'B' : [10, 20, 30],
                        'C' : [100, 200, 300]})
    df

    次に、Aの列のAichiの行を抜き出します。

    a = df[df["A"] == "Aichi"]
    
    print(a)

    そうすることで、Aichiを含む行を抜き出すことができました。
    最後に、この行のBの列の値を抜き出します。

    b = a.at[a.index[0], "B"]
    
    print(b)

    このようにすることで、抜き出すことができます。
    回りくどいですが、これが僕が現在使っている方法です。

    他に方法があればコメント等で教えていただけると幸いです。

    import pandas as pd
    df = pd.DataFrame({ 'A' : ["Tokyo", "Aichi", "Osaka"],
                        'B' : [10, 20, 30],
                        'C' : [100, 200, 300]})
    
    a = df[df["A"] == "Aichi"]
    b = a.at[a.index[0], "B"]
    print(b)

    上記のプログラムのまとめです。

  • Pythonの例外処理を行うtry, except

    Pythonの例外処理を行うtry, except

    pythonでのプログラムの時に、エラーが起こることがあります。
    エラーはプログラムが正常に組み立てられていないことを示してくれるいいやつなのですが、
    時に、エラーのせいでプログラムが動かなくなってしまう時があります。

    構文的には正しいのに、実行時にエラーが出ることがあります。
    構文が文法的に正しくない時に出るエラーを構文エラー
    文法的に正しいのに、論理的に間違っているエラーを例外と言います。

    例外の例として、
    TypeError:演算する者同士の方が異なっている
    EX. word/2 , 4*number

    ZeroDivisionError:0で割ってしまっている
    EX. 3/0

    ValueError:型は合っているが、値が適切でない
    EX. int(“string”)

    条件分岐をすることによって、エラーを未然に防ぎ、論理的に正いプログラムを作成することも可能ですが、エラーが怒った時には例外処理を行うという処理を行うという選択肢を取ることもできます。

    その時に使用するのがtry, exceptです。

    try: 
        実行したい処理(例外を含むかもしれない)
    except エラー名:
        例外発生時に行う処理

    といったように使います。
    例として、

    try:
        print(10 / 0)
    except ZeroDivisionError:
        print('できませんでした')
    #出力
    できませんでした

    となります。
    ただ、exceptで捉えることができるエラーは指定されたエラーのみ
    (今回のプログラムではZeroDivisionErrorのみ)なので、そのほかのエラーが発生した場合に関しては、プログラム実行時にエラーとして出力されます。

    複数のエラーが想定される際には、except エラー名: を追加しましょう。

    try:
        print(10 / 0)
    except ZeroDivisionError:
        print('できませんでした')
    except ValueError:
        print('値がうまく合致しませんでした')

    except節は複数指定することができます。

    except節で例外名を全て指定しないと、全ての例外をキャッチすることが可能です。

    try:
        print(10 / 0)
    except:
        print('できませんでした')

    ただ、これに関して、全ての例外をキャッチしてしまうということで、プログラム制作者が想定していない例外が発生した時にもそのエラーを隠してしまうので、使用する際には非常に注意が必要です。

    try-exceptの構文に関連して、例外が発生した後の処理を指定したりする説があります。
    それを軽く記述しておきます。
    詳しくは別のブログで紹介しようと思います。

    • raise:故意に例外を発生させる
    • pass例外発生後に何も処理を行わない
    • else例外が発生しなかった場合にのみ処理
    • finally例外の発生に関わらず必ず処理

  • PythonでArduinoを制御したいのだ!

    PythonでArduinoを制御したいのだ!

    ArduinoはArduino言語によって制御します。
    ただ、もっと複雑な処理をしたい、何かのプログラムと一緒にArduinoを制御したいという時が訪れることでしょう。

    今回紹介するpySerialというモジュールはRaspberry PiやArduinoとシリアル通信を行うことができます。
    シリアル通信をすることによって、pythonのプログラムからArduinoやRaspberry Piに指令を出し、pythonプログラムを通して制御することができます。

    今回はその基本的なプログラム紹介します。
    これが使えるだけで、プログラムでできることの幅がかなり広がるでしょう。

    インストール方法

    pip install pyserial

    ターミナルやコマンドプロントでpythonを開き、インストールできます。
    もしくは、PyCharmなどのターミナルでインストールもできます。

    プログラム例

    今回は1秒ずつLEDをつけたり消したりするプログラムです。
    もともとArduinoについているLEDの13ピンに出力して検証したいと思います。
    Pythonのプログラムでは

    import serial, time
    
    def main():
        #  COMポートを開く
        print("Open Port")
        ser = serial.Serial("COM3", 9600)
        while True:
            #  LED点灯
            ser.write(b"1")
            time.sleep(1)
            #  LED消灯
            ser.write(b"0")
            time.sleep(1)
    
        print("Close Port")
        ser.close()
    
    if __name__ == '__main__':
        main()

    serial.Serialでポートと、シリアル通信の設定を行います。
    Arduino UNOでは9600を指定します。
    これはボードによって異なるので、Arduino IDEで確認しましょう。

    b”1″のbは非常に重要な役割を担っています。
    serial.write()関数では、シリアル通信をするためにはbyte列にして数字や文字列を送信しなければなりません。
    このようにして、byte列であることを示す必要性があります。

    このプログラムは無限ループなので、1秒ごとのLEDのオンオフがプログラムを止めるまで続きます。

    次にArduino側のプログラムです。

    void setup() {
      Serial.begin(9600);
      pinMode(13, OUTPUT);
      digitalWrite(13, LOW);  //  初期化
    }
    
    void loop() {
      byte var;
      var = Serial.read();
      switch(var){
        case '0':
          digitalWrite(13, LOW);
          break;
        case '1':
          digitalWrite(13, HIGH);
          break;
        default:
          break;
      }
    }

    ここではswitch case構文を使っています。
    このほうがプログラムがわかりやすいです。
    詳しくは前回のブログを見てみてください。

    ここでは0が送信されるとLOW、1が送信されるとHIGHとなります。
    このプログラムをベースに使うことによって、色々なパターンでArduinoをPythonプログラムで制御することができます。