読者です 読者をやめる 読者になる 読者になる

東大理三生のプログラミング奮闘記

初心者プログラマーが半年間でどれだけ成長するか!についてのブログです。勉強方法とか使った本とかについて書いていくと思います!プログラミングをもっと身近に感じてもらえたら嬉しいです!毎日更新を目指します!

単なるメモ機能が作れて感動した話

Django

まあ一応つけとくか〜〜ぐらいで作り始めたメモ機能。

こいつにめちゃ苦しめられました。

でもおかげでGETとかPOSTとかのHTTPレスポンスのあたりのお話がちょっとわかった気になったのでよかった。


<成果物>
f:id:gragragrao:20170315132448p:plain

これにメモを書いて更新を押すと、ずっと保存されます。

f:id:gragragrao:20170315132606p:plain



<コード>

models.py

class Note(models.Model):
    worker = models.ForeignKey(Worker, null=True, blank=True)
    content = models.TextField(null=True, blank=True)

    def __str__(self):
        return self.worker.worker_name

    @classmethod
    def get_note(cls, worker):
        notes = cls.objects.filter(worker=worker)
        if notes.count() > 0:
            return notes[0]
        else:
            return None


views.py

# Djangoの組み込みモジュールをインポート
from django.shortcuts import get_object_or_404, render_to_response, redirect
from django.views import generic

# 自分で作ったモジュールをインポート
from managings.models import *
import managings.forms as managings_form_module

class WorkerDetailView(generic.TemplateView):
    model = Worker
    template_name = 'managings/each_worker.html'

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(request, *args, **kwargs)
        return super(WorkerDetailView, self).render_to_response(context)

    def get_context_data(self, request, *args, **kwargs):
        context = super(WorkerDetailView, self).get_context_data(**kwargs)

        worker_id = args[0]
        target_worker = get_object_or_404(Worker, id=int(worker_id))
        context{'worker'] = target_worker

        note = Note.get_note(target_worker)
        redirect_url = "/worker/{}".format(target_worker.id)
        content = note.content if note else ""
        context['note_form'] = managings_form_module.NoteForm(initial={'content':content, 'redirect_url':redirect_url, 'worker_id':target_worker.id})

        return context

def add_note_view(request, *args, *kwargs):
    form_data = request.POST
    if form_data:
        worker_id = int(args[0])
        worker = get_object_or_404(Worker, id=worker_id)
        content = form_data['content']
 
       note = Note.get_note(worker)

        if note:
            note.content = content
        else:
            note = Note(worker=worker, content=content)

        note.save()

        return redirect("/managings/worker/{}".format(worker_id))

    else:
        raise Http404


forms.py

from django import forms
from django.forms import ModelForm

from managings.models import *

class NoteForm(forms.Form):
    content = forms.CharField(widget=forms.Textarea(attrs={'class'="workernote-content"}))
    redirect_url = forms.CharField(widget=forms.HiddenInput())
    worker_id = forms.CharField(widget=forms.HiddenInput())

あとはurlを設定すればできます。



<引っかかったポイント>

>>そもそも、Djangoの組み込みがどれで使い方がわかってなかった

振り返ってみると、これが全てだったような気がします。Djangoのドキュメントも読んだりしてましたが、使ってみないことには実感がわかないし、使ってみようとしたら使い方がわからないしで大変でした。今回で少し足場ができたので、ちょっとは進みがよくなりそうです。


足場が少しできた感じがするので、少しずつドキュメントももう一回読み始めようかな〜と思います。

久しぶりの投稿でした。

ボタンの作り方 CSS編

Djangoの勉強をしているとあんまり書くことないので、調べた小技・小知識とかについても書こうかなと思います。

f:id:gragragrao:20170312124749p:plain

こんなやつを作りたい!っていうとき

HTML

<a class="btn" href="#">Button</a>

CSS

a.btn{
  width: 200px;
  font-size: 24px;
  font-weight: bold;
  text-decoration: none;
  display: block;
  text-align: center;
  padding: 8px 0 10px;
  margin: 0 auto;
  color: white;
  background: rgba(0, 140, 140, 1);
  border-radius: 4px;
}

a.btn:hover{
  background: rgba(0, 140, 140, 0.7);
  cursor: pointer;
}

って感じです!

簡単ですね〜〜

それでは!

ご無沙汰です〜

しばらくブログ更新していませんでした。

この5日間ぐらいは旅行ばっかりで、久しぶりに休みを堪能した感じでした!


スキー旅行も行けたし、楽しかったです(^^)

