☆☆ 新着記事 ☆☆

2019年2月27日水曜日

WindowsでPythonの仮想環境(venv)を起動する

WindowsパソコンでもPythonの仮想環境を使いたい、という場合のて手順のメモです。
Windowsパソコンは、Linux系のサーバーとは、ちょっとコマンドが違うので、いつも忘れてしまうので。


(パソコンに既にPython3.xがインストールされていることが前提です。)


1.  プロジェクト・フォルダの作成
仮想環境を使う目的は、Pythonのpackageを、他のグローバル環境から独立して、プロジェクト独自に用意したい、ということなので、後でパッケージをインストールすることになるプロジェクト・フォルダを作ります。

miniprojectというDirectoryを作ります。

C:\Users\ユーザ名>mkdir miniproject

2. 仮想環境の構築
1) miniprojectに移ります。
C:\Users\ユーザ名>cd miniproject

2) pythonのコマンド実行
C:\Users\ユーザ名\miniproject>python -m venv venv
(2つめのvenvは新しく作られるフォルダ名です。任意で構いません。)

結果、以下のようなフォルダが自動で作られる。
C:\Users\ユーザ名\miniproject>dir
2019/02/27  20:45    <DIR>          .
2019/02/27  20:45    <DIR>          ..
2019/02/27  20:45    <DIR>          venv

C:\Users\ユーザ名\miniproject>dir venv
2019/02/27  20:45    <DIR>          .
2019/02/27  20:45    <DIR>          ..
2019/02/27  20:45    <DIR>          Include
2019/02/27  20:45    <DIR>          Lib
2019/02/27  20:45               119 pyvenv.cfg
2019/02/27  20:45    <DIR>          Scripts


*Global環境にインストールされたパッケージを、仮想環境にインストールするパッケージと
 一緒に使いたい場合。

仮想環境を作る際に、以下のオプションをつけて実行する。

C:\Users\ユーザ名\miniproject>python -m venv venv --system-site-packages




2.  仮想環境のアクティベイト

このScriptに,venvを実行するパッケージが格納されているので(Linuxのbinフォルダ相当)
以下のコマンドを実行。
C:\Users\ユーザ名\miniproject>venv\Scripts\activate
(しつこいですが、source venv/bin/activate に相当します。備忘として)
miniproject>venvのvenvはフォルダ名なので、1-2)で作成したフォルダ名になります。

するとコマンドラインの画面が以下のように切り替わり、仮想環境に入れます。
プロンプトは、以下になっています。
(venv) C:\Users\ユーザ名\miniproject>





3.  仮想環境でPython アプリを起動


(venv) C:\Users\ユーザ名\miniproject>set FLASK_APP=app.py

で、仮想環境にインストールされたパッケージを使うことが可能です。


おわりです。

2019年2月23日土曜日

Google アナリスティクスをきちんと使うメモ

公式、非公式のWebを読んでも良くわからない、Google Analyticsをきちんと使う為のメモです。


まずは、Google Anayticsにログインして、どこかにある、歯車マーク(管理ボタン)をクリック。
(Chromeでは、左サイドバーの一番下。 デザインは頻繁に変わるので。)


アカウントを作成


1. アカウント名; 
任意のようなので、Mossymobにしておく。

2. ウェブサイトの名前
任意のようなので、Mossymob(uslife)と、このトラッキングIDで管理したいサブドメイン名にしておく。


グローバル サイトタグ(gtag.js)

このプロパティで使用できる Global Site Tag(gtag.js)トラッキング コードです。このコードをコピーして、トラッキングするすべてのウェブページの <HEAD> 内の最初の要素として貼り付けてください。ページにすでに Global Site Tag が配置されている場合は、以下のスニペットの config 行のみを既存の Global Site Tag に追加してください

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135034430-1"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'UA-135034430-1');
</script>

が、取得できました。

これで、全てのページに貼り付けるんですね。

割と深いDirectoryもあるのですが、サイトマップをまだ送っていないない状況で、きちんと把握してくれるのか興味があります。

Wordpressには、
「外観」→「テーマ編集」→右側バーの「header.php」
に上記のタグを挿入するらしい。

が、

Cocoonを使っているので、
外観」→「テーマ編集」→右側「テーマ・ファイル」バーの「temp-user
->「head-insert.php

に、挿入する。

