らずぱい日記

定年したので日記でもかくか。って感じ

気になるニュースは?

Pythonで面白そうなライブラリがあったので、触ってみた。

「GoogleNews - PyPI」というやつで、Googleニュースの記事を気になるカテゴリー

で収集するのに持って来い!ってやつ。

使い方は、[GoogleNews · PyPI]で確認してや。

こんな感じで取得や。

# -*- coding: utf-8 -*-
# 主要ニュース取得
from GoogleNews import GoogleNews
 
#検索したいニュースをkensakuに設定
kensaku = ["Python","無料講座","windows11","BTC","XRP","ETH","tips","仮想通貨"]

for ke in kensaku:
   googlenews = GoogleNews(lang='ja', encode='utf-8', period='1d')
   print(f"-----------------{ke}-------------\n")
   googlenews.get_news(ke)
   googlenews.search(ke)
   print(f'ニュース数:{googlenews.total_count()}本')
   res = googlenews.results()
   for n in res:
      title = n.get("title")
      link = n.get("link")
      if link.rfind("https://") == -1:
        link = "https://" + link
      else:
        pass
      print(f"■{title}\n{str(link)}\n")
      googlenews.clear()

はじめてのpython

一昔前はphpがもてはやされていたような気がしたが、最近はpython「ぱいそん]とやらが流行っているようで、RPAやって楽しようと思ってググってみたらpythonに行き当たった。幸い時間が少しできたのでいろいろ触ってみることにした。

まったくpythonを知らないのでいろいろググってメモした備忘録を残しておく。

 

======Pythonメモ=========

開発環境もいろいろ便利なものがあるが、その操作方法が複雑でどぅも敷居が高い

ので初心者としては、テキストエディタのみで十分かな?DOSプロンプトとエディタで開始することとした。(DOSプロンプトはパワーシェルの方が便利)

 

■基礎:プログラムの書き方ルール(coding:)
日本語など、ASCII以外の文字を含むスクリプトを作成する場合は
スクリプトの1行目、または2行目に、下記の形式でスクリプト
エンコードルール(coding:) 大文字・小文字は無視されます。
コメントが正規表現 coding[=:]\s*([-\w.]+) にマッチする場合、
コメントはエンコード宣言として処理されます;

# coding: utf-8
Emacs との互換性を考慮し、下記の様に記述することもできます。
# -*- coding: utf-8 -*-

エンコード宣言
# -*- coding: <encoding-name> -*-

エンコードルールには下記などがあります。
# coding: utf-8
# coding: Shift_JIS
# coding: EUC-JP
# coding: cp932

書き方の例
-----
良い例:
# 開き括弧に揃える
foo = long_function_name(var_one, var_two,
□□□□□□□□var_three, var_four)
悪い例:
# 折り返された要素を縦に揃えない場合、1行目の引数は禁止
foo = long_function_name(var_one, var_two,
□□□□□var_three, var_four)
----
良い例:
# 引数とそれ以外を区別するため、スペースを4つ(インデントをさらに)加える
def long_function_name(
□□□□var_one, var_two, var_three,
□□□□var_four):
□□□print(var_one)

悪い例:
# インデントが区別できないので、2行目以降でさらにインデントが必要
def long_function_name(
□□□□var_one, var_two, var_three,
□□□□var_four):
□□□□print(var_one)
--------
読みやすくするためすべての行の長さを、最大79文字までに制限しましょう。

 

■基礎:インデント行頭の空白文字数が重要!

pythhonを書くにあたってまずは作法ですね。いきなり書いて最初うまくいかずググったのでメモしてました。

---

※1レベルインデントするごとに、スペースを4つ使いましょう。
Pythonでのブロック(複文)構成はインデント(行頭の空白文字の数)
が重要な意味を持ち、同じ数の空白でインデントされた文がブロックとみなされます。
if a == 5:
□□□□print "AAA" # if文の対象
□□□□print "BBB" # if文の対象
□□□□print "CCC" # if文の対象ではない(行頭の空白数が違う)

※インデントには通常、4個の空白文字を使用します。
タブ文字は、インデントが8の倍数になるように1~8個の空白文字とみなされます。
python作成エディターのTABを空白4に設定したエディターを使うと良いらしい)

 

■基礎:Python シングルクォーテーションとダブルクォーテーションの違い
Pythonの文字列リテラルを扱う際には、'シングルクォーテーション' と
"ダブルクォーテーション" のいずれも使えます。
# どちらも同じ文字列
str1 = "abc"
str2 = 'xyz'

 

■基礎:Pythonには「モジュール」「クラス」class「メソッド」があります。
Pythonのクラスとメソッドとは
>「クラス」は何かというと、「メソッド」を集めてひと固まりのグループにしたものです。似たような機能を集めて1つのクラスにするのが一般的です。
>メソッドとは関数のことですね。「def 関数名():」で定義されます。
「クラス」が親、「メソッド」が子です。この親子関係が基本です。
Pythonには「クラス」と「メソッド」以外にも「モジュール」があります。
>「モジュール」とは何か?というと、「モジュール」は「クラス」を集めてひとかたまりにしたものです
「クラス」は「メソッド」を集めたものですが、その「クラス」を集めたものが「モジュール」です。
モジュールが1つの物理ファイルとなります。Pythonでは拡張子「py」とします。「モジュール」は「ファイル」のことですね。
Pythonの「モジュール」「クラス」「メソッド」の関係についてまとめると

モジュール
クラス
メソッド

・モジュールはファイルのこと(拡張子はpy)
・モジュールの中にクラスを定義する
・クラスの中にメソッドを定義する
・モジュールが親、クラスが子、メソッドが孫にあたる

ここで、こんがらがって「いら~!」としてきた。

初心者的には呼び方の定義を押さえていけば、以降ググった時に混乱しないのかな。。

 

■基礎:class クラスの作り方
Pythonにおけるクラスの基本的な構文
class ClassName():
□□□□def __init__(self, ):
□□□□□□□□hogehoge
小文字の「class」の後に、好きなクラス名を指定
関数では「def」で定義
classから始まる構文の内部に「__init__」という関数が定義されています。
これはコンストラクタという、クラスの中でも重要な機能になります。
コンストラクタとは
コンストラクタは、インスタンス(実体)を作成する際に重要な処理を含むものです。
どのように生成するか、どのようなデータを持たせるかなど、といった情報を
定義するのに必要なメソッドになります。
引数にselfというものがあるのに注意してください。selfとはインスタンス自身を指し、
基本的にはこの引数は必須なので忘れないように気を付けてくださいね。
メソッドとは
メソッドとは、クラス内に定義された関数のことです。
メソッドは定義されたクラスからしか呼び出すことが出来ないのも、特徴の一つです。

 

説明が全く入ってこない。理系の人はどうしてこういう説明するのかね?

説明を理解するのにまたググるって最低じゃん。とにかく見るたびにググってそのうち自然と入ってくるのを期待するしかないね。

 

■基礎:importとfromの意味

いろいろプログラムを見ていると、importを使ったりfromを使ったりしているが、

これってなんなん?
Pythonには便利なライブラリがたくさんあり、自由に組み込んで使用することができます。Pythonでライブラリやモジュールを使用するにはimportを使います。
>importのあとに半角開けてモジュール名をつけることで、そのモジュールを読み込むことができます。
importはプログラムのどこに記載しても構いませんが、一般的にはプログラムの一番初めに記述します。
そうすることで「このソースコードではこのモジュールを使用する」ということが一目で分かります。
>「as」を利用して別名をつける
インポートした際に「as」というキーワードを使うことで、インポートしたモジュールに別名をつけることができます。
>import モジュール名 as 別名
モジュール名が長い場合はasを使って短い名前を付けることでコードが見やすくなりますし、入力もしやすくなります。
>fromで省略する
モジュールの関数や変数を直接使えるようにインポートしたい場合は後述のfromを使う。
from <モジュール名> import <オブジェクト名>でオブジェクトをインポートできる。
from <パッケージ名> import <モジュール名>でもOK。
fromを使ってクラスをインポートするのはOK。
---モジュールから特定の関数だけを別名をつけてインポートする
from モジュール名 import 関数名 as 別名
----

importでモジュールをインポートできるということですが、インポートしたモジュールのクラスを扱う場合、
import文でインポートすると記述が少し面倒くさいことがあります。
例えば、
import openpyxl
openpyxl.styles.fonts.Font(color='FF0000')
長いので、fromで省略する
from openpyxl.styles.fonts import Font
Font(color='FF0000')
これは「openpyxl.styles.fonts」の「Font」をインポートするという意味です。
これにより「openpyxl.styles.fonts」を記述する必要はなく、
「Font」だけでよくなります。例1と比較すると、かなりコード量が短くなりました。
しかし、「Font」に限定されているため、「openpyxl」パッケージの他のモジュールが
使えないというデメリットもあります。
from import次第でコード量を省略できますが、汎用性がなくなるため、使い方には注意が必要です。
以下の例もあります。
---
from openpyxl.styles import fonts
fonts.Font(color='FF0000')
これは「openpyxl.styles」の「fonts」をインポートするという意味です。
これにより「openpyxl.styles」を記述する必要はなく、「fonts.Font」だけでよくなります。
例1と比較すると、コード量がやや長くなりました。
---
from openpyxl import styles
styles.fonts.Font(color='FF0000')
これは「openpyxl」の「styles」をインポートするという意味です。
これにより「openpyxl」を記述する必要はなく、「styles」だけでよくなります。
これまでの例と比較すると、コード量がやや長くなりました。
しかし、「openpyxl.styles」が使えるため、汎用性はありますね。
これで何となくPythonの「from import」の書き方がわかってきたかと思います。
> import ~ as ~で別名をつける
import openpyxl as op
op.styles.fonts.Font(color='FF0000')
長い名前の場合、「AS」で別名をつけて短い名前にリネームすることができます。
ここでは「openpyxl」を何度も使用するケースに備え、「op」にして短い名称に別名をつけました。
> import *
from openpyxl import *
importでアスタリスク「*」も使えます。これはimportした「openpyxl 」以下のオブジェクトがすべて使用できます。
ワイルドカード*を使うとすべてのオブジェクトがインポートされる。
なお、*を使ったインポートはどの名前が名前空間に存在しているか不明瞭であるため
推奨されていない。

 

■基礎:モジュールの関数一覧を表示する
>>> import math
>>> dir(math)
['__doc__', '__name__', '__package__', 'acos', 'acosh', ...]

使い方
help(math)

 

■基礎:文と式
Python では、改行が文の区切りとなります。
PerlPHP の様にセミコロン(;)で区切ることもできます。
a = 5; b = 3; c = a + b

文を数行に分けて記述したい場合は、行末にバックスラッシュ(\)を書きます。
total = 123 \
+ 456 \
+ 789

(...), [...], {...} 中のカンマ(,)の後ろはバックスラッシュ(\)を省略することができます。
months = [ 'Jan', 'Feb', 'Mar', 'Apr',
□□□□□□□□□'May', 'Jun', 'Jul', 'Aug',
□□□□□□□□□'Sep', 'Oct', 'Nov', 'Dec' ]

 

■基礎:エスケープシーケンス(\x)
\改行 : バックスラッシュと改行が無視される
\\ : バックスラッシュ(\)
\' : シングルクォート(')
\" : ダブルクォート(")
\a : ベル(BEL)
\b : バックスペース(BS)
\f : フォームフィード(FF)
\n : 改行(LF)
\r : 復帰(CR)
\t : タブ(TAB)
\v : 垂直タブ(VT)
\nnn : 8進表記文字(nは0~7)
\xnn : 16進表記文字(nは0~f)
\uxxxx : ユニコード文字xxxx (例: u"\u3042")
\U....xxxx : ユニコード文字xxxxxxxx (例: U"\U00003042")
\N{name} : Unicodeデータベース文字 (例: u"\N{HIRAGANA LETTER A}")

 

■基礎:%演算子による文字列フォーマット

# 基本形(python3)
print('Hello, %s' % 'world!')
Hello, world!
変換型
変換型      意味
'd' 符号付き10進整数 
'i'  符号付き10進整数 
'x' 符号付き16進数(小文字) 
'X' 符号付き16進数(大文字) 
'e' 指数表記の浮動小数点数(小文字) 
'E' 指数表記の浮動小数点数(大文字) 
'f' 10進浮動小数点数 
'F' 10進浮動小数点数 
'c' 文字一文字 
'r' 文字列(repr()で変換) 
's' 文字列(str()で変換) 

フラグ
'0' 数値型に対してゼロによるパディングを行う 
'-' 変換された値を左寄せにする 
' ' 符号付きの変換で正の数の場合、前に一つスペースを空ける 
'+' 変換の先頭に符号文字をつける 
数字(0以外) その桁数になるように出力 

 

■基礎:文字操作
Pythonで文字列の最初・最後の1文字(数文字)を削除する
前から1文字削除したい場合は
list = 'ABCDE'
list = list[1:]
もし複数の文字を削除したければ,コロンの前の1を任意の数に変更すれば良いです.
例えば2文字削除したい場合は以下のようになります.
list = list[2:]
後ろから1文字削除したい場合は
list = list[:-1]
例えば3文字削除したい場合は以下のようになります
list = list[:-3]

 

■基礎:if __name__ == '__main__':の意味

コマンドラインからスクリプトファイルを指定してPythonインタプリタを起動すると、
指定されたファイルは、__main__という名前のモジュールとしてPythonに読み込まれる。
実行中スクリプトのモジュールの名前は、__name__という名前の変数に設定されている
ため、この値を参照して、ファイルがコマンドラインから実行されたのか、
それともimport文でインポートされたのかを識別できる。

__name__属性は、
•モジュール作成と同時に自動的に与えられて以下の設定が行われる
•モジュールファイルがトップレベルファイル(main)として機能する ==> __name__に__main__ が代入される
•モジュールファイルがインポートされる ==> __name__にモジュール名が代入される
言い換えると、
「 if name == 'main': 」ステートメント
コマンドラインでファイルを指定して起動された場合は True で実行される
•importでインポートされた場合は False で実行されない

どう応用する?
たとえば、
「モジュールを作っているとき、かんたんにテストしたい
(値をprintするなどで確認する)コードを書くとき」
これは、他のモジュールにインポートされた時には表示する必要がなかったりする。
そういう時は、テストするためのコードを「if __name__ == '__main__':」の中にかけば、
トップレベルファイルで実行された時にのみ、テスト用の値出力処理が行われるようにすることができる。
他のモジュールからインポートされた時は False となり、実行されない。ちょっと便利。
この他にも使いドコロがありそう!
「直接実行されているのか、それともimportされて実行されているのかが、
この__name__変数の値を確認することで分かる!」

 

■基礎:Python の文
1. 同じだけ字下げされた連続した文は1 つの(ブロック)文である。
2. for 文は1 つの文である
3. if 文の各ファミリーは1 つの文である。
4. while 文は1 つの文である。
5. 以上の手続きによって得られるものだけが文である。
6. 空文:0 個以上の空白と改行文字からなる行は文ではない。

■基礎:関数の定義
関数を定義するには、関数名と仮引数(arguments) の並びを括弧( ) 内に書く。
※引数をとらない関数でも括弧( ) は省略できない。
def 関数名(引数の並び):
関数本体の記述

def greeting():
print('Hello!')
print('How are you?')
# main script
greeting()

 

■基礎:コマンドライン引数
python起動時に引数を渡すには?

import sys
args = sys.argv
print(args)
print("第1引数:" + args[1])
print("第2引数:" + args[2])
print("第3引数:" + args[3])

pythonn test.py a b c
第1引数:a
第2引数:b
第3引数:c
※ args[0]は実行ファイル名test.pyが入る。
--------
# -*- coding: utf8 -*-
# 引数の取り込み
# 引数の数を数えて表示させる。
import sys
args = sys.argv
lengs = len(args)  #引数の数を数える
# print(args)
# print(lengs)
#for x in range(int(lengs)):
for x in range(1,lengs):   #[0]はプログラミ名なので[1]から表示
□□□□□print("第" + str(x) + "引数:" + str(args[x]))

--------

 

はじめてのpython

一昔前はphpがもてはやされていたような気がしたが、最近はpython「ぱいそん]とやらが流行っているようで、RPAやって楽しようと思ってググってみたらpythonに行き当たった。幸い時間が少しできたのでいろいろ触ってみることにした。

まったくpythonを知らないのでいろいろググってメモした備忘録を残しておく。

 

======Pythonメモ=========

開発環境もいろいろ便利なものがあるが、その操作方法が複雑でどぅも敷居が高い

ので初心者としては、テキストエディタのみで十分かな?DOSプロンプトとエディタで開始することとした。(DOSプロンプトはパワーシェルの方が便利)

 

■基礎:プログラムの書き方ルール(coding:)
日本語など、ASCII以外の文字を含むスクリプトを作成する場合は
スクリプトの1行目、または2行目に、下記の形式でスクリプト
エンコードルール(coding:) 大文字・小文字は無視されます。
コメントが正規表現 coding[=:]\s*([-\w.]+) にマッチする場合、
コメントはエンコード宣言として処理されます;

# coding: utf-8
Emacs との互換性を考慮し、下記の様に記述することもできます。
# -*- coding: utf-8 -*-

エンコード宣言
# -*- coding: <encoding-name> -*-

エンコードルールには下記などがあります。
# coding: utf-8
# coding: Shift_JIS
# coding: EUC-JP
# coding: cp932

書き方の例
-----
良い例:
# 開き括弧に揃える
foo = long_function_name(var_one, var_two,
□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□var_three, var_four)
悪い例:
# 折り返された要素を縦に揃えない場合、1行目の引数は禁止
foo = long_function_name(var_one, var_two,
□□□□□var_three, var_four)
----
良い例:
# 引数とそれ以外を区別するため、スペースを4つ(インデントをさらに)加える
def long_function_name(
□□□□var_one, var_two, var_three,
□□□□var_four):
□□□print(var_one)

悪い例:
# インデントが区別できないので、2行目以降でさらにインデントが必要
def long_function_name(
□□□□var_one, var_two, var_three,
□□□□var_four):
□□□□print(var_one)
--------
読みやすくするためすべての行の長さを、最大79文字までに制限しましょう。

 

■基礎:インデント行頭の空白文字数が重要!

pythhonを書くにあたってまずは作法ですね。いきなり書いて最初うまくいかずググったのでメモしてました。

---

※1レベルインデントするごとに、スペースを4つ使いましょう。
Pythonでのブロック(複文)構成はインデント(行頭の空白文字の数)
が重要な意味を持ち、同じ数の空白でインデントされた文がブロックとみなされます。
if a == 5:
□□□□print "AAA" # if文の対象
□□□□print "BBB" # if文の対象
□□□□print "CCC" # if文の対象ではない(行頭の空白数が違う)

※インデントには通常、4個の空白文字を使用します。
タブ文字は、インデントが8の倍数になるように1~8個の空白文字とみなされます。
python作成エディターのTABを空白4に設定したエディターを使うと良いらしい)

 

■基礎:Python シングルクォーテーションとダブルクォーテーションの違い
Pythonの文字列リテラルを扱う際には、'シングルクォーテーション' と
"ダブルクォーテーション" のいずれも使えます。
# どちらも同じ文字列
str1 = "abc"
str2 = 'xyz'

 

■基礎:Pythonには「モジュール」「クラス」class「メソッド」があります。
Pythonのクラスとメソッドとは
>「クラス」は何かというと、「メソッド」を集めてひと固まりのグループにしたものです。似たような機能を集めて1つのクラスにするのが一般的です。
>メソッドとは関数のことですね。「def 関数名():」で定義されます。
「クラス」が親、「メソッド」が子です。この親子関係が基本です。
Pythonには「クラス」と「メソッド」以外にも「モジュール」があります。
>「モジュール」とは何か?というと、「モジュール」は「クラス」を集めてひとかたまりにしたものです
「クラス」は「メソッド」を集めたものですが、その「クラス」を集めたものが「モジュール」です。
モジュールが1つの物理ファイルとなります。Pythonでは拡張子「py」とします。「モジュール」は「ファイル」のことですね。
Pythonの「モジュール」「クラス」「メソッド」の関係についてまとめると

モジュール
クラス
メソッド

・モジュールはファイルのこと(拡張子はpy)
・モジュールの中にクラスを定義する
・クラスの中にメソッドを定義する
・モジュールが親、クラスが子、メソッドが孫にあたる

ここで、こんがらがって「いら~!」としてきた。

初心者的には呼び方の定義を押さえていけば、以降ググった時に混乱しないのかな。。

 

■基礎:class クラスの作り方
Pythonにおけるクラスの基本的な構文
class ClassName():
□□□□def __init__(self, ):
□□□□□□□□hogehoge
小文字の「class」の後に、好きなクラス名を指定
関数では「def」で定義
classから始まる構文の内部に「__init__」という関数が定義されています。
これはコンストラクタという、クラスの中でも重要な機能になります。
コンストラクタとは
コンストラクタは、インスタンス(実体)を作成する際に重要な処理を含むものです。
どのように生成するか、どのようなデータを持たせるかなど、といった情報を
定義するのに必要なメソッドになります。
引数にselfというものがあるのに注意してください。selfとはインスタンス自身を指し、
基本的にはこの引数は必須なので忘れないように気を付けてくださいね。
メソッドとは
メソッドとは、クラス内に定義された関数のことです。
メソッドは定義されたクラスからしか呼び出すことが出来ないのも、特徴の一つです。

 

説明が全く入ってこない。理系の人はどうしてこういう説明するのかね?

説明を理解するのにまたググるって最低じゃん。とにかく見るたびにググってそのうち自然と入ってくるのを期待するしかないね。

 

■基礎:importとfromの意味

いろいろプログラムを見ていると、importを使ったりfromを使ったりしているが、

これってなんなん?
Pythonには便利なライブラリがたくさんあり、自由に組み込んで使用することができます。Pythonでライブラリやモジュールを使用するにはimportを使います。
>importのあとに半角開けてモジュール名をつけることで、そのモジュールを読み込むことができます。
importはプログラムのどこに記載しても構いませんが、一般的にはプログラムの一番初めに記述します。
そうすることで「このソースコードではこのモジュールを使用する」ということが一目で分かります。
>「as」を利用して別名をつける
インポートした際に「as」というキーワードを使うことで、インポートしたモジュールに別名をつけることができます。
>import モジュール名 as 別名
モジュール名が長い場合はasを使って短い名前を付けることでコードが見やすくなりますし、入力もしやすくなります。
>fromで省略する
モジュールの関数や変数を直接使えるようにインポートしたい場合は後述のfromを使う。
from <モジュール名> import <オブジェクト名>でオブジェクトをインポートできる。
from <パッケージ名> import <モジュール名>でもOK。
fromを使ってクラスをインポートするのはOK。
---モジュールから特定の関数だけを別名をつけてインポートする
from モジュール名 import 関数名 as 別名
----

