「技術」カテゴリーアーカイブ

【C#】【アルゴリズム】約数を列挙する

値Nが持つ約数を列挙するアルゴリズムです。

        /**
         * 引数Nの約数をリストで返す
         * 
         * @param N 約数を求める値
         * @return Nの約数のリスト
         */
        public List<long> CalculateIsprimeList(long N)
        {
            List<long> list = new List<long>();
            for (long i = 2; i * i <= N; i++)
            {
                if (N % i != 0)
                {
                    continue;
                }
                list.Add(i);
                if(i != N / i)
                {
                    list.Add(N / i);
                }
            }

            list.Sort();
            return list;
        }

前回の素数判定のコードと似ています。

小さい値から、Nの約数を求めていき、約数だった場合、その値と商も約数として出力します。

【数学】【PYTHON】連立方程式を解く

2点を通る直線のグラフを書く、の前に、連立方程式を解くコードを書いてみます。

from sympy import Symbol, solve

a = Symbol('a')
b = Symbol('b')
ex1 = a + b - 1
ex2 = 5 * a + b - 3

print(solve((ex1, ex2)))
:~/python$ python3 simultaneous_equations.py 
{a: 1/2, b: 1/2}

上のコードは1=a + b、3 = 5a + bの解を求めるコードです。

文字a,bをSymbolとして定義することによって、

ex1,ex2に式を設定し、それをsolve()にタプル式として渡します。

そうすると、解が出力されます。

Pythonすげぇ。

RUST勉強中、8/21の積み上げ

前回の続き

データベースに追加する処理と削除する処理を作成していきます。

まず、フォームのデータを取得するのにserdeクレートを使用します。

[package]
name = "todo"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
actix-web = { version = "4.1" }
actix-rt = { version = "2.7" }
thiserror = { version = "1.0" }
askama = { version = "0.11" }
rusqlite = { version = "0.28", features=["bundled"] }
r2d2 = { version = "0.8" }
r2d2_sqlite = { version = "0.21" }
serde = { version = "1.0", feature = ["derive"] }

次に追加、削除のパスを作成していきます。

まずは追加処理。

#[post("/add")]
async fn add_todo (
    params: web::Form<AddParams>,
    db: web::Data<r2d2::Pool<SqliteConnectionManager>>,
) -> Result<HttpResponse, MyError> {
    let conn = db.get()?;
    conn.execute("INSERT INTO todo (text) VALUES (?)", &[&params.text])?;
    Ok(HttpResponse::SeeOther()
        .header(header::LOCATION, "/")
        .finish())
}

同じように削除処理。

#[post("/delete")]
async fn delete_todo(
    params: web::Form<DeleteParams>,
    db: web::Data<r2d2::Pool<SqliteConnectionManager>>,
) -> Result<HttpResponse, MyError> {
    let conn = db.get()?;
    conn.execute("DELETE FROM todo WHERE id=?", &[&params.id])?;
    Ok(HttpResponse::SeeOther()
        .header(header::LOCATION, "/")
        .finish())
}

そして、追加・削除のパスをサーバに登録。

#[actix_rt::main]
async fn main() -> Result<(), actix_web::Error> {
    let manager = SqliteConnectionManager::file("todo.db");
    let pool = Pool::new(manager).expect("Failed to inithialize the connection pool.");
    let conn = pool.get().expect("Failed to get the connection from the pool.");
    conn.execute(
        "CREATE TABLE IF NOT EXISTS todo (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            text TEXT NOT NULL
        )",
        params![],
    )
    .expect("Failed to create a table 'todo'.");
    HttpServer::new(move || {
        App::new()
        .service(index)
        .service(add_todo)
        .service(delete_todo)
        .data(pool.clone())
        })
        .bind("0.0.0.0:8080")?
        .run()
        .await?;
    Ok(())
}

ソースコードにおけるコメントについて。

プログラマーを悩ませる問題の一つとして、コメントがあると思います。

基本的にコメントには正しいことを書かなければいけないのですが

修正を加えられることによって、コメントと内容が異なってしまうことが多々ありまして

コメントと実装が異なると、のちにコードをメンテナンスするプログラマーは混乱します。

で、コメントはどれくらいの頻度であるべきか?ですが、