スクリプトは、
<?php //ログインユーザーも含めてカウントする場合は以下に挿入?>
の下に挿入すればよく、<?php //この間に挿入するのはないよ ?>



これで設定は終了。






2019年2月15日金曜日

VPSにWordpressをインストールしたら投稿が表示されない(404エラー)、という時の対処

安さに目が眩んで、VPSでWordpressを運用するひとも多くなっていると思いますが、インストールした直後に、固定ページは表示されるが、投稿したページが表示されなくて困る、という方も多いのでは。

各ファイルやディレクトリの所有者(apache)や権限(660 等)も確認したが問題ない。なのに投稿ページが '404' エラーになる。

検索しても、なかなか適切なアドバイスがなかったので、メモしておきます。



(1) Wordpressフォルダ内の .httpacess の内容を確認する。

以下のような記述になっていれば大丈夫。

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

(2)VirtualHostを自分で書いている場合は

 <Directory /var/directory/to/your/wordpress>
   AllowOverride ALL
   Require all granted
  </Directory>

の設定を書いておく。

自分の場合、だいたい(2)で404エラーがでなくなります。
試してみてください。

2019年2月9日土曜日

Vimの便利な使い方

◇行番号の表示
表示
:set number
非表示
:set nonumber

2019年2月8日金曜日

Wgetコマンドに関するトラブル対応


・wgetでフォルダを指定してダウンロードできない時の対策
・PIPでインストールしたwgetが認識されない


wgetでフォルダを指定してダウンロードできない時の対策
githubのファイルをダウンロードする場合、目的のファイルのrawが見れるurlがファイルディレクトリ
が、ファイル単体のURLとなる。

・カレントディレクトリからwgetを実行するとファイルをダウンロードできる。
wget https://raw.githubusercontent.com/xxxx/xxxx/xxxx.csv

・-Pオプションでダウンロード先のフォルダを指定してダウンロードすると
wget -p /var/xxx/xxx/ https://raw.githubusercontent.com/xxxx/xxxx/xxxx.csv
sheme missingというエラーになり、root directoryに
raw.githubusercontent.com/xxxx/xxxx/というフォルダが作成され
xxxx.csvがダウンロードされる。

schme missingは、http://xxx.xxx.xx 等のURLに’’が付いているとエラーになるという投稿を多く見るが、それだけではないよう。上記現象は、オプションpを小文字にしたら発生した。オプションは -Pと大文字にして解決。

wget -P /var/xxx/xxx/ https://raw.githubusercontent.com/xxxx/xxxx/xxxx.csv


・-Oオプションでダウンロード先のフォルダと新しいファイル名を指定してダウンロードすると上手くいく
wget -O /var/xxx/xxx/[保存時のファイル名] https://raw.githubusercontent.com/xxxx/xxxx/xxxx.csv


PIPでインストールしたwgetが認識されない
(wget の入手)
  $ pip install wget
  Successfully installed wget-3.2

(wgetがコマンドとして実行されない場合)

 これでwgetを取得すると、wgetというPython moduleがダウンロードされる。

 pip install wgetを再び実行すると、
 Requirement already satisfied: wget in /usr/lib/python2.7/site-packages (3.2)
 
 となり、site-packagesに格納されている事がわかる。

site-packages のディレクトリを確認すると、
>wget-3.2-py2.7.egg-info
>wget.py
>wget.pyc
>yum
などが格納されていることが分かる。

この場合、wgetを実行したい場合、
python -m wget [取得したいURL]
で、実行できる。

FLASKのRouting記述方法を忘れない為にメモ

* FLASKをサーバー環境で動かすときには、Confファイルでのバーチャルホストの書き方と、Flask APPでの Routeの記載の仕方、htmlのactionの書き方が整合をとれていないと失敗するので、個人メモです。結構、苦労する。

VirtualHost
 <VirtualHost *:80>
   ServerName mossymob.tk
   DocumentRoot /var/www/html
   WSGIDaemonProcess firstapp user=apache group=apache python-home=/home/venv_env/python37
   WSGIScriptAlias /firstapp /var/www/html/firstapp/app.wsgi
                <Directory /var/www/html/firstapp>
                WSGIProcessGroup firstapp
                WSGIApplicationGroup %{GLOBAL}
                Require all granted
                </Directory>
   WSGIDaemonProcess secondapp user=apache group=apache python-home=/home/venv_env/python37
   WSGIScriptAlias /secondapp /var/www/html/secondapp/app.wsgi
                <Directory /var/www/html/secondapp>
                WSGIProcessGroup secondapp
                WSGIApplicationGroup %{GLOBAL}
                Require all granted
                </Directory>