明日からまた頑張ります!!

Record of study 〜一ヶ月が経過して〜

プログラミング勉強記録

pythonを勉強してからちょうど一ヶ月が経ちました。月日が経つのは早いですね〜

2月は本当にインターンと勉強に捧げた月でした。笑


得るものもすごく多くて充実していたので、楽しかったです。


3月は少し遊びの予定も入っていて、友達とスキー・釣り・ゴルフとか、彼女さんと箱根とかに出かけます!

f:id:gragragrao:20170301223126j:plain

2月はほぼ遊びがなかったのですごく楽しみです〜



それはさておき、ついに自分のアプリケーションを作る段階に入りました!


というのも、Djangoのdocumentを読んでいたのですが、「何に使うかわからない」+「量が多い」で早速挫折したのです。笑

f:id:gragragrao:20170301223251j:plain


今後は、自分でアプリケーションを作りながら、わからないところを自分で調べたり、社長たちに方法とか調べ方とかを聞いたりして勉強して行きます。


「わからないところ」とか「作りたい機能(現状の技術力じゃ無理なやつ)」をノートに貯めて行くのが主にやることになります。


昨日始めたばかりでやり方はどんどん変わるかもしれませんが、まあぼちぼちやります。


それでは〜

ABC #054 D問題 を python で解いてみた!

python3

今日の晩の体操は AtCoder Biginner Contest の D 問題です。

問題はこちら↓
D: Mixing Experiment - AtCoder Beginner Contest 054 | AtCoder

(解答)

from itertools import combinations

N,Ma,Mb = [int(n) for n in input().split()]
medicine_list = []
for i in range(N):
    medicine_list.append([int(n) for n in input().split()])

money_possible = []
counter = 0

for i in range(1, N+1):
    for medicine_comb in combinations(medicine_list, i):
        sum_a = 0
        sum_b = 0
        sum_c = 0
        for k in range(i):
            sum_a += medicine_comb[k][0]
            sum_b += medicine_comb[k][1]
            sum_c += medicine_comb[k][2]
        if sum_a/sum_b == Ma/Mb:
            money_possible.append(sum_c)

if len(money_possible) == 0:
    print(-1)
else:
    print(str(min(money_possible))+"円")


一応、AtCoderの検証例だとあっていることがわかります。(さすがに少なすぎませんか...)

f:id:gragragrao:20170301221435p:plain


5分強ぐらいで書けましたが、このコードには問題があると思います。

N が最大で 40 にまでなるので、for で回す回数が、約2の40乗回にまで膨れ上がります(二項定理より)。

これは、1099511627776回と、1兆回を超えます。

さらにこの中で i に対する for 文を回しているので、最大で800兆回( 40 × 40 ÷ 2 × 兆?)ぐらいの計算量になると思います。

これはpythonで処理できる範囲を超えているはずです。(Cとかならワンチャン??よくわかりません。)


ですが、この問題では「当てはまる組がなければ "-1" と表示しなければいけない」ので、全通りためさなくてはいけません。


「全通りためす」かつ「計算量を激減させる」方法を考える必要がありますが...どうやればいいんでしょうね〜思いつきません。



「こんな方法あるよ」とかあったら教えてください。

それでは〜

ABC #055 を python で解いてみた!

python3

おはようございます。

朝の準備体操に、AtCoderの#055の D問題をときました。
D: Menagerie - AtCoder Beginner Contest 055 | AtCoder


D問題が解けるようになってきたので、楽しくなってきました!!

でも、よくない傾向なのは、最近はDjangoが少し辛くなってきていて、AtCoderの問題を解く方に逃げてしまうことなんですよね..
朝と晩に1題ずつ解くことにして、その他はDjangoに時間を回すようにしようかな。


問題D

from copy import deepcopy

print("--入力--")

N = int(input())
statement_first = input()
statement = statement_first + statement_first[:2]

animal_arrange = [["S", "S"], ["S", "W"], ["W", "S"], ["W", "W"]]
animal_final_arrange = []

for animal_pattern in animal_arrange:
    i = 0
    while i <= N:
        if animal_pattern[i:] == ["S", "S"]:
            if statement[i+1] == "o":
                animal_pattern.append("S")
            elif statement[i+1] == "x":
                animal_pattern.append("W")
        elif animal_pattern[i:] == ["S", "W"]:
            if statement[i+1] == "o":
                animal_pattern.append("W")
            elif statement[i+1] == "x":
                animal_pattern.append("S")
        elif animal_pattern[i:] == ["W", "S"]:
            if statement[i+1] == "o":
                animal_pattern.append("W")
            elif statement[i+1] == "x":
                animal_pattern.append("S")
        elif animal_pattern[i:] == ["W", "W"]:
            if statement[i+1] == "o":
                animal_pattern.append("S")
            elif statement[i+1] == "x":
                animal_pattern.append("W")
        i += 1
    animal_final_arrange.append(animal_pattern)

