Pythonでフォントを指定して数字の画像ファイルを生成する

Python3とPILが必要(Anacondaを使うと勝手に入ってて便利ですね)。

フォントのディレクトリや画像サイズを適宜変えるとよさそう。

"""
フォントを指定して数字の文字画像を生成する(黒背景白文字)
"""
import os
import re
from PIL import Image, ImageDraw, ImageFont
 
SIZE = W, H = 28, 28
 
 
def num_to_english(x):
    """ 数字の英語文字列を返す """
    assert 0 <= x <= 9, "Input int x (0 <= x <= 9)"
    return ("ZERO", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE")[x]
 
 
def make_image(idx, font_name):
    """ フォントを指定して 0-9 の画像ファイルを作る """
    fnt = ImageFont.truetype("C:/Windows/Fonts/{}".format(font_name), 25)
    for i in range(10):
        back_image = Image.new("RGBA", SIZE, (255, 255, 255, 0))
        txt_image = Image.new('RGBA', SIZE, (0, 0, 0, 255))
        draw = ImageDraw.Draw(txt_image)
 
        tw, th = fnt.getsize(str(i))  # フォントを指定した時のサイズ(位置計算に使用)
        draw.text(((W - tw) / 2, (H - th) / 2), str(i), font=fnt, fill=(255, 255, 255, 255))
        file_name = "{}_{}.png".format(num_to_english(i), idx)
        out = Image.alpha_composite(back_image, txt_image)
        out.save("images/" + file_name)
 
 
def main():
    # ttfファイルのみ取得する
    rp = re.compile(".*ttf")
    font_list = [fnt for fnt in os.listdir("C:/Windows/Fonts") if rp.match(fnt)]
 
    for idx, font_name in enumerate(font_list):
        make_image(idx, font_name)
 
 
if __name__ == '__main__':
    main()

0-9の数字画像がたくさん得られます。

結果の一部

f:id:fushime2:20170113193620p:plainf:id:fushime2:20170113193628p:plainf:id:fushime2:20170113193641p:plainf:id:fushime2:20170113193650p:plainf:id:fushime2:20170113193707p:plainf:id:fushime2:20170113193719p:plain

基本情報受かった

f:id:fushime2:20161119201523j:plain

午前午後共に合格ラインぎりぎりだった。

勉強に使ったのは基本情報技術者試験ドットコムというサイトで、午前の過去問の一問一答を 3 年分埋めたりした。安定させるためにもう少しやるべきだったと思う。

午後はアルゴリズムが 1 問ミスで C 言語の問題は時間が無くて適当に選んだけどなんとかなったらしい。よかったですね。

nCrについてのメモ

n 個から r 個を選ぶ組み合わせは nCr = n! / (k! * (n-r)!) と書ける。ただ、mod p(pは素数) で計算するときは、分母にある「階乗の逆元」を求めるのがやや面倒である。

この逆元はフェルマーの小定理で求められる。説明を省略すると、a は p で割り切れないとき、a の逆元は a ^ (p-2) となる。

n = (H+W-2), r = (H-1), p = 10 ^ 9 + 7 としたときはこんな感じ(atcoderの問題)。factとその逆元invfを計算すると、nCr = fact[n] * invf[r] * invf[n-r] で求められる。

C: 経路 - AtCoder Beginner Contest 034 | AtCoder

#include <iostream>
using namespace std;

typedef long long ll;

const int mod = 1e9 + 7;
int w, h;
ll f[200010] = {0}; // f(n) = (n!) % mod

// 繰り返し二乗法 O(log n)
ll mod_pow(ll x, ll n){
    ll res = 1LL;
    while(n > 0){
        if(n & 1) res = res * x % mod;
        x = x*x % mod;
        n >>= 1;
    }
    return res;
}

ll mod_inv(ll x){
    return mod_pow(x, mod-2) % mod;
}

// nCr % mod
ll comb(int n, int r){
    return (((f[n] * mod_inv(f[r])) % mod) * mod_inv(f[n-r])) % mod;
}

int main() {
    cin >> w >> h;

    // O(w+h) で階乗テーブルをつくる
    f[0] = f[1] = 1;
    for(int i=2; i<=w+h-2; ++i) f[i] = (i * f[i-1]) % mod;
    ll res = comb(h+w-2, h-1);
    cout << res << endl;
    return 0;
}

python だと標準ライブラリを駆使してこう http://abc034.contest.atcoder.jp/submissions/978322

オーバーフローには気を付けよう!(注意喚起)

// 追記