importでモジュールをインポートできるということですが、インポートしたモジュールのクラスを扱う場合、
import文でインポートすると記述が少し面倒くさいことがあります。
例えば、
import openpyxl
openpyxl.styles.fonts.Font(color='FF0000')
長いので、fromで省略する
from openpyxl.styles.fonts import Font
Font(color='FF0000')
これは「openpyxl.styles.fonts」の「Font」をインポートするという意味です。
これにより「openpyxl.styles.fonts」を記述する必要はなく、
「Font」だけでよくなります。例1と比較すると、かなりコード量が短くなりました。
しかし、「Font」に限定されているため、「openpyxl」パッケージの他のモジュールが
使えないというデメリットもあります。
from import次第でコード量を省略できますが、汎用性がなくなるため、使い方には注意が必要です。
以下の例もあります。
---
from openpyxl.styles import fonts
fonts.Font(color='FF0000')
これは「openpyxl.styles」の「fonts」をインポートするという意味です。
これにより「openpyxl.styles」を記述する必要はなく、「fonts.Font」だけでよくなります。
例1と比較すると、コード量がやや長くなりました。
---
from openpyxl import styles
styles.fonts.Font(color='FF0000')
これは「openpyxl」の「styles」をインポートするという意味です。
これにより「openpyxl」を記述する必要はなく、「styles」だけでよくなります。
これまでの例と比較すると、コード量がやや長くなりました。
しかし、「openpyxl.styles」が使えるため、汎用性はありますね。
これで何となくPythonの「from import」の書き方がわかってきたかと思います。
> import ~ as ~で別名をつける
import openpyxl as op
op.styles.fonts.Font(color='FF0000')
長い名前の場合、「AS」で別名をつけて短い名前にリネームすることができます。
ここでは「openpyxl」を何度も使用するケースに備え、「op」にして短い名称に別名をつけました。
> import *
from openpyxl import *
importでアスタリスク「*」も使えます。これはimportした「openpyxl 」以下のオブジェクトがすべて使用できます。
ワイルドカード*を使うとすべてのオブジェクトがインポートされる。
なお、*を使ったインポートはどの名前が名前空間に存在しているか不明瞭であるため
推奨されていない。

 

■基礎:モジュールの関数一覧を表示する
>>> import math
>>> dir(math)
['__doc__', '__name__', '__package__', 'acos', 'acosh', ...]

使い方
help(math)

 

■基礎:文と式
Python では、改行が文の区切りとなります。
PerlPHP の様にセミコロン(;)で区切ることもできます。
a = 5; b = 3; c = a + b

文を数行に分けて記述したい場合は、行末にバックスラッシュ(\)を書きます。
total = 123 \
+ 456 \
+ 789

(...), [...], {...} 中のカンマ(,)の後ろはバックスラッシュ(\)を省略することができます。
months = [ 'Jan', 'Feb', 'Mar', 'Apr',
□□□□□□□□□'May', 'Jun', 'Jul', 'Aug',
□□□□□□□□□'Sep', 'Oct', 'Nov', 'Dec' ]

 

■基礎:エスケープシーケンス(\x)
\改行 : バックスラッシュと改行が無視される
\\ : バックスラッシュ(\)
\' : シングルクォート(')
\" : ダブルクォート(")
\a : ベル(BEL)
\b : バックスペース(BS)
\f : フォームフィード(FF)
\n : 改行(LF)
\r : 復帰(CR)
\t : タブ(TAB)
\v : 垂直タブ(VT)
\nnn : 8進表記文字(nは0~7)
\xnn : 16進表記文字(nは0~f)
\uxxxx : ユニコード文字xxxx (例: u"\u3042")
\U....xxxx : ユニコード文字xxxxxxxx (例: U"\U00003042")
\N{name} : Unicodeデータベース文字 (例: u"\N{HIRAGANA LETTER A}")

 

■基礎:%演算子による文字列フォーマット

# 基本形(python3)
print('Hello, %s' % 'world!')
Hello, world!
変換型
変換型      意味
'd' 符号付き10進整数 
'i'  符号付き10進整数 
'x' 符号付き16進数(小文字) 
'X' 符号付き16進数(大文字) 
'e' 指数表記の浮動小数点数(小文字) 
'E' 指数表記の浮動小数点数(大文字) 
'f' 10進浮動小数点数 
'F' 10進浮動小数点数 
'c' 文字一文字 
'r' 文字列(repr()で変換) 
's' 文字列(str()で変換) 

フラグ
'0' 数値型に対してゼロによるパディングを行う 
'-' 変換された値を左寄せにする 
' ' 符号付きの変換で正の数の場合、前に一つスペースを空ける 
'+' 変換の先頭に符号文字をつける 
数字(0以外) その桁数になるように出力 

 

■基礎:文字操作
Pythonで文字列の最初・最後の1文字(数文字)を削除する
前から1文字削除したい場合は
list = 'ABCDE'
list = list[1:]
もし複数の文字を削除したければ,コロンの前の1を任意の数に変更すれば良いです.
例えば2文字削除したい場合は以下のようになります.
list = list[2:]
後ろから1文字削除したい場合は
list = list[:-1]
例えば3文字削除したい場合は以下のようになります
list = list[:-3]

 

■基礎:if __name__ == '__main__':の意味

コマンドラインからスクリプトファイルを指定してPythonインタプリタを起動すると、
指定されたファイルは、__main__という名前のモジュールとしてPythonに読み込まれる。
実行中スクリプトのモジュールの名前は、__name__という名前の変数に設定されている
ため、この値を参照して、ファイルがコマンドラインから実行されたのか、
それともimport文でインポートされたのかを識別できる。

__name__属性は、
•モジュール作成と同時に自動的に与えられて以下の設定が行われる
•モジュールファイルがトップレベルファイル(main)として機能する ==> __name__に__main__ が代入される
•モジュールファイルがインポートされる ==> __name__にモジュール名が代入される
言い換えると、
「 if name == 'main': 」ステートメント
コマンドラインでファイルを指定して起動された場合は True で実行される
•importでインポートされた場合は False で実行されない

