ゼロ知識人の備忘録

ゼロ知識人の備忘録

プログラム的な話題の備忘録的なやつ

Pythonで簡単な字句解析器的なものを実装する

今回やりたいこと

ans = 10 + 2 * 2 / 4

みたいなのを変数・数字・演算子に分割

実装の流れ

  • token クラスの定義

  • lexer クラス

    • 文字列
    • 何番目を見ているかを確認するindex
    • 今見ている文字を返す関数
    • index += 1する関数
    • スペースを無視する関数
    • 文字の1文字目に着目して演算子・数字・変数に分ける関数
    • ↑の関数で分けたものをそれぞれトークンにする関数
    • 次のトークンを作る関数
    • トークンをリストにして返す関数
  • メイン関数

  • 文字列入れてトークンにしてデバッグ

実装の流れにしたがって実装してみる

class token(object):
    kind = ''
    value = ''
    
    def toString(self):
        return self.kind + '  \"' + self.value + '\"'

class lexer(object):
    text = ""
    i = 0

    def init(self, text):
        self.i = 0
        self.text = text
        return self

    def isEOF(self):
        return len(self.text) <= self.i

    def c(self):
        
        if(self.isEOF()):
            print('No more charactor')
        return self.text[self.i]
        
        
    def next(self):
        c = self.c()
        self.i = self.i + 1
        return c

    def skipWhiteSpace(self):
        while(not self.isEOF() and self.c().isspace() ):
            self.next()

    # 演算子かどうか?
    def isSignStart(self, c):
        return c == "=" or c == "+" or c == "-" or c == "*" or c == "/" 
    
    # 数字かどうか
    def isDigitStart(self, c):
        return c.isdigit()

    # アルファベットかどうか
    def isVariableStart(self, c):
        return c.islower()

    def sign(self):
        t = token()
        t.kind = "sign"
        t.value = self.next()
        return t

    def digit(self):
        b = self.next()
        while(not self.isEOF() and self.c().isdigit()):
            b = b + self.next()
        t = token()
        t.kind = "digit"
        t.value = str(b)
        return t

    def variable(self):
        b = self.next()
        while(not self.isEOF() and (self.c().isdigit() or self.c().islower())):
            b = b + self.next()
        t = token()
        t.kind = "variable"
        t.value = str(b)
        return t

    def nextToken(self):
        
        self.skipWhiteSpace()
        if self.isEOF():
            return None
        elif self.isSignStart(self.c()):
            return self.sign()
        elif self.isDigitStart(self.c()):
            return self.digit()
        elif self.isVariableStart(self.c()):
            return self.variable()
        else:
            print('not match token ')

    def tokenize(self):
        tokens = []
        t = self.nextToken()
        while (t is not None):
            tokens.append(t)
            t = self.nextToken() 
        return tokens

# debug ```python lexer.py ```
text = " ans1 = 10 + 902  ans2 = 1 * 2 / 1"
tokens = []
tokens = lexer().init(text).tokenize()
for token in tokens:
  print(token.toString())

コード丸あげだけどまあ見ればわかるだろうし説明いらんでしょって感じ とは言うものの後日細かく説明を残しておきたい

実行結果

 ~/Project/EasyCompiler   master  python3 lexer.py
variable  "ans1"
sign  "="
digit  "10"
sign  "+"
digit  "902"
variable  "ans2"
sign  "="
digit  "1"
sign  "*"
digit  "2"
sign  "/"
digit  "1"

ちゃんとトークンに分かれてるいいね

型推論器実装に挫折した人の話

型推論とは

プログラミング言語の機能の1つで、静的な型付けを持つ言語において、変数や関数の型を宣言しなくてもそれを導くのに使われた関数の型シグネチャなどから自動的に型を決定する機構のこと (Wikipedia より) まあわかりやすく言えば varとかvalとかいうやつだよね

型推論器の実装の話

型推論器 実装あたりで検索してみる 難しくてあんまり理解がっ...... まあなんとなく理解したのでやってみるかってやって見たんだけどすぐさま頓挫... とりあえず人が実装したのを参考にするかって思って見てみるが..... 本当に条件限定的なものしか実装にたどり着けなかった また論文書き終わったらリトライしたい

Python3でTwitter触ってみた

準備

とりあえずtwitterをpipでインストール twitter

apps.twitter.com を英語読みながら作って * CONSUMER_KEY * CONSUMER_SECRET_KEY * ACCESS_TOKEN * ACCESS_TOKEN_SECRET をメモってjsonに入れとく

{
    "CONSUMER_KEY":"",
    "CONSUMER_SECRET_KEY":"",
    "ACCESS_TOKEN":"",
    "ACCESS_TOKEN_SECRET":""
}

とりあえずtokenクラスでも作っとくかということで

token.py

from twitter import *
from src import tools as T
class Token:
    def __init__(self):
        self.ACCESS_TOKEN        =' ' # ACCESS_TOKEN
        self.ACCESS_TOKEN_SECRET =' ' #ACCESS_TOKEN_SECRET
        self.CONSUMER_KEY        =' ' #CONSUMER_KEY
        self.CONSUMER_SECRET_KEY =' ' #CONSUMER_SECRET_KEY
    
    def loadToken(self, jsonPath):
        data                     = T.readJson(jsonPath)
        self.ACCESS_TOKEN        = data['ACCESS_TOKEN']
        self.ACCESS_TOKEN_SECRET = data['ACCESS_TOKEN_SECRET']
        self.CONSUMER_KEY        = data['CONSUMER_KEY']
        self.CONSUMER_SECRET_KEY = data['CONSUMER_SECRET_KEY']
        
    #Debug
    def print_token(self):
        print(self.ACCESS_TOKEN)
        print(self.ACCESS_TOKEN_SECRET)
        print(self.CONSUMER_KEY)
        print(self.CONSUMER_SECRET_KEY)

OAuth認証

結構簡単でこれだけ

main.py

token = TK.Token()
token.loadToken(jsonPath)

auth = OAuth(token.ACCESS_TOKEN, 
             token.ACCESS_TOKEN_SECRET, 
             token.CONSUMER_KEY, 
             token.CONSUMER_SECRET_KEY)

t = Twitter(auth=auth)

タイムラインをひっぱてきて出力する

メインから関数呼べるように関数だけ

timeLine.py

def getTimeLine(t):
    
    timelines = t.statuses.home_timeline()

    for timeline in timelines:
        lang = timeline['lang']
        if lang == 'ja':
            username=timeline['user']['name']
            text=timeline['text']
            print(username + ':')
            print(text)
            print(';----------------------\n')

結構たくさん取れる情報あるからやってみるといいかも データサイエンスとかやったことないけど十分できそう

ツイートする

メインから呼べるように関数だけ

tweet.py

def tweet(t):
    while True:
        print('いまどうしてる?')
        tweet = input()
        if len(tweet) >= 140:
            print('長すぎるよ')
            print(str(len(tweet)) + '文字')
        else:
            t.statuses.update(status=tweet)
            break

すごく簡単ですね

まとめ

ほかにもtwitterいじれるライブラリはあるみたいだけどとりあえず今回はこれで

Qt5とかでGUIつくったらそれっぽくなりそう

1時間くらいで調べながらつくれたので私みたいな初心者にはちょうどいかもね

とりあえずPythonですぐ使えそうなライブラリのメモ

  • py2exe
    • exe形式にしてくれる便利そうなやつ
  • requests
    • HTTPリクエストするやつ
  • shutil *ファイル操作とかできるすげーやつ
  • dis

随時更新します

このブログの情報はあってないかもしれないので注意してください