animal_final_arrange_copy = deepcopy(animal_final_arrange)
print("--出力--")

counter = 0
for animal_arrange in animal_final_arrange_copy:
    if animal_arrange[:2] == animal_arrange[N: N+2]:
        animal = ""
        for animal_string in animal_arrange[:N]:
            animal += animal_string
        print(animal)
    else:
        counter += 1

if counter == len(animal_final_arrange):
    print(-1)

冗長になってる気もしますが、whileで回しているので輪っかの最後の方は複製せざるを得ませんでした。
他にうまいやり方があるのかな...

それはともかく、一応は正しく動きます。
条件を満たすものが全通り出力されるようにしてます。

〜Test〜
f:id:gragragrao:20170228093526p:plain

うまくいっていますね〜

それでは!

ARC #068 を python で解いてみた!

python3

python の練習に、AtCoder #068を解きました〜
arc068.contest.atcoder.jp


少しコツがつかめて来たのか、問題が簡単だったのか分かりませんが、C, D, E 問題が解けました!
F問題は時間の都合(Djangoを勉強しないといけない...)でやめました。

解答を貼っていきます。
おかしいとか、もっとこうすればよくなるとかあれば、ぜひ教えてください!


問題 C
愚直にやるとかなり工数がかかったので、「出る目は6 or 5」と割り切ってやるとうまくいきました。
最初はどうしても愚直に全部パソコンにやらせるクセ?があります。

x = int(input())

set_num = int(x / 11)
remainder = x - set_num * x

if remainder == 0:
    print(set_num * 2)
elif 1 <= remainder <= 6:
    print(set_num * 2 + 1)
else:
    print(set_num * 2 + 2)


問題 D
最初、これも愚直にやらそうとしていましたが、「任意の3枚が全て異なる」のだと勘違いしていたことも相まって、「工数が半端ない and 実現できない」ことになり、しばらく詰まりました。
「任意の3枚が全部違っていい」ことに気づいてからはすっとできた気がします。勘違いって怖いですね...
あとは、関数の中に破壊的メソッドを使ったら、returnで返してもその関数を使った時に引数のオブジェクトが壊れることを知らず、最後の結果がうまくいかなかったので少し調べました。deepcopy()を使えばうまくいくのだとか(以下のリンクを参照しました)。
8.10. copy — Shallow and deep copy operations — Python 3.6.0 documentation

from copy import deepcopy

def remove_repeat(list1,list2):
    for n in list2:
        list1.remove(n)
    return list1

N = int(input())

card = [int(a) for a in input().split()]
card_copy = deepcopy(card)
card_no_repeat = list(set(card))
card_repeat = remove_repeat(card_copy, card_no_repeat)

repeat_num = len(card) - len(card_no_repeat)

if repeat_num == 0:
    print(len(card))
elif repeat_num % 2 == 1:
    print(len(card_no_repeat) - 1)
elif repeat_num % 2 == 0:
    if len(set(card_repeat)) == 2:
        if card_repeat[0] == card_repeat[1] + 1 or card_repeat[0] == card_repeat[1] - 1:
            print(len(card_no_repeat) - 2)
        else:
            print(len(card_no_repeat))
    else:
        print(len(card_no_repeat))


問題 E
これも少し最後調整しました。
「一番下のifの中にbreakを入れていなかったので、重複して数えていて答えがおかしくなっていたこと」と、「なぜが列車は駅をぐるぐる循環すると思っていたので、真ん中ぐらいの内包表記内の if i*m <= M を書いていなかったこと」の2点でした。

N, M = [int(n) for n in input().split()]

# お土産が買える範囲
souvenir_range = []
for i in range(N):
    l, r = [int(n) for n in input().split()]
    souvenir_range.append(list(range(l, r+1)))
print(souvenir_range)

# それぞれの電車が止まる駅の種類
stop_list_each_train = []
for i in range(1, M+1):
    stop_list_each_train.append(list(set([(i*m) % (M+1) for m in range(M+1) if i*m <= M])))
print(stop_list_each_train)

for stop_list in stop_list_each_train:
    counter = 0
    for souvenir in souvenir_range:
        for stop in stop_list:
            if stop in souvenir:
                counter += 1
                break
    print(counter)