どう応用する?
たとえば、
「モジュールを作っているとき、かんたんにテストしたい
(値をprintするなどで確認する)コードを書くとき」
これは、他のモジュールにインポートされた時には表示する必要がなかったりする。
そういう時は、テストするためのコードを「if __name__ == '__main__':」の中にかけば、
トップレベルファイルで実行された時にのみ、テスト用の値出力処理が行われるようにすることができる。
他のモジュールからインポートされた時は False となり、実行されない。ちょっと便利。
この他にも使いドコロがありそう!
「直接実行されているのか、それともimportされて実行されているのかが、
この__name__変数の値を確認することで分かる!」

 

■基礎:Python の文
1. 同じだけ字下げされた連続した文は1 つの(ブロック)文である。
2. for 文は1 つの文である
3. if 文の各ファミリーは1 つの文である。
4. while 文は1 つの文である。
5. 以上の手続きによって得られるものだけが文である。
6. 空文:0 個以上の空白と改行文字からなる行は文ではない。

■基礎:関数の定義
関数を定義するには、関数名と仮引数(arguments) の並びを括弧( ) 内に書く。
※引数をとらない関数でも括弧( ) は省略できない。
def 関数名(引数の並び):
関数本体の記述

def greeting():
print('Hello!')
print('How are you?')
# main script
greeting()

 

■基礎:コマンドライン引数
python起動時に引数を渡すには?

import sys
args = sys.argv
print(args)
print("第1引数:" + args[1])
print("第2引数:" + args[2])
print("第3引数:" + args[3])

pythonn test.py a b c
第1引数:a
第2引数:b
第3引数:c
※ args[0]は実行ファイル名test.pyが入る。
--------
# -*- coding: utf8 -*-
# 引数の取り込み
# 引数の数を数えて表示させる。
import sys
args = sys.argv
lengs = len(args)  #引数の数を数える
# print(args)
# print(lengs)
#for x in range(int(lengs)):
for x in range(1,lengs):   #[0]はプログラミ名なので[1]から表示
□□□□□print("第" + str(x) + "引数:" + str(args[x]))

--------

 

Linux端末どこ行った?

ディスプレイもキーボードも付けてない古いLinuxマシンの電源が入っているがIPアドレス忘れてしまった。

RaspberryPiでブロードキャストpingで見つけようと思ったがなかなかうまくいかない。

 

$ping 192.168.1.255 とやるも応答なし。

ちょっとググって

 

$ sudo sh -c 'echo 0 >/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts'

でブロードキャストpingが打てるようになったが、応答するのはルータだけ。

仕方ないので、pythonで192.168.1.1~192.168.1.254にpingをかけて応答のある者のみ表示するちょんプロを作成した。

 

使用方法:

pythonのpingsモジュールを使用してpingを打つためにrootの権限が必要なので、

モジュールをsudo でインストール。

$ sudo pip3 install pings

 

■pin.pyを作成

---------------------------

# -*- coding: utf-8 -*-

# pingの応答で接続端末のIPアドレスを探す

# 192.168.1.1~254にpingを打って調べる

import pings


p = pings.Ping()
i = 1

for i in range(1,254) :
  res = p.ping("192.168.1." + str(i))

  if res.is_reached():
    print("==>" + "192.168.1." + str(i) +"- OK")
    i += 1
  else:
    i += 1

---------------------------------

 

$python pin.py

==>192.168.1.1- OK
==>192.168.1.2- OK
==>192.168.1.5- OK
==>192.168.1.6- OK
==>192.168.1.8- OK
==>192.168.1.11- OK
==>192.168.1.12- OK
==>192.168.1.13- OK
==>192.168.1.22- OK
==>192.168.1.24- OK
==>192.168.1.30- OK
==>192.168.1.32- OK
==>192.168.1.38- OK
==>192.168.1.111- OK
==>192.168.1.117- OK
==>192.168.1.128- OK
==>192.168.1.253- OK

 

結果:192.168.1.30が古いLinuxマシンでした。

 

ちょっと時間がかかるのが難点ですね。もっと簡単でいい方法ないかな?

$ping 192.168.1.255 これができれば一番いいのですが。。。

 

 

 

Ubuntuのパッケージ管理

今回Ubuntuを触るのが初めてなのでメモっておくことにする。

RaspberryPi4を少し触ったが、ちょくちょくシステムを壊して再インストールを数回してしまったので少し基本的なところを押さえておかないとなかなか感覚だけでは無理っぽい。幸い時間があるので調べたことをメモしておこう。どうせまたシステム壊すので見返しながら素早く再構築できるように。。。

 

-----------------------------------
1.Ubuntuのパッケージ管理
-----------------------------------
ソフトウェアをインストール、アップグレード、構成、および削除するための
パッケージ管理システムがある。パッケージ管理システムは、Debian GNU / Linuxディストリビューションで使用されているものと同じシステムから派生している。
Debianパッケージファイルは拡張子.debパッケージは通常、コンパイル済みのバイナリ形式です。
したがって、インストールは迅速であり、ソフトウェアのコンパイルは必要ありません。

昔はGCCコンパイルしていたのだが便利になったもんじゃの。
./configure -> make -> make install を何回やったもんじゃろ。

新しいソフトウェアパッケージのインストール、既存のソフトウェアパッケージの
アップグレード、パッケージリストインデックスの更新、さらにはUbuntu全体の
アップグレードなどの機能を実行するaptコマンドがある。

 

■aptの使い方(aptはコマンドラインツール)
GUIで行うよりコマンドラインで行った方が精神的に落ち着くわ。

・パッケージのインストール:
$ sudo apt install パッケージ名

・パッケージの削除
$ sudo apt remove パッケージ名

※複数のパッケージ:インストールまたは削除する複数のパッケージをスペースで区切って指定できます。
vineLinuxなどでapt-getコマンドを多用していたが、ubuntuでは注意項目があるみたい

