nprogram’s blog

気ままに、プログラミングのトピックについて書いていきます

Python 仮想環境で楽々モジュール管理 [Windows]

はじめに

pythonで、モジュール管理が大変だと思いませんか?

仮想環境を使用することで、他の環境に影響を与えずに、モジュールをインストールすることが可能です。

環境

OS : Windows 10 (version : 1809)

仮想環境の作成と実行

  1. 仮想環境は以下のコマンドで作成することができます。以下のコマンドを実行することで、ディレクトリ直下に環境名のフォルダーが作成されます。

コマンド : python -m venv [環境名]

例 : python -m venv test

  1. 次に、作成した仮想環境のフォルダーに移動します。(cd test)

  2. 念のため、cdコマンドで現在のディレクトリ階層を確認します。(cd)

  3. dirコマンドで、現在のディレクトリのファイルも確認してください。(dir)

  4. そして、以下のコマンドを実行して、仮想環境を有効にします。

コマンド : Scripts\activate

(test) C:\Users\(あなたのディレクトリ階層)\test>

仮想環境でモジュールのインストールしたモジュールを他の環境でも再現させる

モジュールのインストールは以下のコマンドで実行できます。

pip install [モジュール名]

環境でインストールしたパッケージはpip listコマンドで確認可能です。

または、pip freezeコマンドで確認可能です。

ここで、以下のコマンドで、パッケージリストをテキストファイルに保存します。 pip freezeはバージョン情報も付加するため、バージョンの違いによる動作の違いをなくすことができます。

pip freeze > requirements.txt

このファイルを別の仮想環境のフォルダーにコピーします。 別の仮想環境を有効にして、以下のコマンドを実行することで、まとめてパッケージをインストールします。 pip install -r requirements.txt

仮想環境の終了

仮想環境を終了する場合は、deactivateコマンドを入力します。

参考情報

あとがき

仮想環境とpip freezeコマンドによって、バージョンの差異に悩まされることなく、プログラム実行に必要なパッケージをすばやく取得することができます。仮想環境はとても便利なので、ぜひ使用してみてください。

Django学習 (Djangoサーバー作成とDjango上でアプリケーション実行)

はじめに

Djangoの環境を構築するための学習内容を記載します。

環境

  • Windows 10 (version 1809)
  • Python version : 3.7.1
  • Django version : (2, 1, 7, 'final', 0)

注意点

  • 現在どのディレクトリ階層にいるか、コマンド実施前に必ず確認しましょう (コマンドcdで確認)
  • 現在のディレクトリ階層直下のファイルを把握しましょう (コマンドdirで確認)
  • Djangoサーバーへのアクセスは、httpは可能ですが、httpsでは本記事では実施できません。

Djangoのプロジェクトを作成する

  1. Pythonのインストール インストールディレクトリがわからなくなった場合は、Pythonをアンインストール後、Pythonをディレクトリ指定でインストールします。 そのとき、環境設定にPATHも通すことができるため、PATHも通しましょう。

  2. Pythonのバージョン確認 (python --version)

  3. Pythonのインストールディレクトリ確認(where python)

  4. 仮想環境(virtual environment (virtualenv))のインストール (python -m venv temp)

  5. ディレクトリ移動 (cd temp)

  6. 仮想環境を使用する (Scripts\activate)

  7. pipを最新版にする (python -m pip install --upgrade pip)

  8. Djangoのモジュールをインストールする (pip install Django)

  9. モジュールバージョンを確認する (pip list)

  10. プロジェクトを作成する (django-admin startproject myapp)

myapp
├── manage.py
└── myapp
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

Djangoのサーバーを起動する

  1. ディレクトリを移動する(cd myapp)

  2. Djangoのサーバーを起動する(python manage.py runserver)

  3. Webブラウザでhttp://localhost:8000/を入力する。

f:id:nprogram:20190223111042p:plain

アプリケーション作成して、実行する

bbsで簡単なメッセージを表示します。

(1) manage.pyが直下にいるディレクトリで、python manage.py startapp bbsのコマンドを実行する f:id:nprogram:20190223143122p:plain

(2) Webサーバーのメッセージに応じて、index関数がHello worldを返します。 HttpResponse関数を使用するため、importすること。

bbs/views.py

from django.shortcuts import render
from django.http import HttpResponse

def index(request):
    return HttpResponse('Hello world')

(2) bbs/views.pyのプログラムを呼び出す用にルーティングする。 ルーティングは、WebサーバーのURLとプログラムを紐づける仕組み。 Djangoでは、プロジェクト全体とアプリケーションの2段階でルーティングを行う。

