2024年12月21日土曜日

Linux コマンド: 特定日時以降のファイルとディレクトリを検索する

 例えば、2023年6月1日以降に更新されたファイルとディレクトリを検索するには、以下のようにします。

$ find /path/to/search -newermt "2023-06-01"


2024年12月12日木曜日

Python クロージャーによるカウンタ作成

Pythonのクロージャーによるカウンタ作成

def counter():
    num = 0

    def add_one():
        nonlocal num
        result = num #JavaScriptの後置インクリメントに相当する操作で0始まりにする
        num += 1
        return result

    return add_one #関数を返す ()を付けない


counter1 = counter()

print(counter1()) #結果 0
print(counter1()) #結果 1
print(counter1()) #結果 2
print(counter1()) #結果 3

ポイント:

  • add_one()の中から外側の num を増加させること(Pythonでは nonlocal num とすることにより変数のスコープを変更)
  • return add_one  のように関数を返すこと(add_one()ではない)
  • PythonはJSのn++相当が無いので0始まりにする操作を追加
  • return文は最後に書く(returnの後で関数定義ができないため)

JavaScriptのクロージャーによるカウンタ作成基礎

JavaScriptのクロージャーによるカウンタ作成基礎

function counter() {
    let num = 0;
    return add_one; //関数を返す ()を付けない

    function add_one() {
        return num++; //後置インクリメントで0始まりにする(まずnを返してからn+1を実行)
    }
}

const counter1 = counter();

console.log(counter1()); //結果 0
console.log(counter1()); //結果 1
console.log(counter1()); //結果 2
console.log(counter1()); //結果 3

ポイント:

  • add_one()の中から外側の let num を増加させること
  • return add_one;  のように関数を返すこと(add_one()ではない)
  • n++で0始まりにすること

2024年11月29日金曜日

jQueryでscrollTop, scrollHeight, clientHeightを求める方法

 

scrollTop, scrollHeight, clientHeightをjQueryで求める方法です。

$(document).ready(function() {

    let element = $('#myDiv'); // 対象の要素


    let scrollTop = element.scrollTop();

    let scrollHeight = element[0].scrollHeight;

    let clientHeight = element[0].clientHeight;


    console.log('Scroll Top:', scrollTop);

    console.log('Scroll Height:', scrollHeight);

    console.log('Client Height:', clientHeight);

});


2024年10月9日水曜日

HTML テーブル アクセシビリティの例

HTML table accessibility

scope属性

<table class="table table-bordered">
  <caption>商品の販売データ</caption>
  <thead>
    <tr>
      <th scope="col">商品名</th>
      <th scope="col" colspan="2">販売数</th> <!-- 2列にまたがるヘッダー -->
      <th scope="col">総売上</th>
    </tr>
    <tr>
      <th scope="col"> </th> <!-- 空のセル -->
      <th scope="col">国内</th>
      <th scope="col">海外</th>
      <th scope="col"> </th> <!-- 空のセル -->
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">商品A</th>
      <td>100</td>
      <td>50</td>
      <td>150</td>
    </tr>
    <tr>
      <th scope="row">商品B</th>
      <td>200</td>
      <td>80</td>
      <td>280</td>
    </tr>
  </tbody>
</table>
商品の販売データ
商品名 販売数 総売上
国内 海外
商品A 100 50 150
商品B 200 80 280

headers属性

<table class="table table-bordered">
  <caption>商品の販売データ</caption>
  <thead>
    <tr>
      <th id="product">商品名</th>
      <th id="sales" colspan="2">販売数</th>
      <th id="total">総売上</th>
    </tr>
    <tr>
      <th> </th> <!-- 空のセル -->
      <th id="domestic">国内</th>
      <th id="international">海外</th>
      <th> </th> <!-- 空のセル -->
    </tr>
  </thead>
  <tbody>
    <tr>
      <td headers="product">商品A</td>
      <td headers="sales domestic">100</td>
      <td headers="sales international">50</td>
      <td headers="total">150</td>
    </tr>
    <tr>
      <td headers="product">商品B</td>
      <td headers="sales domestic">200</td>
      <td headers="sales international">80</td>
      <td headers="total">280</td>
    </tr>
  </tbody>
</table>
商品の販売データ
商品名 販売数 総売上
国内 海外
商品A 100 50 150
商品B 200 80 280

ARIA role属性

<table role="table" class="table table-bordered">
  <caption>商品の販売データ</caption>
  <thead role="rowgroup">
    <tr role="row">
      <th id="product" role="columnheader">商品名</th>
      <th id="sales" role="columnheader" colspan="2">販売数</th>
      <th id="total" role="columnheader">総売上</th>
    </tr>
    <tr role="row">
      <th> </th> <!-- 空のセル -->
      <th id="domestic" role="columnheader">国内</th>
      <th id="international" role="columnheader">海外</th>
      <th> </th> <!-- 空のセル -->
    </tr>
  </thead>
  <tbody role="rowgroup">
    <tr role="row">
      <td role="cell" headers="product">商品A</td>
      <td role="cell" headers="sales domestic">100</td>
      <td role="cell" headers="sales international">50</td>
      <td role="cell" headers="total">150</td>
    </tr>
    <tr role="row">
      <td role="cell" headers="product">商品B</td>
      <td role="cell" headers="sales domestic">200</td>
      <td role="cell" headers="sales international">80</td>
      <td role="cell" headers="total">280</td>
    </tr>
  </tbody>
</table>
商品の販売データ
商品名 販売数 総売上
国内 海外
商品A 100 50 150
商品B 200 80 280

2024年10月4日金曜日

正規表現で前後で同じ内容に一致させる場合には「バックリファレンス」

 例えば、 以下のようなパターンの場合

<foo@example.com<mailto:foo@example.com>> 

正規表現は

<(.+?)<mailto:(.+?)>> 

となりますが、前方の (.+?) と後方の (.+?) が同じ文字列であることを指定するには、2つ目のキャプチャグループに対してバックリファレンス (\1) を使用して以下のようにします。

<(.+?)<mailto:\1>>


2024年10月3日木曜日

Windows IISサーバーの停止

Windows 11に設置したIISサーバーを停止するコマンド

停止
> iisreset /stop

開始
> iisreset /start




2024年10月2日水曜日

Python: ジェネレーター作成方法

ChatGPTによる回答

#### 1. ジェネレーター式(generator expression)を使った方法

```python

data_a = [0, 1, 2, 3]

gen_a = (item for item in data_a)

```

このコードでは、**ジェネレーター式**(generator expression)を使ってジェネレーターを作成しています。ジェネレーター式は、リスト内包表記のような書き方で、`()` で囲むことでジェネレーターを生成する方法です。



#### 2. `yield` キーワードを使ったジェネレーター関数

関数の中で `yield` キーワードを使うと、ジェネレーターを作成できます。この方法は、ジェネレーター式より柔軟で、複雑な処理を行いたい場合に便利です。



```python

# ジェネレーター関数の定義

def my_generator():

    for i in range(4):

        yield i



# ジェネレーターの作成

gen_a = my_generator()



# 1つずつ値を取り出す

for value in gen_a:

    print(value)

```



このコードでは、`my_generator` 関数は `yield` を使って値を一つずつ返すジェネレーターを作成しています。



#### 3. `itertools` モジュールを使う

Pythonの標準ライブラリ `itertools` には、ジェネレーターを扱うための便利な関数が多数用意されています。いくつかの例を紹介します。



```python

import itertools



# 無限の数値を生成するジェネレーター

gen_a = itertools.count(start=0, step=1)  # 0, 1, 2, 3, ...



# リストの要素を繰り返すジェネレーター

data_a = [0, 1, 2]

gen_b = itertools.cycle(data_a)  # 0, 1, 2, 0, 1, 2, ...



# 要素を繰り返し指定回数生成するジェネレーター

gen_c = itertools.repeat('A', times=3)  # 'A', 'A', 'A'

```



これらのジェネレーターは、無限に続くものや、特定の条件に基づいて値を生成するものなど、多様な使い方ができます。



#### 4. `map` や `filter` 関数を使う

`map` や `filter` もジェネレーターの一種として機能します。`map` は関数を適用した結果を逐次生成し、`filter` は条件を満たす要素だけを生成します。



```python

# mapを使ったジェネレーター

data_a = [0, 1, 2, 3]

gen_a = map(lambda x: x * 2, data_a)  # 0, 2, 4, 6



# filterを使ったジェネレーター

gen_b = filter(lambda x: x % 2 == 0, data_a)  # 0, 2

```



### まとめ

- `()` を使った **ジェネレーター式**(質問の方法)

- `yield` を使った **ジェネレーター関数**

- `itertools` モジュールの関数を使ったジェネレーター

- `map` や `filter` での関数適用によるジェネレーター



これらが Python でジェネレーターを作成する主な方法です。用途に応じて最適な方法を選んでください。

2024年9月5日木曜日

WordPress: プラグインBogoを利用して翻訳した投稿を他のユーザーが編集できない場合

WordPressのBogoを利用して投稿を英訳しました。
他のユーザー(編集者権限)は、日本語(元言語)は編集できるのですが、英語の投稿が編集できません。

管理者のユーザー一覧で、他のユーザー(編集者権限)にアクセス権限を与えないといけませんでした。
以下の画面で英語にチェックを入れます。




2024年7月31日水曜日

Django: プロジェクト全体でテンプレートタグを使いたい

以下のような構成とします。

/myproject
/myproject/myproject
/myproject/myapp
/myproject/templates
/myproject/templatetags/__init__.py
/myproject/templatetags/custom_tags.py

settings.py

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')], #/myproject/templates
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
            'libraries': {
                'custom_tags': 'templatetags.custom_tags', #myproject/myproject以下にしたい場合はmyproject.templatetags.custom_tags とすればよい
            }
        },
    },
]

テンプレートの方で {% load custom_tags %} とすれば、自作テンプレートタグがプロジェクトで共用できるようになる。

2024年7月4日木曜日

MySQL プライマリキーのインクリメントをリセットする

MySQLでは、以下の手順でincrementを1に初期化できます。

MySQLのDBに接続して以下のalterコマンドを実行します。


$ use <データベース名>;

$ alter table <テーブル名> auto_increment = 1;


auto_increment = 10にすると、10から始まります。


参考 Djangoノウハウ集【データベース操作編】
https://sinyblog.com/django/knowledge/


Django: 今日の日付 datetime.date.today() が1日前になってしまう

settings.py で、タイムゾーン設定 USE_TZ が True になっている場合、DjangoはデフォルトでUTCを使用します。このため、表示時に適切なタイムゾーンに変換する必要があります。

Djangoのタイムゾーン設定を確認する:

# settings.py
USE_TZ = True  # タイムゾーン対応を有効にする
TIME_ZONE = 'Asia/Tokyo'  # サーバーのデフォルトタイムゾーンを設定する


ビューでのタイムゾーン変換:
Djangoのビューで、datetime.date.today()を使う場合は、タイムゾーンを考慮して今日の日付を取得します。

from django.utils import timezone
from datetime import date

def get_today_date():
    # 現在のタイムゾーンを取得
    current_tz = timezone.get_current_timezone()
    # 現在の日付と時刻を取得し、タイムゾーンを設定
    now = timezone.now().astimezone(current_tz)
    # 現在の日付を返す
    return now.date()

テンプレートでの表示:
Djangoのテンプレートで日付を表示する際には、タイムゾーンを考慮して表示します。

<!-- テンプレートファイル (例: my_template.html) -->
{% load tz %}

{% get_current_timezone as TIME_ZONE %}
{% localtime on %}
    <p>今日の日付: {{ today }}</p>
{% localtime off %}

2024年7月1日月曜日

Django: フォームのウィジエットテンプレート上書き

フォームのウィジェットテンプレートをDjangoアプリのテンプレートで上書きしたいとき
settings.py に以下の追加1、追加2部分が必要

INSTALLED_APPS = [
    'app.apps.AppConfig',  # マイアプリケーション
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.forms',  # 追加1
]

FORM_RENDERER = 'django.forms.renderers.TemplatesSetting' # 追加2
例: 以下のようにアプリ下のtemplatesにデフォルトのウィジェットテンプレートを保存する場合
/myproject/app_name/templates/django/forms/widgets/select_option.html

2024年6月25日火曜日

Django: django-debug-toolbarのパネルが表示されない

django-debug-toolbarを設定したところ右サイドバーは表示されたが、右サイドバー項目をクリックしたときメインの画面が表示されず困りました。

Django管理画面では表示されるのですが、公開ページでは表示されないという現象。


調べたところ、公開ページでページ内スクロールするJavaScriptコードがdjango-debug-toolbarとかぶっていたのが原因でした。

$('a[href^="#"]').click(function () { //・・・ }


一例ですが、以下のように公開ページのイベントの動作範囲を制限して表示できるようになりました。

$('.anker a[href^="#"]').click(function ()  { //・・・ }


参考:django-debug-toolbarが動かない - エンジニアもどきの技術メモ
https://chantsune.github.io/articles/122/


2024年5月11日土曜日

Linux findとgrepでファイル内文字列検索

# 現在のディレクトリ以下にある「xyz*」ファイル内に「aiueo」が含まれているものを検索する

$ find . -name 'xyz*' -type f -print0 | xargs -0 grep aiueo


# 現在のディレクトリ以下にあるphpファイル内に「aiueo」が含まれているものを検索する

$ find . -name '*.php' -print0 | xargs -0 grep aiueo


# /var/www/htmlディレクトリ以下にあるファイル内に「aiueo」が含まれているものを検索する

$ find /var/www/html -type f -print0 | xargs -0 grep aiueo


2024年5月10日金曜日

PHP URL文字列の取得まとめ

URL例: https://example.co.jp/ja/company/

$_SERVER['REQUEST_URI']; 
パスとクエリ取得(ファイル名あり)
⇒ /ja/company/index.html?year=2017&page=2 

$_SERVER['QUERY_STRING']; 
 クエリ取得(?は除外)
⇒ year=2017&page=2 

$_SERVER['SCRIPT_NAME'];
クエリを除外したパス(ファイル名あり) 
⇒ /ja/company/index.html 

str_replace($_SERVER['QUERY_STRING'],"",$_SERVER['REQUEST_URI']); 
ファイル名無しパス(末尾に?が残る)
⇒ /ja/company/?

2024年5月2日木曜日

PHP 連想配列をJSONにしてHTTP送信する



  $data = array();
  $data["name"] = 'tanaka';
  $data["age"] = 30;

  // 連想配列をJSON形式に変換する
  $json_data = json_encode($data);

  // HTTPヘッダを設定してJSONデータを送信する
  header("Content-Type: application/json");
  
  echo $json_data;

2024年4月11日木曜日

Django モデルフォームではModelでblank=Falseにするとrequired=Trueになる

Djangoのモデルからフォームを作りました。

forms.pyのほうでこんな感じで required=Trueにしました。

def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
        for field in self.fields.values():
            field.widget.attrs['class'] = 'form-control'
            field.widget.attrs['required'] = True

こうすると、inputにrequiredが追加されます。

このrequiredをテンプレートで判定するため以下のように

{% for field in form %}
    {% if field.required %}必須{% endif %}
{% endfor %}

とすればOKかと思ったら、field.required がどうしてもTrueになりません。

以下を参照すると {% if field.field.required %} にしろと書いてある。

Tell if a Django Field is required from template

それでも field.field.required はFalseのままでだめでした。

さらに以下を参照すると

Django: Make certain fields in a ModelForm required=False

you ought to add blank=True to the corresponding model

The documentation says

If the model field has blank=True, then required is set to False on the form field. Otherwise, required=True.

とありました。モデルのフィールドを blank=False にしないとテンプレートでは required=True 判定しないようです。

結論としては以下となります。

  • 必須にしたいモデルのフィールドを blank=False にする
  • テンプレートでは
    {% for field in form %}
        {% if field.field.required %}必須{% endif %}
    {% endfor %}
    のようにする。


2024年4月3日水曜日

ffmpeg 一括操作のコマンド (Windowsの場合)

ffmpeg 一括操作のコマンドのメモです。Windowsの例です。


複数のMP4ファイルから静止画を1枚ずつ保存する

> for %i in (./*.mp4) do ffmpeg -i ./%~ni.mp4 -ss 0 -t 1 -r 1 -f image2 ./%~ni.jpg

※この例は動画の0秒から1秒の間で1つの画像を保存するコマンド



音声の削除
> ffmpeg -i 入力ファイル名 -vcodec copy -an 出力ファイル名

音声の一括削除(no_soundフォルダ内に出力)
> for %i in (./*.mp4) do ffmpeg -i ./%~ni.mp4 -vcodec copy -an ./no_sound/%~ni.mp4