--purgeオプションを追加apt removeすると、パッケージ構成ファイルも削除される。
これは望ましい効果である場合とそうでない場合があるため、注意して使用してください。

・パッケージインデックスの更新
APTパッケージインデックスは、基本的に、/etc/apt/sources.listファイルと/etc/apt/sources.list.dディレクトリで
定義されたリポジトリから利用可能なパッケージのデータベースです。
リポジトリで行われた最新の変更でローカルパッケージインデックスを更新するには、次のように入力します。

※updateはインデックスの更新のみです。

$ sudo apt update

・パッケージのアップグレード
システムをアップグレードするには、まず、パッケージインデックスを更新(update)してから、次のように入力します。

$ sudo apt upgrade

※新たなUbuntuのリリースの参照は、
https://ubuntu.com/server/docs/upgrade-introduction
で詳細がわかります。

APTの使用の詳細はapt helpで確認してください。

list - パッケージ名に基づいてパッケージを一覧表示します
search - パッケージの説明を検索
show - パッケージの詳細を表示します
install - パッケージをインストールします
reinstall - パッケージを再インストールします
remove - パッケージを削除します
autoremove - 未使用のパッケージをすべて自動的に削除します
update - 利用可能なパッケージのリストを更新します
upgrade - パッケージをインストール/アップグレードしてシステムをアップグレードします
full-upgrade - パッケージを削除/インストール/アップグレードしてシステムをアップグレードします
edit-sources - ソース情報ファイルを編集します
satisfy - 依存関係の文字列を満たす

■dpkg
dpkgは、Debianベースのシステム用のパッケージマネージャーです。
パッケージのインストール、削除、ビルドはできますが、他のパッケージ管理システムとは異なり、
パッケージまたはその依存関係を自動的にダウンロードしてインストールすることはできません。
以下はdpkgを使用してローカルにインストールされたパッケージを管理する方法について説明します。

・インストールおよびアンインストールされたすべてのパッケージを含む、システムのパッケージデータベース内
のすべてのパッケージをターミナルプロンプトから一覧表示するには、次のように入力します。

$dpkg -l

・システム上のパッケージの数によっては、これにより大量の出力が生成される可能性があります。
出力をgrepにパイプして、特定のパッケージがインストールされているかどうかを確認します。

$ dpkg -l | grep apache2
ii apache2 2.4.41-4ubuntu3.1 arm64 Apache HTTP Server
ii apache2-bin 2.4.41-4ubuntu3.1 arm64 Apache HTTP Server (modules and other binary files)
ii apache2-data 2.4.41-4ubuntu3.1 all Apache HTTP Server (common files)
ii apache2-utils 2.4.41-4ubuntu3.1 arm64 Apache HTTP Server (utility programs for web servers)

・パッケージ(この場合はufwパッケージ)によってインストールされたファイルを一覧表示するには、次のように入力します。

$ dpkg -L ufw

・どのパッケージがファイルをインストールしたかわからない場合はdpkg -S、教えてくれる。例えば:

$ dpkg -S /etc/apache2/apache2.conf
apache2: /etc/apache2/apache2.conf

apache2パッケージによってインストールされたことがわかる。

※パッケージのインストールプロセス中に自動的に生成され、ファイルシステム上にあるdpkg -S場合でも、
どのパッケージに属しているかわからない場合があります。

・次のように.deb入力して、ローカルファイルをインストールできます。

$ sudo dpkg -i インストールするローカル.debファイルの実際のファイル名

・パッケージのアンインストールは、次の方法で実行できます。
$ sudo dpkg -r zip

※上の場合zipパッケージが削除されますが、それに依存するパッケージは引き続きインストールされていて、正しく機能しなくなる可能性があります。
  あまり使わない方がよい。

■APT構成
システムのリポジトリ
/etc/apt/sources.listファイルと
/etc/apt/sources.list.dディレクトリ。
に格納されている。
ファイルを編集して、リポジトリを有効または無効にすることができます。
ファイルの先頭に表示される適切な行をコメントアウトするだけです。
コメントアウトは行頭に#で行えます。
デフォルトでは、ユニバースリポジトリマルチバースリポジトリは有効になっていますが、無効にする場合は/etc/apt/sources.list、次の行を編集してコメントします。

■自動更新
無人アップグレードパッケージは、更新されたパッケージを自動的にインストールするために使用でき、
すべてのパッケージを更新するか、セキュリティ更新プログラムをインストールするように構成できます。
まず、ターミナルに次のように入力してパッケージをインストールします。

$sudo apt install unattended-upgrades

無人アップグレードを構成/etc/apt/apt.conf.d/50unattended-upgradesするには、ニーズに合わせて以下を編集および調整します。
※二重の「//」はコメントとして機能するため、「//」に続くものは評価されません。

Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}";
"${distro_id}:${distro_codename}-security"
// "${distro_id}:${distro_codename}-updates";
// "${distro_id}:${distro_codename}-proposed";
// "${distro_id}:${distro_codename}-backports";


ブラックリストに登録すると特定のパッケージも自動的に更新されません。パッケージをブラックリストに登録するには、パッケージをリストに追加します。

Unattended-Upgrade::Package-Blacklist {
// "vim";
// "libc6";
// "libc6-dev";
// "libc6-i686";
};

自動更新を有効にするに/etc/apt/apt.conf.d/20auto-upgradesは、適切なapt構成オプションを編集および設定します。

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
APT::Periodic::Unattended-Upgrade "1";

上記の構成では、パッケージリストが更新され、利用可能なアップグレードが毎日ダウンロードおよびインストールされます。
ローカルダウンロードアーカイブは毎週クリーンアップされます。
新しいバージョンのUbuntuにアップグレードされたサーバーでは、応答によっては、上記のファイルが存在しない場合があります。
この場合、この名前の新しいファイルの作成も機能するはずです。

