As rookie

ルーキーインフラエンジニアがインフラのこと以外も結構書いてしまうブログ

pythonでmp3の再生時間を取得する

こんにちは。

持っている音楽(mp3)の再生時間を調べたいときありますよね?

python mp3」

で検索するとでてくるとは思います。pygame とか

今回は再生する気がありません。

どうやらmutagen というモジュールがあるらしい

https://mutagen.readthedocs.io/en/latest/

とっても簡単。pipでインストールできる。

pip install mutagen

vim ongaku.py

from mutagen.mp3 import MP3
audio = MP3('example.mp3')
print (audio.info.length)
python ongaku.py
2.1149886621315193[f:id:shigeru-mokicks:20161118032426p:plain]

f:id:shigeru-mokicks:20161118032426p:plain

finderで確認すると。2秒。

これでmp3の長さを取得することができました!

ちなみにこれはcentOS で試しまし!

それでは!

Djangoのモデル作ってるときにタイプミスしてた。

こんにちは。

最近Djangoでwebアプリケーションを作りたいということで、Djangoのチュートリアルをしています。

チュートリアルと進めていてモデルを作成してデータベースをマイグレーションするという章があります

はじめての Django アプリ作成、その2

です。

問題のタイプミスがこちら `polls/models.py

from django.db import models


class Question(models.Model):
    qeustion_text = models.CharField(max_length=200) # クェウッションってなんぞ?
    pub_date = models.DateTimeField('date published')


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

それに気づかずドンドンチュートリアルを進めていってました。

python manage.py makemigration polls もして、 python manage.py sqlmigrate polls 0001もした よし!確認OK!

python manage.py migrate よしできた!

確認するぞ!!

python manage.py shell
>>> from polls.models import Question, Choice   # Import the model classes we just wrote.
# No questions are in the system yet.
>>> Question.objects.all()
<QuerySet []>
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())

は?エラーでるやんけ!invalid?は?なんでや

そこで以前紹介した

>>> dir(Question)

qeustionってなんやねん 早速models.py 編集さっそくmakemigrations

`python manage.py makemigration polls` 
`python manage.py sqlmigrate polls 0001`

変更されてない。

polls/migrationsを確認しにいくと

0002_auto_20161111_1739.py あ、新しくできるんだ

Djangoチュートリアルと読むと

migrate コマンドはすべての適用されていないマイグレーション(Djangoはデータベース内のdjango_migrationsと呼ばれる特別なテーブルを利用してどれが適用されているかを追跡しています)を捕捉してデータベースに対してそれを実行します - 重要なのは、モデルに対して行った変更はデータベースのスキーマに同期するということです。

なるほど! じゃあもうmigrateしちゃおう

Operations to perform:
  Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
  Applying polls.0002_auto_20161111_1739... OK

更新された感あるぞ

python manage.py shell

>>> from polls.models import Question, Choice
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())
>>> q.save()
>>> q.question_text
"What's new?"

更新された!

重要なのはモデルに対して行った変更はデータベースのスキーマに同期するということです。

また学びサンクス

pythonでつくったクラスのフィールドとかの確認

pythonインスタンスを作成するときに

h = Hoge(hoge_field='hoge')
Traceback (most recent call last):
  File "<console>", line 1, in <module>
NameError: name 'hoge_field' is not defined

とかなったことありませんか? あるあるですよね。

おそらくクラス変数の名前が想定しているものと違うものになっているのだろうと考えます。

クラスを定義しているところを確認すれば良いのですが、「名前何になってるんだ」ってすぐに確認する方法です。

>>> from tmp import Hoge
>>> dir(hoge)

これでクラスの変数、メソッドの一覧を確認できます。

オブジェクトの内容を表示してくます。

dir() の戻り値はリストです。ですので、

>>> 'hoge_field' in dir(Hoge)
True

で存在するか確認できます

文字列などのオブジェクトも同じように

# 文字列の特殊変数、メソッドを表示
>>> str = 'text'
>>> dir(str)
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

Djangoのモデルの変数名わからなくなったときに実行するとできたので、覚書です。 * tmp/models.py

from django.db import models

class Hoge(models.Model):
    hoge_field = models.CharField(max_length=200)

モデルの内容

python manage.py makemigrations
python manage.py shell
>>> from tmp import Hoge
>>> dir(Hoge)
['DoesNotExist', 'MultipleObjectsReturned', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_check_column_name_clashes', '_check_field_name_clashes', '_check_fields', '_check_id_field', '_check_index_together', '_check_local_fields', '_check_long_column_names', '_check_m2m_through_same_relationship', '_check_managers', '_check_model', '_check_ordering', '_check_swappable', '_check_unique_together', '_do_insert', '_do_update', '_get_FIELD_display', '_get_next_or_previous_by_FIELD', '_get_next_or_previous_in_order', '_get_pk_val', '_get_unique_checks', '_meta', '_perform_date_checks', '_perform_unique_checks', '_save_parents', '_save_table', '_set_pk_val', 'check', 'choice_set', 'clean', 'clean_fields', 'date_error_message', 'delete', 'from_db', 'full_clean', 'get_deferred_fields', 'get_next_by_pub_date', 'get_previous_by_pub_date', 'id', 'objects', 'pk', 'prepare_database_save', 'hoge_field', 'refresh_from_db', 'save', 'save_base', 'serializable_value', 'unique_error_message', 'validate_unique']

モデルの変数を確認するときに利用してみよう

以上

pythonでスライシングを使ってHTMLを生成(力技)

こんにちは

前々回でスライシングを身につけました

mokicks.hatenablog.com

今回も文字列関係です(先に進めない)

今回はトリプルクォーテーションと特殊文字について書きます。

トリプルクウォーテーション

"""で文字列を囲むことで複数行に跨いだ文字列をひとまとまりにして扱うことができます

>>> """ one line #複数行文字列開始
... two line
... three line
... """ #複数行文字列終わり
' one line\ntwo line\nthree line\n'

"""で囲い複数行で書いたときに改行は\n として文字列にはいります。\n特殊文字の改行を表します

特殊文字

文字列内で\を記号を使って改行などの特殊な文字列を表現することができます。 上記の複数行の代入を例にすると

>>> tmp = """one line #tmpに複数行の文字列を代入
... two line
... three line"""
>>> print tmp
one line
two line
three line

このような感じで\n が入っていたものをprintすると改行されていることがわかります。

今回は\n で改行。\t でタブということだけ書いておきます

www.pythonweb.jp

ここでまとめてくれていますので、参考にさせてもらいましょう。

本題

この二つのことと前回のスライシングでHTMLを生成したいと思います。

方法は

htmlタグを代入した文字列オブジェクトとspanタグを代入した文字列オブジェクトを用意しfindメソッドとスライシングでHTMLを生成する

>>> html = """<html>
... </html>"""
>>> print html
<html>
</html>

>>> span = "\t<spna></span>\n"
>>> print span
    <spna></span>

>>> html.find("\n")
6
>>> print html[:html.find("\n")] #htmlの改行文字までを表示
<html>

>>> print html[:html.find("\n")] + span #改行文字が出力されていない。 
<html>    <spna></span>

>>> print html[:html.find("\n")] + span + html[html.find("\n")+1:] #やっぱり改行文字が表示されていない。
<html>    <span></span>
</html>

>>> print html[:html.find("\n")+1] + span + html[html.find("\n")+1:] #1足す。いい感じになる
<html>
    <span></span>
</html>

>>> print html[:html.find("\n")+1] + span[:span.find(">")] + "torick" + span[span.find(">"):] + html[html.find("\n")+1:] #findで検索した文字の一つ前になるからミス
<html>
    <spantorick></span>
</html>
>>> print html[:html.find("\n")+1] + span[:span.find(">")+1] + "torick" + span[span.find(">")+1:] + html[html.find("\n")+1:] #成功
<html>
    <span>torick</span>
</html>

こんな感じで力技でHTMLを書くことができました!

最初にhtml.find()をして6が返ってきてますね

< h t m l > \n
0 1 2 3 4 5 6

なのでスライシングで html[:6]としてなぜ出ないのか謎でした。そこでちょっと試してみた。

>>> html.find("<")
0
>>> html.find("h")
1
>>> html.find("t")
2
>>> html.find("m")
3
>>> html.find("l")
4
>>> html.find(">")
5
>>> html.find("\n")
6
>>> print html[:html.find("\n")] #6文字目までを指定
<html> #改行は表示されない
>>> print html[:html.find("\n")+1] #1足す
<html> #改行は表示されている

>>> print html[:6] #数字で指定
<html> #やはり改行は表示されていない

スライシングの認識が間違っているのかもしれない。

スライシングで指定する[0:6]この場合の6は要素番号じゃなくて「6番目の文字」という認識なら[:6]で改行文字が指定ができないことを納得できる

< h t m l > \n
0 1 2 3 4 5 6 #要素番号
< h t m l > \n
1 2 3 4 5 6 7 #個数

別の方法で試してみる

>>> tmp = "abcdefg"
>>> tmp[5]
'f' #要素番号5番目のfが帰ってくる
>>> tmp[:5] 
'abcde' #5個目の文字まで返ってくる

>>> tmp[5:]
'fg' #5個目の要素から最後までが返ってくる

スライシングの始まり[こっちがわ:]は要素番号

スライシングの終わり[:こっち側]は先頭から何文字目(個数)がいれられる

という認識になりました

>>> tmp[3:3]
''
>>> tmp[3:4]
'd'

スライシングで数字で「どこまで」を指定する場合は「何個目まで」というので抽出しているのでしょう。

以上。HTMLを力技で生成でした

pythonで文字列の先頭文字を大文字にする

結論から capitalize()で文字列の先頭文字を大文字にしたオブジェクトを返せます。

>>> str.capitalize()
'Test'

こんにちは。

「はじめてのpython」でpythonの勉強をしている続きです。python基礎です。 Amazon:はじめてのpython

文字列の操作をしたときに返ってくるのは別のオブジェクトということは前回知りました。 mokicks.hatenablog.com

つまり、文字列は不変性を持つオブジェクトです。

そして文字列もオブジェクトなのでいくつかメソッドを持っています。

文字列がもつメソッドをつかっても返ってくるのは別のオブジェクトなのです。

たとえば upperメソッド 使った場合だと

>>> str = 'test'
>>> str.upper()
'TEST'
>>> str
'test'
>>> 

こんな感じで元の変数strは何も操作されていない状態のままです。

文字列の操作として文字列の先頭を大文字にしたいときはどうすれば良いのでしょうか?

upperメソッドを使っても返ってくるのは別のオブジェクトですから、返ってきたオブジェクトを変数に代入して元の文字列のオブジェクトと結合すれば良いのだ!という結論になりました。

>>> str = 'test'
>>> tmp = str.upper() #tmpに'TEST'を代入
>>> str = tmp[0] + str[1:]
>>> str
'Test'

う〜んわざわざtmp邪魔だなぁ〜

文字列のシーケンスの各要素にメソッドを実行できないものかねぇ〜

できました。

>>> str = 'test'
>>> str = str[0].upper() + str[1:]
>>> str
'Test'

インデックスを指定して特定の要素(ここでいうstr[0] = t)に対して操作をしているように見えるがpythonが扱っているオブジェクトは文字列のオブジェクトなんだぁ〜

これで無事文字列の先頭を大文字にすることができました。

不変性をもつオブジェクトに対して変更を加えているのではなく、オブジェクトを操作して同じオブジェクトに代入することでオブジェクトに変更を加えているようにできるのですね!

ちなみにcapitalize()で文字列の先頭文字を大文字にしたオブジェクトを返せます。

>>> str.capitalize()
'Test'

pythonで文字列をスライシング

こんにちは。

最近「はじめてのpython」でpythonの勉強をしています。

Amazon:はじめてのpython

文字列がシーケンス(配列(正確には配列ではない))ということを知り(なんとなく知ってはいた)スライシングをしました。特に特殊なことはしていません。最後に問題があります。

スライシングとはシーケンスの要素xからy(x < y)までを抽出することです。 書き方は

>>> str = 'mojiretu'
>>> str[0:4] #0から4番目を抽出
'moji'
>>> str[4:len(str)] #4から 最後の要素までを抽出
'retu'

今回新たに学んだことは シーケンスの左端がデフォルトでインデックス"0"に対応し、右端がシーケンスの長さを表す数値と同じになるということです。

>>> str[:4] #さきほどと同じ結果
'moji'
>>> str[4:] #さきほどと同じ結果
'retu'
>>> str[:] 両端がデフォルトの値がと対応しているので
'mojiretu'

わけのわからない検証かもしれませんがシーケンス後ろの方の要素を[こっち側に:]それより前の要素を[:こっち側]にして試すと

>>> str = 'mojiretu'

>>> str[-1:2]
''
>>> str[-1:-2]
''

空文字列が帰ってきました。

ちなみにスライシングをして上記のように出力されている文字列は、変数strとは別のオブジェクトが戻されているようです。だから抽出なんですね。

ここで問題です。 上記はスライシングをして文字列を抽出しましたが、「シーケンスの要素番号を指定して抽出する」ことをなんというでしょうか?

>>> str[2]
'j'

こういうことを何というでしょうか。

そうインデクシング(indexing)ですね。そのままですね

git rebaseメモ

こんにちは

引き続きlearn Git Branchingでgit のbranchの操作を学んでいます。

前回

mokicks.hatenablog.com

またつまずきました。その時のメモです。

Rebaseをモノにする の1でつまずきました。

複数に別れたブランチを一つのシーケンシャルにまとめるという問題です。 ちなみにシーケンシャルとは

e-words.jp

f:id:shigeru-mokicks:20161004024111p:plain

これを

f:id:shigeru-mokicks:20161004024155p:plain

をこうしたいのですが

やはり回数をオーバーしてしまいます。。

git checkout bugFix
git rebase master
git checkout side
git rebase bugFix
git checkout another
git rebase side
git checkout master
git rebase another

8回ですが、模範回答では7回でした!

いやいや無理でしょ!

自分の中では最小でやってきたつもりだ。

こんなところで時間使っていてもしかたない、答え見ちゃえ

git checkout bugFix
git rebase master
git checkout side
git rebase bugFix
git checkout another
git rebase side
git rebase another master

おいおい git rebase anoter master とかありかよ

んじゃ

git rebase master bugFix
git rebase bugFix side
git rebase side another
git rebase another maseter

でいけるんじゃね?

いけました。

わかったことまとめ。

◻︎rebase したいブランチにcheckoutしている状態のrebaseは

git rebase <リベースのされる(宛先)ブランチ>

◻︎checkout しないでのrebaseは

git rebase <リベースのされる(宛先)ブランチ> <リベースする(元)ブランチ>
git rebase <何のブランチに> <何のブランチを> ぶらさげるか

別のブランチのコミットはリベースされるブランチにぶらさがり、一つのシーケンシャルの以前のコミットにいてるブランチは、最新のコミットのところまで移動する。

こんな感じですね!

わーい!