- 投稿日:2021-12-03T23:55:07+09:00
【超初心者向け】Python if文 比較演算子まとめ
if文は、プログラムの中で条件分岐によって処理を行いたい時に使用します。 if文は、真(True)か偽(False)によって判定を行います。 (「True(真)」または「False(偽)」のいずれかの値をとる組み込み型のことを「bool型」という) 今回は、if文を書く時に初心者が覚えづらい「比較演算子」について超簡潔にまとめます。 a == b a=bであればTrue (「=」の数は2つ!) a != b a≠bであればTrue a < b aがbより小さい値であればTrue (a=bの時はFalse) a > b aがbより大きい値であればTrue (a=bの時はFalse) a =< b aがbの値以下であればTrue (a=bの時もTrue) a => b aがbの値以上であればTrue (a=bの時もTrue) a in b aがbの要素であればTrue a not in b aがbの要素でなければTrue a is b aとbが同じオブジェクトであればTrue a is not b aとbが同じオブジェクトでなければTrue
- 投稿日:2021-12-03T23:49:07+09:00
【Python】for文で回せるオブジェクト
昨日の@nyaxさんの記事は、GPT-3についてでした! MYJLab Advent Calendar 2021の4日目はPythonのfor文についてです。 はじめに Pythonのfor文は、range、リスト、辞書、文字列など様々なオブジェクトを回すことができます。 では、for文で回すことのできるオブジェクトとはどんなオブジェクトなのでしょうか。 今までなんとなーく雰囲気で使っていたfor文について整理してみました。 PythonのバージョンはPython3.8.2です。 for文で回せるのはイテラブルなオブジェクト いきなり結論を書いてしまいますが、for文で回せるのは「イテラブルなオブジェクト」です。 「イテラブルなオブジェクト」とは次のいずれかに該当するオブジェクトです。 1. __iter__ メソッドを定義したオブジェクト 2. __getitem__ メソッドをシーケンスとして定義したオブジェクト __iter__ メソッドを定義したオブジェクト このようなfor文を書いたとき iterable_object = [0, 1, 2] for elem in iterable_object: print(elem) # 0 # 1 # 2 内部ではこのように動いています。 iterable_object = [0, 1, 2] iterator = iterable_object.__iter__() # __iter__メソッドを呼び出し、イテレータを生成 while True: try: elem = iterator.__next__() # __next__メソッドを呼び出し、イテレータから要素を取り出す。要素がない場合はStopIteration例外を投げる。 except StopIteration: break print(elem) # 0 # 1 # 2 ここで「イテレータ」という単語がでてきました。 「イテレータ」とは、データの流れを表現するオブジェクトで、内部に__next__メソッドを持ちます。 __next__メソッドを繰り返し呼び出すことで、流れの中の要素を一つずつ取り出すことができます。 データがなくなると、要素を取り出す代わりにStopIteration例外を投げます。 オブジェクト内部にイテレータを生成する__iter__メソッドを実装すれば、for文で回せるオブジェクトを自作することができます。 ここでは、「クラスによる実装」と「yieldを使った実装」の2通りの方法で自作してみます。 クラスによる実装 class MyIterableObject(): def __init__(self): self._elements = ['あいうえお', 'かきくけこ', 'さしすせそ'] self._i = 0 def __iter__(self): # __next__()はselfが実装してるのでそのままselfを返す return self def __next__(self): if self._i == len(self._elements): raise StopIteration() elem = self._elements[self._i] self._i += 1 return elem iterable_object = MyIterableObject() for elem in iterable_object: print(elem) # あいうえお # かきくけこ # さしすせそ yieldを使った実装 yieldを使うことで__iter__メソッドや__next__メソッドを明示的に定義することなくイテラブルなオブジェクトを作成することができます。 def my_iterable_object(): yield 'あいうえお' yield 'かきくけこ' yield 'さしすせそ' iterable_object = my_iterable_object() for elem in iterable_object: print(elem) # あいうえお # かきくけこ # さしすせそ __getitem__ メソッドをシーケンスとして定義したオブジェクト __getitem__メソッドは、Pythonの特殊メソッドの一つで、オブジェクトに角括弧[ ]でアクセスしたときの挙動を定義できます。 class Sample: def __getitem__(self, index): if 1 <= index < 4: # [1],[2],[3]でアクセスしたときの値 return 'index is ' + str(index) else: raise IndexError sample = Sample() print(sample[1]) print(sample[2]) print(sample[3]) # index is 1 # index is 2 # index is 3 __getitem__メソッドをシーケンスとして(0から始まる連続する整数でアクセスできるように)定義すると、for文で回すことができるオブジェクトになります。 class MyIterableObject: def __init__(self): self._elements = ['あいうえお', 'かきくけこ', 'さしすせそ'] def __getitem__(self, index): if 0 <= index < 3: return self._elements[index] else: raise IndexError iterable_object = MyIterableObject() for elem in iterable_object: print(elem) # あいうえお # かきくけこ # さしすせそ 2つ以上の変数を受け取るfor文 for文で回せるオブジェクトの中には、enumerate()や辞書型.items()など、for文で回したときに変数を二つ受け取るものがあります。 これらのオブジェクトと変数を一つしか受け取らないオブジェクトは何が違うのでしょうか。 list = ['Alice', 'Bob', 'Charlie'] for index, elem in enumerate(list): print(index, elem) # 0 Alice # 1 Bob # 2 Charlie dict = {'key1': 1, 'key2': 2, 'key3': 3} for key, value in dict.items(): print(key, value) # key1 1 # key2 2 # key3 3 ここで、enumerateについて見ていきます。 enumerateオブジェクトは内部に__iter__メソッドを持っています。 enumerateオブジェクトから__iter__メソッドを呼び出し、__next__メソッドで取り出される要素を見てみます。 list = ['Alice', 'Bob', 'Charlie'] enumerate_object = enumerate(list) enumerate_object.__iter__() print(enumerate_object.__next__()) print(type(enumerate_object.__next__())) # (0, 'Alice') # <class 'tuple'> __next__メソッドでタプルが取り出されているのが分かります。 for文で回したリテラブルなオブジェクトから取り出された要素は、Pythonの標準の代入規則によって代入されます。 標準の代入規則では、シーケンス型(リスト, 文字列, タプル, range)は複数の変数への代入を一度に行えるので、その規則に則って変数が代入されます。 つまり、for文で回したオブジェクトから取り出された要素がシーケンス型(リスト, 文字列, タプル, range)であれば、for文で複数の変数を受け取ることができます。 最後に、enumerate関数もどきを自作してみたいと思います。 ※本来のenumerate関数は引数にstartを持ちますがここでは無視します。 class MyEnumerate(): def __init__(self, iterable): self._elements = iterable self._i = 0 def __iter__(self): return self def __next__(self): if self._i == len(self._elements): raise StopIteration() elem = (self._i, self._elements[self._i]) self._i += 1 return elem def my_enumerate(iterable): return MyEnumerate(iterable) list = ['Alice', 'Bob', 'Charlie'] for index, elem in my_enumerate(list): print(index, elem) # 0 Alice # 1 Bob # 2 Charlie おわりに なんとなーく雰囲気で使っていて特に困ることもなかったfor文ですが、調べてみると知らなかったことがいろいろあって面白かったです。 参考 Pythonドキュメント for文 Pythonドキュメント 用語集 iterable Pythonドキュメント イテレータ型 Pythonドキュメント __getitem__ イテラブル, iterable ってなに? Pythonのイテレータとジェネレータ
- 投稿日:2021-12-03T23:32:59+09:00
Flask入門①~文字の表示~
はじめに python自体は触れていたけど、フレームワークの知識が全くないことに気づきました。 まずは代表的なDjangoの説明を見てみたけど、いきなりこれは…ハードルが高い!と開始2秒で撃沈 フレームワーク触るのやめようと思ったけど、調べていたら「Flask」なるものを発見。 機能がもっとシンプルだし、自分でもまだ何とかなりそうと期待を持てたので学ぶことにしました。 flaskのインストール conda install flask 普段のモジュールをcondaで管理しているので、pipではなくこっちでインストール(condaでも実施確認)。 環境は以下の通り。 windows10 flask2.0.2 python3.8.10 動作確認 flask1.py #!/usr/bin/env python # -*- coding: utf-8 -*- #flaskモジュールのインポート from flask import Flask #flaskオブジェクトの作成 app = Flask(__name__) #「/」にアクセスがあったときに、'Hello world'を表示 @app.route('/') def index(): return 'Hello world' #pythonで実行されたときに処理をする if __name__ == '__main__': app.run(debug=True, host='0.0.0.0', port=5000) appという名前のオブジェクトを作成して、実行内容を書く(ここでは'Hello world'の表示)。スクリプトが実行されると、'Hello world'が表示される。 ブラウザでlocalhost:5000にアクセスすると、表示されていることを確認。 応用~おみくじの作成~ まずは簡単なものからスタート。ランダムに運勢を出してくれる、おみくじを作成してみました。 flask2.py #!/usr/bin/env python # -*- coding: utf-8 -*- #flaskモジュールのインポート from flask import Flask #flaskオブジェクトの作成 app = Flask(__name__) #「/」にアクセスがあったときに、'Hello world'を表示 @app.route('/') def index(): import random #おみくじの種類 omikuzis = ['大吉','吉','中吉','小吉','末吉','凶'] #番号をランダムに選ぶ number = random.randint(0,6) #おみくじを表示 omikuzi = omikuzis[number] print('今日の運勢は{}です。'.format(omikuzi)) #pythonで実行されたときに処理をする if __name__ == '__main__': app.run(debug=True, host='0.0.0.0', port=5000) まずは上記のコードで実施したらエラー画面が出ました。 説明分を読むと、returnで実行していないことが原因らしい。そこで次のようにコードを書き換えてみました。 #おみくじを表示 omikuzi = omikuzis[number] return '今日の運勢は'+omikuzi+'です。' これで再度localhost:5000にアクセスしたら、ちゃんと運勢が表示されてました。 吉ということでそこそこよさそう。もう1回実施してみた。 たまには小吉になることもあるようです。 まとめ Flaskが起動できた おみくじマシン作れた 次はhtmlの操作を扱ってみようと思います。
- 投稿日:2021-12-03T23:10:38+09:00
pandas.json_normalize の逆
ネストされた dict の list をいい感じにフラットにしてくれる pandas.json_normalize っていうのがあるんだけど、 https://pandas.pydata.org/pandas-docs/version/1.2.0/reference/api/pandas.json_normalize.html 元に戻す方法がないので書いた。 ちなみに数値はだいたい float64 になっちゃうので基本元の型には戻せないです。 import functools import pandas as pd def denormalize_json(df, sep="."): def _denormalize_series(sr): result = dict() def _default_dict(acc, x): if x not in acc: acc[x] = dict() return acc[x] for k, v in sr.items(): p = k.split(sep) d = functools.reduce(_default_dict, p[:-1], result) if not pd.isna(v): d[p[-1]] = v return result return [ _denormalize_series(sr) for _, sr in df.iterrows() ] In [2]: l_nested = [{'name': 'Alice', 'age': 25, 'id': {'x': 2, 'y': 8}}, ...: {'name': 'Bob', 'id': {'x': 10, 'y': 4}}] ...: l_nested Out[2]: [{'name': 'Alice', 'age': 25, 'id': {'x': 2, 'y': 8}}, {'name': 'Bob', 'id': {'x': 10, 'y': 4}}] In [3]: pd.json_normalize(l_nested) Out[3]: name age id.x id.y 0 Alice 25.0 2 8 1 Bob NaN 10 4 In [4]: denormalize_json(pd.json_normalize(l_nested)) Out[4]: [{'name': 'Alice', 'age': 25.0, 'id': {'x': 2, 'y': 8}}, {'name': 'Bob', 'id': {'x': 10, 'y': 4}}]
- 投稿日:2021-12-03T22:13:27+09:00
【Python】株価データ分析 株価チャートを描く~mplfinance編 その3~
はじめに 前回は,mplfinance を使ってローソク足,ボリンジャーバンド,MACD,RSI チャートを描いてみた 今回は一目均衡表チャートを描いてみる 一目均衡表チャートとは 五本の線とローソク足をあわせて一目均衡表チャートという 詳しい説明はこちらなどにおまかせるとして 一目均衡表チャートを描く上での最低限の用語と計算式を整理しておく 一目均衡表の五線と抵抗帯 基準線: (当日を含めた過去26日間の最高値+最安値) $\div$ 2 転換線: (当日を含めた過去9日間の最高値+最安値) $\div$ 2 先行スパン1: {(転換値+基準値) $\div$ 2}を26日先行させて表示 先行スパン2: {(当日を含めた過去52日間の最高値+最安値) $\div$ 2}を26日先行させて表示 遅行スパン: 当日の終値を26日遅行させて表示 抵抗帯: 先行スパン1と先行スパン2の間(先行スパン1と先行スパン2の間の色を塗る) 一目均衡表の五線の値を求める関数 def ichimoku(o, h, l, c): ## 当日を含めた過去26日間の最高値 ## 当日を含めた過去 9日間の最高値 ## 当日を含めた過去52日間の最高値 max26 = h.rolling(window=26).max() max9 = h.rolling(window=9).max() max52 = h.rolling(window=52).max() ## 当日を含めた過去26日間の最安値 ## 当日を含めた過去 9日間の最安値 ## 当日を含めた過去52日間の最安値 min26 = l.rolling(window=26).min() min9 = l.rolling(window=9).min() min52 = l.rolling(window=52).min() ## 基準線=(当日を含めた過去26日間の最高値+最安値)÷2 ## 転換線=(当日を含めた過去9日間の最高値+最安値)÷2 kijun = (max26 + min26) / 2 tenkan = (max9 + min9) / 2 ## 先行スパン1={(転換値+基準値)÷2}を26日先行させて表示 senkospan1 = (kijun + tenkan) / 2 senkospan1 = senkospan1.shift(26) ## 先行スパン2={(当日を含めた過去52日間の最高値+最安値)÷2}を26日先行させて表示 senkospan2 = (max52 + min52) / 2 senkospan2 = senkospan2.shift(26) ## 遅行スパン= 当日の終値を26日遅行させて表示 chikouspan = c.shift(-26) return kijun, tenkan, senkospan1, senkospan2, chikouspan 前回の,【Python】株価データ分析 株価チャートを描く~mplfinance編 その2~のコードからの主な変更点を書いておく 一目均衡表の五線の値を求める関数を呼び出し # 一目均衡表 kijun, tenkan, senkospan1, senkospan2, chikouspan = ichimoku(o, h, l, c) プロットを作成する際に,mplfinance.make_addplot を呼ぶが, 一目均衡表の五線をプロットする際のパラメータ辞書を用意して,プロットする ボリンジャーバンドは ±2σ のみの表示に変更する(チャートがゴチャゴチャするので) # 一目均衡表 axes No.1 に描く ichimokuargs = dict(ax=ax1, width=.5) # プロットを作成する(ボリンジャーバンド,MACD,RSI,一目均衡表) ap = [ ## mpf.make_addplot(bbh1, **bbargs), ## mpf.make_addplot(bbl1, **bbargs), mpf.make_addplot(bbh2, **bbargs), mpf.make_addplot(bbl2, **bbargs), ## mpf.make_addplot(bbh3, **bbargs), ## mpf.make_addplot(bbl3, **bbargs), mpf.make_addplot(macd_, **macdargs, color='blue'), mpf.make_addplot(macdsignal, **macdargs, color='orange'), mpf.make_addplot(histogramplus, **macdargs, color='red', type='bar'), mpf.make_addplot(histogramminus, **macdargs, color='green', type='bar'), mpf.make_addplot(rsi_, **rsiargs, color='blue'), mpf.make_addplot(kijun, **ichimokuargs, color='orange'), mpf.make_addplot(tenkan, **ichimokuargs, color='royalblue'), mpf.make_addplot(senkospan1, **ichimokuargs, color='black'), mpf.make_addplot(senkospan2, **ichimokuargs, color='purple'), mpf.make_addplot(chikouspan, **ichimokuargs, color='red') ] 先行スパン1と先行スパン2の間を塗りつぶす # 一目均衡表(axes=1)の先行スパン1と先行スパン2の間を塗りつぶす ax1.fill_between(x=range(0, len(df.index)), y1=senkospan1.values, y2=senkospan2.values, alpha=0.5, color='gray') まとめ import numpy as np import pandas as pd import pandas_datareader.data as pdr import datetime from dateutil.relativedelta import relativedelta import matplotlib.pyplot as plt import mplfinance as mpf # 12か月チャート month = 12 # チャートの基本設定 kwargs = dict(type = 'candle', style = 'yahoo') ## starsandstripes, yahoo # 12か月前から本日までのデータを取得する ed = datetime.datetime.now() st = ed - relativedelta(months = month) # トヨタ df = pdr.DataReader('7203.T', 'yahoo', st, ed) def bollingerband(c, period): bbma = c.rolling(window=period).mean() ## 平均 bbstd = c.rolling(window=period).std() ## 標準偏差 bbh1 = bbma + bbstd * 1 bbl1 = bbma - bbstd * 1 bbh2 = bbma + bbstd * 2 bbl2 = bbma - bbstd * 2 bbh3 = bbma + bbstd * 3 bbl3 = bbma - bbstd * 3 return bbh1,bbl1,bbh2,bbl2,bbh3,bbl3 def macd(c, n1, n2, ns): ema_short = c.ewm(span=n1,adjust=False).mean() ema_long = c.ewm(span=n2,adjust=False).mean() macd = ema_short - ema_long signal = macd.ewm(span=ns,adjust=False).mean() histogram = macd - signal histogramplus = histogram.where(histogram > 0, 0) histogramminus = histogram.where(histogram < 0, 0) return macd,signal,histogram,histogramplus,histogramminus def rsi(c, period): diff = c.diff() #前日比 up = diff.copy() #上昇 down = diff.copy() #下落 up = up.where(up > 0, np.nan) #上昇以外はnp.nan down = down.where(down < 0, np.nan) #下落以外はnp.nan #upma = up.rolling(window=period).mean() #平均 #downma = down.abs().rolling(window=period).mean() #絶対値の平均 upma = up.ewm(span=period,adjust=False).mean() #平均 downma = down.abs().ewm(span=period,adjust=False).mean() #絶対値の平均 rs = upma / downma rsi = 100 - (100 / (1.0 + rs)) return rsi def ichimoku(o, h, l, c): ## 当日を含めた過去26日間の最高値 ## 当日を含めた過去 9日間の最高値 ## 当日を含めた過去52日間の最高値 max26 = h.rolling(window=26).max() max9 = h.rolling(window=9).max() max52 = h.rolling(window=52).max() ## 当日を含めた過去26日間の最安値 ## 当日を含めた過去 9日間の最安値 ## 当日を含めた過去52日間の最安値 min26 = l.rolling(window=26).min() min9 = l.rolling(window=9).min() min52 = l.rolling(window=52).min() ## 基準線=(当日を含めた過去26日間の最高値+最安値)÷2 ## 転換線=(当日を含めた過去9日間の最高値+最安値)÷2 kijun = (max26 + min26) / 2 tenkan = (max9 + min9) / 2 ## 先行スパン1={(転換値+基準値)÷2}を26日先行させて表示 senkospan1 = (kijun + tenkan) / 2 senkospan1 = senkospan1.shift(26) ## 先行スパン2={(当日を含めた過去52日間の最高値+最安値)÷2}を26日先行させて表示 senkospan2 = (max52 + min52) / 2 senkospan2 = senkospan2.shift(26) ## 遅行スパン= 当日の終値を26日遅行させて表示 chikouspan = c.shift(-26) return kijun, tenkan, senkospan1, senkospan2, chikouspan # float 型に df['Open'] = df['Open'].astype(float) df['High'] = df['High'].astype(float) df['Low'] = df['Low'].astype(float) df['Close'] = df['Close'].astype(float) o = df['Open'] c = df['Close'] l = df['Low'] h = df['High'] ''' チャートを描く ''' # ボリンジャーバンド(移動平均25日線) bbh1, bbl1, bbh2, bbl2, bbh3, bbl3 = bollingerband(c, 25) # MACD(短期=12,長期=26,シグナル=9) macd_, macdsignal, histogram, histogramplus, histogramminus = macd(c, 12, 26, 9) # RSI(14日) rsi_ = rsi(c, 14) # 一目均衡表 kijun, tenkan, senkospan1, senkospan2, chikouspan = ichimoku(o, h, l, c) # 高さの比を 3:1:1 で GridSpec を用意する fig = mpf.figure(figsize=(9.6, 9.6), style='starsandstripes') gs = fig.add_gridspec(3, 1, hspace=0, wspace=0, height_ratios=(3, 1, 1)) (ax1,ax2,ax3) = gs.subplots(sharex='col') # ボリンジャーバンドは axes No.1 に描く bbargs = dict(ax=ax1, width=.5, linestyle='dashdot', color='black') # MACD は axes No.2 に描く macdargs = dict(ax=ax2, width=1, ylabel='MACD') # RSI は axes No.3 に描く rsiargs = dict(ax=ax3, width=1, ylabel='RSI') # 一目均衡表 axes No.1 に描く ichimokuargs = dict(ax=ax1, width=.5) # プロットを作成する(ボリンジャーバンド,MACD,RSI,一目均衡表) ap = [ mpf.make_addplot(bbh2, **bbargs), mpf.make_addplot(bbl2, **bbargs), mpf.make_addplot(macd_, **macdargs, color='blue'), mpf.make_addplot(macdsignal, **macdargs, color='orange'), mpf.make_addplot(histogramplus, **macdargs, color='red', type='bar'), mpf.make_addplot(histogramminus, **macdargs, color='green', type='bar'), mpf.make_addplot(rsi_, **rsiargs, color='blue'), mpf.make_addplot(kijun, **ichimokuargs, color='orange'), mpf.make_addplot(tenkan, **ichimokuargs, color='royalblue'), mpf.make_addplot(senkospan1, **ichimokuargs, color='black'), mpf.make_addplot(senkospan2, **ichimokuargs, color='purple'), mpf.make_addplot(chikouspan, **ichimokuargs, color='red') ] # RSI(axes=3) の25%と75%に線を引く ax3.hlines(xmin=0, xmax=len(df.index), y=25, linewidth=1, color='red') ax3.hlines(xmin=0, xmax=len(df.index), y=75, linewidth=1, color='red') # 一目均衡表(axes=1)の先行スパン1と先行スパン2の間を塗りつぶす ax1.fill_between(x=range(0, len(df.index)), y1=senkospan1.values, y2=senkospan2.values, alpha=0.5, color='gray') # ローソク足を描く,用意したプロットを渡す mpf.plot(df, ax=ax1, addplot=ap, style='starsandstripes', type='candle', xrotation=30, ylabel='Price') mpf.show() このようなチャートが描かれる おわりに 一目均衡表を描くことはできたが, 抵抗帯の未来の部分が描けていないのがいけてない… 次回はこの問題を解決してみたい
- 投稿日:2021-12-03T22:11:55+09:00
fairseqの使い方
はじめに faiseqを使ってFusion-in-decoderを実装しようとしたら予想以上に苦労したのでfairseqにあるクラスファイルについて細かく説明する. dataloaderはどこにあるのか, そもそものデータの読み込みはどこで行っているのか, モデルはどこで定義されているのか, などコードリーディングの負荷を下げるためのメモ程度に書いていく. 目次 fairseqとは 簡単な使い方 各種ファイルの役割 faieseqとは 翻訳, 要約, 言語モデリング, その他のテキスト生成タスクのためにモデルをトレーニングすることができる自然言語処理向けのツールキットのこと. pytorchベースで作成されているので一部分のみを使うこと, モデルやタスクを自分で定義してトレーニングや評価することが可能 fairseq用のクラスを定義して用いてるので細かい部分で融通が利かないのが難点. 簡単な使い方 インストールからモデルの学習, テストによる評価までを簡単に書いていく. 細かい説明はドキュメントがあるので省略する. 1. fairseqのインストール gitからcloneすることでインストールを行う. pipのみでインストールすることもできるが, gitからcloneすることを推奨. git clone https://github.com/pytorch/fairseq cd fairseq pip install --editable ./ 上記コマンドでは最新版がインストールされることに注意 インストールが正常に終了すればコマンドプロンプトでfairseqのコマンドが使用できる command not foundが出たらインストールできていないのでインストールからやり直す必要がある. C:User> fairseq-train 2. データセットの作成 fairseqで処理できるにデータセットを作成する必要がある. データセットはsrcとtgtの二つに分けてtrain.src, train.tgtのように作成する. train.src モデルへの入力文A モデルへの入力文B モデルへの入力文C train.tgt モデルの出力A モデルの出力B モデルの出力C train.srcのN行目とtrain.tgtのN行目が一つのペアとなる preprocessは最低限以下のコマンドのように指定すればいい. pref : 各ファイルのpath destdir : 作成したデータセットの保存先 task : 翻訳, 分類,などモデルに学習させるタスクの種類 fairseq-preprocess --trainpref dataset/raw/train \ --validpref dataset/raw/valid \ --testpref dataset/raw/test \ --source-lang src --target-lang tgt \ --destdir dataset/tokenized \ --srcdict dataset/dict.src.txt \ --tgtdict dataset/dict.dst.txt \ --task translation 3. モデルのトレーニング 今回は1つのGPUを使って学習する場合について記載する. teeやリダイレクトを使ってログを取っておくことを推奨. arch : 使用するモデルのアーキテクチャを指定 restore-file : 事前学習済みのものをfinetuneするならファイルを指定 lr : learning rateの初期値, default=0.25となってるから指定することを推奨 max-epoch : epoch数の指定, 指定しないと永遠に学習を続けるので適当に値を入れておくといい fairseq-train dataset/tokenized/ \ --task translation \ --arch transformer \ --restore-file model/model.pt \ --reset-optimizer --reset-dataloader --reset-lr-scheduler \ --source-lang src --target-lang dst \ --max-epoch 20 \ --lr 1e-4 \ | tee train.log 4. モデルの評価 評価についても1つのGPUを用いて行う. モデルのトレーニングと同様にtee, リダイレクトを用いることを推奨. path : 評価するモデルの相対パス gen-subset : 使用するデータセットの指定(ex. train, valid, test) fairseq-generate dataset/tokenized --path checkpoint/checkpoint_best.pt \ --task translation \ --gen-subset test \ -s src -t tgt \ > result.txt 各種ファイルの役割 fairseqはpytorchをベースにしているため拡張性は高いが, 独自のクラスを定義するため一部のみを利用したり, 細かい部分で書き換えるときに参照すべきファイルが多い. ここではtasks, models, criterions, dataなど各フォルダの中でメインとなる部分について説明していく. 1. ディレクトリ構造について(一部省略) 基本的には下記のファイルとディレクトリについて理解しておけば十分. 特にtasksは各クラスとの関係性が強いのでtasksを中心に各ファイルについて詳細を説明する. fairseq_cliはfairseqディレクトリの処理内容が分かれば理解しやすいので省略する fairseq/ ├ fairseq ├ criterions #lossの算出方法などのファイルがあるディレクトリ ├ data #dataloader, ファイルからデータの読み込みなどを行う ├ models #モデルの定義ファイルのあるディレクトリ └ tasks #タスク(翻訳, 分類, etc..)の定義のあるディレクトリ └ fairseq_cli ├ preprocess.py #データセット作成時に実行したプログラム ├ train.py #モデルのトレーニング時に実行したプログラム └ generate.py #モデルの評価時に実行したプログラム 2. tasks taskクラスを基にデータセットの読み込み, モデルの読み込みなど行う. fairseq_task.pyにあるFairseqTaskクラスがtaskの基準となるため, FairseqTaskクラスを継承すればtaskを個人で定義することが可能. load_dataset関数内でload_langpair_dataset関数が呼び出されることでデータの読み込みを行うのでここは詳しく確認する必要はない def load_dataset(self, split, epoch=1, combine=False, **kwargs): """Load a given dataset split. Args: split (str): name of the split (e.g., train, valid, test) """ taskを個人で定義する場合は以下のリンクを参照すればいい. 今回はdataloader, datasetの読み込み時についてなので省略する. 3. data language_pair_dataset.py, indexed_dataset.py, prepend_token_dataset.pyの3つについて定義されている関数や, 各ファイルの役割について説明する language_pair_dataset.py indexed_dataset.pyで一つ一つのファイルから読み込みを行うが実際にデータセットとして管理するのはlanguage_pair_datasetで行われる. train.srcとtrain.tgtの2つのファイルを繋げるための役割を担っている. class LanguagePairDataset(FairseqDataset): def __init__(...): ...省略... データの取り出しはgetitem()を使っている. しかし, 実際にモデルの入力として渡されるのはここの返却値であるexampleではないこと注意が必要 class LanguagePairDataset(FairseqDataset): def __getitem__(self, index): tgt_item = self.tgt[index] if self.tgt is not None else None src_item = self.src[index] ...省略... example = { "id": index, "source": src_item, "target": tgt_item, } retrun example dataloaderを定義する際にlanguage_pair_dataset.pyにあるcollate()が呼ばれるように設定される. 上記のexampleを受け取り, モデルへの入力にするために変換する関数として作用する. 具体的にはbatchにあるnet_inputがモデルへの入力として用いられる. def collate(...): ...省略... batch = { "id": id, "nsentences": len(samples), "ntokens": ntokens, "net_input": { "src_tokens": src_tokens, "src_lengths": src_lengths, }, "target": target, } ...省略... return batch indexed_dataset.py ここでfairseq-preprocess時に作成したファイルを参照し, datasetとして読み込む dataset-implによって作成されるデータセットの型が変わるが, fairseq-preprocess時にdataset-implを指定しない場合はIndexedRawTextDatasetになるため基本的にはここを見ればいい. class IndexedRawTextDataset(FairseqDataset): def read_data(self, path, dictionary): ...省略... ここでファイルからデータを読み込んでいる, train.srcとtrain.tgtのどちらもこの関数を用いるのでプログラムを書き換える際には注意が必要. prepend_token_dataset.py データセットからデータが読み込まれる際はこのファイルにあるgetitem()などが呼ばれる. データセットの形を変えた場合この部分も同様に変更する必要がある. idxはデータセットから取り出すデータのidでありint型. def __getitem__(self, idx): item = self.dataset[idx] if self.token is not None: item = torch.cat([item.new([self.token]), item]) return 4. criterions lossの算出方法が定義されているフォルダ, defaultではcross_entropy.pyを呼び出される. modelからfoward()を呼び出すのではなく, criterionsを通してmodelのfoward()が呼ばれるので処理順で確認するならばcriterionsを見ることを推奨する. sampleはlanguage_pair_datasetのcollate()で変換されたbatchに対応している. class CrossEntropyCriterion(FairseqCriterion): def __init__(self, task, sentence_avg): super().__init__(task) self.sentence_avg = sentence_avg def forward(self, model, sample, reduce=True): net_output = model(**sample["net_input"]) ...省略... 5. model modelにはfairseq_encoder.pyやtransformer_lm.pyなどモデルを定義する際に用いられるモジュールと, BART, RoBERTa, Wav2Vecなどの定義済みモデルがある. 定義済みモデルはフォルダで分けられているので, 同様にモデルを作成することが可能. class TransformerModelBase(FairseqEncoderDecoderModel): """ Transformer model from `"Attention Is All You Need" (Vaswani, et al, 2017) <https://arxiv.org/abs/1706.03762>`_. """ def forward( self, src_tokens, src_lengths, prev_output_tokens, return_all_hiddens: bool = True, features_only: bool = False, alignment_layer: Optional[int] = None, alignment_heads: Optional[int] = None, ): encoder_out = self.encoder( src_tokens,src_lengths=src_lengths,return_all_hiddens=return_all_hiddens) decoder_out = self.decoder( prev_output_tokens, encoder_out=encoder_out, features_only=features_only, alignment_layer=alignment_layer, alignment_heads=alignment_heads, src_lengths=src_lengths, return_all_hiddens=return_all_hiddens, ) return decoder_out 各ファイルにあるfoward()を確認すれば処理の内容が分かる. 上記はtrnasformerなのでencoderとdecoderから構成されており, encoderの出力とdecoderの入力をつなげている. 関数にある引数はcritrionsで呼んでいるsample['net_input']を受け取るようなっているので, 実質はcollate()で返却されるbatchのnet_inputと同じ値となる. おわりに 基本的にはデータの読み込みからモデルの出力を流れを追う際に見るべきファイルについて説明したが, 細かい処理の内容については複雑になるので省略したので悪しからず. Fusion-in-Decoderの実装手順については別記事?で書くかもしれない. fairseq_trainのコマンドを追うように説明したので処理を理解する助けになることを祈ってます.
- 投稿日:2021-12-03T21:17:15+09:00
【Python】BeautifulSoupを使ってスクレイピングで気象データを取得
概要 スクレイピングとはWebサイトからデータを取得すること。 Webスクレイピングとも呼ばれます。 サイトによっては禁止されている場合やマナーなどがあるので、使うときは注意が必要です。 今回はBeautifulSoupとurllib.requestいうモジュールを使って気象データを取得します。 最終的にこのようなCSVファイルを作成しました。 sample.csv 日時,現地気圧,海面気圧,降水量,平均気温,最高気温,最低気温,湿度,平均風速,最大風速,最大風向,日照時間 2020-01-01,1018.0,1021.0,--,5.5,10.2,3.2,49,2.6,6.1,337.5,7.4 ... Pythonで実装 今回は気象庁HPより、表になったデータを取得しました。 BeautifulSoupとurllib.requestがない場合はpipなどで入れてください。 pip公式では下記のように書かれていました。 bash pip install beautifulsoup4 pip install pycopy-urllib.request それでは実装していきます。 scraping.py import urllib.request from bs4 import BeautifulSoup url = "https://..." html = urllib.request.urlopen(url).read() soup = BeautifulSoup(html, "lxml") tbl = soup.find("table", { "class" : "data2_s" }) for tr in tbl.findAll('tr'): tdList = tr.findAll('td') print(tdList[0].string) urllib.requestでhtmlコードを取得し、BeautifulSoupで解析していきます。 第二引数には下記があります。必要なライブラリがない場合はエラーを吐きます。 lxml html.parser xml html5lib 変数soupにはBeautifulSoupによって綺麗なコードが格納されています。 これを加工してデータを取得できます。 今回は表なので、htmlから表の部分を取り出し、trの中にあるtdを取得します。 findAllにはリスト型で入っているので、欲しい要素番号を指定しましょう。 stringをつけることで文字列になります。 これをCSVモジュール等でファイルに書き出せば、冒頭のようなCSVファイルを作成することができます。 詳しい説明はこちらでしています。 まとめ PythonのBeautifulSoupを使って超簡単にスクレイピングを実現できました。 データ取得が自動化できるのはかなりありがたいですね。 その他 ブログに詳細版を書いています。詳しい説明が欲しい方は是非ご覧ください。 今回実装したソースコードはGitHubにも置いてあります。 作成にあたり、下記サイトを参考にさせていただきました。 この場を借りて感謝申し上げます。
- 投稿日:2021-12-03T20:58:57+09:00
blenderで縦書きテキストを作るアドオンを書いたよ
まえがき この記事は、 QiitaのBlender Advent Calendar 2021 の6日目と、 BLUGjpさん主催のBlender Advent Calendar 2021 の4日目の記事です。 さて今年のアドベントカレンダーが始まって少し立ちましたね。 あんまりエントリーが集まらない事に時代の流れを感じます。 かつて「俺だけが良さを知っているんだ…」という気分で使っていたblenderもどんどんメジャーになっていって日々話題に事欠かなくなったのであんまりアドベントカレンダーのお祭り感がなくなったのかなと思っているblender厄介オタクです。 記事概要 この記事では私が実装したtategaki text toolsアドオンを紹介します。 このアドオン何ができるかというと、blender上で縦書きテキストの作成が出来ます。 まず、blenderのテキストオブジェクトって縦書きに対応してませんよね。 これが地味に不便だなーと思っていて、無理やり素のblenderで縦書きテキストを作ろうと思うと1文字ずつ改行する必要があるので面倒だし、複数行にしようとするとレイアウトが汚くてイマイチになる… これらを解決してblender上で縦書きテキストオブジェクトの作成、レイアウトの調整、メッシュなどへ変換する機能を実装しました 出来上がったもの 機能紹介 以下機能は縦書きテキストのコンテナ(エンプティオブジェクト)を選択状態で使えます 縦書きテキストに変換 選択テキストオブジェクトから縦書きテキストを生成 テキストオブジェクトのフォントやマテリアルを引き継いだ状態で生成することができます 分割解像度だけ、縦書きテキスト生成時に重くなるので下げて生成します 縦書きテキストを複製 選択された縦書きテキストから新規に縦書きテキストを生成 単純にコレクションとか、選択して複製するとIDかぶりするので同じ状態のオブジェクトをIDを変えて再生成します 行間調整 行間を調整する 字間調整 字間、自動カーニングの有無を調整する 固定値での文字配置と、グリフの大きさを基準にした文字配置の調整ができます グリフの大きさ(というか高さ)をいちいち計算すると重かったのでキャッシュするようになっています 行文字数調整 縦書きテキストの 1 行あたりの文字数制限を調整する 作文用紙みたいに一定の文字数で改行したいときに調整します 内部データの行を分割して改行表示しているので一応非破壊に調整できます 変換 縦書きテキストを単一のオブジェクトにそれぞれ変換する メッシュ カーブ gpencil 縦書きテキストオブジェクトは大量のテキストオブジェクトで構成されているので、作りっぱなしにしているとオブジェクトの参照などが遅くなっていきます。 なので必要に応じてメッシュやカーブに変換しておくと良いです。 gpencilへの変換は、例えばgpencilで漫画を描いたときに文字入れするのに使えないかなと思って実装してみました。 あとがき そんな難しくないだろうと思って実装し始めたら結構たいへんでした 縦書き時に回転する文字とか位置の調整が必要な句読点など細かい工夫があります 愚直に実装すると動作が重くなりすぎるので細かい軽量化や最適化をしてあります(bpy.opsで処理すると重い部分をbpy.dataで代替する処理を色々実装) コア部分で1200行を越えててでか過ぎるなーと思いつつファイルを分割するとアドオン開発時にリロードがうまく行かなくなったりそもそも分割する領域が定かじゃないので手が付けられない… 本文編集機能も実装したいなーと思いつつめんどくささが勝っているのでしばらくはやらないと思います この記事とは別に、つい最近rename toolというアドオンを書いたのでちょっと紹介 https://github.com/nepia11/rename_tool ざっくり紹介すると、非ascii文字を含む語句を含むアイテム名(オブジェクトとかモディファイアとか色々)を一括置換するツールです blendファイル内のマルチバイト文字を一層したいときに使えます それでは
- 投稿日:2021-12-03T20:41:03+09:00
rhel7でdnfコマンドを使いたい
OS Red Hat Enterprise Linux Server release 7.7 注意事項 コマンドの実行順番に気を付ける ・librepoやlibcomp関連パッケージの前にpython-libcompのパッケージをインストールしない(エラーになります) ・librepoやlibcomp、python-libcomp関連パッケージの前に yum install python-dnf-0.6.4-2.sdl7.noarch.rpm dnf-0.6.4-2.sdl7.noarch.rpm dnf-conf-0.6.4-2.sdl7.noarch.rpm これ実行しないように(エラーになります) 入力コマンド 実際に入力するコマンド yum install wget wget http://springdale.math.ias.edu/data/puias/unsupported/7/x86_64/python-dnf-0.6.4-2.sdl7.noarch.rpm wget http://springdale.math.ias.edu/data/puias/unsupported/7/x86_64/dnf-0.6.4-2.sdl7.noarch.rpm wget http://springdale.math.ias.edu/data/puias/unsupported/7/x86_64/dnf-conf-0.6.4-2.sdl7.noarch.rpm wget http://ftp.riken.jp/Linux/centos/7/updates/x86_64/Packages/python-librepo-1.8.1-8.el7_9.x86_64.rpm wget --no-check-certificate https://cbs.centos.org/kojifiles/packages/libcomps/0.1.6/13.el7.centos/x86_64/python-libcomps-0.1.6-13.el7.centos.x86_64.rpm wget --no-check-certificate https://cbs.centos.org/kojifiles/packages/libcomps/0.1.6/13.el7.centos/x86_64/libcomps-devel-0.1.6-13.el7.centos.x86_64.rpm wget --no-check-certificate https://cbs.centos.org/kojifiles/packages/libcomps/0.1.6/13.el7.centos/x86_64/libcomps-debuginfo-0.1.6-13.el7.centos.x86_64.rpm wget --no-check-certificate https://cbs.centos.org/kojifiles/packages/libcomps/0.1.6/13.el7.centos/x86_64/libcomps-0.1.6-13.el7.centos.x86_64.rpm yum install python-librepo-1.8.1-8.el7_9.x86_64.rpm yum install libcomps-0.1.6-13.el7.centos.x86_64.rpm libcomps-debuginfo-0.1.6-13.el7.centos.x86_64.rpm libcomps-devel-0.1.6-13.el7.centos.x86_64.rpm yum install python-libcomps-0.1.6-13.el7.centos.x86_64.rpm yum install python-dnf-0.6.4-2.sdl7.noarch.rpm dnf-0.6.4-2.sdl7.noarch.rpm dnf-conf-0.6.4-2.sdl7.noarch.rpm 参考リンク RPMパッケージ http://ftp.riken.jp/Linux/centos/7/updates/x86_64/Packages/ https://buildlogs.centos.org/c7-extras.x86_64/libcomps/20170127101611/0.1.6-13.el7.x86_64/ dnfコマンド必要パッケージ参考 https://re-engines.com/2018/06/25/centos7%E3%81%A7web%E3%82%B5%E3%83%BC%E3%83%90%E3%81%AE%E5%88%9D%E6%9C%9F%E8%A8%AD%E5%AE%9A/ https://qiita.com/skanno/items/7ac41c7e6a12bcfcfed3 おまけ 実際にした実行の出力結果を含めたログを添付いたします [root@ip-10-0-1-244 ec2-user]# yum install wget Loaded plugins: amazon-id, search-disabled-repos rhui-client-config-server-7 | 2.1 kB 00:00:00 rhui-rhel-7-server-rhui-rh-common-rpms | 2.1 kB 00:00:00 rhui-rhel-7-server-rhui-rpms | 2.0 kB 00:00:00 (1/9): rhui-client-config-server-7/x86_64/updateinfo | 92 B 00:00:00 (3/9): rhui-client-config-server-7/x86_64/primary 0% [ ] 0.0 B/s | 92 B --:--:-- ETA (2/9): rhui-client-config-server-7/x86_64/group | 124 B 00:00:00 (3/9): rhui-client-config-server-7/x86_64/primary | 3.0 kB 00:00:00 (5/9): rhui-rhel-7-server-rhui-rh-common-rpms/7Server/x86_64/update 0% [ ] 4.7 kB/s | 3.3 kB 03:34:46 ETA (4/9): rhui-rhel-7-server-rhui-rh-common-rpms/7Server/x86_64/group | 124 B 00:00:00 (5/9): rhui-rhel-7-server-rhui-rh-common-rpms/7Server/x86_64/updateinfo | 35 kB 00:00:00 (6/9): rhui-rhel-7-server-rhui-rh-common-rpms/7Server/x86_64/primary | 68 kB 00:00:00 (8/9): rhui-rhel-7-server-rhui-rpms/7Server/x86_64/updateinfo 0% [ ] 25 kB/s | 106 kB 00:40:46 ETA (7/9): rhui-rhel-7-server-rhui-rpms/7Server/x86_64/group | 773 kB 00:00:00 (8/9): rhui-rhel-7-server-rhui-rpms/7Server/x86_64/updateinfo | 4.1 MB 00:00:00 (9/9): rhui-rhel-7-server-rhui-rpms/7Server/x86_64/primary 69% [=======================================- ] 8.2 MB/s | 41 MB 00:00:02 ETA (9/9): rhui-rhel-7-server-rhui-rpms/7Server/x86_64/primary | 54 MB 00:00:00 rhui-client-config-server-7: [####### ] 1/18rhui-client-config-server-7: [############## ] 2/18rhui-client-config-server-7: [##################### ] 3/18rhui-client-config-server-7: [############################ ] 4/18rhui-client-config-server-7: [################################### ] 5/18rhui-client-config-server-7: [########################################## ] 6/18rhui-client-config-server-7: [################################################# ] 7/18rhui-client-config-server-7: [######################################################## ] 8/18rhui-client-config-server-7: [############################################################### ] 9/18rhui-client-config-server-7: [###################################################################### ] 10/18rhui-client-config-server-7: [############################################################################# ] 11/18rhui-client-config-server-7: [#################################################################################### ] 12/18rhui-client-config-server-7: [########################################################################################### ] 13/18rhui-client-config-server-7: [################################################################################################## ] 14/18rhui-client-config-server-7: [######################################################################################################### ] 15/18rhui-client-config-server-7: [################################################################################################################ ] 16/18rhui-client-config-server-7: [####################################################################################################################### ] 17/18rhui-client-config-server-7 18/18 rhui-rhel-7-server-rhui-rh-common-rpms: [ ] 1/243rhui-rhel-7-server-rhui-rh-common-rpms: [ ] 2/243rhui-rhel-7-server-rhui-rh-common-rpms: [# ] 3/243rhui-rhel-7-server-rhui-rh-common-rpms: [# ] 4/243rhui-rhel-7-server-rhui-rh-common-rpms: [## ] 5/243rhui-rhel-7-server-rhui-rh-common-rpms: [## ] 6/243rhui-rhel-7-server-rhui-rh-common-rpms: [### ] 7/243rhui-rhel-7-server-rhui-rh-common-rpms: [### ] 8/243rhui-rhel-7-server-rhui-rh-common-rpms: [#### ] 9/243rhui-rhel-7-server-rhui-rh-common-rpms: [#### ] 10/243rhui-rhel-7-server-rhui-rh-common-rpms: [##### ] 11/243rhui-rhel-7-server-rhui-rh-common-rpms: [##### ] 12/243rhui-rhel-7-server-rhui-rh-common-rpms: [###### ] 13/243rhui-rhel-7-server-rhui-rh-common-rpms: [###### ] 14/243rhui-rhel-7-server-rhui-rh-common-rpms: [####### ] 15/243rhui-rhel-7-server-rhui-rh-common-rpms: [####### ] 16/243rhui-rhel-7-server-rhui-rh-common-rpms: [####### ] 17/243rhui-rhel-7-server-rhui-rh-common-rpms: [######## ] 18/243rhui-rhel-7-server-rhui-rh-common-rpms: [######## ] 19/243rhui-rhel-7-server-rhui-rh-common-rpms: [######### ] 20/243rhui-rhel-7-server-rhui-rh-common-rpms: [######### ] 21/243rhui-rhel-7-server-rhui-rh-common-rpms: [########## ] 22/243rhui-rhel-7-server-rhui-rh-common-rpms: [########## ] 23/243rhui-rhel-7-server-rhui-rh-common-rpms: [########### ] 24/243rhui-rhel-7-server-rhui-rh-common-rpms: [########### ] 25/243rhui-rhel-7-server-rhui-rh-common-rpms: [############ ] 26/243rhui-rhel-7-server-rhui-rh-common-rpms: [############ ] 27/243rhui-rhel-7-server-rhui-rh-common-rpms: [############# ] 28/243rhui-rhel-7-server-rhui-rh-common-rpms: [############# ] 29/243rhui-rhel-7-server-rhui-rh-common-rpms: [############## ] 30/243rhui-rhel-7-server-rhui-rh-common-rpms: [############## ] 31/243rhui-rhel-7-server-rhui-rh-common-rpms: [############### ] 32/243rhui-rhel-7-server-rhui-rh-common-rpms: [############### ] 33/243rhui-rhel-7-server-rhui-rh-common-rpms: [############### ] 34/243rhui-rhel-7-server-rhui-rh-common-rpms: [################ ] 35/243rhui-rhel-7-server-rhui-rh-common-rpms: [################ ] 36/243rhui-rhel-7-server-rhui-rh-common-rpms: [################# ] 37/243rhui-rhel-7-server-rhui-rh-common-rpms: [################# ] 38/243rhui-rhel-7-server-rhui-rh-common-rpms: [################## ] 39/243rhui-rhel-7-server-rhui-rh-common-rpms: [################## ] 40/243rhui-rhel-7-server-rhui-rh-common-rpms: [################### ] 41/243rhui-rhel-7-server-rhui-rh-common-rpms: [################### ] 42/243rhui-rhel-7-server-rhui-rh-common-rpms: [#################### ] 43/243rhui-rhel-7-server-rhui-rh-common-rpms: [#################### ] 44/243rhui-rhel-7-server-rhui-rh-common-rpms: [##################### ] 45/243rhui-rhel-7-server-rhui-rh-common-rpms: [##################### ] 46/243rhui-rhel-7-server-rhui-rh-common-rpms: [###################### ] 47/243rhui-rhel-7-server-rhui-rh-common-rpms: [###################### ] 48/243rhui-rhel-7-server-rhui-rh-common-rpms: [###################### ] 49/243rhui-rhel-7-server-rhui-rh-common-rpms: [####################### ] 50/243rhui-rhel-7-server-rhui-rh-common-rpms: [####################### ] 51/243rhui-rhel-7-server-rhui-rh-common-rpms: [######################## ] 52/243rhui-rhel-7-server-rhui-rh-common-rpms: [######################## ] 53/243rhui-rhel-7-server-rhui-rh-common-rpms: [######################### ] 54/243rhui-rhel-7-server-rhui-rh-common-rpms: [######################### ] 55/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################## ] 56/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################## ] 57/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################### ] 58/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################### ] 59/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################ ] 60/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################ ] 61/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################# ] 62/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################# ] 63/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################## ] 64/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################## ] 65/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################## ] 66/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################### ] 67/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################### ] 68/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################ ] 69/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################ ] 70/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################# ] 71/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################# ] 72/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################## ] 73/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################## ] 74/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################### ] 75/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################### ] 76/243rhui-rhel-7-server-rhui-rh-common-rpms: [#################################### ] 77/243rhui-rhel-7-server-rhui-rh-common-rpms: [#################################### ] 78/243rhui-rhel-7-server-rhui-rh-common-rpms: [##################################### ] 79/243rhui-rhel-7-server-rhui-rh-common-rpms: [##################################### ] 80/243rhui-rhel-7-server-rhui-rh-common-rpms: [###################################### ] 81/243rhui-rhel-7-server-rhui-rh-common-rpms: [###################################### ] 82/243rhui-rhel-7-server-rhui-rh-common-rpms: [###################################### ] 83/243rhui-rhel-7-server-rhui-rh-common-rpms: [####################################### ] 84/243rhui-rhel-7-server-rhui-rh-common-rpms: [####################################### ] 85/243rhui-rhel-7-server-rhui-rh-common-rpms: [######################################## ] 86/243rhui-rhel-7-server-rhui-rh-common-rpms: [######################################## ] 87/243rhui-rhel-7-server-rhui-rh-common-rpms: [######################################### ] 88/243rhui-rhel-7-server-rhui-rh-common-rpms: [######################################### ] 89/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################################## ] 90/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################################## ] 91/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################################### ] 92/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################################### ] 93/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################ ] 94/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################ ] 95/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################# ] 96/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################# ] 97/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################# ] 98/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################## ] 99/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################## ] 100/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################## ] 101/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################### ] 102/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################### ] 103/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################ ] 104/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################ ] 105/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################# ] 106/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################# ] 107/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################## ] 108/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################## ] 109/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################### ] 110/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################### ] 111/243rhui-rhel-7-server-rhui-rh-common-rpms: [#################################################### ] 112/243rhui-rhel-7-server-rhui-rh-common-rpms: [#################################################### ] 113/243rhui-rhel-7-server-rhui-rh-common-rpms: [##################################################### ] 114/243rhui-rhel-7-server-rhui-rh-common-rpms: [##################################################### ] 115/243rhui-rhel-7-server-rhui-rh-common-rpms: [##################################################### ] 116/243rhui-rhel-7-server-rhui-rh-common-rpms: [###################################################### ] 117/243rhui-rhel-7-server-rhui-rh-common-rpms: [###################################################### ] 118/243rhui-rhel-7-server-rhui-rh-common-rpms: [####################################################### ] 119/243rhui-rhel-7-server-rhui-rh-common-rpms: [####################################################### ] 120/243rhui-rhel-7-server-rhui-rh-common-rpms: [######################################################## ] 121/243rhui-rhel-7-server-rhui-rh-common-rpms: [######################################################## ] 122/243rhui-rhel-7-server-rhui-rh-common-rpms: [######################################################### ] 123/243rhui-rhel-7-server-rhui-rh-common-rpms: [######################################################### ] 124/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################################################## ] 125/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################################################## ] 126/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################################################### ] 127/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################################################### ] 128/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################################################### ] 129/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################ ] 130/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################ ] 131/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################# ] 132/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################# ] 133/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################## ] 134/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################## ] 135/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################### ] 136/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################### ] 137/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################ ] 138/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################ ] 139/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################# ] 140/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################# ] 141/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################## ] 142/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################## ] 143/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################## ] 144/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################### ] 145/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################### ] 146/243rhui-rhel-7-server-rhui-rh-common-rpms: [#################################################################### ] 147/243rhui-rhel-7-server-rhui-rh-common-rpms: [#################################################################### ] 148/243rhui-rhel-7-server-rhui-rh-common-rpms: [##################################################################### ] 149/243rhui-rhel-7-server-rhui-rh-common-rpms: [##################################################################### ] 150/243rhui-rhel-7-server-rhui-rh-common-rpms: [###################################################################### ] 151/243rhui-rhel-7-server-rhui-rh-common-rpms: [###################################################################### ] 152/243rhui-rhel-7-server-rhui-rh-common-rpms: [####################################################################### ] 153/243rhui-rhel-7-server-rhui-rh-common-rpms: [####################################################################### ] 154/243rhui-rhel-7-server-rhui-rh-common-rpms: [######################################################################## ] 155/243rhui-rhel-7-server-rhui-rh-common-rpms: [######################################################################## ] 156/243rhui-rhel-7-server-rhui-rh-common-rpms: [######################################################################### ] 157/243rhui-rhel-7-server-rhui-rh-common-rpms: [######################################################################### ] 158/243rhui-rhel-7-server-rhui-rh-common-rpms: [######################################################################### ] 159/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################################################################## ] 160/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################################################################## ] 161/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################################################################### ] 162/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################################################################### ] 163/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################ ] 164/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################ ] 165/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################# ] 166/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################# ] 167/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################## ] 168/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################## ] 169/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################### ] 170/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################### ] 171/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################### ] 172/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################################ ] 173/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################################ ] 174/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################################# ] 175/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################################# ] 176/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################################## ] 177/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################################## ] 178/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################################### ] 179/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################################### ] 180/243rhui-rhel-7-server-rhui-rh-common-rpms: [#################################################################################### ] 181/243rhui-rhel-7-server-rhui-rh-common-rpms: [#################################################################################### ] 182/243rhui-rhel-7-server-rhui-rh-common-rpms: [##################################################################################### ] 183/243rhui-rhel-7-server-rhui-rh-common-rpms: [##################################################################################### ] 184/243rhui-rhel-7-server-rhui-rh-common-rpms: [###################################################################################### ] 185/243rhui-rhel-7-server-rhui-rh-common-rpms: [###################################################################################### ] 186/243rhui-rhel-7-server-rhui-rh-common-rpms: [###################################################################################### ] 187/243rhui-rhel-7-server-rhui-rh-common-rpms: [####################################################################################### ] 188/243rhui-rhel-7-server-rhui-rh-common-rpms: [####################################################################################### ] 189/243rhui-rhel-7-server-rhui-rh-common-rpms: [######################################################################################## ] 190/243rhui-rhel-7-server-rhui-rh-common-rpms: [######################################################################################## ] 191/243rhui-rhel-7-server-rhui-rh-common-rpms: [######################################################################################### ] 192/243rhui-rhel-7-server-rhui-rh-common-rpms: [######################################################################################### ] 193/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################################################################################## ] 194/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################################################################################## ] 195/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################################################################################### ] 196/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################################################################################### ] 197/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################################ ] 198/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################################ ] 199/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################################# ] 200/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################################# ] 201/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################################# ] 202/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################################## ] 203/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################################## ] 204/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################################### ] 205/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################################### ] 206/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################################################ ] 207/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################################################ ] 208/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################################################# ] 209/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################################################# ] 210/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################################################## ] 211/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################################################## ] 212/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################################################### ] 213/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################################################### ] 214/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################################################### ] 215/243rhui-rhel-7-server-rhui-rh-common-rpms: [#################################################################################################### ] 216/243rhui-rhel-7-server-rhui-rh-common-rpms: [#################################################################################################### ] 217/243rhui-rhel-7-server-rhui-rh-common-rpms: [##################################################################################################### ] 218/243rhui-rhel-7-server-rhui-rh-common-rpms: [##################################################################################################### ] 219/243rhui-rhel-7-server-rhui-rh-common-rpms: [###################################################################################################### ] 220/243rhui-rhel-7-server-rhui-rh-common-rpms: [###################################################################################################### ] 221/243rhui-rhel-7-server-rhui-rh-common-rpms: [####################################################################################################### ] 222/243rhui-rhel-7-server-rhui-rh-common-rpms: [####################################################################################################### ] 223/243rhui-rhel-7-server-rhui-rh-common-rpms: [######################################################################################################## ] 224/243rhui-rhel-7-server-rhui-rh-common-rpms: [######################################################################################################## ] 225/243rhui-rhel-7-server-rhui-rh-common-rpms: [######################################################################################################### ] 226/243rhui-rhel-7-server-rhui-rh-common-rpms: [######################################################################################################### ] 227/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################################################################################################## ] 228/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################################################################################################## ] 229/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################################################################################################## ] 230/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################################################################################################### ] 231/243rhui-rhel-7-server-rhui-rh-common-rpms: [########################################################################################################### ] 232/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################################################ ] 233/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################################################ ] 234/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################################################# ] 235/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################################################# ] 236/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################################################## ] 237/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################################################## ] 238/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################################################### ] 239/243rhui-rhel-7-server-rhui-rh-common-rpms: [############################################################################################################### ] 240/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################################################################ ] 241/243rhui-rhel-7-server-rhui-rh-common-rpms: [################################################################################################################ ] 242/243rhui-rhel-7-server-rhui-rh-common-rpms 243/243 rhui-rhel-7-server-rhui-rpms: [ ] 1/32534rhui-rhel-7-server-rhui-rpms: [ ] 162/32534rhui-rhel-7-server-rhui-rpms: [# ] 324/32534rhui-rhel-7-server-rhui-rpms: [# ] 486/32534rhui-rhel-7-server-rhui-rpms: [## ] 648/32534rhui-rhel-7-server-rhui-rpms: [### ] 810/32534rhui-rhel-7-server-rhui-rpms: [### ] 972/32534rhui-rhel-7-server-rhui-rpms: [#### ] 1134/32534rhui-rhel-7-server-rhui-rpms: [#### ] 1296/32534rhui-rhel-7-server-rhui-rpms: [##### ] 1458/32534rhui-rhel-7-server-rhui-rpms: [##### ] 1620/32534rhui-rhel-7-server-rhui-rpms: [###### ] 1782/32534rhui-rhel-7-server-rhui-rpms: [####### ] 1944/32534rhui-rhel-7-server-rhui-rpms: [####### ] 2106/32534rhui-rhel-7-server-rhui-rpms: [######## ] 2268/32534rhui-rhel-7-server-rhui-rpms: [######## ] 2430/32534rhui-rhel-7-server-rhui-rpms: [######### ] 2592/32534rhui-rhel-7-server-rhui-rpms: [########## ] 2754/32534rhui-rhel-7-server-rhui-rpms: [########## ] 2916/32534rhui-rhel-7-server-rhui-rpms: [########### ] 3078/32534rhui-rhel-7-server-rhui-rpms: [########### ] 3240/32534rhui-rhel-7-server-rhui-rpms: [############ ] 3402/32534rhui-rhel-7-server-rhui-rpms: [############# ] 3564/32534rhui-rhel-7-server-rhui-rpms: [############# ] 3726/32534rhui-rhel-7-server-rhui-rpms: [############## ] 3888/32534rhui-rhel-7-server-rhui-rpms: [############## ] 4050/32534rhui-rhel-7-server-rhui-rpms: [############### ] 4212/32534rhui-rhel-7-server-rhui-rpms: [################ ] 4374/32534rhui-rhel-7-server-rhui-rpms: [################ ] 4536/32534rhui-rhel-7-server-rhui-rpms: [################# ] 4698/32534rhui-rhel-7-server-rhui-rpms: [################# ] 4860/32534rhui-rhel-7-server-rhui-rpms: [################## ] 5022/32534rhui-rhel-7-server-rhui-rpms: [################### ] 5184/32534rhui-rhel-7-server-rhui-rpms: [################### ] 5346/32534rhui-rhel-7-server-rhui-rpms: [#################### ] 5508/32534rhui-rhel-7-server-rhui-rpms: [#################### ] 5670/32534rhui-rhel-7-server-rhui-rpms: [##################### ] 5832/32534rhui-rhel-7-server-rhui-rpms: [###################### ] 5994/32534rhui-rhel-7-server-rhui-rpms: [###################### ] 6156/32534rhui-rhel-7-server-rhui-rpms: [####################### ] 6318/32534rhui-rhel-7-server-rhui-rpms: [####################### ] 6480/32534rhui-rhel-7-server-rhui-rpms: [######################## ] 6642/32534rhui-rhel-7-server-rhui-rpms: [######################### ] 6804/32534rhui-rhel-7-server-rhui-rpms: [######################### ] 6966/32534rhui-rhel-7-server-rhui-rpms: [########################## ] 7128/32534rhui-rhel-7-server-rhui-rpms: [########################## ] 7290/32534rhui-rhel-7-server-rhui-rpms: [########################### ] 7452/32534rhui-rhel-7-server-rhui-rpms: [############################ ] 7614/32534rhui-rhel-7-server-rhui-rpms: [############################ ] 7776/32534rhui-rhel-7-server-rhui-rpms: [############################# ] 7938/32534rhui-rhel-7-server-rhui-rpms: [############################# ] 8100/32534rhui-rhel-7-server-rhui-rpms: [############################## ] 8262/32534rhui-rhel-7-server-rhui-rpms: [############################### ] 8424/32534rhui-rhel-7-server-rhui-rpms: [############################### ] 8586/32534rhui-rhel-7-server-rhui-rpms: [################################ ] 8748/32534rhui-rhel-7-server-rhui-rpms: [################################ ] 8910/32534rhui-rhel-7-server-rhui-rpms: [################################# ] 9072/32534rhui-rhel-7-server-rhui-rpms: [################################## ] 9234/32534rhui-rhel-7-server-rhui-rpms: [################################## ] 9396/32534rhui-rhel-7-server-rhui-rpms: [################################### ] 9558/32534rhui-rhel-7-server-rhui-rpms: [################################### ] 9720/32534rhui-rhel-7-server-rhui-rpms: [#################################### ] 9882/32534rhui-rhel-7-server-rhui-rpms: [#################################### ] 10044/32534rhui-rhel-7-server-rhui-rpms: [##################################### ] 10206/32534rhui-rhel-7-server-rhui-rpms: [##################################### ] 10368/32534rhui-rhel-7-server-rhui-rpms: [###################################### ] 10530/32534rhui-rhel-7-server-rhui-rpms: [####################################### ] 10692/32534rhui-rhel-7-server-rhui-rpms: [####################################### ] 10854/32534rhui-rhel-7-server-rhui-rpms: [######################################## ] 11016/32534rhui-rhel-7-server-rhui-rpms: [######################################## ] 11178/32534rhui-rhel-7-server-rhui-rpms: [######################################### ] 11340/32534rhui-rhel-7-server-rhui-rpms: [########################################## ] 11502/32534rhui-rhel-7-server-rhui-rpms: [########################################## ] 11664/32534rhui-rhel-7-server-rhui-rpms: [########################################### ] 11826/32534rhui-rhel-7-server-rhui-rpms: [########################################### ] 11988/32534rhui-rhel-7-server-rhui-rpms: [############################################ ] 12150/32534rhui-rhel-7-server-rhui-rpms: [############################################# ] 12312/32534rhui-rhel-7-server-rhui-rpms: [############################################# ] 12474/32534rhui-rhel-7-server-rhui-rpms: [############################################## ] 12636/32534rhui-rhel-7-server-rhui-rpms: [############################################## ] 12798/32534rhui-rhel-7-server-rhui-rpms: [############################################### ] 12960/32534rhui-rhel-7-server-rhui-rpms: [############################################### ] 13122/32534rhui-rhel-7-server-rhui-rpms: [################################################ ] 13284/32534rhui-rhel-7-server-rhui-rpms: [################################################# ] 13446/32534rhui-rhel-7-server-rhui-rpms: [################################################# ] 13608/32534rhui-rhel-7-server-rhui-rpms: [################################################## ] 13770/32534rhui-rhel-7-server-rhui-rpms: [################################################## ] 13932/32534rhui-rhel-7-server-rhui-rpms: [################################################### ] 14094/32534rhui-rhel-7-server-rhui-rpms: [#################################################### ] 14256/32534rhui-rhel-7-server-rhui-rpms: [#################################################### ] 14418/32534rhui-rhel-7-server-rhui-rpms: [##################################################### ] 14580/32534rhui-rhel-7-server-rhui-rpms: [##################################################### ] 14742/32534rhui-rhel-7-server-rhui-rpms: [###################################################### ] 14904/32534rhui-rhel-7-server-rhui-rpms: [####################################################### ] 15066/32534rhui-rhel-7-server-rhui-rpms: [####################################################### ] 15228/32534rhui-rhel-7-server-rhui-rpms: [######################################################## ] 15390/32534rhui-rhel-7-server-rhui-rpms: [######################################################## ] 15552/32534rhui-rhel-7-server-rhui-rpms: [######################################################### ] 15714/32534rhui-rhel-7-server-rhui-rpms: [########################################################## ] 15876/32534rhui-rhel-7-server-rhui-rpms: [########################################################## ] 16038/32534rhui-rhel-7-server-rhui-rpms: [########################################################### ] 16200/32534rhui-rhel-7-server-rhui-rpms: [########################################################### ] 16362/32534rhui-rhel-7-server-rhui-rpms: [############################################################ ] 16524/32534rhui-rhel-7-server-rhui-rpms: [############################################################# ] 16686/32534rhui-rhel-7-server-rhui-rpms: [############################################################# ] 16848/32534rhui-rhel-7-server-rhui-rpms: [############################################################## ] 17010/32534rhui-rhel-7-server-rhui-rpms: [############################################################## ] 17172/32534rhui-rhel-7-server-rhui-rpms: [############################################################### ] 17334/32534rhui-rhel-7-server-rhui-rpms: [############################################################### ] 17496/32534rhui-rhel-7-server-rhui-rpms: [################################################################ ] 17658/32534rhui-rhel-7-server-rhui-rpms: [################################################################# ] 17820/32534rhui-rhel-7-server-rhui-rpms: [################################################################# ] 17982/32534rhui-rhel-7-server-rhui-rpms: [################################################################## ] 18144/32534rhui-rhel-7-server-rhui-rpms: [################################################################## ] 18306/32534rhui-rhel-7-server-rhui-rpms: [################################################################### ] 18468/32534rhui-rhel-7-server-rhui-rpms: [#################################################################### ] 18630/32534rhui-rhel-7-server-rhui-rpms: [#################################################################### ] 18792/32534rhui-rhel-7-server-rhui-rpms: [##################################################################### ] 18954/32534rhui-rhel-7-server-rhui-rpms: [##################################################################### ] 19116/32534rhui-rhel-7-server-rhui-rpms: [###################################################################### ] 19278/32534rhui-rhel-7-server-rhui-rpms: [####################################################################### ] 19440/32534rhui-rhel-7-server-rhui-rpms: [####################################################################### ] 19602/32534rhui-rhel-7-server-rhui-rpms: [######################################################################## ] 19764/32534rhui-rhel-7-server-rhui-rpms: [######################################################################## ] 19926/32534rhui-rhel-7-server-rhui-rpms: [######################################################################### ] 20088/32534rhui-rhel-7-server-rhui-rpms: [########################################################################## ] 20250/32534rhui-rhel-7-server-rhui-rpms: [########################################################################## ] 20412/32534rhui-rhel-7-server-rhui-rpms: [########################################################################### ] 20574/32534rhui-rhel-7-server-rhui-rpms: [########################################################################### ] 20736/32534rhui-rhel-7-server-rhui-rpms: [############################################################################ ] 20898/32534rhui-rhel-7-server-rhui-rpms: [############################################################################# ] 21060/32534rhui-rhel-7-server-rhui-rpms: [############################################################################# ] 21222/32534rhui-rhel-7-server-rhui-rpms: [############################################################################## ] 21384/32534rhui-rhel-7-server-rhui-rpms: [############################################################################## ] 21546/32534rhui-rhel-7-server-rhui-rpms: [############################################################################### ] 21708/32534rhui-rhel-7-server-rhui-rpms: [############################################################################### ] 21870/32534rhui-rhel-7-server-rhui-rpms: [################################################################################ ] 22032/32534rhui-rhel-7-server-rhui-rpms: [################################################################################# ] 22194/32534rhui-rhel-7-server-rhui-rpms: [################################################################################# ] 22356/32534rhui-rhel-7-server-rhui-rpms: [################################################################################## ] 22518/32534rhui-rhel-7-server-rhui-rpms: [################################################################################## ] 22680/32534rhui-rhel-7-server-rhui-rpms: [################################################################################### ] 22842/32534rhui-rhel-7-server-rhui-rpms: [#################################################################################### ] 23004/32534rhui-rhel-7-server-rhui-rpms: [#################################################################################### ] 23166/32534rhui-rhel-7-server-rhui-rpms: [##################################################################################### ] 23328/32534rhui-rhel-7-server-rhui-rpms: [##################################################################################### ] 23490/32534rhui-rhel-7-server-rhui-rpms: [###################################################################################### ] 23652/32534rhui-rhel-7-server-rhui-rpms: [####################################################################################### ] 23814/32534rhui-rhel-7-server-rhui-rpms: [####################################################################################### ] 23976/32534rhui-rhel-7-server-rhui-rpms: [######################################################################################## ] 24138/32534rhui-rhel-7-server-rhui-rpms: [######################################################################################## ] 24300/32534rhui-rhel-7-server-rhui-rpms: [######################################################################################### ] 24462/32534rhui-rhel-7-server-rhui-rpms: [########################################################################################## ] 24624/32534rhui-rhel-7-server-rhui-rpms: [########################################################################################## ] 24786/32534rhui-rhel-7-server-rhui-rpms: [########################################################################################### ] 24948/32534rhui-rhel-7-server-rhui-rpms: [########################################################################################### ] 25110/32534rhui-rhel-7-server-rhui-rpms: [############################################################################################ ] 25272/32534rhui-rhel-7-server-rhui-rpms: [############################################################################################# ] 25434/32534rhui-rhel-7-server-rhui-rpms: [############################################################################################# ] 25596/32534rhui-rhel-7-server-rhui-rpms: [############################################################################################## ] 25758/32534rhui-rhel-7-server-rhui-rpms: [############################################################################################## ] 25920/32534rhui-rhel-7-server-rhui-rpms: [############################################################################################### ] 26082/32534rhui-rhel-7-server-rhui-rpms: [############################################################################################### ] 26244/32534rhui-rhel-7-server-rhui-rpms: [################################################################################################ ] 26406/32534rhui-rhel-7-server-rhui-rpms: [################################################################################################# ] 26568/32534rhui-rhel-7-server-rhui-rpms: [################################################################################################# ] 26730/32534rhui-rhel-7-server-rhui-rpms: [################################################################################################## ] 26892/32534rhui-rhel-7-server-rhui-rpms: [################################################################################################## ] 27054/32534rhui-rhel-7-server-rhui-rpms: [################################################################################################### ] 27216/32534rhui-rhel-7-server-rhui-rpms: [#################################################################################################### ] 27378/32534rhui-rhel-7-server-rhui-rpms: [#################################################################################################### ] 27540/32534rhui-rhel-7-server-rhui-rpms: [##################################################################################################### ] 27702/32534rhui-rhel-7-server-rhui-rpms: [##################################################################################################### ] 27864/32534rhui-rhel-7-server-rhui-rpms: [###################################################################################################### ] 28026/32534rhui-rhel-7-server-rhui-rpms: [####################################################################################################### ] 28188/32534rhui-rhel-7-server-rhui-rpms: [####################################################################################################### ] 28350/32534rhui-rhel-7-server-rhui-rpms: [######################################################################################################## ] 28512/32534rhui-rhel-7-server-rhui-rpms: [######################################################################################################## ] 28674/32534rhui-rhel-7-server-rhui-rpms: [######################################################################################################### ] 28836/32534rhui-rhel-7-server-rhui-rpms: [########################################################################################################## ] 28998/32534rhui-rhel-7-server-rhui-rpms: [########################################################################################################## ] 29160/32534rhui-rhel-7-server-rhui-rpms: [########################################################################################################### ] 29322/32534rhui-rhel-7-server-rhui-rpms: [########################################################################################################### ] 29484/32534rhui-rhel-7-server-rhui-rpms: [############################################################################################################ ] 29646/32534rhui-rhel-7-server-rhui-rpms: [############################################################################################################# ] 29808/32534rhui-rhel-7-server-rhui-rpms: [############################################################################################################# ] 29970/32534rhui-rhel-7-server-rhui-rpms: [############################################################################################################## ] 30132/32534rhui-rhel-7-server-rhui-rpms: [############################################################################################################## ] 30294/32534rhui-rhel-7-server-rhui-rpms: [############################################################################################################### ] 30456/32534rhui-rhel-7-server-rhui-rpms: [############################################################################################################### ] 30618/32534rhui-rhel-7-server-rhui-rpms: [################################################################################################################ ] 30780/32534rhui-rhel-7-server-rhui-rpms: [################################################################################################################# ] 30942/32534rhui-rhel-7-server-rhui-rpms: [################################################################################################################# ] 31104/32534rhui-rhel-7-server-rhui-rpms: [################################################################################################################## ] 31266/32534rhui-rhel-7-server-rhui-rpms: [################################################################################################################## ] 31428/32534rhui-rhel-7-server-rhui-rpms: [################################################################################################################### ] 31590/32534rhui-rhel-7-server-rhui-rpms: [#################################################################################################################### ] 31752/32534rhui-rhel-7-server-rhui-rpms: [#################################################################################################################### ] 31914/32534rhui-rhel-7-server-rhui-rpms: [##################################################################################################################### ] 32076/32534rhui-rhel-7-server-rhui-rpms: [##################################################################################################################### ] 32238/32534rhui-rhel-7-server-rhui-rpms: [###################################################################################################################### ] 32400/32534rhui-rhel-7-server-rhui-rpms 32534/32534 Resolving Dependencies --> Running transaction check ---> Package wget.x86_64 0:1.14-18.el7_6.1 will be installed --> Finished Dependency Resolution Dependencies Resolved ==================================================================================================================================================================== Package Arch Version Repository Size ==================================================================================================================================================================== Installing: wget x86_64 1.14-18.el7_6.1 rhui-rhel-7-server-rhui-rpms 547 k Transaction Summary ==================================================================================================================================================================== Install 1 Package Total download size: 547 k Installed size: 2.0 M Is this ok [y/d/N]: y Downloading packages: wget-1.14-18.el7_6.1.x86_64.rpm 0% [ ] 0.0 B/s | 0 B --:--:-- ETA wget-1.14-18.el7_6.1.x86_64.rpm | 547 kB 00:00:00 Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : wget-1.14-18.el7_6.1.x86_64 [ ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [###### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [########## ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [############# ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [################## ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [##################### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [###################### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [######################### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [########################## ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [########################### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [############################## ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [############################### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [################################# ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [################################### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [###################################### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [######################################### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [############################################ ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [############################################# ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [############################################## ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [################################################# ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [################################################### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [#################################################### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [###################################################### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [########################################################## ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [########################################################### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [############################################################ ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [############################################################### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [################################################################## ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [#################################################################### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [####################################################################### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [########################################################################## ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [############################################################################ ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [############################################################################### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [################################################################################### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [#################################################################################### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [####################################################################################### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [########################################################################################### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [############################################################################################# ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [################################################################################################ ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [################################################################################################### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [###################################################################################################### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [####################################################################################################### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [######################################################################################################## ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [########################################################################################################### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [############################################################################################################## ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [############################################################################################################### ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 [################################################################################################################ ] 1/1 Installing : wget-1.14-18.el7_6.1.x86_64 1/1 Verifying : wget-1.14-18.el7_6.1.x86_64 1/1 Installed: wget.x86_64 0:1.14-18.el7_6.1 Complete! [root@ip-10-0-1-244 ec2-user]# wget http://springdale.math.ias.edu/data/puias/unsupported/7/x86_64/python-dnf-0.6.4-2.sdl7.noarch.rpm --2021-12-03 11:24:54-- http://springdale.math.ias.edu/data/puias/unsupported/7/x86_64/python-dnf-0.6.4-2.sdl7.noarch.rpm Resolving springdale.math.ias.edu (springdale.math.ias.edu)... 3.86.61.3 Connecting to springdale.math.ias.edu (springdale.math.ias.edu)|3.86.61.3|:80... wget http://springdale.math.ias.edu/data/puias/unsupported/7/x86_64/dnf-0.6.4-2.sdl7.noarch.rpm wget http://springdale.math.ias.edu/data/puias/unsupported/7/x86_64/dnf-conf-0.6.4-2.sdl7.noarch.rpm wget http://ftp.riken.jp/Linux/centos/7/updates/x86_64/Packages/python-librepo-1.8.1-8.el7_9.x86_64.rpm wget --no-check-certificate https://cbs.centos.org/kojifiles/packages/libcomps/0.1.6/13.el7.centos/x86_64/python-libcomps-0.1.6-13.el7.centos.x86_64.rpm wget --no-check-certificate https://cbs.centos.org/kojifiles/packages/libcomps/0.1.6/13.el7.centos/x86_64/libcomps-devel-0.1.6-13.el7.centos.x86_64.rpm wget --no-check-certificate https://cbs.centos.org/kojifiles/packages/libcomps/0.1.6/13.el7.centos/x86_64/libcomps-debuginfo-0.1.6-13.el7.centos.x86_64.rpm wget --no-check-certificate https://cbs.centos.org/kojifiles/packages/libcomps/0.1.6/13.el7.centos/x86_64/libcomps-0.1.6-13.el7.centos.x86_64.rpmconnected. HTTP request sent, awaiting response... 200 OK Length: 416988 (407K) [application/x-rpm] Saving to: ‘python-dnf-0.6.4-2.sdl7.noarch.rpm’ 0% [ ] 0 --.-K/s 12% [==============> ] 51,279 176KB/s 53% [================================================================> ] 223,591 384KB/s 100%[==========================================================================================================================>] 416,988 714KB/s in 0.6s 2021-12-03 11:24:55 (714 KB/s) - ‘python-dnf-0.6.4-2.sdl7.noarch.rpm’ saved [416988/416988] [root@ip-10-0-1-244 ec2-user]# wget http://springdale.math.ias.edu/data/puias/unsupported/7/x86_64/dnf-0.6.4-2.sdl7.noarch.rpm --2021-12-03 11:24:55-- http://springdale.math.ias.edu/data/puias/unsupported/7/x86_64/dnf-0.6.4-2.sdl7.noarch.rpm Resolving springdale.math.ias.edu (springdale.math.ias.edu)... 3.86.61.3 Connecting to springdale.math.ias.edu (springdale.math.ias.edu)|3.86.61.3|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 213696 (209K) [application/x-rpm] Saving to: ‘dnf-0.6.4-2.sdl7.noarch.rpm’ 0% [ ] 0 --.-K/s 23% [============================> ] 51,279 176KB/s 100%[==========================================================================================================================>] 213,696 488KB/s in 0.4s 2021-12-03 11:24:55 (488 KB/s) - ‘dnf-0.6.4-2.sdl7.noarch.rpm’ saved [213696/213696] [root@ip-10-0-1-244 ec2-user]# wget http://springdale.math.ias.edu/data/puias/unsupported/7/x86_64/dnf-conf-0.6.4-2.sdl7.noarch.rpm --2021-12-03 11:24:55-- http://springdale.math.ias.edu/data/puias/unsupported/7/x86_64/dnf-conf-0.6.4-2.sdl7.noarch.rpm Resolving springdale.math.ias.edu (springdale.math.ias.edu)... 3.86.61.3 Connecting to springdale.math.ias.edu (springdale.math.ias.edu)|3.86.61.3|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 62404 (61K) [application/x-rpm] Saving to: ‘dnf-conf-0.6.4-2.sdl7.noarch.rpm’ 0% [ ] 0 --.-K/s 82% [====================================================================================================> ] 51,281 175KB/s 100%[==========================================================================================================================>] 62,404 213KB/s in 0.3s 2021-12-03 11:24:56 (213 KB/s) - ‘dnf-conf-0.6.4-2.sdl7.noarch.rpm’ saved [62404/62404] [root@ip-10-0-1-244 ec2-user]# wget http://ftp.riken.jp/Linux/centos/7/updates/x86_64/Packages/python-librepo-1.8.1-8.el7_9.x86_64.rpm --2021-12-03 11:24:56-- http://ftp.riken.jp/Linux/centos/7/updates/x86_64/Packages/python-librepo-1.8.1-8.el7_9.x86_64.rpm Resolving ftp.riken.jp (ftp.riken.jp)... 134.160.38.1 Connecting to ftp.riken.jp (ftp.riken.jp)|134.160.38.1|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 54528 (53K) [application/x-rpm] Saving to: ‘python-librepo-1.8.1-8.el7_9.x86_64.rpm’ 0% [ ] 0 --.-K/s 100%[==========================================================================================================================>] 54,528 --.-K/s in 0.01s 2021-12-03 11:24:56 (4.67 MB/s) - ‘python-librepo-1.8.1-8.el7_9.x86_64.rpm’ saved [54528/54528] [root@ip-10-0-1-244 ec2-user]# wget --no-check-certificate https://cbs.centos.org/kojifiles/packages/libcomps/0.1.6/13.el7.centos/x86_64/python-libcomps-0.1.6-13.el 7.centos.x86_64.rpm --2021-12-03 11:24:56-- https://cbs.centos.org/kojifiles/packages/libcomps/0.1.6/13.el7.centos/x86_64/python-libcomps-0.1.6-13.el7.centos.x86_64.rpm Resolving cbs.centos.org (cbs.centos.org)... 8.43.84.196 Connecting to cbs.centos.org (cbs.centos.org)|8.43.84.196|:443... connected. WARNING: cannot verify cbs.centos.org's certificate, issued by ‘/C=US/O=Let's Encrypt/CN=R3’: Issued certificate has expired. HTTP request sent, awaiting response... 200 OK Length: 43652 (43K) [application/x-rpm] Saving to: ‘python-libcomps-0.1.6-13.el7.centos.x86_64.rpm’ 0% [ ] 0 --.-K/s 100%[==========================================================================================================================>] 43,652 119KB/s 100%[==========================================================================================================================>] 43,652 119KB/s in 0.4s 2021-12-03 11:24:57 (119 KB/s) - ‘python-libcomps-0.1.6-13.el7.centos.x86_64.rpm’ saved [43652/43652] [root@ip-10-0-1-244 ec2-user]# wget --no-check-certificate https://cbs.centos.org/kojifiles/packages/libcomps/0.1.6/13.el7.centos/x86_64/libcomps-devel-0.1.6-13.el7 .centos.x86_64.rpm --2021-12-03 11:24:57-- https://cbs.centos.org/kojifiles/packages/libcomps/0.1.6/13.el7.centos/x86_64/libcomps-devel-0.1.6-13.el7.centos.x86_64.rpm Resolving cbs.centos.org (cbs.centos.org)... 8.43.84.196 Connecting to cbs.centos.org (cbs.centos.org)|8.43.84.196|:443... connected. WARNING: cannot verify cbs.centos.org's certificate, issued by ‘/C=US/O=Let's Encrypt/CN=R3’: Issued certificate has expired. HTTP request sent, awaiting response... 200 OK Length: 26572 (26K) [application/x-rpm] Saving to: ‘libcomps-devel-0.1.6-13.el7.centos.x86_64.rpm’ 0% [ ] 0 --.-K/s 100%[==========================================================================================================================>] 26,572 146KB/s in 0.2s 2021-12-03 11:24:59 (146 KB/s) - ‘libcomps-devel-0.1.6-13.el7.centos.x86_64.rpm’ saved [26572/26572] [root@ip-10-0-1-244 ec2-user]# wget --no-check-certificate https://cbs.centos.org/kojifiles/packages/libcomps/0.1.6/13.el7.centos/x86_64/libcomps-debuginfo-0.1.6-13 .el7.centos.x86_64.rpm --2021-12-03 11:24:59-- https://cbs.centos.org/kojifiles/packages/libcomps/0.1.6/13.el7.centos/x86_64/libcomps-debuginfo-0.1.6-13.el7.centos.x86_64.rpm Resolving cbs.centos.org (cbs.centos.org)... 8.43.84.196 Connecting to cbs.centos.org (cbs.centos.org)|8.43.84.196|:443... connected. WARNING: cannot verify cbs.centos.org's certificate, issued by ‘/C=US/O=Let's Encrypt/CN=R3’: Issued certificate has expired. HTTP request sent, awaiting response... 200 OK Length: 286948 (280K) [application/x-rpm] Saving to: ‘libcomps-debuginfo-0.1.6-13.el7.centos.x86_64.rpm’ 0% [ ] 0 --.-K/s 5% [=====> ] 15,661 75.6KB/s 36% [===========================================> ] 103,661 179KB/s 100%[==========================================================================================================================>] 286,948 382KB/s in 0.7s 2021-12-03 11:25:00 (382 KB/s) - ‘libcomps-debuginfo-0.1.6-13.el7.centos.x86_64.rpm’ saved [286948/286948] [root@ip-10-0-1-244 ec2-user]# wget --no-check-certificate https://cbs.centos.org/kojifiles/packages/libcomps/0.1.6/13.el7.centos/x86_64/libcomps-0.1.6-13.el7.cento s.x86_64.rpm --2021-12-03 11:25:07-- https://cbs.centos.org/kojifiles/packages/libcomps/0.1.6/13.el7.centos/x86_64/libcomps-0.1.6-13.el7.centos.x86_64.rpm Resolving cbs.centos.org (cbs.centos.org)... 8.43.84.196 Connecting to cbs.centos.org (cbs.centos.org)|8.43.84.196|:443... connected. WARNING: cannot verify cbs.centos.org's certificate, issued by ‘/C=US/O=Let's Encrypt/CN=R3’: Issued certificate has expired. HTTP request sent, awaiting response... 200 OK Length: 72228 (71K) [application/x-rpm] Saving to: ‘libcomps-0.1.6-13.el7.centos.x86_64.rpm’ 0% [ ] 0 --.-K/s 65% [================================================================================> ] 47,662 125KB/s 100%[==========================================================================================================================>] 72,228 190KB/s in 0.4s 2021-12-03 11:25:08 (190 KB/s) - ‘libcomps-0.1.6-13.el7.centos.x86_64.rpm’ saved [72228/72228] [root@ip-10-0-1-244 ec2-user]# yum install python-librepo-1.8.1-8.el7_9.x86_64.rpm Loaded plugins: amazon-id, search-disabled-repos Examining python-librepo-1.8.1-8.el7_9.x86_64.rpm: python-librepo-1.8.1-8.el7_9.x86_64 Marking python-librepo-1.8.1-8.el7_9.x86_64.rpm to be installed Resolving Dependencies --> Running transaction check ---> Package python-librepo.x86_64 0:1.8.1-8.el7_9 will be installed --> Processing Dependency: librepo(x86-64) = 1.8.1-8.el7_9 for package: python-librepo-1.8.1-8.el7_9.x86_64 --> Processing Dependency: librepo.so.0()(64bit) for package: python-librepo-1.8.1-8.el7_9.x86_64 --> Running transaction check ---> Package librepo.x86_64 0:1.8.1-8.el7_9 will be installed --> Finished Dependency Resolution Dependencies Resolved ==================================================================================================================================================================== Package Arch Version Repository Size ==================================================================================================================================================================== Installing: python-librepo x86_64 1.8.1-8.el7_9 /python-librepo-1.8.1-8.el7_9.x86_64 169 k Installing for dependencies: librepo x86_64 1.8.1-8.el7_9 rhui-rhel-7-server-rhui-rpms 82 k Transaction Summary ==================================================================================================================================================================== Install 1 Package (+1 Dependent package) Total size: 251 k Total download size: 82 k Installed size: 342 k Is this ok [y/d/N]: y Downloading packages: librepo-1.8.1-8.el7_9.x86_64.rpm | 82 kB 00:00:00 Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : librepo-1.8.1-8.el7_9.x86_64 [ ] 1/2 Installing : librepo-1.8.1-8.el7_9.x86_64 [######################################## ] 1/2 Installing : librepo-1.8.1-8.el7_9.x86_64 [################################################################################## ] 1/2 Installing : librepo-1.8.1-8.el7_9.x86_64 [############################################################################################ ] 1/2 Installing : librepo-1.8.1-8.el7_9.x86_64 [############################################################################################################# ] 1/2 Installing : librepo-1.8.1-8.el7_9.x86_64 [############################################################################################################### ] 1/2 Installing : librepo-1.8.1-8.el7_9.x86_64 1/2 Installing : python-librepo-1.8.1-8.el7_9.x86_64 [ ] 2/2 Installing : python-librepo-1.8.1-8.el7_9.x86_64 [############################### ] 2/2 Installing : python-librepo-1.8.1-8.el7_9.x86_64 [######################################################################## ] 2/2 Installing : python-librepo-1.8.1-8.el7_9.x86_64 [######################################################################################################## ] 2/2 Installing : python-librepo-1.8.1-8.el7_9.x86_64 2/2 Verifying : librepo-1.8.1-8.el7_9.x86_64 1/2 Verifying : python-librepo-1.8.1-8.el7_9.x86_64 2/2 Installed: python-librepo.x86_64 0:1.8.1-8.el7_9 Dependency Installed: librepo.x86_64 0:1.8.1-8.el7_9 Complete! [root@ip-10-0-1-244 ec2-user]# [root@ip-10-0-1-244 ec2-user]# yum install libcomps-0.1.6-13.el7.centos.x86_64.rpm libcomps-debuginfo-0.1.6-13.el7.centos.x86_64.rpm libcomps-devel-0.1.6-13.el7.cen tos.x86_64.rpm Loaded plugins: amazon-id, search-disabled-repos Examining libcomps-0.1.6-13.el7.centos.x86_64.rpm: libcomps-0.1.6-13.el7.centos.x86_64 Marking libcomps-0.1.6-13.el7.centos.x86_64.rpm to be installed Examining libcomps-debuginfo-0.1.6-13.el7.centos.x86_64.rpm: libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 Marking libcomps-debuginfo-0.1.6-13.el7.centos.x86_64.rpm to be installed Examining libcomps-devel-0.1.6-13.el7.centos.x86_64.rpm: libcomps-devel-0.1.6-13.el7.centos.x86_64 Marking libcomps-devel-0.1.6-13.el7.centos.x86_64.rpm to be installed Resolving Dependencies --> Running transaction check ---> Package libcomps.x86_64 0:0.1.6-13.el7.centos will be installed ---> Package libcomps-debuginfo.x86_64 0:0.1.6-13.el7.centos will be installed ---> Package libcomps-devel.x86_64 0:0.1.6-13.el7.centos will be installed --> Finished Dependency Resolution Dependencies Resolved ==================================================================================================================================================================== Package Arch Version Repository Size ==================================================================================================================================================================== Installing: libcomps x86_64 0.1.6-13.el7.centos /libcomps-0.1.6-13.el7.centos.x86_64 202 k libcomps-debuginfo x86_64 0.1.6-13.el7.centos /libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 1.4 M libcomps-devel x86_64 0.1.6-13.el7.centos /libcomps-devel-0.1.6-13.el7.centos.x86_64 122 k Transaction Summary ==================================================================================================================================================================== Install 3 Packages Total size: 1.8 M Installed size: 1.8 M Is this ok [y/d/N]: y Downloading packages: Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : libcomps-0.1.6-13.el7.centos.x86_64 [ ] 1/3 Installing : libcomps-0.1.6-13.el7.centos.x86_64 [################################ ] 1/3 Installing : libcomps-0.1.6-13.el7.centos.x86_64 [################################################################## ] 1/3 Installing : libcomps-0.1.6-13.el7.centos.x86_64 [############################################################################################## ] 1/3 Installing : libcomps-0.1.6-13.el7.centos.x86_64 [####################################################################################################### ] 1/3 Installing : libcomps-0.1.6-13.el7.centos.x86_64 [######################################################################################################## ] 1/3 Installing : libcomps-0.1.6-13.el7.centos.x86_64 1/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [ ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [### ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [#### ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [###### ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [#################### ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [########################## ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [############################### ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [###################################### ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [######################################### ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [############################################# ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [################################################## ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [#################################################### ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [##################################################### ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [####################################################### ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [######################################################## ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [########################################################### ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [################################################################# ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [######################################################################## ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [############################################################################## ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [################################################################################ ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [################################################################################### ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [###################################################################################### ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [######################################################################################## ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [########################################################################################## ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [################################################################################################# ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 [################################################################################################### ] 2/3 Installing : libcomps-devel-0.1.6-13.el7.centos.x86_64 2/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [ ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [######## ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [############ ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [################ ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [#################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [######################## ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [########################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [############################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [#################################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [######################################## ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [########################################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [############################################# ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [############################################## ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [################################################ ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [################################################# ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [################################################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [#################################################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [##################################################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [###################################################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [####################################################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [######################################################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [########################################################## ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [########################################################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [############################################################# ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [############################################################## ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [############################################################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [################################################################ ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [################################################################## ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [#################################################################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [###################################################################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [####################################################################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [######################################################################## ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [######################################################################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [########################################################################## ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [########################################################################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [############################################################################ ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [############################################################################# ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [############################################################################## ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [############################################################################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [################################################################################ ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [################################################################################## ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [################################################################################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [#################################################################################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [##################################################################################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [###################################################################################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [####################################################################################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [######################################################################################## ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [########################################################################################## ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [########################################################################################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [############################################################################################ ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [############################################################################################## ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 [############################################################################################### ] 3/3 Installing : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 3/3 Verifying : libcomps-0.1.6-13.el7.centos.x86_64 1/3 Verifying : libcomps-devel-0.1.6-13.el7.centos.x86_64 2/3 Verifying : libcomps-debuginfo-0.1.6-13.el7.centos.x86_64 3/3 Installed: libcomps.x86_64 0:0.1.6-13.el7.centos libcomps-debuginfo.x86_64 0:0.1.6-13.el7.centos libcomps-devel.x86_64 0:0.1.6-13.el7.centos Complete! [root@ip-10-0-1-244 ec2-user]# yum install python-libcomps-0.1.6-13.el7.centos.x86_64.rpm Loaded plugins: amazon-id, search-disabled-repos Examining python-libcomps-0.1.6-13.el7.centos.x86_64.rpm: python-libcomps-0.1.6-13.el7.centos.x86_64 Marking python-libcomps-0.1.6-13.el7.centos.x86_64.rpm to be installed Resolving Dependencies --> Running transaction check ---> Package python-libcomps.x86_64 0:0.1.6-13.el7.centos will be installed --> Finished Dependency Resolution Dependencies Resolved ==================================================================================================================================================================== Package Arch Version Repository Size ==================================================================================================================================================================== Installing: python-libcomps x86_64 0.1.6-13.el7.centos /python-libcomps-0.1.6-13.el7.centos.x86_64 140 k Transaction Summary ==================================================================================================================================================================== Install 1 Package Total size: 140 k Installed size: 140 k Is this ok [y/d/N]: y Downloading packages: Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : python-libcomps-0.1.6-13.el7.centos.x86_64 [ ] 1/1 Installing : python-libcomps-0.1.6-13.el7.centos.x86_64 [############################################ ] 1/1 Installing : python-libcomps-0.1.6-13.el7.centos.x86_64 [########################################################################################## ] 1/1 Installing : python-libcomps-0.1.6-13.el7.centos.x86_64 [################################################################################################## ] 1/1 Installing : python-libcomps-0.1.6-13.el7.centos.x86_64 1/1 Verifying : python-libcomps-0.1.6-13.el7.centos.x86_64 1/1 Installed: python-libcomps.x86_64 0:0.1.6-13.el7.centos Complete! [root@ip-10-0-1-244 ec2-user]# yum install python-dnf-0.6.4-2.sdl7.noarch.rpm dnf-0.6.4-2.sdl7.noarch.rpm dnf-conf-0.6.4-2.sdl7.noarch.rpm Loaded plugins: amazon-id, search-disabled-repos Examining python-dnf-0.6.4-2.sdl7.noarch.rpm: python-dnf-0.6.4-2.sdl7.noarch Marking python-dnf-0.6.4-2.sdl7.noarch.rpm to be installed Examining dnf-0.6.4-2.sdl7.noarch.rpm: dnf-0.6.4-2.sdl7.noarch Marking dnf-0.6.4-2.sdl7.noarch.rpm to be installed Examining dnf-conf-0.6.4-2.sdl7.noarch.rpm: dnf-conf-0.6.4-2.sdl7.noarch Marking dnf-conf-0.6.4-2.sdl7.noarch.rpm to be installed Resolving Dependencies --> Running transaction check ---> Package dnf.noarch 0:0.6.4-2.sdl7 will be installed ---> Package dnf-conf.noarch 0:0.6.4-2.sdl7 will be installed --> Processing Dependency: libreport-filesystem for package: dnf-conf-0.6.4-2.sdl7.noarch ---> Package python-dnf.noarch 0:0.6.4-2.sdl7 will be installed --> Processing Dependency: python-hawkey >= 0.5.3 for package: python-dnf-0.6.4-2.sdl7.noarch --> Processing Dependency: deltarpm for package: python-dnf-0.6.4-2.sdl7.noarch --> Running transaction check ---> Package deltarpm.x86_64 0:3.6-3.el7 will be installed ---> Package libreport-filesystem.x86_64 0:2.1.11-53.el7 will be installed ---> Package python2-hawkey.x86_64 0:0.6.3-4.el7 will be installed --> Processing Dependency: hawkey(x86-64) = 0.6.3-4.el7 for package: python2-hawkey-0.6.3-4.el7.x86_64 --> Processing Dependency: libsolvext.so.0(SOLV_1.0)(64bit) for package: python2-hawkey-0.6.3-4.el7.x86_64 --> Processing Dependency: libsolv.so.0(SOLV_1.0)(64bit) for package: python2-hawkey-0.6.3-4.el7.x86_64 --> Processing Dependency: libsolvext.so.0()(64bit) for package: python2-hawkey-0.6.3-4.el7.x86_64 --> Processing Dependency: libsolv.so.0()(64bit) for package: python2-hawkey-0.6.3-4.el7.x86_64 --> Processing Dependency: libhawkey.so.2()(64bit) for package: python2-hawkey-0.6.3-4.el7.x86_64 --> Running transaction check ---> Package hawkey.x86_64 0:0.6.3-4.el7 will be installed ---> Package libsolv.x86_64 0:0.6.34-4.el7 will be installed --> Finished Dependency Resolution Dependencies Resolved ==================================================================================================================================================================== Package Arch Version Repository Size ==================================================================================================================================================================== Installing: dnf noarch 0.6.4-2.sdl7 /dnf-0.6.4-2.sdl7.noarch 652 k dnf-conf noarch 0.6.4-2.sdl7 /dnf-conf-0.6.4-2.sdl7.noarch 29 k python-dnf noarch 0.6.4-2.sdl7 /python-dnf-0.6.4-2.sdl7.noarch 1.8 M Installing for dependencies: deltarpm x86_64 3.6-3.el7 rhui-rhel-7-server-rhui-rpms 82 k hawkey x86_64 0.6.3-4.el7 rhui-rhel-7-server-rhui-rpms 89 k libreport-filesystem x86_64 2.1.11-53.el7 rhui-rhel-7-server-rhui-rpms 41 k libsolv x86_64 0.6.34-4.el7 rhui-rhel-7-server-rhui-rpms 329 k python2-hawkey x86_64 0.6.3-4.el7 rhui-rhel-7-server-rhui-rpms 73 k Transaction Summary ==================================================================================================================================================================== Install 3 Packages (+5 Dependent packages) Total size: 3.0 M Total download size: 614 k Installed size: 3.7 M Is this ok [y/d/N]: y Downloading packages: (2/5): hawkey-0.6.3-4.el7.x86_64.rpm 0% [ ] 0.0 B/s | 0 B --:--:-- ETA (1/5): hawkey-0.6.3-4.el7.x86_64.rpm | 89 kB 00:00:00 (2/5): libreport-filesystem-2.1.11-53.el7.x86_64.rpm | 41 kB 00:00:00 (3/5): libsolv-0.6.34-4.el7.x86_64.rpm | 329 kB 00:00:00 (4/5): deltarpm-3.6-3.el7.x86_64.rpm | 82 kB 00:00:00 (5/5): python2-hawkey-0.6.3-4.el7.x86_64.rpm | 73 kB 00:00:00 -------------------------------------------------------------------------------------------------------------------------------------------------------------------- Total 743 kB/s | 614 kB 00:00:00 Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : libsolv-0.6.34-4.el7.x86_64 [ ] 1/8 Installing : libsolv-0.6.34-4.el7.x86_64 [######### ] 1/8 Installing : libsolv-0.6.34-4.el7.x86_64 [################### ] 1/8 Installing : libsolv-0.6.34-4.el7.x86_64 [############################# ] 1/8 Installing : libsolv-0.6.34-4.el7.x86_64 [####################################### ] 1/8 Installing : libsolv-0.6.34-4.el7.x86_64 [################################################## ] 1/8 Installing : libsolv-0.6.34-4.el7.x86_64 [########################################################### ] 1/8 Installing : libsolv-0.6.34-4.el7.x86_64 [##################################################################### ] 1/8 Installing : libsolv-0.6.34-4.el7.x86_64 [############################################################################### ] 1/8 Installing : libsolv-0.6.34-4.el7.x86_64 [####################################################################################### ] 1/8 Installing : libsolv-0.6.34-4.el7.x86_64 [################################################################################################## ] 1/8 Installing : libsolv-0.6.34-4.el7.x86_64 [########################################################################################################### ] 1/8 Installing : libsolv-0.6.34-4.el7.x86_64 [################################################################################################################ ] 1/8 Installing : libsolv-0.6.34-4.el7.x86_64 1/8 Installing : hawkey-0.6.3-4.el7.x86_64 [ ] 2/8 Installing : hawkey-0.6.3-4.el7.x86_64 [######################################### ] 2/8 Installing : hawkey-0.6.3-4.el7.x86_64 [#################################################################################### ] 2/8 Installing : hawkey-0.6.3-4.el7.x86_64 [################################################################################################ ] 2/8 Installing : hawkey-0.6.3-4.el7.x86_64 [################################################################################################# ] 2/8 Installing : hawkey-0.6.3-4.el7.x86_64 [################################################################################################################## ] 2/8 Installing : hawkey-0.6.3-4.el7.x86_64 2/8 Installing : python2-hawkey-0.6.3-4.el7.x86_64 [ ] 3/8 Installing : python2-hawkey-0.6.3-4.el7.x86_64 [###### ] 3/8 Installing : python2-hawkey-0.6.3-4.el7.x86_64 [############### ] 3/8 Installing : python2-hawkey-0.6.3-4.el7.x86_64 [####################### ] 3/8 Installing : python2-hawkey-0.6.3-4.el7.x86_64 [################################################################# ] 3/8 Installing : python2-hawkey-0.6.3-4.el7.x86_64 [################################################################################################# ] 3/8 Installing : python2-hawkey-0.6.3-4.el7.x86_64 [################################################################################################## ] 3/8 Installing : python2-hawkey-0.6.3-4.el7.x86_64 [######################################################################################################### ] 3/8 Installing : python2-hawkey-0.6.3-4.el7.x86_64 [########################################################################################################## ] 3/8 Installing : python2-hawkey-0.6.3-4.el7.x86_64 3/8 Installing : libreport-filesystem-2.1.11-53.el7.x86_64 [ ] 4/8 Installing : libreport-filesystem-2.1.11-53.el7.x86_64 [############# ] 4/8 Installing : libreport-filesystem-2.1.11-53.el7.x86_64 [########################### ] 4/8 Installing : libreport-filesystem-2.1.11-53.el7.x86_64 [########################################## ] 4/8 Installing : libreport-filesystem-2.1.11-53.el7.x86_64 [######################################################## ] 4/8 Installing : libreport-filesystem-2.1.11-53.el7.x86_64 [####################################################################### ] 4/8 Installing : libreport-filesystem-2.1.11-53.el7.x86_64 [###################################################################################### ] 4/8 Installing : libreport-filesystem-2.1.11-53.el7.x86_64 4/8 Installing : dnf-conf-0.6.4-2.sdl7.noarch [ ] 5/8 Installing : dnf-conf-0.6.4-2.sdl7.noarch [##################### ] 5/8 Installing : dnf-conf-0.6.4-2.sdl7.noarch [###################### ] 5/8 Installing : dnf-conf-0.6.4-2.sdl7.noarch [####################### ] 5/8 Installing : dnf-conf-0.6.4-2.sdl7.noarch [########################### ] 5/8 Installing : dnf-conf-0.6.4-2.sdl7.noarch [############################# ] 5/8 Installing : dnf-conf-0.6.4-2.sdl7.noarch [############################## ] 5/8 Installing : dnf-conf-0.6.4-2.sdl7.noarch [################################### ] 5/8 Installing : dnf-conf-0.6.4-2.sdl7.noarch [################################################################################################### ] 5/8 Installing : dnf-conf-0.6.4-2.sdl7.noarch [##################################################################################################### ] 5/8 Installing : dnf-conf-0.6.4-2.sdl7.noarch [############################################################################################################### ] 5/8 Installing : dnf-conf-0.6.4-2.sdl7.noarch 5/8 Installing : deltarpm-3.6-3.el7.x86_64 [ ] 6/8 Installing : deltarpm-3.6-3.el7.x86_64 [################################## ] 6/8 Installing : deltarpm-3.6-3.el7.x86_64 [##################################### ] 6/8 Installing : deltarpm-3.6-3.el7.x86_64 [################################################################## ] 6/8 Installing : deltarpm-3.6-3.el7.x86_64 [#################################################################################################### ] 6/8 Installing : deltarpm-3.6-3.el7.x86_64 [####################################################################################################### ] 6/8 Installing : deltarpm-3.6-3.el7.x86_64 [############################################################################################################## ] 6/8 Installing : deltarpm-3.6-3.el7.x86_64 [################################################################################################################# ] 6/8 Installing : deltarpm-3.6-3.el7.x86_64 [################################################################################################################## ] 6/8 Installing : deltarpm-3.6-3.el7.x86_64 6/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [ ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [####### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [########### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [############# ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [############### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [################# ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [##################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [####################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [########################## ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [########################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [############################ ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [############################# ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [############################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [################################ ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [################################# ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [################################## ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [#################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [######################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [########################################## ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [############################################# ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [############################################## ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [################################################# ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [################################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [#################################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [##################################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [###################################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [####################################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [######################################################## ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [######################################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [########################################################## ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [########################################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [############################################################# ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [############################################################## ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [############################################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [################################################################# ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [################################################################## ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [#################################################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [##################################################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [####################################################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [######################################################################## ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [######################################################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [############################################################################# ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [################################################################################# ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [#################################################################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [##################################################################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [###################################################################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [######################################################################################## ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [######################################################################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [########################################################################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [############################################################################################ ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [############################################################################################# ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [############################################################################################## ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [############################################################################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [################################################################################################ ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [################################################################################################## ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [################################################################################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [##################################################################################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [###################################################################################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [####################################################################################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [######################################################################################################## ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [######################################################################################################### ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [########################################################################################################## ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [############################################################################################################ ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch [############################################################################################################# ] 7/8 Installing : python-dnf-0.6.4-2.sdl7.noarch 7/8 Installing : dnf-0.6.4-2.sdl7.noarch [ ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [# ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [#### ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [####### ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [########### ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [################ ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [###################### ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [####################### ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [######################### ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [############################### ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [#################################### ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [###################################### ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [############################################## ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [############################################### ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [################################################ ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [###################################################### ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [######################################################### ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [############################################################### ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [################################################################### ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [####################################################################### ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [######################################################################### ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [########################################################################## ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [################################################################################# ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [####################################################################################### ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [########################################################################################## ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [############################################################################################## ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [################################################################################################ ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [################################################################################################### ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [######################################################################################################### ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [############################################################################################################# ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [################################################################################################################### ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch [#################################################################################################################### ] 8/8 Installing : dnf-0.6.4-2.sdl7.noarch 8/8 Verifying : dnf-conf-0.6.4-2.sdl7.noarch 1/8 Verifying : python-dnf-0.6.4-2.sdl7.noarch 2/8 Verifying : deltarpm-3.6-3.el7.x86_64 3/8 Verifying : libsolv-0.6.34-4.el7.x86_64 4/8 Verifying : libreport-filesystem-2.1.11-53.el7.x86_64 5/8 Verifying : python2-hawkey-0.6.3-4.el7.x86_64 6/8 Verifying : hawkey-0.6.3-4.el7.x86_64 7/8 Verifying : dnf-0.6.4-2.sdl7.noarch 8/8 Installed: dnf.noarch 0:0.6.4-2.sdl7 dnf-conf.noarch 0:0.6.4-2.sdl7 python-dnf.noarch 0:0.6.4-2.sdl7 Dependency Installed: deltarpm.x86_64 0:3.6-3.el7 hawkey.x86_64 0:0.6.3-4.el7 libreport-filesystem.x86_64 0:2.1.11-53.el7 libsolv.x86_64 0:0.6.34-4.el7 python2-hawkey.x86_64 0:0.6.3-4.el7 Complete! [root@ip-10-0-1-244 ec2-user]# redhatcat /etc/redhat-release Red Hat Enterprise Linux Server release 7.7 (Maipo) [root@ip-10-0-1-244 ec2-user]# whic h dnf /bin/dnf [root@ip-10-0-1-244 ec2-user]#
- 投稿日:2021-12-03T20:32:30+09:00
ゼロから作るDeep Learning 自然言語処理編を理解する Chap3
概要 本記事では,ゼロから作るDeep Learning 自然言語処理編を理解することを目指し,その箇所の引用・自分なりに大事だなと思ったこと・感想などをまとめていきます.(知識不足な所も多々ありますが,温かい目で見守って頂ければと思います) これまでの記事はこちらから 1章:ニューラルネットワークの復習 2章:自然言語と単語の分散表現 本記事では,書籍の3章(word2vec)を扱います. Chap3 - word2vec(pp. 93~129) 前章では,周囲の語の共起を元にした,カウントベース手法による単語分散表現を扱いました. 単語分散表現を得る手法として,カウントベース手法の他に,推論ベース手法があります. 本章では推論ベース手法の中でもword2vecを扱い,その仕組み,実装を理解するだけでなく,カウントベース手法との違いについて理解することがGoalになります. 3.1 推論ベースの手法とニューラルネットワーク この節では,カウントベース手法の問題点と,推論ベース手法の強みについて理解することがGoalになります. ・ 推論ベース手法とは 推論ベースの手法では,「推論」することが主な作業になります.これは,周囲の単語(コンテキスト)が与えられた時に,「?」(周囲のコンテキストに対して中心の語)にどのような単語が出現するのかを推測する作業です. 推論ベースの手法では,あえて正解データに対して「マスク」をし,マスクをした部分に対する(推論問題)穴埋め問題を繰り返し解きます.その穴埋め問題に対するアプローチが「モデル」であり,穴埋めが正しいものとなるように学習させていきます. そうした穴埋め問題による学習の結果得られるのが,単語の分散表現であり,あくまで学習の副産物に過ぎない点は要注意です. 3.2 シンプルなword2vec この節では,word2vecを実現するNNの仕組み,具体的に入力層と中間層,出力層について理解することがGoalになります. ・ そもそもword2vecとは?? word2vecという言葉は,(中略)ニューラルネットワークのモデルを指す場合も多く見受けられます.正しくは,CBOWモデルとskip-gramモデルという2つのモデルがword2vecで使用されるニューラルネットワークです. word2vecはEfficient Estimation of Word Representations in Vector Spaceという論文で提案されたNNモデルになります. 2層のNNである点に注目ですね. ・ CBOWモデルについて CBOWモデルは,コンテキストからターゲットを推測することを目的としてニューラルネットワークです.(「ターゲット」は中央の単語,その周囲の単語が「コンテキスト」).このCBOWモデルをできるだけ正確な推測ができるように訓練することで,私たちは単語の分散表現を獲得することができます. CBOW(Continuous Bag-of-Words)とは,周辺の単語から中心の語を予測する教師あり学習モデルです.以下は,CBOWモデルの概略図で,参考【1】から引用しました. 図にあるように,入力は周辺語であり出力は中心語になります. 簡単に各層について理解していきます. Input Layer(入力層) $V$次元($V$=登場する語彙数)で,$C$個($C=$コンテキストの数)のニューロンからなります. Hidden Layer(隠れ層,または中間層) $N$次元からなります Output Layer(出力層) $V$次元のニューロンからなります.出力層のニューロンは$V$個ある単語のスコアになっており,その値が高いほどその単語が出現しやすいことを表しています.このスコアに対してSoftmax関数を当てはめると確率的な解釈を行うことができ,ある語を入力した時に出現しやすい語の「確率」を求めることができます. ここで注目したいのが,全結合層が入力層→中間層の $W_{V×N}(W_{in})$ と,中間層→出力層の$W_{N×V}(W_{out})$の2種類存在する点です. この全結合層の重み$W$の各行(行は語彙数$V$の数だけ存在)には,単語の分散表現が格納されていると考えることができます. なぜなら,元々入力層の数だけあったニューロンをN次元に圧縮していると考えることができ,結果的に単語の情報がコンパクトにまとめられたと言える為です. ・ 利用する分散表現 word2vecで使用されるネットワークには2つの重みがあります.それは入力側の全結合層の重み($W_{in}$)と,出力層の全結合層の重み($W_{out}$)です. Point : W_{in}\, or \,W_{out} これまでも紹介したように,CBOWモデルで学習の結果得られる単語の分散表現には,入力側の重みである$W_{in}$と,出力側の重みである$W_{out}$の2種類があります. ここで1つの疑問が湧きます. それは,どちらの重みを使ったら良い結果が得られるのかという問題です. 多くの研究では,$W_{in}$だけを単語の分散表現として用いた方が良い結果が得られることが明らかにされていますが,$W_{out}$も使いようによっては,精度向上に役立つかもしれません. 3.3 学習データの準備 この節では,実際のコーパスを処理・分析する関数を理解することがGoalになります. 書籍では,実際のSentenceをどのようにNNに学習させるか,いわゆる前処理の段階を扱っています. 3.4 CBOWモデルの実装 この節では,word2vecをCBOWモデルを使って実装することを目指します. CBOWモデルの学習を重ねるごとに,lossが小さくなるのを実感して喜ぶのがGoalになります 実際に書籍のプログラムを回し,感動して見て下さい!! 3.5 word2vecに関する補足 この節では,word2vecのCBOWモデルを確率的な視点で見ること,また,word2vecのもう1つのモデルであるskip-gramモデルについて理解することがGoalになります. ・ CBOWモデルと確率 CBOWモデルが行うことは,コンテキストを与えるとターゲットとなる単語の確率を出力することでした.(中略)コンテキストとして$w_{t-1}$と$w_{t+1}$が与えられた時にターゲットが$w_{t}$となる確率は次のように表すことができます. P(\,w_{t}\, |\, w_{t-1},w_{t+1}) コンテキスト($w_{t-1}$,$w_{t+1}$)からターゲット$w_{t}$が出現する確率を知りたい,と考えた時にCBOWモデルは上の式をモデル化していると考えることができます. ・ skip-gramモデル word2vecでは2つのモデルが提案されています.1つはこれまで見てきたCBOWモデル,そしてもう1つはskip-gramと呼ばれるモデルです.skip-gramは,CBOWで扱うコンテキストとターゲットを逆転させたモデルです. skip-gramモデルは,入力として中心語を与え,その周辺語を予測する教師あり学習モデルです.以下は,skip-gramモデルの概略図で,参考【1】から引用しました. 図にあるように,入力は中心語(1語)であり,出力は周辺語(コンテキストの数だけ存在)になります. 簡単に各層について理解していきます. Input Layer(入力層) $V$次元($V$=登場する語彙数)で,$1$つのニューロンからなります. Hidden Layer(隠れ層,または中間層) $N$次元からなります Output Layer(出力層) $V$次元($V$=登場する語彙数)で,$C$個($C=$コンテキストの数)のニューロンからなります.ある中心語に対する$C$つのコンテキストにおいて,出現されやすい語がスコアとして表されます. 先に示したCBOWモデルと比べてみると,skip-gramは入力が1ニューロンの一方で出力は周辺語の数だけ必要になり,学習難しくない?? CBOWの方が絶対良いじゃんと思いました. そうした予想に反して,特に大規模なコーパスの場合にskip-gramモデルの方が良い精度を示す場合が多いそうです.以下のような理由からそのように考えられると思われます. 損失を計算する際に,コンテキストの数だけ求める必要があり1回の学習に時間がかかる これは一見デメリットのように思えますが,それだけしっかりと(??)学習しているとも捉えることができます. 大規模なコーパスの場合,低頻出な語(レアな語)が多い skip-gramはこうしたレアな語に対しても,良い感じに学習できるようです. ちなみに,こちらの論文ではCBOWモデルとskip-gramモデルの双方で実験を行ない,やはりskip-gramモデルの方が良い精度が出たそうです. ・カウントベースと推論ベースの比較 カウントベースの手法は,コーパス全体の統計データから1回の学習で単語の分散表現を得ました.一方,推論ベースでは,コーパスの一部を何度も見ながら学習しました(ミニバッチ学習). ここでは,カウントベース手法と推論ベース手法の比較を行いたいと思います. 新しい語彙を追加したい時:推論ベースが良い カウントベース ゼロから計算を行う為,大変(共起行列を作り直す必要があるため). 推論ベース これまで学習した「重み」を活かして,再学習できる 分散表現の性質・精度:類似性に関する定量評価では遜色なし カウントベース 単語の類似性を捉えることができる 類推問題は解けない 推論ベース 類似性&パターンも捉えることができる 例えば,「king - man + woman = queen」といった類推問題が解ける 3.6 まとめ word2vecについて以下のようにまとめることができます. word2vecは・・・ 2層のNNで構成される CBOWモデルとskip-gramモデルがあり,中心語(ターゲット)と周囲語(コンテキスト)の関係に注目する 重みの再学習が行える点で,カウントベース手法より優位 ただし,精度においてカウントベースと大きな差がある訳ではない Chap3のまとめと所感 本章では,単語の分散表現を得るために推論ベースの手法,特にword2vecについての理解を深めることができました. 次章では,word2vecをより良いモデルにするための工夫について見ていきます. それでは,次章Chapter4でお会いしましょう? 参考文献 【1】word2vec Parameter Learning Explained
- 投稿日:2021-12-03T20:21:12+09:00
Google Cloud Talent Solutionで求人検索までしてみる
はじめに 株式会社じげん エンジニアの酒匂(さこう)と申します。 「アルバイトEX」「転職EX」をはじめとした求人サービスを担当しています。 今回は求人検索で使えそうなGoogle Cloud Talent Solution(以降CTSと呼ぶ)という検索サービスを使ってみます。 Google Cloud Talent Solutionとは GoogleのAIを使って検索ワードのスペルミスを補助したり、検索条件に対してより関連度の高いものを結果として出してくれるものらしいです。 また、過去の集計データに基づいた通勤方法、移動時間、開始座標を用いて通勤時間での検索や指定した場所の半径数マイル(可変)範囲内にある求人を検索することもできます。 1ヶ月あたりの呼び出した求人数、登録した求人&企業数がそれぞれ10,000件までであれば無料で使えますが、10,001件以上は料金が発生するようです。 事前準備 こちらに沿って設定を進めてCTSを開始する為の事前準備をします。 このまま行えば問題ないのですが、新しいサービスアカウントにロールを割り当てる際は ・管理者 ・ジョブ編集者 ・プロファイル編集者 の3つを設定すると求人情報の登録が行えるようになります。 これでCTSを使う準備は完了です。 会社を作成 今回はPythonを使用していきます。 クイックスタートの「会社と求人の作成編」にサンプルコードがありますのでそちらを使用します。 まず求人情報の親となる会社を作成します。 が、ここに罠が潜んでます... サンプルコードに引数を渡しただけでは動かないので、以下のように修正します。 cts1.py from google.cloud import talent import six def create_company(project_id, tenant_id, display_name, external_id): client = talent.CompanyServiceClient() if isinstance(project_id, six.binary_type): project_id = project_id.decode("utf-8") if isinstance(tenant_id, six.binary_type): tenant_id = tenant_id.decode("utf-8") if isinstance(display_name, six.binary_type): display_name = display_name.decode("utf-8") if isinstance(external_id, six.binary_type): external_id = external_id.decode("utf-8") parent = f"projects/{project_id}/tenants/{tenant_id}" # tenant_idを指定していなければデフォルトで作成されているtenantの下に保存される if not tenant_id: parent = f"projects/{project_id}" company = {"display_name": display_name, "external_id": external_id} response = client.create_company(parent=parent, company=company) print("Created Company") print("Name: {}".format(response.name)) print("Display Name: {}".format(response.display_name)) print("External ID: {}".format(response.external_id)) return response.name tenantはすでに作成されているidを指定するか、そもそもtenantを指定しないようにしなければ会社を作成することができません。 tenantを指定しない場合はデフォルトで作成されているtenantの下に会社が作成されます 実行 $ python3 -c "import cts1; cts1.create_company('project_id','','test','1')" 会社を作成できたので次に求人情報を作成していきます。 求人を作成 今回も例の罠があるので、サンプルコードを以下のように修正します。 cts2.py from google.cloud import talent import six def create_job(project_id, tenant_id, company_id, requisition_id): client = talent.JobServiceClient() job_application_url = f"https://www.example.org/job-posting/{requisition_id}" if isinstance(project_id, six.binary_type): project_id = project_id.decode("utf-8") if isinstance(tenant_id, six.binary_type): tenant_id = tenant_id.decode("utf-8") if isinstance(company_id, six.binary_type): company_id = company_id.decode("utf-8") if isinstance(requisition_id, six.binary_type): requisition_id = requisition_id.decode("utf-8") if isinstance(job_application_url, six.binary_type): job_application_url = job_application_url.decode("utf-8") parent = f"projects/{project_id}/tenants/{tenant_id}" # tenant_idを指定していなければデフォルトで作成されているtenantの下に保存される if not tenant_id: parent = f"projects/{project_id}" uris = [job_application_url] application_info = {"uris": uris} addresses = [ "1600 Amphitheatre Parkway, Mountain View, CA 94043", "111 8th Avenue, New York, NY 10011", ] job = { "company": company_id, "requisition_id": requisition_id, "title": "Software Developer", "description": "Develop, maintain the software solutions.", "application_info": application_info, "addresses": addresses, "language_code": "en-US", } response = client.create_job(parent=parent, job=job) print("Created job: {}".format(response.name)) return response.name company_idには先ほど作成した会社のidを使用します。 projects/project_id/tenants/tenant_id/companies/○○ この○○の部分が会社IDになりますので、これを引数に渡して指定します。 $ python3 -c "import cts2; cts2.create_job('project_id','','company_id','1')" これで求人が作成できました。 いくつか求人を作成したら次はいよいよ検索してみましょう。 検索 クイックスタートの「検索編」では最初にフィールドごとの求人数のヒストグラムを取得するとあるのですが、今回は結果がわかりやすいようにキーワード検索を作ってみました。 cts3.py from google.cloud import talent import six def search_job(project_id, tenant_id, query): client = talent.JobServiceClient() if isinstance(project_id, six.binary_type): project_id = project_id.decode("utf-8") if isinstance(tenant_id, six.binary_type): tenant_id = tenant_id.decode("utf-8") if isinstance(query, six.binary_type): query = query.decode("utf-8") parent = f"projects/{project_id}/tenants/{tenant_id}" # tenant_idを指定していなければデフォルトで作成されているtenantの下に保存される if not tenant_id: parent = f"projects/{project_id}" domain = "www.example.com" session_id = "Hashed session identifier" user_id = "Hashed user identifier" request_metadata = {"domain": domain, "session_id": session_id, "user_id": user_id} job_query = talent.JobQuery( query=query, query_language_code='en-US' ) results = [] request = talent.SearchJobsRequest( parent=parent, request_metadata=request_metadata, job_query=job_query ) for response_item in client.search_jobs(request=request).matching_jobs: print(f"Job summary: {response_item.job_summary}") print(f"Job title snippet: {response_item.job_title_snippet}") job = response_item.job results.append(job) print(f"Job name: {job.name}") print(f"Job title: {job.title}") return results これで引数に渡したキーワードで検索できるようになったので、先ほど作成した求人が検索できるか見てみます。 $ python3 -c "import cts3; cts3.search_job('project_id','','Software')" Job summary: Develop, maintain the software solutions. Job title snippet: <b>Software</b> Developer Job name: projects/project_id/tenants/tenant_id/jobs/requisition_id Job title: Software Developer 検索できましたね。 まとめ いつもはRubyを使っているので今回初めてPythonを使っていろいろハマりました... 今はまだ検索精度についてメリットがあるかどうかはわかりませんが、今後検証していってみたいと思います。 あまり日本語のCTSについての記事が無いので、みなさんの参考になれば幸いです。
- 投稿日:2021-12-03T19:23:53+09:00
Tkinterだってアンチエイリアスしたい。
Tkinterだってアンチエイリアスしたい それくらい夢見たっていいでしょう。 ってことですが、元々は業務で利用しているTkinterのラッパーで用事があったものです。 その時は良い結果が得られずに結局ギザギザの通常の描画で流したのですが、使えば使うほどやっぱり滑らかな描画さえできれば世界が変わる、そんな気がしたんだ! MacのTkinterは元々アンチエイリアスありで描画されるらしい?ので無関係かもしれませんがー? とりあえず考えてみる。 アンチエイリアスのラインアルゴリズムでは Xiaolin Wu 先生のものが有名です。 試しに一度Canvasに仕込んでみたのですが普通にラインを描くだけなら良いのですけれどもその他諸々をしようとすると何かと不便があったのでここでは別の方法を使います。 座標は自然数で扱うこととし(ぁ) 一つの描画座標はx~x+1、y~y+1の合計4点の座標に作用するとしてそれぞれの座標に対して色の濃さを表してゆけば事実上アンチエイリアスが可能だろうと。そういうことを考えたので実装してみます。 ※頭の中の概念図 そして、直接Canvasに描画すると何か問題があった記憶があるのでPhotoImageとして扱うことにします。 アンチエイリアス対応PhotoImage、AAImage コード aaimage.py import tkinter as tk class AAImage(tk.PhotoImage): def __init__(self, conf={}, **kwargs): super().__init__(conf, **kwargs) self.pixpos = [(0, 0), (1, 0), (0, 1), (1, 1)] def rgbtohex(self, r, g, b): return "#%02x%02x%02x" % (int(r), int(g), int(b)) def hexcolor(self, color): return self.rgbtohex(int(color[0]), int(color[1]), int(color[2])) """ color fill """ def fill(self, color): d = [self.hexcolor(color)] * int(self.height()) for x in range(int(self.width())): self.put(d, (x, 0)) """ 4 point antialiasing ** Not optimized ** """ def pset(self, x, y, color=(255,255,255)): R, G, B = color pp = [0] * 4 pp[0] = (1 - self.pp(x)) * (1 - self.pp(y)) pp[1] = self.pp(x) * (1 -self.pp(y)) pp[2] = (1 - self.pp(x)) * self.pp(y) pp[3] = self.pp(x) * self.pp(y) for i in range(4): px = int(x + self.pixpos[i][0]) py = int(y + self.pixpos[i][1]) if pp[i] > 0: if px >= 0 and px < int(self.width()) \ and py >= 0 and py < int(self.height()): bR, bG, bB = self.get(px, py) tc = ( int(R * pp[i] + bR * (1 - pp[i])), int(G * pp[i] + bG * (1 - pp[i])), int(B * pp[i] + bB * (1 - pp[i])) ) self.put(self.hexcolor(tc), (px, py)) """ draw line """ def line(self, x1, y1, x2, y2, color=(0, 0, 0)): xmax = max(x1, x2) ymax = max(y1, y2) xmin = min(x1, x2) ymin = min(y1, y2) xr = xmax - xmin yr = ymax - ymin x = x1 y = y1 if xr > yr: yy = (y2 - y1) / xr for i in range(xr): self.pset(x, y, color) x += 1 y += yy else: xx = (x2 - x1) / yr for i in range(yr): self.pset(x, y, color) x += xx y += 1 def pp(self, value): return value - int(value) 解説 とりあえず1ピクセルを描画するための pset(実際には最大4ピクセルが描画される)とそれを利用した line を実装しました。 画面を塗り替えたい事も多かったのでついでに fill も。 キモは pset なのですが残念ながら最適化はしていません。 誰かがカッコよく使いやすくして各種の描画アルゴリズムも実装して公開してくれるのを期待しています 各種描画アルゴリズムを実装すると便利に使えそうですね! 実際に使ってみる import random as rnd import tkinter as tk import aaimage root = tk.Tk() c = tk.Canvas(root) c.pack(fill="both", expand=True) image = aaimage.AAImage(width=150, height=150) c.create_image(0, 0, image=image, anchor="nw") image.fill((255,255,255)) # random dot for i in range(200): x = rnd.random() * image.width() y = rnd.random() * image.height() image.pset(x, y, (0,0,255)) # somooth line image.line(100, 5, 20, 120, (255, 0, 0)) image.line(10, 10, 130, 30, (0, 255, 0)) root.mainloop() 継承してるので当たり前ですが tk.PhotoImage のノリでそのまま使えます。 実行結果 単体のドットには思うところがありますけれども1ピクセル以下を表現しようとしているわけなのでこれ以上どうともならないでしょう。 ということで、大成功! これをガンd 何事も諦めなければどうにかなるものですネ!
- 投稿日:2021-12-03T19:08:03+09:00
【Python】Tポイントカンタンくじを自動で引く+1円寄付するスクリプト【Selenium】
やりたいこと ↑のくじを毎日引いて、翌日にどこかでTポイントを使いましょう この記事では1円寄付してます 動作環境 OS:Windows10 GoogleChrome バージョン: 96.0.4664.45(Official Build) (64 ビット) Python:3.6.9 Selenium Webdriver:3.141.0 chromedriver.exe:96.0.4664.45 ※スクリプトと同じフォルダに'chromedriver.exe'を置いてください。 ※待機時間は適当なので適宜変更してください。 くじ引き kujibiki.py from selenium import webdriver from time import sleep url = "https://lot.tsite.jp/#/detail2/cccmk_yxm_005" driver = webdriver.Chrome('./chromedriver.exe') #ブラウザを開く driver.get(url) #「ログインしてくじを引く!」ボタンをクリックする kuji_login = driver.find_element_by_xpath("//*[@id=\"app\"]/app-button-top/main/article/section/div[3]/div/span/img") kuji_login.click() #「ログイン」ボタンをクリックする login_button = driver.find_element_by_xpath("//*[@id=\"contentInner\"]/div[2]/div[2]/div[2]/input") login_button.click() #Yahoo!iD、パスワードを入力する your_id = "あなたのID" your_password = "あなたのパスワード" #IDを入力する id_input = driver.find_element_by_xpath("//*[@id=\"username\"]") id_input.send_keys(your_id) #「次へ」をクリックする next = driver.find_element_by_xpath("//*[@id=\"btnNext\"]") next.click() sleep(1) #パスワードを入力する password_input = driver.find_element_by_xpath("//*[@id=\"passwd\"]") password_input.send_keys(your_password) #「ログイン」をクリックする login = driver.find_element_by_xpath("//*[@id=\"btnSubmit\"]") login.click() sleep(1) #「くじを引く!」をクリックする #Tカードを登録していなければ初回のみ登録画面が出る(上手くいかなかったら手動で押してください……) cur_url = driver.current_url if cur_url == "https://lot.tsite.jp/#/detail2/cccmk_yxm_005": get_kuji = driver.find_element_by_xpath("//*[@id=\"app\"]/app-button-top/main/article/section/div[3]/div/span/img") get_kuji.click() else: try: #「登録する」のチェックを外す checkbox = driver.find_element_by_xpath("//*[@id=\"tmallmail\"]") checkbox.click() # 「登録する」を押す register = driver.find_element_by_xpath("//*[@id=\"form1\"]/div/input") register.click() #くじを引く get_kuji = driver.find_element_by_xpath("//*[@id=\"app\"]/app-button-top/main/article/section/div[3]/div/span/img") get_kuji.click() except: driver.quit() sleep(1) driver.quit() 寄付 kifu.py from selenium import webdriver from time import sleep url = "https://tsite.jp/donation/index.pl" driver = webdriver.Chrome('./chromedriver.exe') #ブラウザを開く driver.get(url) #ログイン login = driver.find_element_by_xpath("//*[@id=\"user-nav\"]/ul/li[2]/a/span") login.click() #「ログイン」ボタンをクリックする login_button = driver.find_element_by_xpath("//*[@id=\"contentInner\"]/div[2]/div[2]/div[2]/input") login_button.click() sleep(1) #Yahoo!iD、パスワードを入力する your_id = "あなたのID" your_password = "あなたのパスワード" #idを入力 id_input = driver.find_element_by_xpath("//*[@id=\"username\"]") id_input.send_keys(your_id) #「次へ」をクリック next = driver.find_element_by_xpath("//*[@id=\"btnNext\"]") next.click() sleep(1) #パスワードを入力する password_input = driver.find_element_by_xpath("//*[@id=\"passwd\"]") password_input.send_keys(your_password) #「ログイン」をクリックする login = driver.find_element_by_xpath("//*[@id=\"btnSubmit\"]") login.click() #募金ページに移動する bokin_url = "https://tsite.jp/donation/index.pl?xpg=PCTC0202&bokin_id=507" #任意の募金ページを指定できます driver.get(bokin_url) #「寄付する」ボタンをクリックする bokin_button = driver.find_element_by_xpath("//*[@id=\"charity_button\"]/div/a/img") bokin_button.click() #パスワードの再入力 password_input = driver.find_element_by_xpath("//*[@id=\"passwd\"]") password_input.send_keys(your_password) #「ログイン」をクリックする login = driver.find_element_by_xpath("//*[@id=\"btnSubmit\"]") login.click() #募金額を入力する money_box = driver.find_element_by_xpath("//*[@id=\"charity_input_point\"]/input") money_box.send_keys(1) #募金額はここで変えられます。デフォルトでは1円 sleep(0.5) #「次へ」をクリックする next = driver.find_element_by_xpath("//*[@id=\"charity_button\"]/div[1]/input") next.click() sleep(0.5) #「確定」をクリックする confirm = driver.find_element_by_xpath("//*[@id=\"charity_button\"]/div[1]/input[1]") confirm.click() sleep(1) driver.quit()
- 投稿日:2021-12-03T19:00:33+09:00
Webex Meetingsの仮想背景を自動的に切り替える
はじめに この記事はシスコの有志による Cisco Systems Japan Advent Calendar 2021 (2枚目)の 4日目です。 2017年版: https://qiita.com/advent-calendar/2017/cisco 2018年版: https://qiita.com/advent-calendar/2018/cisco 2019年版: https://qiita.com/advent-calendar/2019/cisco 2020年版 1枚目: https://qiita.com/advent-calendar/2020/cisco 2020年版 2枚目: https://qiita.com/advent-calendar/2020/cisco2 2021年版 1枚目: https://qiita.com/advent-calendar/2021/cisco 2021年版 2枚目: https://qiita.com/advent-calendar/2021/cisco2 <---こちら 本記事は昨年の Cisco Systems Japan Advent Calendar 2020 (1枚目)の23日目「Merakiカメラで3密を避けるシリーズ」”第三弾:イベント広告のダイナミック掲示”の続編になります。 https://qiita.com/hiokazak/items/9dc63725fe9000256e88 今年はバーチャルイベントやリモート参加もできるハイブリッドイベント会場で、Webex Meetingsを使ってリモートからイベントへ入っている参加者の属性に合わせた広告をダイナミック掲示するソリューションをCisco有志メンバーで考案しました。 今回やりたいこと Webex Desk Proを使ってWebex Meetingsの仮想背景に、参加者の属性に合わせた広告を自動的に表示します。 広告掲示手順 Step1: Webex Desk ProのAPIでWebex Meetings参加者情報を取得 Step2: イベント登録データベースから参加者の属性をマッピング Step3: 人数の多い属性向けの広告を仮想背景に表示する 今回のソリューションを使えば、技術者が多い場合にはエンジニアイベントの案内、パリピが多い場合にはパーティーの案内など、参加者とデータベースを組み合わせて最適な広告を自動表示することができます。 仕組み Webex Desk ProのAPIを使ってビデオ会議参加者情報を取得し、参加者に合わせた広告を表示します。 ビデオ会議参加者が増減し、属性が変化すると以下の手順で広告が自動的に切り替わります 広告配信サーバがWebex Meetings参加者情報とイベントデータベースから属性を特定 属性に合わせて広告画像を準備 広告画像を仮想背景としてWebex Desk Proへアップロード 仮想背景を新しい広告へ変更 Webex Desk ProのAPIの使い方 詳しい使い方は Webex デバイスのマクロを使って朝から元気にお仕事 をご覧下さい 実行コード Pythonスクリプト webexbg.py import requests import shutil import os import xml.etree.ElementTree as ET import urllib3 import http.client import ssl import sys import operator from PIL import Image, ImageDraw, ImageFont import base64 from io import BytesIO import configparser import csv from collections import Counter import ast import time configFile = "webex_settings.ini" def read_csv(): csv_file = open("./test.csv", "r", errors="", newline="") f = csv.reader(csv_file, delimiter=",", doublequote=True, lineterminator="\r\n", quotechar='"', skipinitialspace=True) header = next(f) dict_from_csv = {i[0]:i[1] for i in f} return dict_from_csv def get_from_ini(key): if config.has_option('Settings', key): key_value = config['Settings'][key] if key == "scale_logo": key_value = config.getboolean('Settings',key) elif len(key_value) > 0 and key_value[0] == "_" and key_value[-1:] == "_": print(f"\n**ERROR** please configure item '{key}' in the .ini file\n") exit() return key_value else: print(f"\n**ERROR** missing entry in .ini file: {key}\nAdd this key or rename the .ini file to create a new one.") exit() config = configparser.ConfigParser(allow_no_value=True) if os.path.isfile("./" + configFile): try: config.read('./' + configFile) endpoint_ip = get_from_ini("endpoint_ip") d_inputfile = ast.literal_eval(get_from_ini("my_inputfile")) my_logofolder = r'{}'.format(get_from_ini("my_logofolder")) if my_logofolder[-1:] == "\\": my_logofolder = r'{}'.format(my_logofolder[:-1]) my_token_xapi = get_from_ini("my_token_xapi") my_user_image_location = get_from_ini("my_user_image_location") except Exception as e: print(f"\n**ERROR** reading settings file.\n ERROR: {e} ") exit() else: try: config = configparser.ConfigParser(allow_no_value=True) config.add_section('Settings') config.set('Settings', 'endpoint_ip ', 'IP') config.set('Settings', 'my_inputfile ', '{BACKGROUND_IMAGE_FILENAMES}') config.set('Settings', 'my_logofolder', '') config.set('Settings', 'my_token_xapi', 'TOKEN') config.set('Settings', 'my_user_image_location ', 'User3') with open('./' + configFile, 'w') as configfile: config.write(configfile) print(f"\n*NOTE* configuration .ini file does not exist\n ---> open the generated .ini file to configure this script\n") exit() except Exception as e: print(f"\n**ERROR** creating config file.\n ERROR: {e} ") exit() def read_allparticipants(): getparticipant_payload = "<Command><Conference><ParticipantList><Search></Search></ParticipantList></Conference></Command>" participant_xml = xapiCall(headers,getparticipant_payload, endpoint_ip) #print(participant_xml) if "not found" in participant_xml: print(f"\n*NOTE* No active call\n") exit() if "error" in participant_xml.lower(): print(f"\n**ERROR** Getting participant details. \n Message: {participant_xml}\n") exit() userdomain_array = dict() tree = ET.fromstring(participant_xml) username = [] for elem in tree.iter(): if elem.tag == "DisplayName": username.append(elem.text) return username def xapiCall(headers,payload,endpointip): conn = http.client.HTTPSConnection(endpointip, context = ssl._create_unverified_context(), timeout=20) try: conn.request("POST", "/putxml", payload, headers) res = conn.getresponse() except Exception as e: print(f"\n**ERROR** connecting to video device ({endpointip}).\n Message: {e}\n") exit() if res.status == 200: data = res.read().decode("utf-8") if "error" in data.lower(): data = "**ERROR** xapiCall: " + data.split("status=")[1].split("/>")[0] else: data = "**ERROR** xapiCall: status: " + str(res.status) + " -- reason: " + str(res.reason) return data def image_to_b64(base64object,new_logo): my_image_extension = new_logo.rsplit('.',1)[1].lower() if my_image_extension != "png": my_image_extension = "jpeg" # (not 'jpg') needed by base64 encoder buffer = BytesIO() base64object.convert('RGB') base64object.save(buffer,format=my_image_extension) myimage = buffer.getvalue() myimage_b64 = str(base64.b64encode(myimage))[2:][:-1] return myimage_b64 if __name__ == '__main__': headers = { 'Authorization': 'Basic ' + my_token_xapi, 'Content-Type': 'text/xml' } p_job_m = '' while True: time.sleep(10) # _1_ READ ALL PARTICIPANTS webex_users = read_allparticipants() print('1_ READ all the participants:', webex_users) dict_jobs = read_csv() jobs = [dict_jobs[webex_users[i]] for i in range(len(webex_users))] print('The jobs of the participants:', jobs) job_c = Counter(jobs) job_m = job_c.most_common()[0][0] if p_job_m == job_m: print('Already using the background for', job_m) continue p_job_m = job_m # _2_ PREPARE BACKGROUND FOR UPLOAD print('2_ PREPARE the background for', job_m) logos = d_inputfile print(logos) new_logo = logos[job_m] imBackground = Image.open(new_logo) back_im64 = image_to_b64(imBackground,new_logo) imBackground.convert('RGB').save(my_logofolder + "/_result.jpg") payload = "<Command><Cameras><Background><Upload><Image>" + my_user_image_location + "</Image><body>xxx</body></Upload></Background></Cameras></Command>" payload = payload.replace("xxx", back_im64) # _3_ UPLOAD BACKGROUND print("3_ UPLOADING background to video device @" + endpoint_ip) xapiresult = xapiCall(headers,payload, endpoint_ip) if "**ERROR**" in xapiresult: print(f"\n**ERROR** Can't add new background:\n {xapiresult}\n") # _4_ SWITCH TO BLUR print(f"4_ Switch to Blur and then back to {my_user_image_location} to make changes visible.") payl_switchbg = "<Command><Cameras><Background><Set><Mode>BlurMonochrome</Mode></Set></Background></Cameras></Command>" xapiresult = xapiCall(headers,payl_switchbg, endpoint_ip) if "**ERROR**" in xapiresult: print(f"\n**ERROR** Can't switch to blur:\n {xapiresult}\n") # _5_ SWITCH TO NEW BACKGROUND payl_switchbg = "<Command><Cameras><Background><Set><Image>" + my_user_image_location + "</Image><Mode>Image</Mode></Set></Background></Cameras></Command>" xapiresult = xapiCall(headers,payl_switchbg, endpoint_ip) if "**ERROR**" in xapiresult: print(f"\n**ERROR** Can't switch to new background\n{xapiresult}\n") print("____ finished ___________________________________\n") 終わりに 上位2つの属性を特定し左右にそれぞれの広告を表示したり、属性の割合に応じて広告の表示時間を変えるなどの応用も考えられそうです。DevNet Code ExchangeとGitHubにも情報を掲載していますので、よろしければご活用ください。 DevNet Code Exchange GitHub アドベントカレンダー後半には、Merakiカメラを使って実際のイベント会場とバーチャルイベント会場をつなぐソリューションの記事が登場予定です。 免責事項 本サイトおよび対応するコメントにおいて表明される意見は、投稿者本人の個人的意見であり、シスコの意見ではありません。本サイトの内容は、情報の提供のみを目的として掲載されており、シスコや他の関係者による推奨や表明を目的としたものではありません。各利用者は、本Webサイトへの掲載により、投稿、リンクその他の方法でアップロードした全ての情報の内容に対して全責任を負い、本Web サイトの利用に関するあらゆる責任からシスコを免責することに同意したものとします。
- 投稿日:2021-12-03T19:00:15+09:00
Win11上のUbuntu on WSL2 + dockerでGPUを使う
初めに WindowsのPCでGPUが使える環境をなんとか仮想環境で実現しようといろいろ考えた結果タイトルのような構成になりました。 スペックは以下の通りです。 CPU: Corei7 (11th gen) GPU: GeForce RTX3080 RAM: 16GB ただし、動かしてみたところメモリは正直増設したほうがいいかもです。。。 手順はざっと以下の通りです。 Win11にアップデート NVIDIAドライバーの導入 WSL2、Ubuntuのセットアップ UbuntuにCUDA導入 Ubuntuにdocker導入 NVIDIAのdockerイメージを動かす では早速行きます。 1. Win11にアップデート この部分は調べれば色々出てくると思いますので、端折ります。 やることとしては Win11入れるための要件のチェックと必要機能の有効化 Win11のインストール となります。1でBIOSいじる必要性などが出てくるの可能性があり少々厄介ですが、頑張りましょう。 2. NVIDIAドライバーの導入 ゲーミングPCなら導入済みかと思います。 参考までに僕のバージョンはGeForce Game Ready Driver 496.76です。 3. WSL2、Ubuntuのセットアップ 以下のコマンドを管理者権限で実行したPowershellに打ち込むだけで導入可能だと思います。 wsl --install -d Ubuntu-20.04 Ubuntuが自動で起動するので、ユーザー名とパスワードを設定しましょう。 一応、ちゃんと導入できているかPowershellのほうで下記コマンドで確認しましょう。 wsl -l -v 下記のように出力されれば大丈夫です。 NAME STATE VERSION * Ubuntu-20.04 Running 2 もし、表示が違っている場合は今インストールしたUbuntuをアプリと機能から探して一度アンインストールし、下記手順でWSL2にアップデートしたうえでUbuntu導入してみてください。 Ubuntuが導入できたら、後続の作業でいろいろ導入する際にエラーが起きないよう、少しだけ下準備をします。 まず、Ubuntuを起動します。exitなど打ち込んで閉じちゃった場合はタスクバーのアプリ検索をすれば出てきます。 起動したら下記コマンドを入力しましょう sudo vim /etc/wsl.conf vimというエディタが起動するのでiを打ち込むとINSERTモード(書き込むモード)に移行できます。左下がINSERTになっていることを確認しましょう。 下記のような記述を追加します。余談ですが、ctrl+vでの貼り付けは受け付けてくれないので、コピーしたらubuntuのターミナル画面で右クリすればペーストできます。 /etc/wsl.conf [network] generateResolvConf = false [boot] command = "sudo echo 'nameserver 8.8.8.8' > /etc/resolv.conf" 追加したら、Escキーを押してINSERTモードから抜け出します。(左下からINSERTの文字が消えます) その後:wqと入力(左下に入力が見えると思います)してEnterを押して保存、終了しましょう。wが保存、qが終了を意味します。 できたら、exitと打ち込んで一度閉じ、もっかいアプリを開きましょう。 下記のように打ち込むと、ちゃんとresolv.confが生成されていることを確認できると思います。 sudo cat /etc/resolv.conf 4. UbuntuにCUDA導入 先ほど導入したUbuntuにCUDAを導入します。ここで、一点留意してほしいのが WSL用のCUDAを導入するということです。 ここからCudaを選んでインストールします。今回は11.3.0を入れます。 上みたいな感じで選ぶと、下にコマンドが出てきますのでこれを打ち込みます。今回の例では以下のようになります。 wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-wsl-ubuntu.pin sudo mv cuda-wsl-ubuntu.pin /etc/apt/preferences.d/cuda-repository-pin-600 wget https://developer.download.nvidia.com/compute/cuda/11.3.0/local_installers/cuda-repo-wsl-ubuntu-11-3-local_11.3.0-1_amd64.deb sudo dpkg -i cuda-repo-wsl-ubuntu-11-3-local_11.3.0-1_amd64.deb sudo apt-key add /var/cuda-repo-wsl-ubuntu-11-3-local/7fa2af80.pub sudo apt-get update sudo apt-get -y install cuda 5. Ubuntuにdocker導入 次に、dockerというアプリの導入を行います。簡単に言うと、dockerさえ入っていればどんなマシンで構築した環境でもすぐにほかのマシンでも再現できるというものです。 docker周りのインストールを自動で行ってくれる便利なコマンド curl https://get.docker.com | sh nvidia-dockerの導入。順番に打ち込みます distribution=$(. /etc/os-release;echo $ID$VERSION_ID) curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list sudo apt-get update sudo apt-get install -y nvidia-docker2 以下コマンドでユーザーをdockerグループに追加(ユーザーがdockerコマンドを使えるようにする) sudo usermod -aG docker $USER dockerの再起動を行いましょう sudo service docker stop sudo service docker start 6. 実際にdockerイメージを動かす 下記を試しに動かしましょう。 sudo nvidia-docker run --rm -it --gpus all nvcr.io/nvidia/k8s/cuda-sample:nbody nbody -gpu -benchmark -numbodies=512000 GPUで計算が回りますので、下記のような表示ができれば完了です。あとはdockerに少し慣れるだけでいろんなことができるようになります。 ここで、じつはdockerはubuntu起動時に勝手に起動してくれないので、次回起動時にもdockerが自動で立ち上がるようにしましょう。 さっきのwsl.confの内容が以下の通りになるように追記しましょう。 sudo vim /etc/wsl.conf /etc/wsl.conf [network] generateResolvConf = false [boot] command = "sudo echo 'nameserver 8.8.8.8' > /etc/resolv.conf" command = "sudo service docker start" お疲れさまでした。
- 投稿日:2021-12-03T17:58:30+09:00
Python エラー "string index out of range"
エラー string index out of range 原因 リストの範囲外のインデックスを指定した。 例 l = [a,b,c] print(l[3]) Traceback (most recent call last): File "./Main.py", line 2, in <module> print(l[3]) IndexError: list index out of range
- 投稿日:2021-12-03T17:39:33+09:00
PythonからSnowflakeを操作する際のケースインセンシティブな注意点
はじめに データウェアハウスとしてクラウドサービスであるSnowflake、近年注目株で業務に使用している方もいると思います。今回はこのSnowflakeにPythonからクエリを実行させる際、ケースインセンシティブの扱いで当時私がハマった内容と対応方法について記録しておきます。 前提 使用した言語やライブラリ - python 3.8 - pandas 1.1.5 - sqlalchemy 1.3.21 - snowflake-sqlalchemy 1.2.4 Snowflakeのケースインセンシティブな仕様 ドキュメント曰く、Snowflakeではテーブルやスキーマなどのオブジェクト名は大文字がデフォルトであり、小文字として認識させるためには"でオブジェクト名を囲わないといけません。 つまりデータベース名・スキーマ名・テーブル名をhoge.fuga.piyoと書いてクエリを投げると、SnowflakeはHOGE.FUGA.PIYOに変換してオブジェクトを探しに行きます。これを防ぐためには"hoge"."fuga"."piyo"と書く必要があります。 問題になったケースの詳細 Snowflakeだけを使う場合は上記仕様は特に気にしなくていいのですが、実際には外部からデータを継続的にインポートしたりすると思います。 今回私はSnowflakeが提供するデータパイプライン機能を使い、AWSのS3バケット上にアップロードしたファイルのデータを自動でインポートするようにしていました。この際インポート先のスキーマとテーブルを、S3上のフォルダ名からコピーし自動で生成するLambdaを組んでいます。ちなみにテーブル名は自動的に大文字のサフィックスが付きます。 するとS3のオブジェクト名はケースセンシティブなので、同じ名前で大文字と小文字が違うだけのフォルダを作られると一緒のスキーマで扱われてしまいます。稀なケースではありますが、これをケアするためにはSnowflakeもケースセンシティブで扱いたくなります。 ということで、公式がツールキット(Snowflake SQLAlchemy)を用意してくれていますので、"を付けてPandasでread_csvからデータファイルの中身を引っこ抜いてto_sqlすれば自動的にCREATE TABLEしてINSERTして無事終わり…とはなりません (´・ω・`)ドウシテ SQL compilation error: Object does not exist, or operation cannot be performed. The above exception was the direct cause of the following exception: sqlalchemy.exc.ProgrammingError: (snowflake.connector.errors.ProgrammingError) 002043 (02000): 019ace41-008e-12b4-0000-20090001e2f2: SQL compilation error: Object does not exist, or operation cannot be performed. [SQL: SHOW /* sqlalchemy:get_table_names */ TABLES IN fuga] (Background on this error at: http://sqlalche.me/e/13/f405) 具体的には、テーブルは問題なく作成できるのですがエラーメッセージが出力されます。また、エラーになるのはスキーマ名が全て小文字の場合です。 原因 まずはエラーメッセージから問題となった処理を探します。具体的にはpandas内の下記関数の実行時にエラーを吐いていました。 def check_case_sensitive( self, name, schema, ): """ Checks table name for issues with case-sensitivity. Method is called after data is inserted. """ if not name.isdigit() and not name.islower(): # check for potentially case sensitivity issues (GH7815) # Only check when name is not a number and name is not lower case engine = self.connectable.engine with self.connectable.connect() as conn: if _gt14(): from sqlalchemy import inspect insp = inspect(conn) table_names = insp.get_table_names( schema=schema or self.meta.schema ) else: table_names = engine.table_names( schema=schema or self.meta.schema, connection=conn ) if name not in table_names: msg = ( f"The provided table name '{name}' is not found exactly as " "such in the database after writing the table, possibly " "due to case sensitivity issues. Consider using lower " "case table names." ) warnings.warn(msg, UserWarning) コメント部分にあるように、データがインサートされた後にわざわざテーブル名を確認して、ケースセンシティブな食い違いがあったら警告してくれるようです。 そしてengine.table_namesから更に辿っていくと、Snowflake SQLAlchemyの関数からテーブル名を取得しています。SHOW /* sqlalchemy:get_table_names */ TABLES INの部分がエラーメッセージに出ています。 def get_table_names(self, connection, schema=None, **kw): """ Gets all table names. """ schema = schema or self.default_schema_name current_schema = schema if schema: cursor = connection.execute(text( "SHOW /* sqlalchemy:get_table_names */ TABLES IN {0}".format( self._denormalize_quote_join(schema)))) else: cursor = connection.execute(text( "SHOW /* sqlalchemy:get_table_names */ TABLES")) _, current_schema = self._current_database_schema(connection) ret = [self.normalize_name(row[1]) for row in cursor] return ret def _denormalize_quote_join(self, *idents): ip = self.identifier_preparer split_idents = reduce( operator.add, [ip._split_schema_by_dot(ids) for ids in idents if ids is not None]) return '.'.join( ip._quote_free_identifiers(*split_idents)) denormalize_quote_join(schema)…どうやらケースセンシティブな扱いが必要かを自動で判断して補正してくれる関数のようです。(´・ω・`)ココガアヤシイ そしてさらに辿っていくと、最終的にケースセンシティブな扱いが必要かどうかを判断するロジックがSQLAlchemy内にありました。 def _requires_quotes(self, value): """Return True if the given identifier requires quoting.""" lc_value = value.lower() return ( lc_value in self.reserved_words or value[0] in self.illegal_initial_characters or not self.legal_characters.match(util.text_type(value)) or (lc_value != value) ) これを見るとlc_value != value、つまり与えられたオブジェクト名が全て小文字の場合は"が必要ないと見なしています。(´・ω・`)ギャクジャン つまりテーブル作成やインサートはできるものの、その後の確認処理でスキーマ名が全て小文字だとケースインセンシティブなままSnowflakeにクエリを投げてしまい、Snowflake側で大文字に変換されるためスキーマが不在でObject does not existと出てきたわけです。(スキーマ自体は小文字で作成されている) これはSnowflakeのドキュメントにあるように、SQLAlchemyとSnowflakeのケースセンシティブな条件が異なることに起因します。ただドキュメント通りならあらかじめ"で囲ってあげれば問題ないはずですが、残念ながらエラーになります。というのも、ダブルクォーテーションは処理の中でオブジェクトの区切り文字として使われ省かれてしまうからです。 実際スキーマ名を"で囲って実行してログに出しても見事に剝がされます。 def _split_schema_by_dot(self, schema): ret = [] idx = 0 pre_idx = 0 in_quote = False while idx < len(schema): if not in_quote: if schema[idx] == '.' and pre_idx < idx: ret.append(schema[pre_idx:idx]) pre_idx = idx + 1 elif schema[idx] == '"': in_quote = True pre_idx = idx + 1 else: if schema[idx] == '"' and pre_idx < idx: ret.append(schema[pre_idx:idx]) in_quote = False pre_idx = idx + 1 idx += 1 if pre_idx < len(schema) and schema[pre_idx] == '.': pre_idx += 1 if pre_idx < idx: ret.append(schema[pre_idx:idx]) return ret この処理をちょっと弄った上でスキーマ名を"で囲ってあげると、無事小文字オンリーのスキーマ名でテーブルを確認しにいってくれるようになりました。 対応方法 ライブラリを弄って自分で管理し続けるのは嫌なのでそれ以外で考えます。ということで自分でCREATE TABLEしてデータ行ごとにINSERTするか、もしくはエラーメッセージでフィルターしてスルーするか。今回は誤作動もなさそうだし後者にしました。 以上
- 投稿日:2021-12-03T17:33:45+09:00
Python でけたたましくアラート音を鳴らしまくる
目的 バッチ処理が完了した際や,常駐型プログラムの異常検知時など,注意を引きたいときにアラート音を鳴らしまくりたい 1回だけ音を鳴らす print('\a') 連続で音を鳴らす import sys import time for _ in range(10): sys.stdout.write('\a') sys.stdout.flush() time.sleep(0.15) 鳴らす回数,スリープ間隔はお好みで. なぜこんなややこしいのか print('\a' * 10) ではいかんのか? -> いかんのです. バッファにまとめて標準出力される都合上,全ての音がまとめて一回だけ鳴ります. 面倒でも1回ずつ書き込み&出力すれば連続で音が鳴りまくります.
- 投稿日:2021-12-03T16:55:01+09:00
pythonのcontrolライブラリの使用方法メモ
概要 Pythonにデフォルトでインストールされているcontrolライブラリの使用方法の個人的メモです。 ただ、一部の関数を使用するには、slycotを追加でインストールする必要があり、そのインストールがなかなかうまくいかなかったので覚悟してください。 include import control Matlab関数も使用する場合 from control import matlab 伝達関数定義 tf = matlab.tf([1],[1 , 0]) print(tf) -> 1 - s 状態方程式定義 A=[[1 , 0], [1 , 2]] B=[[1], [0]] C=[[1 , 0]] D=[[0]] sys = matlab.ss(A,B,C,D) 伝達関数・状態方程式相互変換 tf2 = control.ss2tf(sys) sys2 = control.tf2ss(tf2) A,B,C,D行列へのアクセス A=sys.A B=sys.B C=sys.C D=sys.D np.linalg.eig(A) 最後の行は安定判別に使えます bode線図 matlab.bode(sys) ちなみに import matplotlib.pyplot as plt fig = plt.figure() matlab.bode(sys) fig2 = plt.figure() matlab.nyquist(sys) とすれば、ナイキストも連続して書けます 離散化 tf_d = control.c2d(tf,0.01,method='zoh') を参考にさせていただきました。 リカッチ方程式(連続) を参考にさせていただきました。 ModuleNotFoundError: No module named 'slycot' と出たら うえのリンクの内容で、slycotを探すときは、ctr+Fの方が現実的です(一応)。あと、下の内容で、 from pip._internal.utils.compatibility_tags import get_supported print(get_supported()) を実行し、cp38,cp,39等を確認し、どれをインストールするか決める必要があるかもしれません。 を参考にしてください。 先人の方ありがとうございます。 助かりました。 と思ったらだめでした。 (追記) で conda install -c conda-forge control slycot をすれば、解決! 先人の方ありがとうございました。 疲れた リカッチ方程式の解法 import control from control import matlab import numpy as np import matplotlib.pyplot as plt A=[[1 , 0], [1 , 2]] B=[[1], [0]] C=[[1 , 0]] D=[[0]] sys = matlab.ss(A,B,C,D) Q=np.array([[1,0], [0,1]] )*10 R=np.array([[1]] ) N =[[0], [0]] K,P,e = matlab.lqr(A,B,Q,R,N) さらに、正しく解が得られているか確認します。 hoge = np.dot(sys.A.T,P) + np.dot(P,sys.A) hoge2 = np.dot(P,sys.B) hoge3 = np.dot(np.dot(hoge2,np.linalg.inv(R)),hoge2.T) hoge_final = hoge - hoge3 + Q print(hoge_final) -> [[9.80548975e-13 5.37170308e-12] [5.37170308e-12 2.91606739e-11]] ほぼ0になったので、リカッチ方程式が成立していることが確認できました。 ちなみに、Kに関しては u = -Kx とする前提で設計されています。 離散リカッチ方程式の解法 原理的な話はこちら 関数の説明 dareが普通にPythonでも使えるのすごい 引数はnumpyでないとエラーが出るので、注意 [P,L,K] = matlab.dare(sys.A,sys.B,Q,R) とすれば P = A^TPA+Q-(B^TPA)^T(R+B^TPB)^{-1}(B^TPA)\\ K = (R+ B^TPB)^{-1} B^T PA\\ u = -Kx となる、$P,K$を見つけてきてくれます。 検算もしてみます hoge = np.dot(np.dot(sys.A.T,P),sys.A) + Q hoge2 = np.dot(np.dot(sys.B.T,P),A) hoge2_2 = np.linalg.inv(R+np.dot(np.dot(sys.B.T,P),B) ) hoge3 = np.dot(np.dot(hoge2.T, hoge2_2) ,hoge2) print(hoge-hoge3-P) -> [[-8.52651283e-14 -8.52651283e-14] [-1.42108547e-13 -2.55795385e-13]] ほぼ、0になったので確認できました。 可制御・可観測 Ctr = matlab.ctrb(sys.A,sys.B) print(np.linalg.matrix_rank(Ctr)) print("Aの次元と一致すれば、可制御") Obs = matlab.obsv(sys.A,sys.C) print(np.linalg.matrix_rank(Obs)) print("Aの次元と一致すれば、可観測") 極配置 K = matlab.place(sys.A,sys.B,[-1,-2]) eig = np.linalg.eig(sys.A-np.dot(sys.B,K)) print(eig) これで、配置と、確認ができます。[-1,-2]は配置したい場所です。 ただし、同じ場所にBの次元以上の個数、配置しようとするとエラーが出ました。数学的なものかな 伝達関数の分母・分子の取得 tf.den #分母 tf.num #分子 伝達関数に s = jw を代入する fr = matlab.evalfr(tf,1j*w) #s = jw の代入結果を取得 便利すぎ~ 全部あるやん bode線図を関数でない方法で書く import control from control import matlab import numpy as np import matplotlib.pyplot as plt import math import cmath tf = matlab.tf([1],[1 , 0]) w_max = 1000 w_min = 0.01 w = np.linspace(w_min,w_max,10000000) fr = matlab.evalfr(tf,1j*w) #s = jw の代入結果を取得 gain = abs(fr) phase = [] for i in fr: phase.append(cmath.phase(i)) phase = np.array(phase) #もっといい書き方あるかも #グラフ化 fig = plt.figure() # top ax1 = fig.add_subplot(2, 1, 1) ax1.plot(w, gain) ax1.set_xlabel("w[rad/s]") ax1.set_ylabel("gain") ax1.set_yscale('log') ax1.set_xscale('log') ax1.set_xlim(w_min,w_max) # bottom ax2 = fig.add_subplot(2, 1, 2) ax2.plot(w, phase) ax2.set_xlabel("w[rad/s]") ax2.set_ylabel("phase") ax2.set_xlim(w_min,w_max) ax2.set_xscale('log') ax2.set_ylim(-np.pi-0.1,np.pi+0.1) # show plots fig.tight_layout() 悪くないね。 Phaseはdeg表示に変えた方がわかりやすいかな。 z = exp(jwT)を代入して、離散システムのボード線図を書く 離散システムのボード線図を書く場合は、代入してやれば、周波数特性がわかるのでやってみる 0.01sでサンプリングするシステムの場合、0Hzと100Hzの見分けがつかない。つまり、このシステムは0~100Hzまでの伝達関数がわかれば、周りの周波数に関しては、0~100Hzの繰り返しになるということである。 import control from control import matlab import numpy as np import matplotlib.pyplot as plt import math import cmath T_samp = 0.01 #グラフ表示範囲 w_max = 50 * 2*np.pi w_min = 0.01 tf = matlab.tf([1],[1 , 0]) fig = plt.figure() matlab.bode(tf) tf_d = control.c2d(tf,T_samp,method='zoh') print(tf_d) fig2 = plt.figure() matlab.bode(tf_d) w = np.linspace(w_min,w_max,10000000) fr = matlab.evalfr(tf_d,np.exp(1j*w*T_samp)) #s = exp(jwT) の代入結果を取得 gain = abs(fr) phase = [] for i in fr: phase.append(cmath.phase(i)) phase = np.array(phase) *180 / np.pi #もっといい書き方あるかも #グラフ化 fig = plt.figure() # top ax1 = fig.add_subplot(2, 1, 1) ax1.plot(w, gain) ax1.set_xlabel("w[rad/s]") ax1.set_ylabel("gain") ax1.set_yscale('log') ax1.set_xscale('log') ax1.set_xlim(w_min,w_max) # bottom ax2 = fig.add_subplot(2, 1, 2) ax2.plot(w, phase) ax2.set_xlabel("w[rad/s]") ax2.set_ylabel("phase") ax2.set_xlim(w_min,w_max) ax2.set_xscale('log') ax2.set_ylim(-190,190) # show plots fig.tight_layout() 離散化前 離散化後(T=0.01s) Z=exp(jwT)を代入してグラフ化 0.1rad/sで、20dB(10倍)なのが共通しており、形状もかなり近いので、離散システムに対して、bodeは正しく働いていることが分かった 離散ローパスフィルタの設計 を利用 一次 import control from control import matlab import numpy as np import matplotlib.pyplot as plt cut_of_freqency = 10 #Hz :カットオフ周波数 T_samp = 0.01 #s :制御周期 tf = matlab.tf([1],[1/(cut_of_freqency*2*np.pi),1]) fig = plt.figure() matlab.bode(tf) tf_d = control.c2d(tf,T_samp,method='zoh') print(tf_d) fig2 = plt.figure() matlab.bode(tf_d) print("分母") print(tf_d.den) print("分子") print(tf_d.num) 二次 import control from control import matlab import numpy as np import matplotlib.pyplot as plt cut_of_freqency = 1/2/np.pi #Hz :カットオフ周波数 T_samp = 0.01 #s :制御周期 rad = cut_of_freqency*2*np.pi tf = matlab.tf([1],[1/(rad**2),np.sqrt(2)/rad,1]) fig = plt.figure() matlab.bode(tf) tf_d = control.c2d(tf,T_samp,method='zoh') print(tf_d) fig2 = plt.figure() matlab.bode(tf_d) print("分母") print(tf_d.den) print("分子") print(tf_d.num) 離散化前 離散化後 1rad/sでカットオフ、平坦特性、-40dB/decがきれいに表れています。 Arduinoへの実装テンプレート 後で書きます 感想 クッソ便利。 Scilabを使っていたけど、やっぱPythonで書きたいという人には、ほんとにおすすめ。
- 投稿日:2021-12-03T16:45:03+09:00
Pypi(pip)とcondaのPythonライブラリを両方同時にアップデートする方法
前置き condaでインストールされたライブラリをアップデートするためにはconda update ライブラリ名で可能です。 そして、condaでインストールされたすべてのライブラリをアップデートするためにはconda update --allで可能です。 しかし、これによりアップデートされるのはcondaでインストールされたライブラリのみであり、pipでインストールされたライブラリはこれではアップデートができません。 pipでインストールされたライブラリをアップデートするためにはpip install -U ライブラリ名とする必要があります。しかしpipでインストールされたライブラリを一気にすべてアップデートする方法はありません。 一応、pip-reviewというpipのアップデートを一気に行う手法もありますが、これを使うとcondaでインストールされたライブラリもpipでアップデートされるために、大変なことになることが多いです。 そこで、pipでインストールされたライブラリと、condaでインストールされたライブラリをそれぞれ適切にアップデートするPythonコードを書きました。 コード pyLibUpdate.py import re import subprocess #conda listでインストールされているライブラリを確認 conda_list_comm = 'conda list' conda_list_raw = subprocess.run(conda_list_comm, stdout=subprocess.PIPE, shell=True).stdout.decode('utf-8') #インストールされているライブラリをlist化 conda_list_libs = re.split('\r|\n', conda_list_raw) conda_lib_chs = [re.split('\s+', lib) for lib in conda_list_libs if not lib.startswith('#') and not lib.isspace() and lib] #channelにpypiやpipが含まれているライブラリを記録 pypi_libs = [lib[0] for lib in conda_lib_chs if any([pip_str in lib[-1] for pip_str in ('pypi', 'pip')])] #print(pypi_libs) #pip list -oでアップデートが必要なライブラリを確認 pip_list_comm = 'pip list -o' pip_list_raw = subprocess.run(pip_list_comm, stdout=subprocess.PIPE, shell=True).stdout.decode('utf-8') pip_list_libs = re.split('\r|\n', pip_list_raw) #pip listすると「-------」以降にライブラリが羅列するので、そこの行数を確認 pip_list_start_lineno = [pip_list_lib.startswith('-') for pip_list_lib in pip_list_libs].index(True) + 1 #アップデートが必要なライブラリをlist化 pip_update_libs = [re.split('\s+', lib)[0] for lib in pip_list_libs[pip_list_start_lineno:] if not lib.isspace() and lib] #print(pip_libs) #アップデートが必要なライブラリのうち、pypiからインストールされていたものをpip install -U ライブラリ名でアップデート for pip_update_lib in pip_update_libs: if pip_update_lib in pypi_libs: pip_update_comm = f'pip install -U {pip_update_lib}' print(pip_list_comm, '\n') subprocess.run(pip_update_comm, shell=True) #すぐ容量が肥大化するのでpipのキャッシュを削除 pip_cache_clear_comm = 'pip cache purge' subprocess.run(pip_cache_clear_comm, shell=True) #condaのライブラリをアップデート conda_update_comm = 'conda update --all -y' print(conda_update_comm, '\n') subprocess.run(conda_update_comm, shell=True) #まじですぐに容量が肥大化するのでcondaのキャッシュを削除 conda_clean_comm = 'conda clean --all -y' subprocess.run(conda_clean_comm, shell=True) 実行するには python pyLibUpdate.py とするだけです。 注意点 ライブラリをむやみに全て一気にアップデートすると、今まで動いていたコードが急に動かなくなることがあります。 自己責任でお願い致します。 一応WindowsとRaspbian OSでの動作確認をしておりますが、それ以外については行っていません。 疑問点などございましたらコメントください。
- 投稿日:2021-12-03T16:10:34+09:00
UbuntuにCanteraをインストールして,C++のコードを実行するまで
Canteraといつ反応解析のソフトウェアのソースコードを変更したいと思い,以前に書いた記事ではWindows環境下でソースコードからインストールする過程を示した. しかしながらCanteraではC++で記述されたクラスをCythonを経由することでPythonのインターフェースで使用するという,そこそこ複雑な構造になっていて,デバッグなどの昨日だったりエディタのハイライトが対応できないという事から,コードを改変するときに結構不便になってしまう. そこでこの記事では,C++のソースコードを実行及び改変可能な環境を構築することを目指し,WSLを使用して構築したUbuntuに対してCanteraをインストールしてC++のコードを実行する手順を示しておく. 環境 ホストOS: Windows 10 実行環境: Ubuntu 20.04 LTS (WSL2) インストール 公式のUbuntuへのインストールに関するページを参考に実行する. 以下のコマンドを実行してCanteraのインストールを行う. sudo apt install software-properties-common sudo apt-add-repository ppa:cantera-team/cantera sudo apt install cantera-python3 cantera-dev 必要なパッケージのインストールを行う. sudo apt install libfmt-dev libboost-all-dev g++ サンプルコードの実行 公式のページを参考に実行する.ただし,実行用のコマンドは変更している. combustor.cpp #include "cantera/thermo.h" #include <iostream> using namespace Cantera; // The actual code is put into a function that // can be called from the main program. void simple_demo() { // Create a new phase std::unique_ptr<ThermoPhase> gas(newPhase("h2o2.yaml", "ohmech")); // Set its state by specifying T (500 K) P (2 atm) and the mole // fractions. Note that the mole fractions do not need to sum to // 1.0 - they will be normalized internally. Also, the values for // any unspecified species will be set to zero. gas->setState_TPX(500.0, 2.0*OneAtm, "H2O:1.0, H2:8.0, AR:1.0"); // Print a summary report of the state of the gas std::cout << gas->report() << std::endl; } // the main program just calls function simple_demo within // a 'try' block, and catches CanteraError exceptions that // might be thrown int main() { try { simple_demo(); } catch (CanteraError& err) { std::cout << err.what() << std::endl; } } 実行コマンドは以下 -llapackと-lyaml-cppのフラッグを付け加えている. g++ combustor.cpp -o combustor -pthread -O3 -std=c++0x -lcantera -lsundials_cvodes -lsundials_ida -lsundials_nvecserial -llapack -lyaml-cpp ./combustor 無事に実行できると以下の結果が出力される. ohmech: temperature 500 K pressure 2.0265e+05 Pa density 0.36118 kg/m^3 mean mol. weight 7.4093 kg/kmol phase of matter gas 1 kg 1 kmol --------------- --------------- enthalpy -2.4772e+06 -1.8354e+07 J internal energy -3.0382e+06 -2.2511e+07 J entropy 20699 1.5337e+05 J/K Gibbs function -1.2827e+07 -9.5038e+07 J heat capacity c_p 3919.1 29038 J/K heat capacity c_v 2797 20724 J/K mass frac. Y mole frac. X chem. pot. / RT --------------- --------------- --------------- H2 0.21767 0.8 -15.644 H 0 0 O 0 0 O2 0 0 OH 0 0 H2O 0.24314 0.1 -82.953 HO2 0 0 H2O2 0 0 AR 0.53919 0.1 -20.503 N2 0 0
- 投稿日:2021-12-03T15:39:01+09:00
[Docker] flask/uwsgi+nginx+postgresを別コンテナで構築する
はじめに 最近Docker上でアプリを動かしてみたいと思い、1~2週間ほど格闘してようやくタイトルにあるような構成でアプリを動かすことに成功しました。ほかの記事でも結構見かけるような構成ではあるのですが、コンテナ起動時のテーブル構築やデータの永続化といったテーマにも触れていきたいとおもいます。 環境 ・Window10 Home 64bit ・WSL2 ・Docker Desktop for Windows ディレクトリ構成 flask/ ├ app/ │ ├ config/ │ │ ├ requirements.txt │ │ └ uwsgi.ini │ ├ Dockerfile │ └ run.py ├ database/ │ ├ data/ │ ├ docker-entrypoint-initdb.d/ │ │ └ 1_create_table.sql │ └ Dockerfile ├ nginx/ │ ├ config/ │ │ └ nginx.conf │ └ Dockerfile └ docker-compose.yml Githubはこちらです。 app まずDockerfileです。 ワークディレクトリは/var/www/appにしていますが、任意です。 アプリケーションに必要なライブラリはrequirements.txtで管理するのでこれをインストールしています。 Dockerfile FROM python:3.9 # コンテナ内の作業ディレクトリを指定(以降のカレントディレクトリ) WORKDIR /var/www/app RUN apt-get update \ && apt-get install -y vim \ && apt-get autoremove -y \ && rm -rf /var/lib/apt/lists/* # ホストのカレントディレクトリをコンテナ内のカレントディレクトリにコピー COPY . . # ライブラリインストール RUN pip install -U pip \ && pip install --no-cache-dir -r /var/www/app/config/requirements.txt ライブラリ管理はrequirements.txtで行っています。 requirements.txt uwsgi flask psycopg2 uwsgi.iniはnginxからsocketで通信を受け取る設定にしておきます。 uwsgi.ini [uwsgi] master = True socket = :3031 # http = :3031 chdir = /var/www/app/ wsgi-file = run.py callable = app logto = /var/log/uwsgi.log アプリに関してはHello Worldを返す簡単なものを作っていきます。 run.py from flask import Flask, redirect, url_for, render_template import psycopg2 from psycopg2.extras import DictCursor # from werkzeug.middleware.proxy_fix import ProxyFix app = Flask(__name__) # app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_host=1, x_port=1, x_proto=1) def pg_conn(): setting = { 'host': 'flask_db', # dbコンテナ名を指定 'port': '5432', 'dbname': 'postgres', 'user': 'postgres', 'password': 'postgres' } return psycopg2.connect(**setting) @app.get('/') def index(): return 'Hello World' @app.get('/red') def red(): with pg_conn() as conn: with conn.cursor(cursor_factory=DictCursor) as cur: sql = "INSERT INTO users(name) values('jessy')" cur.execute(sql) conn.commit() return redirect(url_for('index')) if __name__ == "__main__": app.run() database Dockerfileです。イメージを取得するだけなのでdocker-compose.ymlで直接取得しても構わないのですが、あとからDockerfileに定義すべき事項が出てきたときに少しめんどくさいと思ったのでDockerfileを使っています。 Dockerfile FROM postgres:latest 次にコンテナ起動時に必要なテーブルが作成されるように.sqlファイルを作っておきます。コンテナ内の/docker-entrypoint-initdb.dに置いておくとコンテナ起動時に実行してくれます。コンテナの中に入ってデータベースやテーブルを作成するといった作業を省略できます。実行対象ファイルは「.sql」「.sh」「.sql.gz」のようです。また、ファイル名のイニシャルに数字をつけておくことでDockerが順番に実行してくれます。 1_create_table.sql create table if not exists users ( id serial not null , name character varying not null , constraint users_PKC primary key (id) ) ; 最後に/dataという空のディレクトリを作成しておきます。これはこの後出てきますが、データを永続化するために使います。 nginx Dockerfile FROM nginx:latest # vimをインストールしています。必要がなければコメントアウトしてください。 RUN apt-get update \ && apt-get install -y vim \ && apt-get autoremove -y \ && rm -rf /var/lib/apt/lists/* 設定 次にnginxの設定ファイルです。おもにnginx-uwsgi間の通信方法についてみていきますので、他の設定については言及しません。今回はTCPソケットとHTTPの2つ通信方法を試してみました。 nginxとuwsgiを同一のコンテナで運用する場合unixソケットで通信することが一般的だと思いますが、今回は別々のコンテナで運用するのでunixソケットは使えません。 TCPソケット 以下はTCPソケットで通信する場合の設定例です。 nginx.conf user nginx; worker_processes auto; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type text/html; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; upstream app_server { # コンテナ名を使用 server flask_app:3031; } # map $http_x_forwarded_proto $real_scheme { # default $scheme; # https "https"; # } # map $http_host $port { # default $server_port; # "~^[^\:]+:(?<p>\d+)$" $p; # } server { listen 80 default; charset utf-8; server_name _; # proxy_set_header X-Forwarded-For $remote_addr; # proxy_set_header X-Forwarded-Host $host; # proxy_set_header X-Forwarded-Port $port; # proxy_set_header X-Forwarded-Proto $real_scheme; location / { client_max_body_size 1m; client_body_buffer_size 8k; include uwsgi_params; # TCPSocket通信 uwsgi_pass app_server; # HTTP通信 # proxy_pass http://app_server; # proxy_redirect off; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } } TCPソケットを使う場合は、uwsgi_passディレクティブに通信先コンテナとポートを記載します。ここでは通信先コンテナにコンテナ名を利用しています(upstreamディレクティブ)。コンテナ名をコンテナのIPアドレスに変えても動くはずです。 HTTP uwsgiと通信する場合、uwsgi_passディレクティブを使うことが推奨されているので通常はTCPソケットでいいと思うのですが、HTTPで通信することもあるかもしれないのでこちらでも設定してみました。その場合uwsgi_passではなく、proxy_passディレクティブを使うことになります。 以下のように設定を変更します。(httpモジュールのみ抜粋) nginx.conf http { include /etc/nginx/mime.types; default_type text/html; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; upstream app_server { # コンテナ名を使用 server flask_app:3031; } # 追加 map $http_x_forwarded_proto $real_scheme { default $scheme; https "https"; } # 追加 map $http_host $port { default $server_port; "~^[^\:]+:(?<p>\d+)$" $p; } server { listen 80 default; charset utf-8; server_name _; # 追加 proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Port $port; proxy_set_header X-Forwarded-Proto $real_scheme; location / { client_max_body_size 1m; client_body_buffer_size 8k; include uwsgi_params; # TCPSocket通信 # uwsgi_pass app_server; # HTTP通信 proxy_pass http://app_server; proxy_redirect off; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } } またuwsgi.iniもHTTPにします。 uwsgi.ini [uwsgi] master = True # socket = :3031 http = :3031 chdir = /var/www/app/ wsgi-file = run.py callable = app logto = /var/log/uwsgi.log さらにアプリ側も設定が必要です。 run.py from flask import Flask, redirect, url_for, render_template import psycopg2 from psycopg2.extras import DictCursor # 追加 from werkzeug.middleware.proxy_fix import ProxyFix app = Flask(__name__) # 追加 app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_host=1, x_port=1, x_proto=1) .... .... いろいろ設定が必要なのはこれらがないとflaskのredirect時にLocationヘッダURLがproxy_passディレクティブに設定されているURL(appコンテナ)になってしまいます。 そうならないようにwerkzeug.middleware.proxy_fixというモジュールを使っています。これはアプリケーションの前にあるプロキシ(ここではnginx)が設定するX-Forwarded-に基づいて、WSGI環境を調整するモジュールです。(ドキュメント) LocationヘッダにはnginxコンテナホストへのURLを設定したいので、X-Forwarded-にはnginxコンテナホストの情報を設定しています(nginx.conf)。 参考:https://github.com/sjmf/reverse-proxy-minimal-example docker-compose.yml ここまでのところがイメージの土台です。 ここからはイメージからコンテナを起動する際の設定について定義になります。 docker-compose.yml version: '3' services: database: container_name: flask_db build: ./database expose: - "5432" volumes: # 1_create_table.sqlをコンテナ内のdocker-entrypoint-initdb.dに置くため - ./database/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d - ./database/data:/var/lib/postgresql/data environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres - POSTGRES-DATABASE=postgres - DATABASE_HOST=localhost app: container_name: flask_app build: ./app expose: - "3031" volumes: - ./app:/var/www/app depends_on: - database command: uwsgi --ini /var/www/app/config/uwsgi.ini nginx: container_name: flask_nginx build: ./nginx restart: always volumes: - ./nginx/config/nginx.conf:/etc/nginx/nginx.conf depends_on: - app ports: - "8080:80" データ永続化 ホストのdatabase/dataをコンテナ内の/var/lib/postgresql/dataにマウントしていますが、これはデータベースの内容が保存される/var/lib/postgresql/dataの内容をホスト上に同期するためです。 したがって、仮にコンテナを削除したとしても新たなコンテナの/var/lib/postgresql/dataにホストのdatabase/dataをマウントさせることで以前のデータを再び同期させ、データを引き継ぐことができます。ちなみに今回のマウント方法をバインドマウントといいます。 Dockerにはもう一つボリュームマウントというマウント方法があります。こちらはバインドマウントのようにホストのディレクトリをマウントさせるのではなく、DockerEngine管理下にあるボリュームと呼ばれる記憶領域をコンテナのディレクトリにマウントするものです。 こちらの方法でもボリュームが存続する限りデータを維持できることになります。ボリュームマウントの方法はトップレベルに明示的にボリュームを作り、バインドマウントのようにコンテナのディレクトリにマウントさせるだけです。 今回の場合であれば、以下のように修正すればよいです。 docker-compose.yml .... services: database: build: ./database container_name: flask_db expose: - "5432" volumes: - ./database/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d # 作成したボリュームをコンテナにマウント - volume_data:/var/lib/postgresql/data environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres - POSTGRES-DATABASE=postgres - DATABASE_HOST=localhost ..... ..... # 明示的にvolume_dataというボリューム(ボリューム名は任意)を作成 volumes: volume_data: 実はもう一つ一時ファイルシステムマウントと呼ばれるマウント機能があるようです。今回は試さなかったので書いてませんが興味のある方は調べてみてください。 おわりに これで一応タイトルのような構成でアプリを動かせます。Githubに上げていますのでぜひ参考にしてみてください。
- 投稿日:2021-12-03T15:21:38+09:00
DockerでPython公式イメージ + MeCab + NEologd辞書
MeCabについて mecab-ipadic-neologd 形態素解析がなんぞや?MeCabとはなんぞや?という疑問に関しては他の方のブログでも詳しく解説されていると思いますので、ここでは省きます。 MeCabの辞書ですが、デフォルトのもの以外では、おそらく多くの人が使っているものとしてmecab-ipadic-neologdが挙げられるかと思います。LINE株式会社さんが開発しているOSSで新語・固有表現に強いMeCabの辞書で、今尚頻繁に更新されています。ちなみに2021年の新語・流行語大賞に輝いたリアル二刀流もNEologdにかかればこんな感じ $ mecab -d {デフォルト辞書のパス} リアル二刀流 リアル 名詞,固有名詞,一般,*,*,*,リアル,リアル,リアル 二刀流 名詞,一般,*,*,*,*,二刀流,ニトウリュウ,ニトーリュー $ mecab -d {mecab-ipadic-neologdのパス} リアル二刀流 リアル二刀流 名詞,固有名詞,一般,*,*,*,リアル二刀流,リアルニトウリュウ,リアルニトウリュー 辞書の設定 MeCabでどの辞書を使うのか設定する方法は以下の通りです 明示的に指定する方法 Pythonでは # python import Mecab mecab = MeCab.Tagger(f'-d {使用する辞書のパス}') ターミナルからは # shell $ mecab -d {使用する辞書のパス} 予めデフォルトの辞書を変更しておく方法 # デフォルトの辞書が設定されているmecabrcというファイルを探す $ mecab-config --sysconfdir # 例えば自分のMacでは以下のディレクトリ直下でした /opt/homebrew/etc # 今回使用するPython公式イメージ3.9(Debian GNU/Linux 11)では以下でした /etc # 一先ずmecabrcがどうなっているか確認すると辞書のパスを指定している行を確認できる dicdir = /var/lib/mecab/dic/debian # こんな感じだったり dicdir = /opt/homebrew/lib/mecab/dic/ipadic # こんな感じだったり # 上の定義を新しく mecab-ipadic-neologdのパスにすることでデフォルト辞書が変更される なおインストールしたmecab-ipadic-neologdのパスですが、以下のコマンドで分かリます。(公式レポジトリにも記載されているので参照してください) $ echo `mecab-config --dicdir`"/mecab-ipadic-neologd" Docker環境の構築 Dockerfile、docker-compose.ymlについては Python公式イメージ DockerHubにあるPythonの公式イメージです。https://hub.docker.com/_/python/ 別にUbuntuイメージでもなんでもいいのですが、自分はPython環境を構築するときはPython公式イメージを引っ張ってくることが多いので今回はこちらを使用します。 Dockerfile Dockerfileで書くべきは以下のような記述です。色々やり方はあると思います。 FROM python:3.9 # mecabの導入 RUN apt-get -y update && \ apt-get -y upgrade && \ apt-get install -y mecab && \ apt-get install -y libmecab-dev && \ apt-get install -y mecab-ipadic-utf8 && \ apt-get install -y git && \ apt-get install -y make && \ apt-get install -y curl && \ apt-get install -y xz-utils && \ apt-get install -y file && \ apt-get install -y sudo # mecab-ipadic-NEologdのインストール RUN git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git && \ cd mecab-ipadic-neologd && \ ./bin/install-mecab-ipadic-neologd -n -y && \ echo dicdir = `mecab-config --dicdir`"/mecab-ipadic-neologd">/etc/mecabrc && \ sudo cp /etc/mecabrc /usr/local/etc && \ cd .. 前半はMeCabの導入、後半でmecab-ipadic-NEologd辞書をインストールしています。また先ほど、 echo `mecab-config --dicdir`"/mecab-ipadic-neologd" でインストールした辞書のディレクトリパスを標準出力できると書きましたが、その結果を/etc/mecabrcにリダイレクトすることでMeCabのデフォルト辞書を再定義しています。丁度下記の部分ですね。 echo dicdir = `mecab-config --dicdir`"/mecab-ipadic-neologd">/etc/mecabrc あと、これは結構ハマりポイントだと思うのですが、以下のようにmecabrcを指定の場所にコピーしてあげ無いと動きません。ターミナルからは使えるんですがpython-mecabで使おうとするとパスが通って無いってエラーが出てしまいます。。。 sudo cp /etc/mecabrc /usr/local/etc && \ 一応、今までの流れ含め GitHub にあげておきました。それにしても早速リアル二刀流が反映されているNEologdは優秀ですね。
- 投稿日:2021-12-03T14:43:10+09:00
【再掲】Classiアンケートの回答を自動化する
※この記事ではWindows環境でPython3.7を用いています。ついでにChromeも入れておいてください。 また、筆者はPython初学者ですので、用語等間違いがあるかもしれません。指摘等あればコメントしてくださると助かります。 Classiのアンケートの回答を自動化したくて作ってみました。 1年半前に掲載して削除したものが残ってたのでその再掲です。 警告 ・担当教員にばれて怒られても責任はとれません。 ・不正アクセスはダメ!ゼッタイ! Classi とは? Classiは、学校のICT化を多角的にサポートする教育プラットフォームです。PCやタブレット、スマートフォンにも対応し、中学校、高校、専門学校など多くの教育現場で活用されています。 準備 まずはSeleniumをインストール。 コマンドプロンプトでpy -m pip install seleniumと実行しよう。 ChromeDriverをダウンロード。 以下のサイトからChromeDriverをダウンロード。 https://chromedriver.chromium.org/downloads 使っているChromeと同じバージョンをダインロードしてください。 ダウンロードが完了したらZIPを解凍して任意の場所に移動しておいてください。 プログラムの流れ 1. 必要なライブラリをインポートする。 classi.py from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.action_chains import ActionChains 先ほど入れたseleniumをインポートします。 2. Chromeを開く。 classi.py driver = webdriver.Chrome(executable_path='xxx\\chromedriver.exe') URL = "https://auth.classi.jp/students?backurl=https%3A%2F%2Fplatform.classi.jp%2F" driver.get(URL) 1行目のexecutable_path='xxx\\chromedriver.exe'には先ほどダウンロードしたChromeDriverのパスを入れてください。 Chromeを開き、Classiに移動します。 3.ログインしてアンケート一覧画面に移動する。 classi.py #IDとパスワードの入力 User_ID = "IDxxx" User_pass = "PASSxxx" #IDとパスワードを入力する場所を探す ID_box = driver.find_element_by_name("classi_id") pass_box = driver.find_element_by_name("password") #IDとパスワードを入力、Enterキーを押す ID_box.send_keys(User_ID) pass_box.send_keys(User_pass) pass_box.send_keys(Keys.RETURN) #アンケート一覧へ driver.get("https://platform.classi.jp/questionnaire#/reply/list") IDxxxとPASSxxxに自分のIDとパスワードを入力して、変数に代入します。 .find_element_by_name("classi_id")で、nameから要素を取得します。 4.アンケートを選択する。 classi.py #アンケート実施画面へ driver.find_element_by_xpath("/html/body/div[1]/div/div/article/div/section/div/div/div/table[1]").click() time.sleep(1) driver.find_element_by_xpath("/html/body/div[1]/div/div/article/div/form/div[2]/button").click() time.sleep(1) #回答するをクリック driver.find_element_by_xpath("/html/body/div[1]/div/div/article/div/form/div[2]/button").click() time.sleep(1) この時、選択するアンケートは一番上にあるアンケートです。また他のアンケートが未回答で残っている場合にはバグりやすいので回答してなくしておきましょう。 time.sleep(1)を追加しているのは、ページを移る時間を考慮しているためです。 5.アンケートに回答する。 ※この例では、上から選択問題、選択問題、記述問題という3問で構成されているアンケートです。 classi.py #回答 #1.選択問題1。2項目目を選択 driver.find_element_by_xpath("/html/body/div[1]/div/div/article/div/form/div[1]/div[2]/div/div/dl[1]/dd[2]/ul/li[2]").click() #2.選択問題2.3項目目を選択 driver.find_element_by_xpath("/html/body/div[1]/div/div/article/div/form/div[1]/div[3]/div/div/dl[1]/dd[2]/ul/li[3]").click() #3.自由記述 textbox = driver.find_element_by_xpath("/html/body/div[1]/div/div/article/div/form/div[1]/div[4]/div/div/dl[1]/dd[2]/div/label/textarea") textbox.send_keys("・英語\n・数学\n・物理\n・化学") time.sleep(1) #スクロール+一時保存 element = driver.find_element_by_xpath("/html/body/div[1]/div/div/article/div/form/div[2]/button[2]") actions = ActionChains(driver) actions.move_to_element(element) actions.perform() driver.find_element_by_xpath("/html/body/div[1]/div/div/article/div/form/div[2]/button[2]").click() time.sleep(1) Classiのアンケートは一番上の問題からdiv2、div3、div4...という順番で指定されています。3問以上ある場合にはdiv5...と増やせばいいのです。 また、選択問題と自由記述問題で形式が異なるので注意が必要です。 選択問題ではxpathの一番最後でクリックする項目を指定します。例)li[2] 6.送信してタブを閉じる。 classi.py #送信 driver.find_element_by_xpath("/html/body/div[1]/div/div/article/div/form/div[2]/button[3]").click() time.sleep(1) driver.find_element_by_xpath("/html/body/div[8]/div/div/div/div[3]/button[2]").click() #とじる time.sleep(5) driver.quit() あとは送信してタブを閉じるだけです。 完成!!! 完成したコードはこちら↓ classi.py from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.action_chains import ActionChains driver = webdriver.Chrome(executable_path='xxx\\chromedriver.exe') URL = "https://auth.classi.jp/students?backurl=https%3A%2F%2Fplatform.classi.jp%2F" driver.get(URL) #IDとパスワードの入力 User_ID = "IDxxx" User_pass = "PASSxxx" #IDとパスワードを入力する場所を探す ID_box = driver.find_element_by_name("classi_id") pass_box = driver.find_element_by_name("password") #IDとパスワードを入力、Enterキーを押す ID_box.send_keys(User_ID) pass_box.send_keys(User_pass) pass_box.send_keys(Keys.RETURN) #アンケート一覧へ driver.get("https://platform.classi.jp/questionnaire#/reply/list") #アンケート実施画面へ driver.find_element_by_xpath("/html/body/div[1]/div/div/article/div/section/div/div/div/table[1]").click() time.sleep(1) driver.find_element_by_xpath("/html/body/div[1]/div/div/article/div/form/div[2]/button").click() time.sleep(1) #回答するをクリック driver.find_element_by_xpath("/html/body/div[1]/div/div/article/div/form/div[2]/button").click() time.sleep(1) #回答 #1.選択問題1 driver.find_element_by_xpath("/html/body/div[1]/div/div/article/div/form/div[1]/div[2]/div/div/dl[1]/dd[2]/ul/li[2]").click() #2.選択問題1 driver.find_element_by_xpath("/html/body/div[1]/div/div/article/div/form/div[1]/div[3]/div/div/dl[1]/dd[2]/ul/li[3]").click() #3.自由記述 textbox = driver.find_element_by_xpath("/html/body/div[1]/div/div/article/div/form/div[1]/div[4]/div/div/dl[1]/dd[2]/div/label/textarea") textbox.send_keys("・英語\n・数学\n・物理\n・化学") time.sleep(1) #スクロール+一時保存 element = driver.find_element_by_xpath("/html/body/div[1]/div/div/article/div/form/div[2]/button[2]") actions = ActionChains(driver) actions.move_to_element(element) actions.perform() driver.find_element_by_xpath("/html/body/div[1]/div/div/article/div/form/div[2]/button[2]").click() time.sleep(1) #送信 driver.find_element_by_xpath("/html/body/div[1]/div/div/article/div/form/div[2]/button[3]").click() time.sleep(1) driver.find_element_by_xpath("/html/body/div[8]/div/div/div/div[3]/button[2]").click() #とじる time.sleep(5) driver.quit() おわりに 結局、このプログラムはどんなアンケートが何問あるかを知っておかなければ使えないんですよね。仮に、同じ内容のアンケートが定期的に配信されるのであれば使える(と思う)ので良ければ活用してみてください。 ただし、自動回答であることが担当教員にばれても(ばれるとは思わないが)責任はとれません。ご了承ください。 ここまで読んでくださりありがとうございました!
- 投稿日:2021-12-03T14:24:12+09:00
数値流体力学2~スカラー移流方程式(cの符号がわからない場合)~
はじめに 数値流体解析(CFD)の基礎シリーズの第2回です。前回は、スカラー移流方程式について数値計算をしてみました。今回はその続きです。よかったら、前回の記事も見てみてください。 何か間違いなどありましたら気軽にコメントしてください! シリーズ構成(順次更新予定です) 1. スカラー移流方程式 1.1 輸送速度が正の場合 1.2 輸送速度の符号が不明の時の線形問題←本記事 1.3 数値流束を利用した方法 1.4 輸送速度が未知量であるとき(Burgers方程式) 1.5 多次元への拡張(2次元スカラー移流方程式) 1.6 実践的な計算法(TVD方程式) 2. 移流方程式の時間積分法 2.1 陽解法と陰解法について 2.2 時間陰解法について(Crank-Nicholson法、近似LU分解) 3. 拡散方程式 3.1 1次元熱伝導方程式の数値計算法 3.2 楕円方程式の数値計算法 4. 圧縮性流れの数値計算法 4.1 オイラー方程式の数値計算法 4.2 MacCormack法による数値計算法 4.3 TVD法による数値計算法 今回扱う内容 今回は、輸送速度の符号がわからない場合のスカラー移流方程式の数値計算法について考えていきます。基本的な考え方を扱った後、具体的にプログラムに落とし込んでいきます。 基本的な考え方 輸送方程式の輸送速度があらかじめわからないとき、以下の分岐をプログラムに組み込む必要があります。 \left \{ \begin{array}{l} q^{n+1}_{j}=q^{n}_{j}-c\Delta{t}\frac{q^{n}_{j}-q^{n}_{j-1}}{\Delta{x}} (c>0) \\ q^{n+1}_{j}=q^{n}_{j}-c\Delta{t}\frac{q^{n}_{j+1}-q^{n}_{j}}{\Delta{x}} (c<0) \\ \end{array} \right. これをプログラムに落とし込むにあたって、If分の分岐を考えると思います。しかし、If文を使ってしまうと計算の過程でコンピュータに負担がかかってしまうのです。なので、以下のような評価式を使うことで解決します。ここでは、一次精度風上法を用いています。 q^{n+1}_{j}=q^{n}_{j}-\Delta{t}\Big(\frac{c+|c|}{2}\frac{q^{n}_{j}-q^{n}_{j-1}}{\Delta{x}}+\frac{c-|c|}{2}\frac{q^{n}_{j+1}-q^{n}_{j}}{\Delta{x}}\Big) プログラムへの実装 import numpy as np import matplotlib.pyplot as plt #初期値の設定、空間初期分布の設定 c = -1 dt = 0.05 dx = 0.1 jmax = 21 nmax = 6 x = np.linspace(0, dx*(jmax-1), jmax) q = np.zeros(jmax) for j in range(jmax): if (j < jmax/2): q[j] = 0 else: q[j] = 1 def do_computing(x, q, c, dt, namax, dx): plt.figure(figsize=(7,7), dpi=100) plt.rcParams["font.size"] = 22 #初期分布の可視化 plt.plot(x, q, marker='o', lw=2, label='n=0') for n in range(1, nmax+1): qold = q.copy() for j in range(1, jmax-1): c2 = (c + abs(c)) / 2 c3 = (c - abs(c)) / 2 q[j] = qold[j] - dt * (c2 * (qold[j] - qold[j-1]) / dx + c3 * (qold[j+1] - qold[j]) / dx) #各ステップの可視化 if n % 2 == 0: plt.plot(x, q, marker='o', lw=2, label=f'n={n}') #グラフの後処理 plt.grid(color="black", linestyle='dashed', linewidth='0.5') plt.xlim([0,2.0]) plt.ylim([0,1.2]) plt.xlabel('x') plt.ylabel('q') plt.legend() plt.show() do_computing(x, q, c, dt, nmax, dx) プログラム結果は、 しっかり計算結果が表れていることがわかりますね。なお、一次精度風上法における数値計算は前回の記事で詳しく解説しています。 まとめ 今回は、輸送速度の符号がわからないときの移流方程式の数値計算法を考えました。If文を使うのではなくて、絶対値を使った処理をすることでコンピュータに負担をかけずに計算を行うことができます。 参考文献 藤井孝蔵、立川智章、Pythonで学ぶ流体力学の数値計
- 投稿日:2021-12-03T14:14:45+09:00
データジャーナリズムの種明かしするよ(衆院選の争点分析)
この記事は朝日新聞社 Advent Calendar 2021の第8日目の記事です。 こんにちは。朝日新聞社デジタル機動報道部でデータジャーナリズムの取り組みに携わっている山崎です。もともとエンジニアとして入社した背景を武器に、データの分析やそのビジュアライゼーションを記事の執筆に活かしているところなのですが、10月にあった衆院選で配信した「候補者つぶやき分析」の種明かしをしたいと思います! 1.目指すこと 執筆したのはこちらの記事↓↓ この中の後半に登場する、与野党の候補者でツイッターの投稿内容にどのような違いがあるのかについて表した、散布図のビジュアライゼーションを作ることがゴールです。 2.つぶやきの収集 収集には、pytyonライブラリ「tweepy」を活用しました。tweepyは、投稿、取得、いいね、リツイートなどの情報を簡単に集めることができるライブラリです。 まず、衆院選に立候補した候補者で、ツイッター社が本人のアカウントと認めた「認証済みバッジ」がある454アカウントに絞って、19日~27日に投稿された与党1万112件、野党1万984件のつぶやきの内容(リツイートを除く)を収集しました。 tweet_get.py import pandas as pd import tweepy # Twitterオブジェクトの生成 # keyやTokenは各自の設定を入れる auth = tweepy.OAuthHandler(consumer_key, consumer_secret) auth.set_access_token(access_token, access_token_secret) api = tweepy.API(auth, wait_on_rate_limit=True, wait_on_rate_limit_notify=True) # 取得したいユーザーのユーザーIDを代入 cols = ["twid", "name", "user", "party", "date", "tweet_text", "favo", "retw"] df_tw = pd.DataFrame(index=[], columns=cols) # df_twitterはアカウント一覧のDataframe for index, row in df_twitter.iterrows(): user_id = row["tw_username"] # つぶやきは(上限の)200件、リツイートは含まない、つぶやきを全文取得するオプションを設定 tweets = api.user_timeline(id=user_id, count=200, include_rts=False, tweet_mode="extended") for tweet in tweets: # つぶやき内容などと政党などの候補者の情報をDataframeに追加していく df_tw = df_tw.append({"twid":tweet.id, "name":row["name"], "user":user_id, "party":row["party"], "date":tweet.created_at, "tweet_text":tweet.full_text, "favo":tweet.favorite_count, "retw":tweet.retweet_count }, ignore_index=True) 3.可視化 単語の出現頻度に合わせたきれいな散布図を生成できる「scattertext」というライブラリを使って可視化していきます。ライブラリでは、2012年にあった米大統領選における「共和党」と「民主党」の討論内容の差を例に散布図を作成しています。そのビジュアルにインスピレーションを受け、日本の選挙でも同じような違いが出るのではないか、と考えました。 日本語の文章はそのままでは解析できないので、分かち書きや品詞解析のためにginzaを活用。名詞、動詞、形容詞、副詞の単語の出現回数を集計します。 scattertext.py import scattertext as st import spacy from collections import Counter from itertools import chain import pandas as pd # 品詞を絞りこんで、単語の出現回数を集計していく class UnigramSelectedPos(st.FeatsFromSpacyDoc): # 名詞、動詞、形容詞、副詞を集計 def __init__(self,use_pos=['NOUN', 'VERB', 'ADJ', 'ADV']): super().__init__() self._use_pos = use_pos def get_feats(self, doc): return Counter([c.lemma_ for c in doc if c.pos_ in self._use_pos]) # Corpusの作成 corpus = (st.CorpusFromPandas(df_tw, category_col='label', text_col='tweet_text', nlp = spacy.load("ja_ginza"), feats_from_spacy_doc=UnigramSelectedPos() ) .build()) 作成したcorpusから、単語の出現回数や単語のスコアを取り出します。また、散布図にプロットするために、単語の出現回数のランキングを与党、野党ごとに計算します。そうすることで、例えば与党で順位が高く、野党で順位が低い単語は「与党が使いがちな単語(争点)といえる可能性がある」ことになります。 scattertextは散布図のHTMLをきれいにはき出す機能も備えていますが、今回は成果物を外部のビジュアライゼーションツールで公開したかったので、その機能は活用しませんでした。 corpus_output.py from scattertext.termscoring.RankDifference import RankDifference from scipy.stats import rankdata import numpy as np # 各単語の出現回数とスコアを吐き出す freq_df = corpus.get_term_freq_df() freq_df["score"] = RankDifference().get_scores(freq_df["与党 freq"], freq_df["野党 freq"]) # 与野党候補のつぶやき総数が100回以下の単語は対象外にする freq_df["count"] = freq_df["与党 freq"] + freq_df["野党 freq"] freq_df = freq_df[freq_df["count"] > 100] # 単語ごとの出現回数の順位を与野党ごとに計算する freq_df["order_与党"] = rankdata(np.array(freq_df["与党 freq"])) freq_df["order_野党"] = rankdata(np.array(freq_df["野党 freq"])) # 出力 freq_df.to_csv('./scattertext_output.csv') 4.Flourishでビジュアライゼーション! データの可視化には、簡単におしゃれでリッチなビジュアルが作れる「Flourish」を活用しました。報道用アカウントを発行してもらうと有料版の機能が無料で利用可能になるというのが採用理由なのですが、無料アカウントでもほぼ全ての機能が使えて、誰でもクオリティーの高いコンテンツを作成→公開まで出来るのが強みだと思います。 ◆公開までの手順 1.テンプレートを選択 まずは散布図用のテンプレートを選択。Flourishは折れ線や棒グラフ、レースチャートなどのテンプレートがあらかじめ用意されていて、データを差し替えるだけですぐにアウトプットができるところも魅力の一つです。 2.データのアップロード 「Data」タブから、先ほどの単語とスコアのデータをアップします。列名は下図のように名付けました。 アップロードが完了したあとに、どの列を使うのかについても設定していきます(図では隠れてしまっていますが、「Filter control」にH列を設定しています)。 3.項目設定(と微調整) Previewタブへ移動すると、すでに散布図が完成していると思います。右側にある設定項目で、見出しやフォントなどを調整。このあたりはマニュアルがなく、経験とセンスに頼る部分が大きく苦労するのですが、頑張って設定します(自分はデザイン部の社員の知恵をかり…笑) 4.公開! 「publish」ボタンを押して、コンテンツを公開します。 公開すると、URLが自動で割り当てられて、作成したビジュアルが誰でも閲覧できる状態になります。今回公開した弊社のコンテンツはこちら。朝日新聞デジタルではこれを記事内に埋め込んで読者に届けています。 与野党それぞれでズームしてもらうと分かりやすいのですが、「消費税」「ジェンダー」「気候」「格差」といった単語の利用頻度で差があることがわかりました。いずれの単語も、野党候補者のつぶやきでそれぞれ100回以上登場していて、「気候危機、ジェンダー、若者の未来を奪う政治を変えなければ」「ジェンダーのテーマを正面に掲げて選挙で訴える」などといった投稿で使われていたのですが、一方の与党候補者ではこれらの単語はいずれも各10回ほどか、それ以下の言及にとどまっていました。 逆に与党側で目立ったのは、「大臣」「担当」などの役職を表す単語。「厳しい」も比較的多く、「初日から党本部から応援が来る厳しい戦いを走り抜けます」といったつぶやきが計185件あって、野党共闘候補などへの危機感を募らせる胸中がうかがえます。 5.終わりに 衆院選候補者ツイッターのつぶやき内容から、ビジュアライゼーションツールを使ってデータの可視化をすることで、単語の出現回数ランキングといった数値の一覧では理解しにくい違いが与野党間であることを、直感的に理解することができました。 デジタル機動報道部では、選挙だけでなく、犯罪やコロナなど気になるニュースや話題をデータから読み解く試みを続けています。取り組みをまとめたページも用意しているので、ぜひこちらもチェックしてみて下さい! 6.参考 scattertextで文章の単語出現頻度を可視化 Twitter APIで遊んでみた ~2. ツイートの投稿と取得~ 朝日新聞社では、技術職の中途採用を強化しています。 ご興味のある方は下記リンクから希望職種の募集ページに進んでください。 皆様からのご応募、お待ちしております!
- 投稿日:2021-12-03T13:55:44+09:00
GoogleAppEngineでCloud SchedulerからのHTTPリクエストのみを受け付ける
概要 アプリの開発にGCPを利用しています。 その中で、定期実行させたい処理を、CloudScheduler→AppEngineで行っています。 CloudSchedulerからAppEngineに対してHTTPリクエストを送るのですが、その際にAppEngine側ではCloudSchedulerからのリクエストのみを受け取るようにしました。 実装方法 HTTPリクエストのヘッダを参照して、CloudSchedulerからのリクエストであるかどうかを判定します。 この時、CloudSchedulerからのリクエストであれば、X-Appengine-User-Ipというヘッダが0.1.0.2であると言うことを利用します。 Cloud Taskで、受け取ったHTTPリクエストのヘッダを参照する。 1から、Cloud Schedulerが送信したHTTPリクエストであるかを判定する。 2が真であった時のみ、処理を実行する。 from flask import Request from flask import request def check_request(request: Request) -> bool: """リクエストがGoogleCloudSchedulerからのものであるかを確認する '""" gae_ip = request.headers.get("X-Appengine-User-Ip") if not gae_ip or not gae_ip.startswith("0.1.0.2"): return False else: return True なぜこの方法にしたのか どうやったらCloudSchedulerからのHTTPリクエストのみを受け付けられるか考えていました。 そこで、Cloud SchedulerからAppEngineにHTTPリクエストを送信したときのヘッダーを調べてみることにしました。 ヘッダーを出力してみたところ、下記のようにX-Appengine-**やX-CloudScheduler-**といったヘッダーが付与されています。 HTTPリクエスト抜粋 'Host': 'XXX', 'X-Forwarded-For': '0.1.0.2, 169.254.1.1', 'X-Forwarded-Proto': 'http', 'Forwarded': 'for="0.1.0.2";proto=http', 'Content-Length': '0', 'User-Agent': 'AppEngine-Google; (+http://code.google.com/appengine)', 'X-Cloudscheduler': 'true', 'X-Cloudscheduler-Jobname': 'XXX', 'X-Appengine-Country': 'ZZ', 'X-Cloud-Trace-Context': 'XXX1', 'Traceparent': 'XXX', 'X-Appengine-Timeout-Ms': '599998', 'X-Appengine-Https': 'off', 'X-Appengine-User-Ip': 'XXX', 'X-Google-Internal-Skipadmincheck': 'true', 'X-Appengine-Request-Log-Id': 'XXX', 'X-Appengine-Default-Version-Hostname': 'XXX' CloudSchedulerのレファレンスにも書かれていますが、これらの特殊なヘッダーはGCP内部用のヘッダーのようです。 今回はこの中から、'X-Appengine-User-Ip': '0.1.0.2'を利用することにしました。 これについて詳しく調べてみると、GCPのAppEngineファイヤーウォールのガイドにも書いてありました。 GCPのサービスから送られるリクエストは、IPアドレスの範囲が決まっており、CloudSchedulerのジョブによるリクエストは、0.1.2.2/32とあります。 0.1で始まるIPアドレスってとても珍しいですよね。
- 投稿日:2021-12-03T12:59:05+09:00
5さいでもわかる(*╹▽╹*) boost python / boost numpy を使った numpy array と C++配列の相互変換
はじめに 江坂キャンパスから梅田キャンパスで動画編集ソフト作ってた人です 自作動画編集ソフト制作においてC++配列とnumpy配列を変換した時に集めた情報をまとめておきます 5さいでもわかるシリーズ2本目です 一本目 >>> 5さいでもわかる(╹▽╹) WebAssemblyを使ってJavaScriptからC++を動かしてみよう! boost pythonとは何か 端的にいうと「C++とpythonを連携できるようにするもの」です boost pythonについてはこちらの記事が参考になると思います numpy配列とC++配列の変換についてまとめられている記事が少なかったので今回書きました boost pythonの使い方についてはドキュメントなどを読む方がいいと思います(boost pythonの使い方記事はそのうち書きます) 前提 C++側の配列は1次元にしましょう C++の配列をわざわざ1 < n次元で扱うなんてめんどくさいです 参考程度に 2次元配列を1次元として扱う式 指定先 = width * y + x 3次元配列を1次元として扱う式(r=3次元目) 指定先 = (width * y + x) * Rsize + r この計算式が使えるのは各次元方向で要素数が全て等しい場合に限ります=画像データ取り扱い時に重宝します 本題 C++からNumpy こっちは簡単 突っ込むだけ cpp_to_py.cpp // 16ビット モノラル #include <bits/stdc++.h> #include <math.h> #include <stdio.h> #include <boost/python.hpp> #include <boost/python/numpy.hpp> #include <iomanip> namespace py = boost::python; namespace np = boost::python::numpy; np::ndarray CppPy() { int draw_RGB = 1280 * 720; int draw_RGBA = 1280 * 720 * 4; //1280x720でRGBA uint8_t *draw = new uint8_t[draw_RGBA]; for (int i = 0; i < draw_RGB; i++) { draw[i * 4 + 0] = 0; //RGBA draw[i * 4 + 1] = 255; draw[i * 4 + 2] = 255; draw[i * 4 + 3] = 255; } py::tuple shape = py::make_tuple(draw_RGBA); py::tuple stride = py::make_tuple(sizeof(uint8_t)); np::dtype dt = np::dtype::get_builtin<uint8_t>(); np::ndarray npdraw = np::from_data(&draw[0], dt, shape, stride, py::object()); //np::from_dataの第一引数に目的の配列の先頭のアドレスを入れる return npdraw; } BOOST_PYTHON_MODULE(cpp_to_py) { Py_Initialize(); np::initialize(); def("CppPy", &CppPy); } test.py import cpp_to_py import cv2 draw = cv2.cvtColor(cpp_to_py.CppPy().astype('uint8').reshape(720, 1280, -1), cv2.COLOR_RGBA2BGR) #C++側からもらったnumpyデータ(1次元)をopencvで表示できるようuint8に変換して3次元変換 #ここから先はopencvのGUIに表示するコード print(draw) print(draw.shape) print(draw.dtype) cv2.imshow("draw", draw) cv2.waitKey(0) cv2.destroyAllWindows() 一面水色の画像が表示される NumpyからC++ ループとポインタが必要 めんどくさい py_to_cpp.cpp // 16ビット モノラル #include <bits/stdc++.h> #include <math.h> #include <stdio.h> #include <iomanip> #include <boost/python.hpp> #include <boost/python/numpy.hpp> namespace py = boost::python; namespace np = boost::python::numpy; np::ndarray PyCpp(np::ndarray npdraw, int width, int hight) { auto pointer_start = reinterpret_cast<uint8_t *>(npdraw.get_data()); auto strides = npdraw.get_strides(); int rgba = 4; int draw_RGBA = width * hight * rgba; //1280x720でRGBA int draw_RGB = width * hight; uint8_t *draw = new uint8_t[draw_RGBA]; for (int i = 0; i < draw_RGBA; i++) { uint8_t *p_color = pointer_start + i; draw[i] = *p_color; } //ここまでcppへの変換 //さっきのと組み合わせてpythonに戻してみる py::tuple shape = py::make_tuple(draw_RGBA); py::tuple stride = py::make_tuple(sizeof(uint8_t)); np::dtype dt = np::dtype::get_builtin<uint8_t>(); np::ndarray npdraw_for_py = np::from_data(&draw[0], dt, shape, stride, py::object()); //np::from_dataの第一引数に目的の配列の先頭のアドレスを入れる return npdraw_for_py; } BOOST_PYTHON_MODULE(py_to_cpp) { Py_Initialize(); np::initialize(); def("PyCpp", &PyCpp); } testnp.py import py_to_cpp import numpy as np import cv2 X = 1280 Y = 720 draw_inp = np.full((Y, X, 4), 255) draw_inp[:, :, 0] = np.full((Y, X), 255) draw_inp[:, :, 1] = np.full((Y, X), 255) draw_inp[:, :, 2] = np.full((Y, X), 0) draw_inp[:, :, 3] = np.full((Y, X), 255) # 無理やり黄色を作る draw = cv2.cvtColor(py_to_cpp.PyCpp(draw_inp.astype('uint8'), X, Y).astype('uint8').reshape(Y, X, -1), cv2.COLOR_RGBA2BGR) print(draw) print(draw.shape) print(draw.dtype) cv2.imshow("draw", draw) cv2.waitKey(0) cv2.destroyAllWindows() 一面黄色の画像が表示される ポインタの型の定義に注意です 送られてくるnumpy配列のデータ型に合わせる必要があります。(例:uint8のnumpyをC++に変換するならC++側のポインタの型はuint8_tを使う) uint_8のnumpy配列なのにint型のポインタを使用するなど、ポインタのbitサイズがあっていない場合はセグメンテーション違反:11が発生します。またuint_8と同じサイズのchar型を使うと違反11を回避することはできますが、意図しない数値が出てきます 使用上の注意 基本的にはnumpyのスライスなどを活用してpython側で処理を済ましてしまいましょう 決して「pythonでループを流すな軍団」への反対材料として利用してはいけません それでは良いC++Pythonライフを
- 投稿日:2021-12-03T12:35:27+09:00
GPT-3で遊んでみた
昨日の@hcpmiyukiさんの記事では、Supabaseという今あついBaaSについて書いてくれました! MYJLab Advent Calendar 2021の3日目はGPT-3に関してです 論文を要約してAPIで遊びます GPT-3とは イーロン・マスク氏が共同会長を務める非営利のAI研究企業であるOpenAIが発表した、汎用言語モデルの3世代目です ネット上のテキストの次の単語を予測するためだけに訓練されたTransformerベースの自己回帰言語モデルで、なんと1750億個のパラメータで動作するそうです あまりの精度の高さに以前話題沸騰でした This is mind blowing.With GPT-3, I built a layout generator where you just describe any layout you want, and it generates the JSX code for you.W H A T pic.twitter.com/w8JkrZO4lk— Sharif Shameem (@sharifshameem) July 13, 2020 以下サイトで紹介されているものもGPT-3が使われています 去年の9月にMicrosoftがOpenAIからライセンスを取得しています 論文要約 2020年に公開された以下論文をざっくりと要約します いつか読みたいなと思っていたのですが、量が多いので、いつかいつかと先延ばしになっていました このアドベントカレンダーを機に 1 Introduction ファインチューニングが近年のトレンドだった(BERTやRoBERTaなど) ただ、ファインチューニングには以下のようなデメリットがある 新しいタスクのたびに、タスクに特化したラベル付きのデータセットとタスクに特化した微調整が必要になる 大量のラベル付きデータを収集することが難しいタスクもある ラベル付きの教師データがなくても、人間みたいに妥協できる範囲内で新しいタスクを実行できるようになりたい 上記デメリットを解決するアプローチの1つがメタ学習 教師なしの事前学習 1つのシーケンスの中に、繰り返されるサブタスクが含まれている場合があることを示している 内包される様々な言語タスクへの処理能力の獲得が期待できる(in-context learning) しかし、メタ学習は、実用的な活用にはまだ改善が必要 そこで近年、億単位のパラーメータにして言語モデルを大きくするのが流行ってることに着目(スケーリング則) こいつはどうやら、文章生成能力や下流タスクの処理能力も向上することが報告されているらしい →大幅にパラメータ数を増やした自己回帰言語モデルであるGPT-3を学習することで、スケーリング則とin-context learningの性能を検証する 2 Approach 事前学習モデルを利用するアプローチ Fine-tuning 近年の最も一般的な手法 事前に学習したモデルの重みを更新する 多くのベンチマークで強力なパフォーマンスを発揮してる 欠点は、タスクごとに新しい大規模なデータセットが必要なこと、一般化がうまくいかない可能性があること Few-shot タスクに関する説明と少量のタスクの例を与える One-shot few-shotにおいてタスクの例を1つ与える Zero-shot タスクに関する説明のみ与え、タスクの例は与えない モデルのアーキテクチャ GPT-2と基本は同じモデル ベースはTransformer Sparse Transformerのように局所的なAttentionパターンを使用 自己回帰による学習 データセット Common Crawlのデータセットを使う 単語数は約1兆個も Common Crawlのデータセットは質が低いものがあるので、質の高いデータセットと、類似度によってフィルタリングするなどして対応する 3 Results モデルサイズと計算量に対するパフォーマンス 言語モデリングの性能はべき乗に従うと報告されている 上の表の8つのモデルに、10万パラメータの6つの小さな(!?)モデルも追加して確認する 黄色の線が175BのGPT-3のLoss(まだまだいける) ※PetaFLOP/s-days : 1秒間に1ペタ(10の15乗)回のニューラルネット上の演算操作を、1日分行った計算量 言語モデル PTBデータセットを使用する SoTA、GPT–3ともに、Zero-Shotでの結果を出す ちなみにPTBデータセットでは学習してない perplexityで確認する SoTAから15.3ポイントも差をつけて改善 Q&A 以下3つのデータセットで確認 NaturalQS WebQS TriviaQA その中でもTriviaQAに関しては、GPT-3のFew-shotがSOTAを達成 翻訳 BLUEスコア フランス語から英語、ドイツ語から英語に関してはSoTAを達成 上記以外にも、非常に多くのタスクで高い性能を発揮 4 Measuring and Preventing Memorization Of Benchmarks インターネットから供給されたデータセットなので、ベンチマークのテストセットを一部で学習しちゃってる可能性がある インターネット規模のデータセットからのテストの汚染を正確に検出することは、新しい研究分野であり、確立されたベストプラクティスは存在しない (汚染を調査せずに大規模なモデルを訓練することは一般的に行われているが、事前訓練用データセットの規模が大きくなっていることを考えると、この問題に取り組むことはますます重要になってる) 5 Limitations GPT-3の限界について 文書レベルで意味的な繰り返しがあったり、十分な長さの文章でまとまりがなくなったり、矛盾が生じたり、時折、連続しない文章や段落が含まれていたりする、などなど 6 Broader Impacts 社会に与える悪いインパクトに関して GPT-3の誤用、公平性、エネルギー使用など 生成される文章に偏見を含む可能性がある 上記に関して分析 性別、人種、宗教に関連するバイアスを特定するなど 偏見を緩和する規範的、技術的、実証的な課題を結びつける共通の用語体系が必要 7 Related Work 関連研究 ここ数年の自然言語処理のトレンドは,データサイズ・モデルサイズ・訓練時間を同時に上げてパフォーマンスを改善すること LSTMベースの言語モデルのパラメータ数を10億以上に増やしたもの など 8 Conclusion タスクに特化した教師データによる学習が不要になる 非常に大きなモデルを非常に大きなコーパスで学習することで、より汎用的なモデルを構築できた すごい 特定のタスクに特化した学習をせずに事前学習のみで、めちゃ多くのタスクで高い性能を出しまっくってるっていう、本当にただただすごいしか出てこない APIで遊ぶ 日本語版のAPIで諸々試していきます 1. 登録 まず、OpenAIのベータ版サイトで利用申請をします 少し待って、申請が認証されてwelcomeメールが届いたら、登録完了です 最初の3ヶ月間に利用できる$18の無料クレジットが提供されるので、この範囲内で遊びます (1.5 おまけ サイト上で試してみる) Playgroundに移動して 試しに、「お腹すいた」と入力して ※Few-shotで試すべきなんだろうけど後で試すので、あえてお腹すいたで 左下のGenerateボタンを押してみると... 文章が! Generateボタンを押していくと、どんどん続きを書いてくれる すごい楽しい Playgroundでも十分色々なタスクを試せます 2. APIキーを取得 右上から確認できます 3. pip install $ pip install openai 4. 実行 import openai openai.api_key = "APIキー" APIキーを設定したら、以下色々試していきます チャット start_sequence = "\nAI:" restart_sequence = "\n私: " prompt = '''チャットボットです。 私: こんにちは、調子はどう? AI: 元気です 私: 最近何してるの? AI:''' response = openai.Completion.create( engine='davinci', prompt=prompt, max_tokens=30, stop="\n") print(prompt+response['choices'][0]['text']) 結果 チャットボットです。 私: こんにちは、調子はどう? AI: 元気です。 私: 最近何してるの? AI: 調子がいいから、努力して何かしはじめました。 Q&A start_sequence = "\nA:" restart_sequence = "\nQ: " prompt = '''私は真実を答える賢い質問応答ボットです。 Q: 日本の人口は? A: 約1億人です。 Q: 世界で一番人口が多い国は? A: ''' response = openai.Completion.create( engine='davinci', prompt=prompt, max_tokens=100, stop="\n") print(prompt+response['choices'][0]['text']) 結果 私は真実を答える賢い質問応答ボットです。 Q: 日本の人口は? A: 約1億人です。 Q: 世界で一番人口が多い国は? A: 南アフリカです。 翻訳 start_sequence = "\nJapanese:" restart_sequence = "\nEnglish: " prompt = '''日本語を英語に翻訳します。 English: I am a student. Japanese: 私は学生です。 English: I do not speak Japanese. Japanese:私は日本語を話しません。 English: I love him very much. Japanese: ''' response = openai.Completion.create( engine='davinci', prompt=prompt, max_tokens=100, stop="\n") print(prompt+response['choices'][0]['text']) 結果 日本語を英語に翻訳します。 English: I am a student. Japanese: 私は学生です。 English: I do not speak Japanese. Japanese:私は日本語を話しません。 English: I love him very much. Japanese: 私は彼をとても愛しています。 映画を絵文字で表現 prompt = ''' Back to Future: ???? Batman: ?? Transformers: ?? Wonder Woman: ?????????? Winnie the Pooh: ??? The Godfather: ?????♂️?? Game of Thrones: ???? Spider-Man:''' response = openai.Completion.create( engine='davinci', prompt=prompt, temperature=0.8, max_tokens=100, top_p=1.0, frequency_penalty=0.0, presence_penalty=0.0, stop="\n") print(prompt+response['choices'][0]['text']) 結果 Back to Future: ???? Batman: ?? Transformers: ?? Wonder Woman: ?????????? Winnie the Pooh: ??? The Godfather: ?????♂️?? Game of Thrones: ???? Spider-Man: ?? キーワードの提示 start_sequence = "\nテキスト:" restart_sequence = "\nキーワード: " prompt = ''' テキスト: 宮治研究室(宮治ゼミ) 本研究室では,ネットやウェブなどに加えて,センサやカメラなどによって収集した実世界の情報を融合することによって,社会や生活の役に立つサービスを創出することを目的としています. その実現の為には,「データ採取」「データ分析」「情報提示」「通信・連携」の 4 領域の技術が必要となります. キーワード:''' response = openai.Completion.create( engine='davinci', prompt=prompt, max_tokens=100, stop="\n") print(prompt+response['choices'][0]['text']) 結果 テキスト: 宮治研究室(宮治ゼミ) 本研究室では,ネットやウェブなどに加えて,センサやカメラなどによって収集した実世界の情報を融合することによって,社会や生活の役に立つサービスを創出することを目的としています. その実現の為には,「データ採取」「データ分析」「情報提示」「通信・連携」の 4 領域の技術が必要となります. キーワード: リモートセンシング, IC ラップ, レーザコンピューティング, センサ, カメラ, インタラクション, カラーチャネル, ウェブモデル, 交流, GPS, 位置情報, 実世界情報 CSSのカラーコードの提案 prompt = ''' 明るくて綺麗な空の色みたいな青のカラーコード: background-color: #''' response = openai.Completion.create( engine="davinci", prompt=prompt, temperature=0, max_tokens=64, top_p=1.0, frequency_penalty=0.0, presence_penalty=0.0, stop=";" ) print(prompt+response['choices'][0]['text']) 結果 明るくて綺麗な空の色みたいな青のカラーコード: background-color: #00b2ff おわり 時々失敗することはあれど、かなりの汎用性の高さと自然な日本語にびっくりしました このレベル感でタスクに特化した学習をしてないっていうのが本当にすごいです、、 簡単に試せて楽しかったです 上記で試したもの以外にも色々あります(感情分析、キャッチコピージェネレータ、難しい文章を優しい文章に要約、住所の抽出、Pythonを自然言語で解説、自然言語からSQLを作成、JavaScriptをPythonに変換、などなど...) 参考文献
- 投稿日:2021-12-03T11:59:39+09:00
Dockerで、検証用サーバーを構築してみた⑤ (最終章 実行編)
[概要] Dockerを使用する際のコマンドを、自分なりに理解した内容も踏まえて 記録しておこう。 [コマンド] [現在のディレクトリ構成] LocalServer/ ├── app/ │ └── local_server.py └── Dockerfile └── docker-compose.yml 最終章 これまでの記事で、必要最低限のソフト、ファイルを用意してきました。 この記事では、実際に自身のPCのみでリクエストからレスポンスを一貫して確認してみようと思います。 Dockerの起動 1, Dockerは起動できている? まず、以下のコマンドを実行して、Dockerが起動しているか確認してみよう terminal #実行しているコンテナ一覧を表示するコマンド $ docker ps ※もし、以下のようなエラーが表示されれば、Dockerそのものをが起動出来ていない。 terminal #Dockerを起動出来ていないので、ちゃんと起動してる?と言われる。。。 $ docker ps Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? 以下コマンドで、Dockerを立ち上げよう terminal /usr/bin/open /Applications/Docker.app 以下の内容が、表示されればOK。 terminal #現在はコンテナを起動していないので各項目のみ表示される $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2, コンテナの起動 以下のコマンドを実行して、[docker-compose]から、コンテナを起動してみましょう。 terminal # 停止中のコンテナを対象に、イメージ作成から、コンテナを作成/起動してくれるコマンド $ docker-compose up ※LocalServerフォルダに移動してから実行してください。 3, コンテナ状態の確認 上記1の、コマンドを実行してコンテナが起動されていることを確認してみましょう。 すると今度は以下のような表示になる筈です。 terminal $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 60567ff2049d localserver_flask "flask run --host 0.…" 12 minutes ago Up 7 minutes 0.0.0.0:8080->8080/tcp localserver_flask_1 [各項目の詳細] CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAME コンテナIDの最初の12桁 コンテナ生成の元となったイメージ 起動時のコマンド コンテナ作成後の経過時間 コンテナ起動/停止後の経過時間 バインドしているポート コンテナ名 これで晴れて、自身のPC内に、Dockerを使用→コンテナ起動→検証用サーバーを立ち上げる事が可能となりました。 4, それではブラウザで、「localhost:8080/test」を開いてみましょう。 pythonファイルの記載されている、「リクエストに成功!!」の文言が表示されればOKだが、、、 どうだ、、 どう、、だ? 気持ちの良い瞬間 4, まとめ 今回、初投稿ではありましたが記事①〜⑤を作成してみました。 詳細な情報、必要な情報が抜けていたり、至らない点がいくつもあると思います。 その点は、すみません。(内容に間違いや、アドバイス等ありましたらご指摘いただけますと幸いです) 今後もっともっと、知識を深めて色々な情報をお届けできればなと思ってます。 それと、最後に記事の投稿に迷われている方等、いらっしゃいましたら 私は、以下の内容を感じましたので、少量でも投稿してみる事をオススメします。 ・アウトプットによる、知識の定着 ・記事を公開するので、今までしっかり理解出来ていなかった内容を理解しないといけない。。が 知識量が増える。(結果、楽しいw) ・再度、技術者として自覚し、モチベーションの向上に繋がった ・記事投稿の達成感により、モチベーションの向上に繋がった 今後、この検証用サーバーに対して、スマホアプリから通信した場合や、 Jsonデータを返却したりなど色々と記事にしていこうと思います。 興味がある方は見ていただければと思います。刺激になるので 見てくださった方々、ありがとうございました。 参考