*WSGIScript Aliasの第一引数は、app.wsgiファイルを配置したファイルまでのディレクトリを、ドキュメント・ディレクトリ配下の部分を書く。

1. app.py

@app.route('/python', methods=['GET', 'POST']) <- インデックスルートだけだとセッションが変わらない。
def index():
   if int(session["current_question"]) in xxxxxx
             redirect(url_for('index'))
             return render_template("end_summary.html")
  return render_template('main.html')

@app.route('/check',methods=['GET','POST'])
def check_answer():

 return render_template('check.html')




2. main.html

<button type="submit"  formaction="/firstapp/python" >Answer</button>
<button type="submit"  formaction="/firstapp/check" >Hint</button>


*PCのバーチャル環境でテストしているように、通常の/pythonのようにTargetのrouteの第一引数だけ記述すると、ボタンをクリックするとjump先のURLが、ドキュメント・ルート/pyhonとなってしまい、404未検出というエラーになる。必ず、ドキュメントルート以下の全ディレクトリ・ルートを記載する。

3.check.html
<input type='submit' value='問題に戻る' formaction="/firstapp//python" /> 

4. end_summary.html
<button type="submit" id="r7" name='startover' formaction="/firstapp//python" class="btn btn-outline-success btn-sm m-1" value='shuffle' >


 
 
全ての処理は、

/firstapp/python で処理される。

2019年2月5日火曜日

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8e in position 87: invalid start byte

PythonでCSVファイルを読み込むとき、以下のようなエラーコードが出ることがある。
特に、windowsのexcelでcsvが作成されていたりすると、エンコードが問題になることが良くあります。

このポストでは、この問題に対応する仕方をメモしておきます。。

1. 文字エンコードの復習。

*ASCII -- 最も基本的な文字コード。 半角英数字128文字から構成されており、全ての文字を1バイトで表します。例えば、「A」は、0x41(0xは16進数を表す。)

*UTF-8 -- 全ての文字を1~4バイトで表します。 世界中の文字を扱えるために、標準的に使われるようになりました。 Pythonの基本のエンコードになります。 UTF-8には、「バイト・オーダー・マーク(BOM)」の有無のオプションがあります。 (Excel形式を保持したい場合、「BOMあり」になります。) 
Pythonで標準のcsvモジュールで、BOMありのUTF-8を読む場合は 、open()関数に encoding='utf_8_sig' と指定します。すると、最初の文字が '\ufeff ' になります。

逆にBOMなしUTF-8を指定して読むと、普通に読めて問題ありません。

*Shift-JIS -- パソコンで利用された日本語の文字コード。 全ての文字を2バイトで表します。

*Code Page932(cp932) -- Windows環境の日本語の文字コード。Shift-JISの一つのバリエーション。

2. CSVファイルのエンコードの判定
open()関数に、開きたいcsvが利用しているエンコードを指定しなくてはいけないので、どの文字コードを利用しているか判定するツール。

