乙Py先生のプログラミング教室
初学者のためのプログラミング学習サイト

プログラミング

はいどーもー
乙pyです。

暇なので受験シーズンだし
有名中学の算数の問題をプログラムで解けないかと
思ったりしたわけですね。

インターネットの
Googleで調べたんですが
そこで問題が難しそうな学校を見つけてしまったんですね。

皆さん

難しい中学校って知ってます?

自分は近所の中学校に行ったので
知らないんですけど
問題を解いてみたんですねー

というものの第二弾です。


動画解説はこちら


初めの問題は
有名中学の入試問題.027


これは初学者の方々には難しいかもしれませんが
順列の問題です。

4つの異なる数字1 ,3 , [ ] ,9
この中から3つの数字を取り出して並べてできる
3桁の整数

これは4P3で24通りあるんですね。

この順列の求め方は実は
pythonだと非常に簡単に出来るんです。

まずはitertoolsをインポートします。
import itertools

このitertoolsを用いると
組み合わせや順列の結果を全部計算してくれます。

さてこの問題の場合は
4つの数値のうち、3つは固定されています。

あとは残る数値を変化させるようにして
試行していけば良いわけです。

なので試行する数値をリストに格納して
for文を書くということになります。

for x in [0,2,4,5,6,7,8]:


さて、順列の方ですが
itertools.permutations(リスト, 個数)
で作ることができます。

なのでfor文で送られる数値を使って
順列の元になる4つの数値を変数に格納します。

あとはこれを用いて順列を作ります。

次に
このライブラリを使って求められるものは
順列の結果が24個入ったリストが帰ってきます。

これはそのままでは3桁の整数になっていないので
この順列24個を3桁の数値に直します。

数値を文字にして連結して
また数値に戻すで3桁の数値にできます。

それを24回やって、一時的にリストに格納します。

問題の条件は平均が555ということなので
このリストに格納した3桁の整数を全部足しあわせたのを
個数24で割ってあげます。

この平均が555であれば
答えということになります。

プログラムはこうなりました。

for x in [0,2,4,5,6,7,8]:
    seq = (1,3,9,x)
    lis = []
    for i in list(itertools.permutations(seq,3)):
        s = int(''.join([str(i[0]),str(i[1]),str(i[2])]))
        lis.append(s)
    if sum(lis)//len(lis) == 555:
        print(x)
        break


順列、文字列操作、数値変換、平均を求めるなど
プログラムでの基本的な操作が
色々と組み合わさるので
プログラミング学習には良い問題ですね

お次は

有名中学の入試問題.025

問題が細かいですが
4桁の整数で条件に合うものが何個有るかを求めるという問題です。

ただし
100の位は0で固定なので
試行するのは千の位、10の位、1の位に絞られます。

次の条件は
10と1の位がひっくり返ってもそれぞれ
7で割れるというものです。

これは数字を文字に置き換えてあげることで
解くことができます。

4桁の整数と
その10の位と1の位がひっくり返ったものの
両方が7で割り切れれば条件に合致します。

という風にして、試行した分の結果を
リストに格納して、その個数が
回答になります。

プログラムだとこうなりました。

r = []
for x in range(1,10): # 1000の位
    for y in range(10): # 10の位
        for z in range(10): # 1の位
            a = '{x}0{y}{z}'.format(x=x,y=y,z=z)
            b = '{x}0{z}{y}'.format(x=x,y=y,z=z)
            if int(a)%7==0 and int(b)%7==0:
                r.append((a,b))
print(len(r))

文字列と数値の使い方は
プログラミングの基本のため
こういった問題を解くことで
プログラミングの基本が身について行くと思います。



はいどーもー
乙pyです。

暇なので受験シーズンだし
有名中学の算数の問題をプログラムで解けないかと
思ったりしたわけですね。

インターネットの
Googleで調べたんですが
そこで問題が難しそうな学校を見つけてしまったんですね。

皆さん

難しい中学校って知ってます?

自分は近所の中学校に行ったので
知らないんですけど
問題を解いてみたんですねー


動画解説はこちら


 


まずはじめの問題は
有名中学の入試問題.002

これの解き方は非常に簡単です。

4つの整数のうち
基準になるのは a で
求める答えも a
a と他の整数b,c,dとの関係はそれぞれ

b = a + 1
c = b + 1
d = c + 1
と1つづつ増えています。

なのでaを基準にして全て変数に置き換えます。

aは基準の数値なので
試行する数値にするため for文の対象にします。

求める答えの条件は
a * b + b * c + c * d + d * a が2400ということなので
この条件に合致した場合に表示させるだけです。

プログラムはこのようになりました。
 for a in range(30):
    b=a+1
    c=b+1
    d=c+1
    if a*b+b*c+c*d+d*a==2400:
        print(a)
        break

非常に簡単ですね

次の問題は
有名中学の入試問題.026

17で割ると3余り、13で割ると7余る
これが出力する際の条件1つ目ですね

もう一つは3桁の整数で最大

なのでまずは3桁の整数のなかで上記の条件に当てはまるものを
全て探します。

探し出す数値を x とすると

for x in range(100,1000):

で3桁の整数を試行できます。

あとは最大値を求めるやり方ですが
条件に当てはまるものが複数でるため

それをリストに格納しておいて
その格納された数値の中で一番大きいものを求めます。

プログラムは
result = []
for x in range(100,1000):
    if x%17==3 and x%13==7:
        result.append(x)
print(max(result))

このようになりますね。
プログラミング初学者の方々には
こういった問題を解くのは非常に勉強になると
思いました。

引き続き
プログラムで入試問題を
解いていきたいと思います。

夢屋まさる氏の「パンケーキ食べたい」スクリプトを作ってみた

どーもー乙pyです。

非常に実用性のないプログラムを作成しました。

夢屋まさる氏のネタ

「パンケーキ食べたい」
を連呼するだけのGIF画像を生成するプログラムです。

使い方は簡単、ソースをコピーして
wish_eat_pancake関数を呼び出すだけ。

一応windowsとmacでフォントの場所が違うので
そこだけ指定が必要ですが・・・

ちょっとした説明を動画に




ソースを貼っておきますね。
In [7]:
from PIL import Image, ImageDraw, ImageFont

pancake_size = 12
img_size  = (320, 180)
img_base_color = (0, 0, 0)

# windows
# font_place = "C:\Windows\Fonts\meiryob.ttc"

# Mac 
font_place = '/System/Library/Fonts/AquaKana.ttc'

def pancake(images):
    for i in range(20):
        img =  Image.new('RGB',img_size, img_base_color)
        draw = ImageDraw.Draw(img)
        font = ImageFont.truetype(font_place, pancake_size+i)
        draw.text((10, 10), '\nパンケーキ食べたい!'  , 
                  fill=(255, 200 - i*4, 0), font=font)
        images.append(img)
    return images

def wish_eat_pancake(texts,gif_name):
    images = []
    for draw_text in texts:
        draw_text = '\n' + draw_text
        for c in range(3):
            images = pancake(images)
        for i in range(20):
            img =  Image.new('RGB',img_size, img_base_color)
            draw = ImageDraw.Draw(img)    
            if len(draw_text)>10:
                if len(draw_text)>=30:
                    draw_text = draw_text[0:30]
                draw_text = ''.join([ t+'\n' if e%10==0 and e>0 
                                     else t for e,t in enumerate(draw_text)])
            font_size = min(pancake_size + i , 29)
            font = ImageFont.truetype(font_place, font_size)
            draw.text((10, 10), draw_text , fill=(255, 200 - i*4, 0), font=font)
            images.append(img)
        
    images[0].save(gif_name ,save_all=True, 
                   append_images=images[1:], 
                   optimize=False, duration=16*len(texts), loop=0)
In []:
# フォントの場所を指定(font_place)

# 使い方 引数にリスト型で文言を指定、第二引数にファイル名

