SQLの窓

2018年05月03日


Python3 : 言語的デザインの特徴と要点


グループ化にインデントを使う

参照 Python ドキュメント
ドキュメントでは、多くのコーディングスタイルは begin/end の括弧にそれぞれ一行を使っている事に対して以下のように述べています。

1) 冗長(無駄が多い)になって画面を浪費する。
2) プログラムの見通しが悪くなる。

一つの関数は一画面に収めるのが理想で、20 行の Python は 20 行の C よりもはるかに多くの作業ができると断言しています。
▼ 確かに行数は 4 : 2 です。
if (x <= y)
{
        x++;
}

if x <= y:
        x += 1
実際問題、結局インデントするんだからそれでブロックを決定してしまうのはとても合理的に感じます。問題がある場合は唯一、勉強し始めの初期のプログラマがインデントをうまくできないという事ぐらいでしょう。 式中で代入ができない 参照 Python ドキュメント
要するにプログラマがとても良くやる、条件の中で == と書くところを、= と書いてしまってバグが発生させるのを避けるという趣旨でした。
▼ 今じゃ、こっちのほうが主流になってますが...
while (line = readline(f)) {
	処理
}
自分は昔々 while(1) {} って書いてました。必ず if で脱出条件書くので、後からソースコードが解りやすいです。で、Python ではそれを勧めているようです。
while True:
	line = f.readline()
	if not line:
		break
	処理
さらに、嫌み(あるいはジョーク)たっぷりに以下のようにも言っています。
熟練した Python プログラマは while True イディオムを受け入れていて、式構造中の代入がなくてもそれほど苦労しないようです。Python にそれを強く求めるのは新人だけです。
結局一番良いのは、イテレータを使用して for 文を使えとの事でした。(確かに... イマドキもう for 系で統一すべきだとは前から思ってました)
for line in f:
	処理
switch や case 文がない 参照 Python ドキュメント 正直自分は switch や case 文が嫌いです。自分では無く、自分以外の人がそれでミスして迷惑をこうむるからです。Python 的には、一画面に収めるのが理想 とか言ってるし、無いのは納得できます。 でも、先を見据えて議論はされているようです。 ラムダ式は文を含むことができない 参照 Python ドキュメント おそらく、ブロックをインデントで表現するという記法上、一般的なブロックを引数として渡すのは無理という事だと思います。しかし、Python はこの事についてとても強気に以下のように述べています。
Python のラムダは単なる、関数を定義するのが面倒すぎる場合のための簡略な記法に過ぎないのです。従って、ローカルで定義された関数ではなくラムダを使う利点は、関数の名前を考える必要が無いことだけです
だそうです。 タプルとリストという別のデータ型が用意されている 参照 Python ドキュメント 一般的な解釈では、タプルは変更不可(イミュータブル)で、リストは変更可(ミュータブル)です。ですが、追加の理解として以下のような記述がありました。
タプルは、Pascal のレコードや C の構造体と同様なものと考えられます。
型が異なっても良い関連するデータの小さな集合です。
グループとして演算されます。(一つの型として扱う?)

リストは他の言語の配列に近いものです。
全て同じ型の可変数のオブジェクトを持ちます。
それらが一つ一つ演算される傾向にあります。

イミュータブルな要素だけが辞書のキーとして使えるのでタプルだけがキーとして使えます
list.sort() はソートされたリストを返さない 参照 Python ドキュメント これは一連のデザインの流れにある『合理性』に基づいています。
ソートするためだけにリストのコピーを作るのは無駄が多いそうです。そしてこの仕様上では、うっかり上書きしてしまうようなことがなくなると言っています。

新しいリストを返したいなら、代わりに組み込みの sorted() 関数を使って下さいとの事です。
for key in sorted(mydict):
	mydict[key] で処理
raw 文字列 (r-strings) はバックスラッシュで終わってはいけない 参照 Python ドキュメント 長々と書いてありましたが、要するに最後の \" が一つの文字として認識されるので、文字列が終わって無い事になるそうです。よって、最後にバックスラッシュを追加する為に以下のような事になります。
dir = r"\this\is\my\dos\dir" "\\"
リストやタプルの最後にカンマがあっても良い 参照 Python ドキュメント これ凄いですね。ありがとうと言う他無いですが、これも無駄を回避するデザインであると断言できます。プログラマが皆疑問に思わず受け入れていた『無駄』です。
タグ:Python
posted by lightbox at 2018-05-03 23:35 | Python | このブログの読者になる | 更新情報をチェックする

2018年04月30日


Python ドキュメントに沿った、テキストファイル読み込みの理解

ソースコードの文字コード

このサンプルでは、ソースコードは SHIFT_JIS を使用しています。( デフォルトでは、Python のソースコードは UTF-8 でエンコードされているものとして扱われます )

※ Python 内で使用される エンコーディングのリスト

# -*- coding: cp932 -*-

try:
	handle = open(r"C:\Users\sworc\Downloads\社員マスタ.csv", "r", encoding="cp932")
except Exception as err:
	print(err)
	quit()

for method in dir(handle):
	if method == "__iter__":
		print(str(type(handle)) + " は for で使える")
		break
else:
	print(str(type(handle)) + " は for で使えない")

for line in handle:
	print(line,end="")


handle.close()

リテラル

ファイルのパスとして使用しているリテラルに、文字 'r' または 'R' をプレフィックスに持つことができます。そのような文字列は raw strings と呼ばれ、バックスラッシュをリテラル文字として扱いますfor 文

for 文は、反復可能なオブジェクト (iterable object) 内の要素に使用できます。