1) cardet を利用する。
(https://pypi.org/project/chardet/ )

これで判別できるのは、

  • ASCII, UTF-8, UTF-16 (2 variants), UTF-32 (4 variants)
  • Big5, GB2312, EUC-TW, HZ-GB-2312, ISO-2022-CN (Traditional and Simplified Chinese)
  • EUC-JP, SHIFT_JIS, CP932, ISO-2022-JP (Japanese)
  • EUC-KR, ISO-2022-KR (Korean)
  • KOI8-R, MacCyrillic, IBM855, IBM866, ISO-8859-5, windows-1251 (Cyrillic)
  • ISO-8859-5, windows-1251 (Bulgarian)
  • ISO-8859-1, windows-1252 (Western European languages)
  • ISO-8859-7, windows-1253 (Greek)
  • ISO-8859-8, windows-1255 (Visual and Logical Hebrew)
  • TIS-620 (Thai)
  • だそうです。

    2)自作のモジュールを利用する(未検証。 メモです。)
      
    *getencモジュールのgetenc.getEncode()でファイルの文字コードの判別を行って、その文字コードをopen関数の引数として指定する。

    enc = getenc.getEncode ('anycsvfilename.csv')
    with open ('anycsvfilename.csv','r', encoding=en) as f:

    など。

    関数自身は、
    http://myfuturesightforpast.blogspot.jp/2015/01/auto-detecting-japanese-file-encoding.html
    参照。

    3)Linuxサーバー上のコマンドで確認
    > file -i [ファイル名]

    # file -i 増減率一覧.csv
    増減率一覧.csv: text/plain; charset=unknown-8bit ・・読み込めないファイル

    # file -i prefectures.csv
    prefectures.csv: text/plain; charset=utf-8

    3. エラー対処

    エラー表示
    UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8e in position xx: invalid start byte
    (0x8e: EUC_JPで使われる制御文字?)

    ① CSVを以下の読み込みの記述にする。

    with open("myanyfilename.csv","r",newline='',encoding='utf_8') as f:
          csv_reader=csv.DictReader(f)

    *Python3.7 で、上記で読み込もうとした際のエラーメッセージ。
    encoding='EUC_JP' とすると読める。


    UnicodeDecodeError: 'cp932' codec can't decode byte 0xef in position 0: illegal multibyte sequence
    ① 以下のencoding用の記述で対処。

    with open("start.csv","r", encoding='utf-8_sig') as f:  #windows encoding用の記述

    但し、(windows環境でutf-8にファイル自体を変えておかないと、この記述をしても、読み込みエラーになる場合もある。)

    又、1つのファイルに複数のエンコード文字が入っていると、これだけで対処は難しい。


    4.究極の対応。

    Editorで、csvファイルを開いて、utf_8 フォーマットで保存する。

    Excelだと、「csv(コンマ区切り)で保存。」だと、エンコードを変換してくれないが、
    新しいExcel(少なくてもOffice365)では、、「csv utf-8 (コンマ区切り)で保存。」すれば、エンコードを変更してくれる。

    csvのサイズも大きくないので、これで、今のところ正しく読みこみできるようになる。
    いちいち、open関数の引数で、各々のエンコードを指定しなくても良いので、便利ではある。

    自分で、Python csvモジュールでcsvを作成する場合、encoding='utf-8' を指定して書き込めば、
    大丈夫。

    以上 :)

    2019年2月1日金曜日

    Flask Session 遷移の例

    **これは、個人的なメモです。 第三者がみても、分かりません。non-indexのページです。**


    CookieSession ID)の確認は、

    Chrome -> Developper Tool -> Application Tab -> 右側コラムのリストの真中下あたりのcookieで確認。

     

    ◆通常操作時のクッキー(セッションIDの遷移)

    ロードした時のクッキー(SessionID)

    eyJjdXJyZW50X3F1ZXN0aW9uIjoiMSJ9.DzWPsQ.PIVPKVBFCYo41pTUXsHhv-gbkH0

    解答した後のクッキー

    eyJjdXJyZW50X3F1ZXN0aW9uIjoyfQ.DzWQFA.4uLnC0q306BPXWLKldKVvuR2QB8

    ヒントボタンをクリックして、ヒントページ移動後のクッキー(変化なし)

    eyJjdXJyZW50X3F1ZXN0aW9uIjoyfQ.DzWQFA.4uLnC0q306BPXWLKldKVvuR2QB8

    解答選択なしで、「問題に戻るボタンを押した後のクッキー

    eyJjdXJyZW50X3F1ZXN0aW9uIjoyfQ.DzWQgw.O-xyQ8G5hwyX1TSwEsBvfWqEG84

    再度、ヒントボタンをクリックして、ヒントページ移動後のクッキー(変化なし)

    eyJjdXJyZW50X3F1ZXN0aW9uIjoyfQ.DzWQgw.O-xyQ8G5hwyX1TSwEsBvfWqEG84

    解答選択して「問題に戻るボタン」をクリックした後のクッキー

    eyJjdXJyZW50X3F1ZXN0aW9uIjozfQ.DzWRLQ.i2F68aM41-N1jhfSlHpjvhqIkSw

     

    ◆第1問目に特化した動き

    i) Hintページで問題を選択して戻る。

    ロードした時のクッキー(SessionID)

    eyJjdXJyZW50X3F1ZXN0aW9uIjoiMSJ9.DzWSGw.M-yFCEF-kPNPcRujcn54K3UcE7s

    ヒントボタンを押した時のクッキー(変化なし)

    eyJjdXJyZW50X3F1ZXN0aW9uIjoiMSJ9.DzWSGw.M-yFCEF-kPNPcRujcn54K3UcE7s

    解答選択して、「問題に戻るボタン」をクリックした後のクッキー

    eyJjdXJyZW50X3F1ZXN0aW9uIjoyfQ.DzWT8w.JHRPJPeBXoz3Hf60nRShDr_--6s

     

    ii) Hintページで問題を選択しないで戻る

    ロードした時のクッキー(SessionID)

    eyJjdXJyZW50X3F1ZXN0aW9uIjoiMSJ9.DzWWCg._xd4LxDaujaLsdQuonsCO6WcqQk

    ヒントボタンを押した時のクッキー(変化なし)

    eyJjdXJyZW50X3F1ZXN0aW9uIjoiMSJ9.DzWWCg._xd4LxDaujaLsdQuonsCO6WcqQk

    解答選択なしで、「問題に戻るボタン」をクリックした後のクッキー

    eyJfZmxhc2hlcyI6W3siIHQiOlsiZXJyb3IiLCJQbGVhc2UgY2hvb3NlIGFuIGFuc3dlciJdfV19.DzWWdQ.2_VhTzTZpbplf0QeodkOuEjsoV4

    Chrome/IE ともに、end pageに遷移してしまった。)

     遷移したのは、
     
    elif:
     session["current_question"] not in random_q2、を
     int(session["current_question"] not in random_q2)
     
    で解決。

    Python FLASKのログインページ(サンプル)とFLASHメッセージ。

    'flash' は、htmlからのrequestに対して、Flaskで簡単にmessageをフィード・バックする仕組みです。

    Flaskのセッションを利用しています。 
    flask側: flash('メッセージ’)
    html側: {% with messages = get_flashed_messages() %}
    で、htmlにメッセージをフィード・バック(print-out)することが可能です。

    セッションを利用しているので、ブラウザやサーバー・サイドでcookieの長さに制限をかけている場合、失敗する場合があります。失敗した場合、メッセージが表示されないだけで、挙動自体に影響は与えません。



    login.py

    import os
    from flask import Flask, flash, redirect, render_template, request, url_for

    app = Flask(__name__)
    app.secret_key = os.urandom(24)

    @app.route('/')
    def index():
         return render_template('index.html')


    @app.route('/login', methods = ['GET', 'POST'])
    def login():
       error = None

       if request.method == 'POST':

            if request.form['username'] != 'admin' or request.form['password'] != 'admin':
              
               flash('Invalid username or password. Please try again!')
               return redirect(url_for('index'))
            
            else:          
               flash('You were successfully logged in')
               return redirect(url_for('index'))


       return render_template('login.html')

    if __name__ == "__main__":
       app.run(debug =True)

    index.html

    <!doctype html>
    <html>
       <head>
          <title>Flask Message flashing</title>
       </head>
       <body>
          {% with messages = get_flashed_messages() %}
             {% if messages %}
                <ul>
                   {% for message in messages %}
                   <li>{{ message }}</li>
                   {% endfor %}
                </ul>
             {% endif %}
          {% endwith %}

      <h1>Flask Message Flashing Example</h1>
          <p>Do you want to <a href = "{{ url_for('login') }}">
             <b>log in?</b></a></p>
       </body>

    </html>


    login.html

    <!doctype html>
    <html>
    <body>
          <h1>Login</h1>
          {% if error %}
             <p><strong>Error:</strong> {{ error }}
          {% endif %}

          <form action = "" method = post>
             <dl>

                <dt>Username:</dt>
                  <dd>
                    <input type = text name = username value = "{{request.form.username }}">

                  </dd>          
                   <dt>Password:</dt>
                  <dd>
                    <input type = password name = password>

          </dd>
             </dl>
             <p> <input type = submit value = Login> </p>
          </form>
       </body>
    </html>


    ブラウザで確認。

    1) index.htmlに最初にアクセスしたとき




    2) ログイン・ページに遷移して、間違ったuser nameとpasswordを入力




    3) FLASH MESSAGEが、index.htmlに表示される。





    4) FLASH MESSAGEが、index.htmlに表示される。
        正しいログイン名とパスワードを入れる。