これはプロジェクトにもよりまして、

1行1コメントとルールが定められているプロジェクトもあれば、

コメントを残してはいけないというプロジェクトもあります。

まぁ、これは両極端の例ですが。

傾向としては、C言語はコメントを残せというケースが多いように思います。

C言語は関数名、変数名を長くするのは好ましくないという印象があります(偏見

だから意味を極端に省略していった結果、コメントがないとコードが理解できない、という結果になります。

逆にJavaなどのオブジェクト指向言語は比較的コメントが少ないように思います。

こちらは関数名、引数名だけで意味が伝わるように命名しなければならない、という傾向が強いので、

コメントがなくても、関数名、変数名である程度意味が伝わったりします。

そこを突き詰めていった結果、コメントが必要なコードが好ましくない、という考えに行き着いたんでしょうね。

コメントといえば。

昔のプロジェクトはSVNやgitなどのソースコードのバージョン管理の仕組みがなかったので、

ソースコードに修正履歴を残しなさい、というルールが存在していました。

昔のエディターはコメントを色付きで表示する機能も無かったので、

一生懸命解析していたところがコメント化した変更前のコードだった、

ということがよくありました。

現在はこういった修正前のコードは残すのは逆に好ましくないとされています。

そう言うのはgitなどで管理してくれるので。

便利な世の中になったもんだ。

【C#】【アルゴリズム】素数かどうかを判定するアルゴリズム

値Nが素数かどうかを判定するには、2~√Nで割り切れなければ素数らしい。

        /**
         * 引数Nが素数かどうかを判定する
         * 
         * @oaram N 素数判定する値
         * @return 素数:true/素数でない:false
         */

        public bool isprime(long N)
        {
            for(long i = 2; i * i <= N; i++)
            {
                if(N % i == 0)
                {
                    return false;
                }
            }
            return true;
        }

【数学】【PYTHON】いろいろな関数のグラフを表示する

もっと複雑なグラフを描画するには、もっと細かい単位でxの値を変化させなければなりません。

なので、pythonのnumpyライブラリを使用します。

import matplotlib.pyplot as plt
import numpy as np

def func1(x):
    return 3 * x

x = np.arange(-1.0, 1.01, 0.01)
y = func1(x)

plt.plot(x, y)
plt.grid(color='0.8')
plt.show()

npを使用するもう一つのメリットは、yの計算にfor文を使用する必要がなく、

1行で書くことができるということです。

なるほど、pythonが支持される理由はここにあるかもしれない。

RUST勉強中、8/13の積み上げ

前回の続き。

indexにダミーデータを使用していましたが、

この部分を実際のDBのデータを表示するようにしています。

use actix_web::{get, web, App, HttpResponse, HttpServer, ResponseError};
use thiserror::Error;
use askama::Template;
use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager;
use rusqlite::params;

struct TodoEntry {
    id: u32,
    text: String,
}

#[derive(Template)]
#[template(path = "index.html")]
struct IndexTemplate {
    entries: Vec<TodoEntry>,
}

#[derive(Error, Debug)]
enum MyError {
    #[error("Failed to render HTML")]
    AskamaError(#[from] askama::Error),

    #[error("Failed to get connection")]
    ConnectionPoolError(#[from] r2d2::Error),

    #[error("Failed SQL execution")]
    SqliteError(#[from] rusqlite::Error),
}

impl ResponseError for MyError {}

#[get("/")]
async fn index(db: web::Data<Pool<SqliteConnectionManager>>) -> Result<HttpResponse, MyError> {
    let conn = db.get()?;
    let mut statement = conn.prepare("SELECT id, text FROM todo")?;
    let rows = statement.query_map(params![], |row| {
        let id = row.get(0)?;
        let text = row.get(1)?;
        Ok(TodoEntry { id, text })
    })?;

    let mut entries = Vec::new();
    for row in rows {
        entries.push(row?);
    }

    let html = IndexTemplate { entries };
    let response_body = html.render()?;
    Ok(HttpResponse::Ok()
        .content_type("text/html")
        .body(response_body))
}



#[actix_rt::main]
async fn main() -> Result<(), actix_web::Error> {
    let manager = SqliteConnectionManager::file("todo.db");
    let pool = Pool::new(manager).expect("Failed to inithialize the connection pool.");
    let conn = pool.get().expect("Failed to get the connection from the pool.");
    conn.execute(
        "CREATE TABLE IF NOT EXISTS todo (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            text TEXT NOT NULL
        )",
        params![],
    )
    .expect("Failed to create a table 'todo'.");
    HttpServer::new(move || App::new().service(index).app_data(pool.clone()))
        .bind("0.0.0.0:8080")?
        .run()
        .await?;
    Ok(())
}

前回の記事で、

テキストではdata(pool.clone())を使用していましたが、
ワーニングが出るので、調べたところ、
推奨されていない処理なので、app_dataを使え、と言うことでした。

と書きましたが、

app_data()を使用するとうまく動作せず、

解決策が見つからないので、

ひとまずdata()に戻しています。

【数学】【PYTHON】簡単な関数のグラフを表示する

こちらのコードを元に、簡単な関数のグラフを書いてみます。

今回はテキストにあるように、y=3x-24のグラフを表示させてみます。

import matplotlib.pyplot as plt

def func1(x):
    return 3 * x - 24

x = list(range(1,11))
y = []
for i in range(10):
    y.append(func1(x[i]))

plt.plot(x, y)
plt.grid(color='0.8')
plt.show()

簡単な関数(一次関数)ていどならこのコードでも問題無いですが、

二次関数とかになると、きれいなグラフを書くのは難しいです。

次回はそのようなグラフも書けるようにしてみます。

【数学】【PYTHON】グラフを表示する

今回から新しい章に入ります。

関数をグラフに表示しようってやつ。

まずは、グラフを表示するライブラリを使えるようにします。

matplotlibというモジュールを使用します。

$ sudo apt-get install python3-matplotlib
import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5, 6, 7]
y = [64.3, 63.8, 63.6, 64.0, 63.5, 63.2, 63.1]

plt.plot(x, y)
plt.grid(color='0.8')
plt.show()

RUST勉強中、7/31の積み上げ

askamaクレートを使用することにより、htmlテンプレートを使用してWebページを作成することができます。

表示するデータは将来的にはデータベースを使用するのですが、

それはまた次回の話なので、今回はダミーデータを使用しています。

[package]
name = "todo"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
actix-web = { version = "4.1" }
actix-rt = { version = "2.7" }
thiserror = { version = "1.0" }
askama = { version = "0.11" }
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <title>Todo App</Applet></title>
</head>

<body>
    <div>
        {% for entry in entries %}
        <div>
            <div>id: {{ entry.id }}, text: {{ entry.text }}</div>
            <form action="/delete" method="post">
                <input type="hidden" name=""id" value="{{ entry.id }}">
                <button>delete</button>
            </form>
        </div>
        {% endfor %}
    </div>

    <form action="/add" method="post">
        <div>
            <input name="text">
        </div>
        <div>
            <button>add</button>
        </div>
    </form>
</body>
</html>
use actix_web::{get, App, HttpResponse, HttpServer, ResponseError};
use thiserror::Error;
use askama::Template;

struct TodoEntry {
    id: u32,
    text: String,
}

#[derive(Template)]
#[template(path = "index.html")]
struct IndexTemplate {
    entries: Vec<TodoEntry>,
}

#[derive(Error, Debug)]
enum MyError {
    #[error("Failed to render HTML")]
    AskamaError(#[from] askama::Error),
}

impl ResponseError for MyError {}

#[get("/")]
async fn index() -> Result<HttpResponse, MyError> {
    let mut entries = Vec::new();
    entries.push(TodoEntry {
        id: 1,
        text: "First entry".to_string(),
    });
    entries.push(TodoEntry {
        id: 2,
        text: "Second entry".to_string(),
    });

    let html = IndexTemplate { entries };
    let response_body = html.render()?;
    Ok(HttpResponse::Ok()
        .content_type("text/html")
        .body(response_body))
}



#[actix_rt::main]
async fn main() -> Result<(), actix_web::Error> {
    HttpServer::new(move || App::new().service(index))
        .bind("0.0.0.0:8080")?
        .run()
        .await?;
    Ok(())
}