wish_eat_pancake
(['新宿はキタナイ','押上もキタナイ','蒲田はジゴク'] , 'wisheatpancake.gif')
In []:
# 実行後にGIFファイルが作られる

!
ls -ls
total 1456
   8 -rw-r--r--  1 ss  staff    3125  2  2 16:37 WishEatPancake.ipynb
1448 -rw-r--r--  1 ss  staff  738944  2  2 16:39 wisheatpancake.gif

                       wisheatpancake

                 その先、仕事とか、研究にどう使えるの?




さて
プログラミングの基礎はいかがだったでしょうか?

まだ、ここまでの段階だと
プログラミングでどんなことができるかとか

どんなことに役立つのかとか・・
イメージが湧かない方の方が多いのではないかと思います。

なので、実際に仕事で使っているコードも見ながら
プログラミングがどういうものなのかを
改めて体験していただき、その後どうすれば良いか
というところを深く掘り下げて行きたいと思います。

ファイルの読み込み

In [1]:
# 同じ階層に配置してあるファイルの中身を表示する。
with open('sample.py') as _r:
    print(_r.read())
def hello(aa):
    print(aa)

CSVファイルの読み込み

In [2]:
# 結果を格納する変数を用意
res = []
# ファイルの読み込み
with open('sample.csv') as _r:
    for row in _r:
        # 改行を取り除き、カンマで区切って配列にする
        rows = row.replace('\n','').split(',')
        # 結果用の変数に追加
        res.append(rows)

print(res)
[['aaa', 'bbb', 'ccc'], ['ddd', 'eee', 'fff'], ['hhh', 'iii', 'jjj'], ['kkk', 'lll', 'mmm']]
In [3]:
for row in res:
    # タブ区切りで表示
    print('\t'.join(row))
aaa	bbb	ccc
ddd	eee	fff
hhh	iii	jjj
kkk	lll	mmm

webサイトへアクセスして情報取得

In [4]:
import requests

# webサイトへアクセスしてデータを取得
html = requests.get('http://yahoo.co.jp')

# 取得したデータの最初の800文字を表示
print(html.content.decode('utf-8')[0:800])
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta http-equiv="content-style-type" content="text/css">
<meta http-equiv="content-script-type" content="text/javascript">
<meta name="description" content="日本最大級のポータルサイト。検索、オークション、ニュース、メール、コミュニティ、ショッピング、など80以上のサービスを展開。あなたの生活をより豊かにする「ライフ・エンジン」を目指していきます。">
<meta name="robots" content="noodp">
<meta name="google-site-verification" content="fsLMOiigp5fIpCDMEVodQnQC7jIY1K3UXW5QkQcBmVs">
<link rel="canonical" href="https://www.yahoo.co.jp/" />
<link rel="alternate" media="only screen and (max-width: 640px)" href="https://m.yahoo.co.jp/">
<link rel="alternate" href="android-app://jp.co.yahoo.android.yjtop/yahooja

機会学習系のライブラリの利用

In [5]:
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
In [6]:
# データフレームの作成
df = pd.DataFrame([[3,4],[4,5],[6,9],[2,8]],columns=['a','b'])
# データフレームを描画
df.plot()
Out[6]:
<matplotlib.axes._subplots.AxesSubplot at 0x10eed5f28>
In [7]:
df = pd.DataFrame([[3,4],[4,5],[6,9],[2,8]],columns=['1','2'])
# 散布図を描画
plt.scatter(df['1'],df['2'])
Out[7]:
<matplotlib.collections.PathCollection at 0x1122ec438>

scikit learn

In [8]:
import pandas as pd
# 必要なライブラリのインポート
from sklearn import datasets, model_selection, svm, metrics