Record of study 〜2、3週間経過〜

プログラミング勉強記録

2、3週間経った頃の話です。

3週間目は業務が結構忙しくて、あまりプログラミングの勉強ができない週でした。

なので、AtCoderの問題をチラッと解いたり、その過程でわからないことが出て来たら本でチェックしたり、人に聞いたりっていう感じでした。


一旦まとめに入った週って感じですね〜


ここまでで大体pythonの(超)基礎は習得したと思います。

とはいえ自分で何ができるかと言われても、「ん〜」という感じです。笑



とりあえず次は、Webアプリケーションが作れるように、Djangoの勉強に移っていこう!ということで、3週間たった頃からDjango Documentを読み始めました。

まだ日本語訳がそんなに進んでいないので、一部は英語でやっています。

英語はそんなにできるわけではないので大変ですが、AI関連で留学してみたいなあ〜という思いもなくはないので、その練習として英語で頑張ってみたいと思います。


目安としては3月中旬までには一通り理解して、そこから自分で何かアプリを作りたいと思っています。

twitterとか何かのSNSAPIを使ったりできたら面白いなあと思うんですが...まあ考え中です。笑



それではこの辺で〜

2017年東大理系数学をpythonで解いてみた!

python3

昨日、今日で東大入試がありましたね!

受験生の方、受験お疲れ様でした。


せっかくなので、数学の問題をpythonで解いてみよう!ということで解いてみました!


pythonの機能(ライブラリ)がまだ全然使いこなせないので、今回は第2問(確率)だけを解いてみました。


(問題)
f:id:gragragrao:20170226144148p:plain

(解答)

# 2017年 東大数学 理系

# 第2問

import itertools
from fractions import Fraction

move_pattern = ["a", "b", "c", "d"]
move_command = list(itertools.product(move_pattern, repeat=6))

whole_event = 4 ** 6
counter_1 = 0
counter_2 = 0

for command in move_command:
    coordinate = [0, 0]
    for s in command:
        if s == "a":
            coordinate[0] += 1
        if s == "b":
            coordinate[0] -= 1
        if s == "c":
            coordinate[1] += 1
        if s == "d":
            coordinate[1] -= 1
    if coordinate[0] == coordinate[1]:
        counter_1 += 1

prob_1 = Fraction(counter_1, whole_event)
print("the answer of (1) is {}".format(prob_1))


for command in move_command:
    coordinate = [0, 0]
    for s in command:
        if s == "a":
            coordinate[0] += 1
        if s == "b":
            coordinate[0] -= 1
        if s == "c":
            coordinate[1] += 1
        if s == "d":
            coordinate[1] -= 1
    if coordinate[0] == 0 and coordinate[1] == 0:
        counter_2 += 1

prob_2 = Fraction(counter_2, whole_event)
print("the answer of (2) is {}".format(prob_2))

見やすいように、同じ処理を設問ごとに書いているので少し冗長になっていますが、ちゃんと動きます。

4048個のループが2回、全部で10000回ぐらいの処理なので工夫なしでやっても計算の時間は全然早いです。
(最初のitertoolsでcommand_listを作った時の処理も入れたら15000回ぐらい??)


計算結果はこれです

f:id:gragragrao:20170226144205p:plain


解答速報と照らし合わせてもあっていますね!


こうやって実際にpythonが使えるのを見ると面白いですよね〜

気が向いたら他の問題もやって見ます。


それでは〜〜

Record of study 〜2週間後前後〜

プログラミング勉強記録

2週間ぐらいで、前にも紹介した教科書(下のやつ↓)を読み終えました。


本で書いてるサンプルコードを理解しながら、自分の手で書いていけば結構実力がつくんじゃないかと思います!

最後の方にはNumpy使ったり、簡単な機械学習のコードもサンプルコードとして乗っているので面白かったです。


初心者の人でも読めるようになっていると思いますが、やはり近くに誰かプログラミングガチ勢の人を見つけて、わからなくなったら聞いた方がいいかもしれないですね!


この本が終わったあとは、「各データ型ごとにどんなメソッドがあったか」を中心に第4章までをしっかり読み返して、破壊的メソッドとそうでないメソッドを区別して覚えました。


それからはAtCoderのBeginner問題をちょくちょくやり始めた感じです!


pythonはしっかりやれば完全な初心者でも2週間ぐらいでなんとなく書けるようになります!(書きやすいらしいです)


みんなpythonを始めよう!笑


それでは〜