無人アップグレードの結果はに記録され/var/log/unattended-upgradesます。

■通知
無人アップグレードで、アップグレードが必要なパッケージや問題のあるパッケージの詳細を管理者にメールで送信できるようになります。
/etc/apt/apt.conf.d/50unattended-upgradesで構成Unattended-Upgrade::Mailする
もう1つの便利なパッケージはapticronです。
apticronは、更新が利用可能なシステム上のパッケージに関する情報と、各パッケージの変更の概要を管理者に
電子メールで送信するようにcronジョブを構成します。

apticronパッケージをインストールするには、ターミナルで次のように入力します。
$ sudo apt install apticron

パッケージがインストールされたら、編集して/etc/apticron/apticron.conf、メールアドレスとその他のオプションを設定します。

EMAIL="root@example.com"

 

apache2いい感じ

2週間ほど電源ONしたままSSHで細かな設定を変えながら使っていたが、

いきなり使えなくなった。確認するとMicroSDカードが壊れて読み込み不可。

熱か?仕方ないので再インストール今度のOSは

Ubuntu 20.04.2 LTS" 64ビットサーバーLTSにしてみた。

ざっくりアップグレードと無線LAN設定をやってまずapach2をインストールで

あっさり完了。前回のOSはエラーが出たが今回はエラーなしで終了。

メモってみた。

$ sudo ufw app list
Available applications:
OpenSSH

まだapache2インストールしてないのでhttpdのF/w設定がはいってない。

$ sudo apt install apache2

Enabling site 000-default.
Created symlink /etc/systemd/system/multi-user.target.wants/apache2.service → /lib/systemd/system/apache2.service.
Created symlink /etc/systemd/system/multi-user.target.wants/apache-htcacheclean.service → /lib/systemd/system/apache-htcacheclean.service.
Processing triggers for ufw (0.36-6) ...
Processing triggers for systemd (245.4-4ubuntu3.4) ...
Processing triggers for man-db (2.9.1-1) ...
Processing triggers for libc-bin (2.31-0ubuntu9.2) ...
ubuntu@ubuntu:~$

あっさりインストール完了

$ sudo ufw app list
Available applications:
Apache
Apache Full
Apache Secure
OpenSSH

F/Wのセットが入っている。

■F/wの調整

※1 Apache: WWW、ポート80 のみを聞く
※2 Apache Full: このプロファイルは、ポート80とポート443の両方を開く
※3 Apache Secure: このプロファイルは、ポート443 のみを聞く

$sudo ufw allow 'Apache Full'

Rules updated
Rules updated (v6)

 

SSHも通るようにしておく
$sudo ufw allow 'OpenSSH' 

$ sudo ufw status
Status: inactive

$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

$ sudo ufw status
Status: active

To Action From
-- ------ ----
Apache Full ALLOW Anywhere
OpenSSH ALLOW Anywhere
Apache Full (v6) ALLOW Anywhere (v6)
OpenSSH (v6) ALLOW Anywhere (v6)

 

■やりたいこと

とりあえずHTTPサーバが立ち上げるので以下のことをやってみる

・指定のディレクトリにアクセスするとBasic認証でIDとパスワードを聞いてくる。

・ID、パスワードを入れるとディレクトリ以下のファイルが見れる

・最後にシンボリックリンクNASサーバのファイルをWEBサーバ経由でアクセス

する。

 

Basic認証を付ける

1.htaccess用パスワード作成ツールで.htpasswdを作成する
2.パーミッションは604


http://192.168,XX,YY/info/ にアクセスしたらIDとパスワードを聞いてくる
Basic認証設定をする

■パスワードファイルの.htpasswdを作成
$sudo htpasswd -c /var/www/.htpasswd ユーザ名
New password:パスワード
Re-type new password:パスワード
Adding password for user ユーザ名

/var/www/.htpasswd が作成されたことを確認

$sudo ls -a /var/www/

あるので

$sudo chmod 604 /var/www/.htpasswd しておく。


■/etc/apache2/apach2.confに設定追加
--------------------------------------------

<Directory /var/www/html/info>
 AllowOverride None
 Order allow,deny
 Allow from all
 Options FollowSymlinks
 Options Indexes FollowSymLinks
 AuthType Basic
 AuthName "erina Please input ID & Password"
 AuthUserFile /var/www/.htpasswd
<Limit GET POST>
 require valid-user
</Limit>
</Directory>

# AccessFileName: The name of the file to look for in each directory
# for additional configuration directives. See also the AllowOverride
# directive.
#
AccessFileName .htpasswd

--------------------------------------------------


■$sudo service apache2 start

もし起動しない場合

$ sudo systemctl status apache2.service

で起動エラー内容を確認。
私の場合
Invalid command 'AuthGroupFile', perhaps misspelled or defined by a module not included in the server configuration
で起動しなかった。
apach2.confの「AuthGroupfile /dev/null」の記述を消し起動OKとなった。

これでBasic認証付きのディレクトリができたのでここからNASサーバに飛ばしファイルのアクセスを可能にする。

次は上記設定でシンボリックリンクアクセス可能かのテストです。

NASサーバのマウント

$sudo mkdir /mnt/oresama1

$sudo mkdir /mnt/oremasa2

2台のNASサーバを/mntにマウント

※マウントする前にcifsがマウントできるように

 cifsユーティリティをインストールしておく。

$ sudo apt install cifs-utils

NASのマウント

$sudo mount -t cifs //192.168.X.X/public /mnt/oresama1 -o user=xxxx,password=YYYY

$sudo mount -t cifs //192.168.X.Y/public /mnt/oresama2 -o user=xxxx,password=YYYY

 

シンボリックリンク作成

$ sudo ln -s /mnt/oresama1 oresama1

$ sudo ln -s /mnt/oresama2 oresama2

 

■WWWブラウザー経由NASサーバアクセス

結構サクサクアクセスできるわ。