# 有名なアヤメのデータの読み込み
iris = datasets.load_iris()
In [9]:
# アヤメのデータをデータフレームに変換する。
iris_data = pd.DataFrame(data=iris.data, columns=iris.feature_names)
# 5行だけ表示
iris_data.head()
Out[9]:
sepal length (cm)sepal width (cm)petal length (cm)petal width (cm)
05.13.51.40.2
14.93.01.40.2
24.73.21.30.2
34.63.11.50.2
45.03.61.40.2
In [10]:
# ラベルデータの読み込み
iris_label = pd.Series(data=iris.target)
# 5行だけ表示
iris_label.head()
Out[10]:
0    0
1    0
2    0
3    0
4    0
dtype: int64
In [11]:
# アヤメのデータを訓練データ、テストデータ、訓練ラベル、テストラベルに分ける。
train_data, test_data, train_label, test_label = model_selection.train_test_split(iris_data, iris_label)
In [12]:
# 訓練データ
train_data.head()
Out[12]:
sepal length (cm)sepal width (cm)petal length (cm)petal width (cm)
705.93.24.81.8
1257.23.26.01.8
776.73.05.01.7
255.03.01.60.2
516.43.24.51.5
In [13]:
# 訓練ラベル
train_label.head()
Out[13]:
70     1
125    2
77     1
25     0
51     1
dtype: int64
In [14]:
#  訓練データとテストデータの個数
print(len(train_data), '\t',  len(test_data))
112 	 38
In [15]:
# SVM学習器の定義
clf = svm.SVC()

# 訓練データで学習
clf.fit(train_data, train_label)

# テストデータで予測
pre = clf.predict(test_data)

print(type(pre))
print(pre)
<class 'numpy.ndarray'>
[0 0 1 1 0 2 1 0 2 1 2 0 2 2 0 1 0 0 2 1 0 0 0 2 0 2 2 2 1 0 2 0 1 2 2 1 0
 1]
In [16]:
# 正答率
ac_score = metrics.accuracy_score(test_label, pre)
print(ac_score)
0.947368421053

最後に

プログラムを作る上で重要になるのが

「目的」です。

プログラミングの重要な部分は
プログラムに何をさせるかということです。

プログラムは手段であり、目的を達成するために
労力を下げるためのものになります。

プログラムを作る労力が目的を達成する時間を
上回っていたらプログラムを作る必要性はなくなります。

まずは目的を明確にして、ものすごく労力のかかる作業であれば
これをプログラムに落とし込む、ということを考えましょう。

すでに同じ機能を有するプログラムが存在していたら
実はプログラムを作る必要性というのは低いです。

こういうのを車輪の再発明といい、すでに有るものを再度作ろうと
試みるのは、無駄なことが多いです。

pythonでは大量のライブラリがあり
ほとんどの機能はそれで実現できると思います。

なので、プログラムを作る際に無駄なことをしないように、
下調べをしておくのも作業時間を減らす良い方法になります。

あくまでもプログラミングは目的を達成するための手段でしかありません。

恐らく仕事で使えるのは、「問題を解決する能力」の方だと思います。

プログラミングを続けると、
自然とこの「問題を解決する能力」が高まります。

この先は恐らくエラーが多発し、それを回避するために、
いろいろ調べたり、人に聞いたりしながら、コードを修正してゆくこととなるでしょう。

そういった経験の積み重ねが、研究や仕事をこなすための能力を高めてくれることでしょう。

この講座を学習したことが、みなさまの能力向上に一役買って頂けてると
とても幸いです。

pythonの基礎編は以上になりますが、この後は応用編や、
他の言語やミドルウェアや、クラウドサービスの使い方などの
講座も続けていきますので、ぜひそちらもチェックしてみてください。

                 39.基礎演習3




それではこれまでに学習した内容を踏まえて、
演習を行っていきましょう。

少し難しめに作ってありますので、
動画を止めながらゆっくり考えて解いてみてください。

第一問:

整数1から100までの和を求めるプログラムを作成してみましょう。

In [ ]:
 

第二問:

フィボナッチ数(0,1,1,2,3,5,8,13・・・)のように
最初の二項は 0, 1 で、以後どの項もその直前の2つの項の和
になるような数のフィボナッチ数と言います。

このフィボナッチ数を求める関数を作成しましょう。

3桁のフィボナッチ数までを表示させる関数にしましょう。

In [ ]:
 

第三問:

前項で取り扱ったrandomライブラリの関数を使って
英小文字のaからzか、数値0から9までの文字だけを使った
32桁の文字列を作成するプログラムを作ろう。

random.randint(最小値、最大値)でランダムな整数値が返せる。

In [ ]:
 

第四問:

aabacdcda

この文字列の「文字別」で集計してみよう。

In [ ]:
 

第五問:

「景子の夫」、「千鳥」、「メンタリスト」
この3つの文字列のうち、1つをランダムで返す関数を作って見ましょう。

In [ ]:
 

すぐに答えが出ない人は、動画を止めて考えてみましょう。

コツとしては何を入力したら、どう計算されて、どう出力されるのか
それを考えながら書いてみましょう。

答えはこの下に





回答

第一問:

整数1から100までの和を求めるプログラムを作成してみましょう。

In [1]:
res = 0
# range(1,101)で1から100まで
for i in range(1,101):
    # += で加算
    res += i
print(res)
5050
In [2]:
# 上記を内包表記で書くと
print(sum([i for i in range(1,101)]))
5050

第二問:

フィボナッチ数(0,1,1,2,3,5,8,13・・・)のように
最初の二項は 0, 1 で、以後どの項もその直前の2つの項の和
になるような数のフィボナッチ数と言います。

このフィボナッチ数を求める関数を作成しましょう。

3桁までのフィボナッチ数を表示させる関数にしましょう。

In [3]:
def fib():
    # まずはじめに変数を2つ用意する
    a = b = 1
    while True:
        print(b)
        # フィボナッチ数は直前の2つの項の和
        a, b = b, a+b
        # 3桁を超えたら抜ける
        if b>999:
            break
In [4]:
# 上記関数の実行
fib()
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987

第三問:

前項で取り扱ったrandomライブラリの関数を使って
英小文字のaからzか、数値0から9までの文字だけを使った
32桁の文字列を作成するプログラムを作ろう。

random.randint(最小値、最大値)でランダムな整数値が返せる。

In [5]:
import random

# 36個の英数字を用意する
words = 'abcdefghijklmnopqrstuvwxyz0123456789'

# 上記の中からランダムで返すのを32回繰り返して配列を作る
# その配列を join で連結して文字列に変換する
print(''.join([words[random.randint(0,35)] for i in range(32)]))
lfkj6bv913np7cq8fxzjjpfjv2u8qv0q

第四問:

aabacdcda

この文字列の「文字別」で集計してみよう。

In [6]:
# まずは集計対象の文字を用意
word = 'aabacdcda'

# 結果を格納するための辞書を用意
result_dict = {}
for w in word:
    # 文字があれば +1 なければ1で辞書に格納する
    if w in result_dict:
        result_dict[w]+=1
    else:
        result_dict[w]=1
print(result_dict)
{'b': 1, 'c': 2, 'a': 4, 'd': 2}

第五問:

「景子の夫」、「千鳥」、「メンタリスト」
この3つの文字列のうち、1つをランダムで返す関数を作って見ましょう。

In [7]:
import random

# 配列を用意する
daigo = ['景子の夫','千鳥','メンタリスト']

# 関数を作る
def random_daigo(daigo):
    # ランダムで整数値を返し、インデックスで上記配列の要素を返す。
    return daigo[random.randint(0,2)]

# 関数の実行
print(random_daigo(daigo))
千鳥

randomライブラリには直接1つの要素をランダムで返すという関数があります。

random.choice(配列)

In [8]:
import random

daigo = ['景子の夫','千鳥','メンタリスト']

def random_daigo(daigo):
    return random.choice(daigo)

print(random_daigo(daigo))
千鳥

さて、演習はいかがだったでしょうか?
あなたのwishは達成されましたか?

プログラミングができるようになると
そのwishを叶えることができるかもしれませんね。

プログラミングは
まずは真似してコードを書くこと、写経、が上達の鍵になります。
書いて書いて書きまくりましょう。

できなかったところは演習を復習してみてくださいね。

このページのトップヘ