まず、プロジェクト全体のルーティングを行う。 myapp/urls.pyファイルは、urlresolverをつかったURLのパターンのリストを含んでいます。 urlspatternsリストの中でpath関数を呼び出す。path関数を呼び出しているため、includeすること。

urls.py

from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('bbs/', include('bbs.urls'))
    path('admin/', admin.site.urls),
]

(3) bbsフォルダーの中に、urls.pyファイルを作成する 次にbbsアプリケーション側のルーティングを設定する。

bbs/urls.py

from django.urls import path
from . import views

urlpatterns = {
    path('', views.index, name='index')
}

(4) setting.pyを開いて、アプリケーションを登録する

INSTALLED_APPS = [
    'bbs.apps.BbsConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

(5) サーバーを起動していなかったら、python manage.py runserverでサーバーを起動しましょう。

(6) Webブラウザでhttp://localhost:8000/bbsを入力する。Hello worldと表示される。

f:id:nprogram:20190223173130p:plain

スーパーユーザーの作成

次に、スーパーユーザーを作成します。ディレクトリの位置を確認しながら、実行しましょう。

(temp) C:\Users\uv2ut\PycharmProjects\temp\myapp>dir

 C:\Users\uv2ut\PycharmProjects\temp\myapp のディレクトリ

2019/02/23  20:40    <DIR>          .
2019/02/23  20:40    <DIR>          ..
2019/02/23  20:37                 7 .gitignore
2019/02/23  15:10    <DIR>          bbs
2019/02/23  14:24                 0 db.sqlite3
2019/02/23  14:22               552 manage.py
2019/02/23  14:24    <DIR>          myapp
2019/02/24  20:46               370 README.md
               4 個のファイル                 929 バイト
               4 個のディレクトリ  713,390,907,392 バイトの空き領域

(temp) C:\Users\uv2ut\PycharmProjects\temp\myapp>python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying sessions.0001_initial... OK

(temp) C:\Users\uv2ut\PycharmProjects\temp\myapp>python manage.py createsuperuser
Username (leave blank to use 'uv2ut'): admin
Email address: abcd@abcd.com
Password:
Password (again):
This password is too short. It must contain at least 8 characters.
This password is too common.
This password is entirely numeric.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.

管理サイトの有効化

管理サイトを表示させてみましょう。

python manage.py runserver で開発用サーバを起動します。

http://127.0.0.1:8000/admin/ にブラウザでアクセスします。

初回の $ python manage.py createsuperuser で初期化したスーパーユーザー admin/hogefuga でログインします。

実行イメージ

f:id:nprogram:20190225080433p:plain

まとめ

今回は、コマンドベースで、Djangoサーバー作成。サーバー上でWebアプリケーション実行。管理サイトの表示まで実行しました。

IDEであるPyCharm上で開発できる方法も調べて記事にできればと思います。

補足

自動作成されたデータベースファイルは、こんな感じです。

DB.Browser.for.SQLiteは無料で使用できるため、データベースを確認するときはおすすめです。

f:id:nprogram:20190225081512p:plain

参考情報

Python3の関数アノテーションの記載方法

はじめに

C++やC#の異なり、Pythonのコードは、関数に引数や戻り値の型を書かなくても問題ありません。

ただし、あとのコード見やすさを考慮すると、関数アノテーションを書いたほうがいいと思います。

関数アノテーションの書き方

  • 関数の引数の型の場合
  • 関数の引数名の後にコロンを付けてに型を記載する
  • 関数の戻り値の場合
  • 引数の閉じカッコの後に、矢印->を付けて戻り値の型を記載する

関数アノテーションなし

def judge_perfect_number(str) :
    return string

関数アノテーションあり

def judge_perfect_number(str : string) -> str:
    return string

参考リンク

TeXで綺麗な数式を書きたい

はじめに

ブログに数式を乗せたい場合があると思います。そのときは、TEXを使用すると、きれいに表示できます。

hatenaブログの場合

K-means法


\begin{align}
min=\sum_{i=1}^n\sum_{x \in X_i}||x - \mu||^2
\end{align}
<div align="center">[tex:
\begin{align}
min=\sum_{i=1}^n\sum_{x \in X_i}||x - \mu||^2
\end{align}
]</div>

Qiitaの場合

Qiitaの場合では以下のようにします。ただし、hatenaではうまく表示できません・・・。

K-means法

\begin{align}
min=\sum_{i=1}^n\sum_{x \in X_i}||x - \mu||^2
\end{align}

参考

抽出・変換・統計をC++テンプレートメソッドで解く [C++]

はじめに

抽出・変換・統計をC++テンプレートメソッドで解きたいと思います。

  • std::accumulateとラムダ式
  • C++テンプレートメソッド
  • C++17畳み込み式、単項右畳み込みでコンパイル時に値を計算
#include <iostream>
#include <algorithm> //copy_if, for_each, transform
#include <vector>
#include <array>
#include <numeric> //iota, accumulate
#include <cassert>
using namespace std;


//C++テンプレートメソッドで解く
template <class T>
auto filter_map_fold(const T& nums)
{
    auto sum = 0;
    for (const auto num : nums) {
        sum += ((num%2==1)? num*2 : 0);
    }
    return sum;
}

//C++17畳み込み式、単項右畳み込みでコンパイル時に値を計算
template<typename... Args> 
constexpr auto filter_map_fold_constexpr(Args... args)
{
   return (((args%2==1)? args*2 : 0) + ...);
}

int main(void){
    // 指定された値から始まる整数列を生成する
    std::array<int, 10> nums;
    std::iota(nums.begin(), nums.end(), 1);
    
    constexpr auto ANSWER = 50;

    //std::accumulateで、答えを求める
    const auto result1 = std::accumulate(nums.cbegin(), nums.cend(), 0, 
        [](int acc, int n) { return (n%2==1)? acc+n*2 : acc; }
    );
    std::cout << "result1 : " << result1 << std::endl;
    assert(result1 == ANSWER);
    
    const auto result2 = filter_map_fold(nums);
    std::cout << "result2 : " << result2 << std::endl;
    assert(result2 == ANSWER);
    
    //C++17畳み込み式で、コンパイル時に答えを求める
    constexpr auto result3 = filter_map_fold_constexpr(1,2,3,4,5,6,7,8,9,10);
    std::cout << "result3 : " << result3 << std::endl;
    static_assert(result3 == ANSWER);
}

templateクラスを用いて、C++で抽出・変換・集計処理を行います

はじめに

templateクラスを用いて、C++で抽出・変換・集計処理を行います。

#include <iostream>
#include <algorithm> //copy_if, for_each, transform
#include <vector>
#include <array>
#include <numeric> //iota, accumulate
#include <cassert>
using namespace std;

void print_num(int num){
    std::cout<< num << std::endl;
}

//int filter_map_fold(const std::vector<int>& nums)
//以下のように宣言を変えるとnumsはvectorでもarrayでも良くなる
template <class T>
auto filter_map_fold(const T& nums)
{
    std::vector<int> odds;
    
    // filter(抽出)(奇数を抽出)
    std::copy_if(nums.begin(), nums.end(), std::back_inserter(odds), [](int num){ return num % 2;});
    
    // 表示内容を確認
    std::for_each(odds.begin(), odds.end(), [](int n){ std::cout << n << std::endl; });
    
    // Map(変換)(2倍する)
    std::vector<int> doubles;
    std::transform(odds.begin(), odds.end(), std::back_inserter(doubles), [](int num){ return num * 2; } );
    
    // 表示内容を確認
    std::for_each(doubles.begin(), doubles.end(), [](int n){ std::cout << n << std::endl; });
    
    // fold(集計)(統計する)
    int result = std::accumulate(doubles.begin(), doubles.end(), 0, [](int acc, int n) { return acc + n;});
    
    return result;
}

int main(void){
    // 指定された値から始まる整数列を生成する
    std::array<int, 10> nums;
    std::iota(nums.begin(), nums.end(), 1);
    
    constexpr auto ANSWER = 50;
    const int result = filter_map_fold(nums);
    std::cout << "result : " << result << std::endl;
    assert(result == ANSWER);
}

初期化構文 [C++17]

初期化構文

#include <iostream>
using namespace std;
int main(void){
    // Your code here!
    
    int test = 2;
    
    if (int x = 2; x > test)
    {
        std::cout << "xは変数testより大きい" << std::endl;
    }
    else if (x == test)
    {
        std::cout << "xは変数testと同じ値" << std::endl;   
    }
    else
    {
        std::cout << "xは変数testより小さい" << std::endl;   
    }
    
        switch (int x = 2)
    {
        case 2:
            std::cout << "xの値は" << x << "です。" << std::endl;
            break;
            
        default:
            break;
    }
}