ここでは、組み込み関数の open 関数で取得した ファイルオブジェクト に対して for を実行します。その前に dir 関数 で取得したメソッド一覧の中に __iter__ がある事を確認しています。オブジェクトの中に __iter__ があれば、反復可能な処理が実装されています。

※ break 文が実行されると、 else 節の処理を実行することなくループを終了します

open で取得された ファイルオブジェクト

open() 関数が返す file object の型はモードに依存します。 open() をファイルをテキストモード ('w', 'r', 'wt', 'rt', など) で開くのに使ったときは io.TextIOBase (特に io.TextIOWrapper) のサブクラスを返します。

io.TextIOWrapper > io.TextIOBase > io.IOBase

※ close メソッドは io.IOBase にあります。

その他

str 関数は、オブジェクトを文字列として返します




posted by lightbox at 2018-04-30 20:17 | Python | このブログの読者になる | 更新情報をチェックする

2018年04月22日


Python3 でメール送信 ( さくらインターネット )

さくらインターネットのユーザ文字列が埋め込みサンプルとして適しているので使用しました。

デフォルトでは、utf-8 で Subject がエンコードされるので email.charset.Charset クラスのメソッドで iso-2022-jp に変換しています。
Subject: =?utf-8?b?UHl0aG9uIOOBi+OCiSBVVEYtOCDjga7mloflrZfliJc=?=
文字列の埋め込みは f-string です。
# *************************
# 型と内容の確認
# *************************
def typrint(obj):
	print(type(obj))
	print(obj)
	print("")

# *************************
# ライブラリ
# *************************
import smtplib
from email.mime.text import MIMEText
import datetime
from  email.charset import Charset

# *************************
# 日付のテスト
# *************************
# 日付だけ欲しい場合はこちら
today = datetime.date.today()
typrint(today)

# datetime オブジェクトは date オブジェクトおよび time オブジェクトの全ての情報が入っている単一のオブジェクトです。
today = datetime.datetime.today()
typrint(today)

# 書式 : https://docs.python.jp/3/library/datetime.html#strftime-strptime-behavior
strdate = today.strftime("%Y-%m-%d %H:%M:%S")
typrint(strdate)

# *************************
# メール用キャラクタセット
# *************************
jis='iso-2022-jp'

# *************************
# 本文
# *************************
text = "Python\n日本語\nUTF-8\n"
text += "Python文字列操作マスター\nhttps://qiita.com/tomotaka_ito/items/594ee1396cf982ba9887"
text += "https://qiita.com/tomotaka_ito/items/594ee1396cf982ba9887"
text = text.encode(jis)		# iso-2022-jp でテキスト全体をエンコード
typrint(text)
msg = MIMEText(text, 'plain', jis)		# メール送信用データのベースを作成

# *************************
# 送信用情報
# *************************
user = "ユーザ"		# さくらインターネットのユーザ
password = "パスワード"
port = 587
to = "宛先メールアドレス"

# *************************
# メールヘッダ
# *************************
charset = Charset(jis)		# Subject 用エンコードに使用( これをしないと utf-8 が使用される )
msg["Subject"] = charset.header_encode("Python から UTF-8 の文字列 : " + strdate )
msg["From"] = f"{user}@{user}.sakura.ne.jp"
msg["To"] = to

# *************************
# 確認用出力
# *************************
print(msg)

# *************************
# メール送信
# *************************
try:

	smtp_server = smtplib.SMTP(f"{user}.sakura.ne.jp",port)
	smtp_server.starttls()
	smtp_server.login(f"{user}@{user}.sakura.ne.jp", password)
	smtp_server.send_message( msg )
	smtp_server.quit()

	print("メールを送信しました")

except Exception as err:

	print(err)
	print("メール送信に失敗しました" )




▼ 出力結果
<class 'datetime.date'>
2018-04-22

<class 'datetime.datetime'>
2018-04-22 20:30:27.176934

<class 'str'>
2018-04-22 20:30:27

<class 'bytes'>
b'Python\n\x1b$BF|K\\8l\x1b(B\nUTF-8\nPython\x1b$BJ8;zNsA`:n%^%9%?!<\x1b(B\nhttps://qiita.com/tomotaka_ito/items/594ee1396cf982ba9887https://qiita.com/tomotaka_ito/items/594ee1396cf982ba9887'

Content-Type: text/plain; charset="iso-2022-jp"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: =?iso-2022-jp?b?UHl0aG9uIBskQiQrJGkbKEIgVVRGLTggGyRCJE5KODt6TnMbKEIgOiAyMDE4LTA0LTIyIDIwOjMwOjI3?=
From: ユーザ@ユーザ.sakura.ne.jp
To: 宛先メールアドレス

Python
$BF|K\8l(B
UTF-8
Python$BJ8;zNsA`:n%^%9%?!<(B
https://qiita.com/tomotaka_ito/items/594ee1396cf982ba9887https://qiita.com/tomotaka_ito/items/594ee1396cf982ba9887
メールを送信しました



posted by lightbox at 2018-04-22 20:40 | Python | このブログの読者になる | 更新情報をチェックする
Seesaa の各ページの表示について
Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。

Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。

また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。

※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです

対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。


※ エキスパートモードで表示しています

アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります

<% if:page_name eq 'archive' -%>
アーカイブページでのみ表示される内容
<% /if %>

<% if:page_name eq 'category' -%>
カテゴリページでのみ表示される内容
<% /if %>

<% if:page_name eq 'tag' -%>
タグページでのみ表示される内容
<% /if %>
この記述は、以下の場所で使用します
container 終わり

フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

CSS ドロップシャドウの参考デモ
BUTTONS (CSS でボタン)
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり