ラベル Python の投稿を表示しています。 すべての投稿を表示
ラベル Python の投稿を表示しています。 すべての投稿を表示

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の後で関数定義ができないため)

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年7月4日木曜日

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年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 %}
    のようにする。


2023年12月5日火曜日

Python: 現在のディレクトリ取得と変更

現在のディレクトリを取得

import os

cwd = os.getcwd()

print(cwd)  # /Users/demo-user/documents/mydir


ディレクトリを変更

os.chdir('/Library')

cwd = os.getcwd()

print(cwd)  # /Library



2023年9月22日金曜日

django-CMSでのチェック方法

django-CMS (https://www.django-cms.org)

$ python manage.py cms check

を実行すると保存されておらずorphanedになったものが発見される場合がある。
以下を実行して削除する。

$ python manage.py cms list plugins

$ python manage.py cms delete-orphaned-plugins


2023年8月10日木曜日

Python クロージャ―で文字列を連続して連結

Pythonでクロージャ―を使って文字列を連続して連結する方法です。
def add_string():
    string = ''
    def add_string_inner(new_string):
        nonlocal string
        string += new_string
        return string
    return add_string_inner
messages = add_string()

print(messages(''))     # 空白
print(messages('abc'))  # abc
print(messages('123'))  # abc123
print(messages('xyz'))  # abc123xyz

2023年8月3日木曜日

Python テキストファイルを1行ずつ読み込み処理する readlines と readline メソッド

readlines() ... テキストファイル内容を一気に読み込み、1行ずつリストにします。ファイルサイズがよほど大きくなければ通常はこれを使います。

readline() ... テキストファイルを1行ずつ読み込みます。すべての行に対する処理は少し工夫が要ります。

以下、TEST.txt の内容が、

あいうえお[改行]
[改行]
かきくけこ[改行]
さしすせそ

というものとします。

2023年7月14日金曜日

Python クラスの定義で (object) は要るのか要らないのか?

Pythonでのクラスの定義を見ると古い情報では以下のように (object) が付いていることが多い。

class NewStyleClass(object):


Python2では、何も継承しないクラスを記述する場合に以下のように記述する。

class MyClass: または class MyClass():

そして、objectクラスを継承したクラスというものがあり、以下のように記述する。

class MyClass(object):

Python2では、この2つは区別される。


Python3では、この3つはすべてobjectクラスを継承したクラスとなるため、同じものになる。そのため、Python3では以下のように簡潔に記述すればよい。

class MyClass:


参考: 新スタイルのクラスと旧スタイルのクラス


2023年5月15日月曜日

Django: shellでのモデルデータの取得方法

 $python manage.py shell

>>> from products.models import Product
>>> Product.objects.get(id=9)
<Product: レーザマシン>


>>> Product.objects.get(id=9).image
<FieldFile: products/product/9/photo1.jpg>


>>> Product.objects.get(id=9).image.name
'products/product/9/photo1.jpg'


>>> Product.objects.get(id=9).image.path
'/var/www/html/products/myproject/media/products/product/9/photo1.jpg'


参考
モデル (Model) - データアクセスの基礎 - Django 入門 - Python 入門
https://python.keicode.com/django/model-data-access-basics.php

2022年12月28日水曜日

JavaScript/Python: 配列要素の追加と取り出し

 Arry = [0,1,2,3,4,5,6,7,8,9]


JavaScript

先頭要素を取り出す Arry.shift();

末尾要素を取り出す Arry.pop();

先頭に0を追加 Arry.unshift(0);

末尾に9を追加 Arry.push(8);


Python

先頭要素を取り出す Arry.pop(0)

末尾要素を取り出す Arry.pop(-1)

先頭に0を追加 Arry.insert(0, 0) #insert(位置, 値)

末尾に9を追加 Arry.append(8)



2022年8月9日火曜日

Python: Keyを指定して辞書データをソートする

 Keyを指定して辞書データをソートする

test = 
[
    {'name': 'taro', 'age': 18},
    {'name': 'jiro', 'age': 12},
    {'name': 'saburo', 'age': 10}
]
#非破壊的 元のtestはそのまま
sorted_data = sorted(test, key=lambda item: item['age']))
#破壊的 元のtest自体を書き換える
test.sort(key=lambda item: item['age'])
#Result
[
    {'name': 'saburo', 'age': 10},
    {'name': 'jiro', 'age': 12},
    {'name': 'taro', 'age': 18}
]




Python: print関数の結果をファイルに出力する

 print関数の結果をファイルに出力する

with open('file.txt', 'w') as f:
    print('abc', file=f)


2022年6月17日金曜日

Django: request.FILESの構造

通常のフィールドは、request.POST によりデータ受け渡しされるが、ファイルフィールドは、request.FILES で受け渡しされる。

フィールドが以下のような形だとすると、

<input type="file" name="file_1"> (選択したファイル名: filename_1.pdf)
<input type="file" name="file_2"> (選択したファイル名: filename_2.jpg)
<input type="file" name="file_3"> (選択したファイル名: filename_3.png)


request.FILES (dict型オブジェクト)は、

object = { 'file_1': file_1, 'file_2': file_3, 'file_1': file_3, }

という構造になっている。

ファイル名を取得するには、

ファイル名取得 object['file1'].name => filename_1.pdf

とする。

その他、以下が取得できる。

ファイルサイズ取得 object['file1'].size

ファイルMIMEタイプ取得 object['file1'].content_type

ファイル文字コード取得 object['file1'].charset


2022年6月16日木曜日

Django: shellでsettings.pyの設定値を取得する



$ python manage.py shell

>>> from django.conf import settings

>>> settings.BASE_DIR

>>> '/var/www/html/myproject/'


2022年6月15日水曜日

Django: urls.pyで単純にリダイレクトする方法

例:

/abc/任意文字列 ⇒ /xyz/任意文字列


from django.views.generic.base import RedirectView

urlpatterns = [

    url(r'^abc/(?P<path>.*)$', RedirectView.as_view(url='/xyz/%(path)s', query_string=True)),

]

2021年2月14日日曜日

PythonをCGIとして実行する - CentOS7の場合

プロバイダ: さくらインターネットVPS
OS: CentOS7
Python3.6を手動でインストール済み

まず、Pythonがインストールされているパスを調べておきます。
通常は /usr/bin/python3.6
ですが、各自環境に合わせてください。

◆cgi-binディレクトリ内でPythonを実行させる場合

1./etc/httpd/conf/httpd.conf 内の以下赤文字部分を追記

<IfModule alias_module>
    ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
</IfModule>

<Directory "/var/www/cgi-bin">
    AllowOverride None
    #Options None #無効化
    Options ExecCGI #追記
    Require all granted
    AddHandler cgi-script .py .pyc #追記
</Directory>

※httpd.conf編集後、Apacheを再起動($ systemctl restart httpd)すること。

2./var/www/cgi-bin 内に以下の内容の hello.py を保存する。

#!/usr/bin/python3.6
import ioimport sys# 日本語を使用する場合、出力ストリームの文字エンコーディングを指定sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
# HTTP ヘッダprint('Content-Type: text/html; charset=utf-8')print() # blank line, end of headers
# HTML 本文print('<html><body>')print('Hello, world.<br>')print('こんにちは、世界。<br>')print('</body></html>')

※hello.pyファイルは、改行コード:LF、パーミッション:755にすること。

3.http://ホスト名/cgi-bin/hello.py にアクセスすると実行される。


◆ドキュメントルート以下で実行する場合

ドキュメントルート例:/var/www/html/python

1.以下の内容で /var/www/html/python/.htaccessファイルを保存する。

Options +ExecCGI
AddHandler cgi-script .py .pyc

2.前述と同じ内容の /var/www/html/python/hello.py を保存する。

3.http://ホスト名/python/hello.py にアクセスすると実行される。


参考
CentOS7上でPython3をCGIとして動かすまで
https://qiita.com/kusyami_p/items/7ca4fd774c12fc6324a2

pythonファイルをCGIとしてレンタルサーバー上でphp経由でCorn実行することで「500 Internal Server Error」を回避する方法 - なろう分析記録
https://karupoimou.hatenablog.com/entry/2019/05/21/184126