diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e37e385
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+dist/
+__pycache__/
+*.py[cod]
+*.egg-info/
diff --git a/INSTALLATION.md b/INSTALLATION.md
new file mode 100644
index 0000000..495b8c5
--- /dev/null
+++ b/INSTALLATION.md
@@ -0,0 +1,78 @@
+## Installation
+
+Press the shortcut key "Win+R", type words "cmd", press "Enter", then open a terminal in Windows.
+
+Execute the following command in a terminal to install (upgrade) Guan package to the latest version (https://pypi.org/project/guan/):
+
+```bash
+pip install --upgrade guan -i https://pypi.python.org/simple
+```
+
+or
+
+```bash
+pip install --upgrade guan
+```
+
+See the installed version of Guan package on your computer:
+
+```bash
+pip show guan
+```
+
+If you do not use this package anymore, you can uninstall it:
+
+```bash
+pip uninstall guan
+```
+
+Usage:
+
+```python
+import guan
+```
+
+Prerequisites:
+
+```text
+Python3
+
+[Packages partially used, which have been included in Anaconda]
+numpy
+math
+cmath
+os
+copy
+matplotlib
+re
+datetime
+bs4
+requests
+functools
+sympy
+collections
+pickle
+time
+urllib
+hashlib
+shutil
+logging
+ssl
+random
+json
+...
+
+[Packages partially used, which need to be additionally installed when they are needed]
+jieba (pip install jieba)
+imageio (pip install imageio)
+pdfplumber (pip install pdfplumber)
+PyPDF2 (pip install PyPDF2)
+pdfminer3k (pip install pdfminer3k)
+pygame (pip install pygame)
+akshare (pip install akshare)
+pyttsx3 (pip install pyttsx3)
+pydub (pip install pydub)
+qrcode (pip install qrcode)
+FFmpeg (http://www.ffmpeg.org/download.html)
+...
+```
diff --git a/PyPI/setup.cfg b/PyPI/setup.cfg
index bd80faa..2546167 100644
--- a/PyPI/setup.cfg
+++ b/PyPI/setup.cfg
@@ -1,7 +1,7 @@
[metadata]
# replace with your username:
name = guan
-version = 0.1.202
+version = 0.2.0
author = guanjihuan
author_email = guanjihuan@163.com
description = An open source python package
diff --git a/PyPI/src/guan.egg-info/PKG-INFO b/PyPI/src/guan.egg-info/PKG-INFO
deleted file mode 100644
index 642414a..0000000
--- a/PyPI/src/guan.egg-info/PKG-INFO
+++ /dev/null
@@ -1,17 +0,0 @@
-Metadata-Version: 2.4
-Name: guan
-Version: 0.1.202
-Summary: An open source python package
-Home-page: https://py.guanjihuan.com
-Author: guanjihuan
-Author-email: guanjihuan@163.com
-Project-URL: Bug Tracker, https://py.guanjihuan.com
-Classifier: Programming Language :: Python :: 3
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Operating System :: OS Independent
-Requires-Python: >=3.6
-Description-Content-Type: text/markdown
-License-File: LICENSE
-Dynamic: license-file
-
-Guan is an open-source python package developed and maintained by https://www.guanjihuan.com/about (Ji-Huan Guan, 关济寰). The primary location of this package is on website https://py.guanjihuan.com. The GitHub location of this package is on https://github.com/guanjihuan/py.guanjihuan.com.
diff --git a/PyPI/src/guan.egg-info/SOURCES.txt b/PyPI/src/guan.egg-info/SOURCES.txt
deleted file mode 100644
index b6c9f7b..0000000
--- a/PyPI/src/guan.egg-info/SOURCES.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-LICENSE
-README.md
-pyproject.toml
-setup.cfg
-src/guan/AI_chat.py
-src/guan/Fourier_transform.py
-src/guan/Green_functions.py
-src/guan/Hamiltonian_of_examples.py
-src/guan/__init__.py
-src/guan/band_structures_and_wave_functions.py
-src/guan/basic_functions.py
-src/guan/data_processing.py
-src/guan/decorators.py
-src/guan/density_of_states.py
-src/guan/figure_plotting.py
-src/guan/file_reading_and_writing.py
-src/guan/machine_learning.py
-src/guan/others.py
-src/guan/quantum_transport.py
-src/guan/topological_invariant.py
-src/guan.egg-info/PKG-INFO
-src/guan.egg-info/SOURCES.txt
-src/guan.egg-info/dependency_links.txt
-src/guan.egg-info/top_level.txt
\ No newline at end of file
diff --git a/PyPI/src/guan.egg-info/dependency_links.txt b/PyPI/src/guan.egg-info/dependency_links.txt
deleted file mode 100644
index 8b13789..0000000
--- a/PyPI/src/guan.egg-info/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/PyPI/src/guan.egg-info/top_level.txt b/PyPI/src/guan.egg-info/top_level.txt
deleted file mode 100644
index ff25243..0000000
--- a/PyPI/src/guan.egg-info/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-guan
diff --git a/PyPI/src/guan/AI_chat.py b/PyPI/src/guan/AI_chat.py
index efc1bde..cd5e5ba 100644
--- a/PyPI/src/guan/AI_chat.py
+++ b/PyPI/src/guan/AI_chat.py
@@ -1,64 +1,5 @@
# Module: AI_chat
-# AI 对话(当前默认模型为 'hunyuan-lite',无记忆)
-def chat(prompt='你好', model=1, stream=1, stream_label=0):
- import requests
- url = "http://api.guanjihuan.com/chat"
- data = {
- "prompt": prompt,
- "model": model,
- }
- if stream == 1:
- if stream_label == 1:
- print('\n--- Start Chat Stream Message ---\n')
- requests_response = requests.post(url, json=data, stream=True)
- response = ''
- if requests_response.status_code == 200:
- for line in requests_response.iter_lines():
- if line:
- if stream == 1:
- print(line.decode('utf-8'), end='', flush=True)
- response += line.decode('utf-8')
- print()
- else:
- pass
- if stream == 1:
- if stream_label == 1:
- print('\n--- End Chat Stream Message ---\n')
- return response
-
-# 加上函数代码的 AI 对话(当前默认模型为 'hunyuan-lite',无记忆)
-def chat_with_function_code(function_name, prompt='', model=1, stream=1):
- import guan
- function_source = guan.get_source(function_name)
- if prompt == '':
- response = guan.chat(prompt=function_source, model=model, stream=stream)
- else:
- response = guan.chat(prompt=function_source+'\n\n'+prompt, model=model, stream=stream)
- return response
-
-# 机器人自动对话(当前默认模型为 'hunyuan-lite',无记忆)
-def auto_chat(prompt='你好', round=2, model=1, stream=1):
- import guan
- response0 = prompt
- for i0 in range(round):
- print(f'\n【对话第 {i0+1} 轮】\n')
- print('机器人 1: ')
- response1 = guan.chat(prompt=response0, model=model, stream=stream)
- print('机器人 2: ')
- response0 = guan.chat(prompt=response1, model=model, stream=stream)
-
-# 机器人自动对话(引导对话)(当前默认模型为 'hunyuan-lite',无记忆)
-def auto_chat_with_guide(prompt='你好', guide_message='(回答字数少于30个字,最后反问我一个问题)', round=5, model=1, stream=1):
- import guan
- response0 = prompt
- for i0 in range(round):
- print(f'\n【对话第 {i0+1} 轮】\n')
- print('机器人 1: ')
- response1 = guan.chat(prompt=response0+guide_message, model=model, stream=stream)
- print('机器人 2: ')
- response0 = guan.chat(prompt=response1+guide_message, model=model, stream=stream)
-
# 使用 OpenAI 框架对话(需要 API Key)
def openai_chat(prompt="你好", model="qwen-plus", temperature=0.7, system_message=None, history=[], print_show=1, load_env=1):
import os
diff --git a/PyPI/src/guan/__init__.py b/PyPI/src/guan/__init__.py
index f6c5d52..02b0e5d 100644
--- a/PyPI/src/guan/__init__.py
+++ b/PyPI/src/guan/__init__.py
@@ -15,4 +15,5 @@ from .data_processing import *
from .AI_chat import *
from .decorators import *
from .others import *
+from .deprecated import *
statistics_of_guan_package()
\ No newline at end of file
diff --git a/PyPI/src/guan/deprecated.py b/PyPI/src/guan/deprecated.py
new file mode 100644
index 0000000..3025508
--- /dev/null
+++ b/PyPI/src/guan/deprecated.py
@@ -0,0 +1,106 @@
+# Module: deprecated
+
+# --- 废弃函数/版本兼容(不推荐使用,并可能在未来的版本中被移除) ---
+
+# AI 对话(当前默认模型为 'hunyuan-lite',无记忆)
+def chat(prompt='你好', model=1, stream=1, stream_label=0):
+ import requests
+ url = "http://api.guanjihuan.com/chat"
+ data = {
+ "prompt": prompt,
+ "model": model,
+ }
+ if stream == 1:
+ if stream_label == 1:
+ print('\n--- Start Chat Stream Message ---\n')
+ requests_response = requests.post(url, json=data, stream=True)
+ response = ''
+ if requests_response.status_code == 200:
+ for line in requests_response.iter_lines():
+ if line:
+ if stream == 1:
+ print(line.decode('utf-8'), end='', flush=True)
+ response += line.decode('utf-8')
+ print()
+ else:
+ pass
+ if stream == 1:
+ if stream_label == 1:
+ print('\n--- End Chat Stream Message ---\n')
+ return response
+
+# 加上函数代码的 AI 对话(当前默认模型为 'hunyuan-lite',无记忆)
+def chat_with_function_code(function_name, prompt='', model=1, stream=1):
+ import guan
+ function_source = guan.get_source(function_name)
+ if prompt == '':
+ response = guan.chat(prompt=function_source, model=model, stream=stream)
+ else:
+ response = guan.chat(prompt=function_source+'\n\n'+prompt, model=model, stream=stream)
+ return response
+
+# 机器人自动对话(当前默认模型为 'hunyuan-lite',无记忆)
+def auto_chat(prompt='你好', round=2, model=1, stream=1):
+ import guan
+ response0 = prompt
+ for i0 in range(round):
+ print(f'\n【对话第 {i0+1} 轮】\n')
+ print('机器人 1: ')
+ response1 = guan.chat(prompt=response0, model=model, stream=stream)
+ print('机器人 2: ')
+ response0 = guan.chat(prompt=response1, model=model, stream=stream)
+
+# 机器人自动对话(引导对话)(当前默认模型为 'hunyuan-lite',无记忆)
+def auto_chat_with_guide(prompt='你好', guide_message='(回答字数少于30个字,最后反问我一个问题)', round=5, model=1, stream=1):
+ import guan
+ response0 = prompt
+ for i0 in range(round):
+ print(f'\n【对话第 {i0+1} 轮】\n')
+ print('机器人 1: ')
+ response1 = guan.chat(prompt=response0+guide_message, model=model, stream=stream)
+ print('机器人 2: ')
+ response0 = guan.chat(prompt=response1+guide_message, model=model, stream=stream)
+
+def make_sh_file(sh_filename='a', command_line='python a.py', cpu_num=1, task_name='task', cd_dir=0):
+ import guan
+ print('Warning: The current function name has been deprecated, which will be deleted in the future version. Please change it into guan.make_sh_file_for_qsub().')
+ guan.make_sh_file_for_qsub(sh_filename=sh_filename, command_line=command_line, cpu_num=cpu_num, task_name=task_name, cd_dir=cd_dir)
+
+def plot_without_starting_fig(plt, fig, ax, x_array, y_array, xlabel='x', ylabel='y', title='', fontsize=20, style='', y_min=None, y_max=None, linewidth=None, markersize=None, color=None, fontfamily='Times New Roman'):
+ import guan
+ print('Warning: The current function name has been deprecated, which will be deleted in the future version. Please change it into guan.plot_without_starting_fig_ax().')
+ guan.plot_without_starting_fig_ax(plt, fig, ax, x_array, y_array, xlabel=xlabel, ylabel=ylabel, title=title, fontsize=fontsize, style=style, y_min=y_min, y_max=y_max, linewidth=linewidth, markersize=markersize, color=color, fontfamily=fontfamily)
+
+def draw_dots_and_lines_without_starting_fig(plt, fig, ax, coordinate_array, draw_dots=1, draw_lines=1, max_distance=1, line_style='-k', linewidth=1, dot_style='ro', markersize=3):
+ import guan
+ print('Warning: The current function name has been deprecated, which will be deleted in the future version. Please change it into guan.draw_dots_and_lines_without_starting_fig_ax().')
+ guan.draw_dots_and_lines_without_starting_fig_ax(plt, fig, ax, coordinate_array, draw_dots=draw_dots, draw_lines=draw_lines, max_distance=max_distance, line_style=line_style, linewidth=linewidth, dot_style=dot_style, markersize=markersize)
+
+def get_days_of_the_current_month(str_or_datetime='str'):
+ import guan
+ print('Warning: The current function name has been deprecated, which will be deleted in the future version. Please change it into guan.get_date_array_of_the_current_month().')
+ date_array = guan.get_date_array_of_the_current_month(str_or_datetime=str_or_datetime)
+ return date_array
+
+def get_days_of_the_last_month(str_or_datetime='str'):
+ import guan
+ print('Warning: The current function name has been deprecated, which will be deleted in the future version. Please change it into guan.get_date_array_of_the_last_month().')
+ date_array = guan.get_date_array_of_the_last_month(str_or_datetime=str_or_datetime)
+ return date_array
+
+def get_days_of_the_month_before_last(str_or_datetime='str'):
+ import guan
+ print('Warning: The current function name has been deprecated, which will be deleted in the future version. Please change it into guan.get_date_array_of_the_month_before_last().')
+ date_array = guan.get_date_array_of_the_month_before_last(str_or_datetime=str_or_datetime)
+ return date_array
+
+def pdf_to_text(pdf_path):
+ import guan
+ print('Warning: The current function name has been deprecated, which will be deleted in the future version. Please change it into guan.pdf_to_text_with_pdfminer3k().')
+ content = guan.pdf_to_text_with_pdfminer3k(pdf_path)
+ return content
+
+def statistics_with_day_and_time(content='', filename='time_logging', file_format='.txt'):
+ import guan
+ print('Warning: The current function name has been deprecated, which will be deleted in the future version. Please change it into guan.logging_with_day_and_time().')
+ guan.logging_with_day_and_time(content=content, filename=filename, file_format=file_format)
\ No newline at end of file
diff --git a/PyPI/src/guan/others.py b/PyPI/src/guan/others.py
index f652d4f..97e2321 100644
--- a/PyPI/src/guan/others.py
+++ b/PyPI/src/guan/others.py
@@ -1282,50 +1282,4 @@ def initialize_hamiltonian_from_atom_object_list(atom_object_list):
hamiltonian = np.zeros((dim*num, dim*num))
for i0 in range(num):
hamiltonian[i0*dim+0:i0*dim+dim, i0*dim+0:i0*dim+dim] = atom_object_list[i0].energy
- return hamiltonian
-
-# --- 废弃函数/版本兼容(不推荐使用,并可能在未来的版本中被移除)deprecated ---
-
-def make_sh_file(sh_filename='a', command_line='python a.py', cpu_num=1, task_name='task', cd_dir=0):
- import guan
- print('Warning: The current function name has been deprecated, which will be deleted in the future version. Please change it into guan.make_sh_file_for_qsub().')
- guan.make_sh_file_for_qsub(sh_filename=sh_filename, command_line=command_line, cpu_num=cpu_num, task_name=task_name, cd_dir=cd_dir)
-
-def plot_without_starting_fig(plt, fig, ax, x_array, y_array, xlabel='x', ylabel='y', title='', fontsize=20, style='', y_min=None, y_max=None, linewidth=None, markersize=None, color=None, fontfamily='Times New Roman'):
- import guan
- print('Warning: The current function name has been deprecated, which will be deleted in the future version. Please change it into guan.plot_without_starting_fig_ax().')
- guan.plot_without_starting_fig_ax(plt, fig, ax, x_array, y_array, xlabel=xlabel, ylabel=ylabel, title=title, fontsize=fontsize, style=style, y_min=y_min, y_max=y_max, linewidth=linewidth, markersize=markersize, color=color, fontfamily=fontfamily)
-
-def draw_dots_and_lines_without_starting_fig(plt, fig, ax, coordinate_array, draw_dots=1, draw_lines=1, max_distance=1, line_style='-k', linewidth=1, dot_style='ro', markersize=3):
- import guan
- print('Warning: The current function name has been deprecated, which will be deleted in the future version. Please change it into guan.draw_dots_and_lines_without_starting_fig_ax().')
- guan.draw_dots_and_lines_without_starting_fig_ax(plt, fig, ax, coordinate_array, draw_dots=draw_dots, draw_lines=draw_lines, max_distance=max_distance, line_style=line_style, linewidth=linewidth, dot_style=dot_style, markersize=markersize)
-
-def get_days_of_the_current_month(str_or_datetime='str'):
- import guan
- print('Warning: The current function name has been deprecated, which will be deleted in the future version. Please change it into guan.get_date_array_of_the_current_month().')
- date_array = guan.get_date_array_of_the_current_month(str_or_datetime=str_or_datetime)
- return date_array
-
-def get_days_of_the_last_month(str_or_datetime='str'):
- import guan
- print('Warning: The current function name has been deprecated, which will be deleted in the future version. Please change it into guan.get_date_array_of_the_last_month().')
- date_array = guan.get_date_array_of_the_last_month(str_or_datetime=str_or_datetime)
- return date_array
-
-def get_days_of_the_month_before_last(str_or_datetime='str'):
- import guan
- print('Warning: The current function name has been deprecated, which will be deleted in the future version. Please change it into guan.get_date_array_of_the_month_before_last().')
- date_array = guan.get_date_array_of_the_month_before_last(str_or_datetime=str_or_datetime)
- return date_array
-
-def pdf_to_text(pdf_path):
- import guan
- print('Warning: The current function name has been deprecated, which will be deleted in the future version. Please change it into guan.pdf_to_text_with_pdfminer3k().')
- content = guan.pdf_to_text_with_pdfminer3k(pdf_path)
- return content
-
-def statistics_with_day_and_time(content='', filename='time_logging', file_format='.txt'):
- import guan
- print('Warning: The current function name has been deprecated, which will be deleted in the future version. Please change it into guan.logging_with_day_and_time().')
- guan.logging_with_day_and_time(content=content, filename=filename, file_format=file_format)
\ No newline at end of file
+ return hamiltonian
\ No newline at end of file
diff --git a/README.md b/README.md
index 24d0047..73eaceb 100755
--- a/README.md
+++ b/README.md
@@ -6,11 +6,15 @@ The primary location of this package is on https://py.guanjihuan.com.
## Installation
+```bash
pip install --upgrade guan
+```
## Usage
+```python
import guan
+```
## Summary of API Reference
@@ -42,4 +46,23 @@ There is no official paper related to this package temporarily, but you can cite
+ Ji-Huan Guan, Wen-Kai Lou, and Kai Chang, Topological hidden phase transition in honeycomb bilayers with a high Chern number, Phys. Rev. B 110, 165303 (2024).
+ Ji-Huan Guan, Yan-Yang Zhang, Si-Si Wang, Yan Yu, Yang Xia and Shu-Shen Li, Barrier Tunneling and Loop Polarization in Hopf Semimetals. Phys. Rev. B 102, 064203 (2020).
-+ Ji-Huan Guan, Yan-Yang Zhang, Wei-Er Lu, Yang Xia and Shu-Shen Li, Barrier tunneling of the loop-nodal semimetal in the hyperhoneycomb lattice. J. Phys.: Condens. Matter 30, 185402 (2018).
\ No newline at end of file
++ Ji-Huan Guan, Yan-Yang Zhang, Wei-Er Lu, Yang Xia and Shu-Shen Li, Barrier tunneling of the loop-nodal semimetal in the hyperhoneycomb lattice. J. Phys.: Condens. Matter 30, 185402 (2018).
+
+## Website
+
+The website (https://py.guanjihuan.com) is generated from the source code in `PyPI/src/guan` by static parsing, so it always matches the source code. It hosts the home page, the module list, the data tables, the full API reference, the about page, the installation page and `api.json`.
+
+
+Build the distribution:
+
+```bash
+python -m build --outdir dist --no-isolation PyPI
+```
+
+Build the website:
+
+```bash
+python website/build_site.py -o dist/site
+```
+
+The build also checks the generated pages for broken links and reports source files that fail to parse. Pass `--strict` to make it exit with a non-zero status when something is wrong, which is handy in CI.
\ No newline at end of file
diff --git a/tutorials/00_test.py b/tutorials/00_test.py
new file mode 100644
index 0000000..071bc5a
--- /dev/null
+++ b/tutorials/00_test.py
@@ -0,0 +1,3 @@
+# 测试代码
+import guan
+guan.test()
diff --git a/tutorials/README.md b/tutorials/README.md
new file mode 100644
index 0000000..88d232d
--- /dev/null
+++ b/tutorials/README.md
@@ -0,0 +1,93 @@
+# Tutorials
+
+Learning examples for the [Guan package](https://py.guanjihuan.com), extracted from the blog post
+[Guan软件包学习示例](https://www.guanjihuan.com/archives/38367).
+
+One example per file. Each file is a self-contained script that you can run directly, or copy the
+functions you need into your own project.
+
+## Installation
+
+```bash
+pip install --upgrade guan
+```
+
+```python
+import guan
+```
+
+## Run the examples
+
+```bash
+python tutorials/daily_scenarios/01_ai_chat.py
+python tutorials/physics_scenarios/03_band_structure.py
+```
+
+## Directory
+
+```
+tutorials/
+├── 00_test.py # package self test
+├── daily_scenarios/ # 一、日常场景
+│ ├── 01_ai_chat.py
+│ ├── 02_timing_log.py
+│ ├── 03_function_timer.py
+│ ├── 04_try_except.py
+│ ├── 05_dump_and_load_data.py
+│ ├── 06_print_array.py
+│ ├── 07_matrix_in_file.py
+│ ├── 08_parallel_calculation.py
+│ ├── 09_loop_calculation.py
+│ ├── 10_is_hermitian.py
+│ └── 11_split_parameters.py
+└── physics_scenarios/ # 二、物理场景
+ ├── 01_pauli_matrices.py
+ ├── 02_real_space_hamiltonian.py
+ ├── 03_band_structure.py
+ ├── 04_chern_number_and_wilson_loop.py
+ ├── 05_density_of_states_with_green_function.py
+ ├── 06_conductance_and_scattering_matrix.py
+ └── 07_wavefunction_gauge.py
+```
+
+## 一、日常场景 / Daily scenarios
+
+| File | 说明 | Requirements |
+| --- | --- | --- |
+| `00_test.py` | 软件包自检 `guan.test()` | - |
+| `01_ai_chat.py` | AI 对话:内置模型、OpenAI 兼容接口、LangChain、Ollama、llama.cpp、ModelScope | OpenAI 接口需要 API Key;Ollama / llama.cpp / ModelScope 需要本地模型 |
+| `02_timing_log.py` | 带日期和时间的运行日志 `guan.logging_with_day_and_time` | - |
+| `03_function_timer.py` | 函数计时器:`@guan.timer_decorator` 与 `guan.timer` | - |
+| `04_try_except.py` | try except 简写:`@guan.try_decorator` 与 `guan.try_except` | - |
+| `05_dump_and_load_data.py` | 变量写入文件并读回 | numpy |
+| `06_print_array.py` | 打印数组 | numpy |
+| `07_matrix_in_file.py` | 矩阵写入 Markdown / LaTeX 格式文件后查看 | numpy |
+| `08_parallel_calculation.py` | 多进程并行计算 | - |
+| `09_loop_calculation.py` | 循环参数计算(一、二、三个参数)与作图 | numpy, matplotlib |
+| `10_is_hermitian.py` | 检查是否为厄米矩阵(相对误差 1e-5) | numpy |
+| `11_split_parameters.py` | 数组分割,为并行计算准备参数 | numpy |
+
+## 二、物理场景 / Physics scenarios
+
+| File | 说明 | Requirements |
+| --- | --- | --- |
+| `01_pauli_matrices.py` | 泡利矩阵 | numpy |
+| `02_real_space_hamiltonian.py` | 一维 / 二维方格 / 三维立方格的实空间哈密顿量 | numpy |
+| `03_band_structure.py` | 能带图计算:一维链、方格带、石墨烯锯齿形带 | numpy, matplotlib |
+| `04_chern_number_and_wilson_loop.py` | 陈数与 Wilson loop 计算 | numpy |
+| `05_density_of_states_with_green_function.py` | 用格林函数计算态密度(方格与立方格,局域态密度) | numpy, matplotlib |
+| `06_conductance_and_scattering_matrix.py` | 电导与散射矩阵的计算 | numpy, matplotlib |
+| `07_wavefunction_gauge.py` | 波函数规范(fixed gauge)的选取 | numpy |
+
+## 说明 / Notes
+
++ Some examples need an API Key, a local Ollama/llama.cpp/ModelScope model, or a specific model path.
+ Edit the paths in the scripts before running them.
++ `04_try_except.py` contains a deliberate `bug_code` call to demonstrate the exception handling.
++ Figures are saved to the current working directory when the plotting functions are used.
+
+## License / 许可
+
+The source post is published under [CC BY](https://www.guanjihuan.com), by
+[Ji-Huan Guan](https://www.guanjihuan.com/about). Please cite the source when quoting:
+https://www.guanjihuan.com/archives/38367
diff --git a/tutorials/daily_scenarios/01_ai_chat.py b/tutorials/daily_scenarios/01_ai_chat.py
new file mode 100644
index 0000000..9028cc0
--- /dev/null
+++ b/tutorials/daily_scenarios/01_ai_chat.py
@@ -0,0 +1,19 @@
+# AI 对话
+import guan
+
+response, history = guan.openai_chat("你好", model="qwen-plus") # 需要 API Key
+print()
+
+response = guan.langchain_chat_without_memory(prompt="你好", model="qwen-plus") # 需要 API Key
+response == guan.langchain_chat_with_memory(prompt="你好", model="qwen-plus") # 需要 API Key
+print()
+
+response = guan.ollama_chat(prompt='你好', model="qwen2.5:0.5b") # 需要运行 Ollama 和下载对应的模型
+print()
+
+llm = guan.load_llama_model(model_path="D:/models/Qwen/Qwen3-0.6B-GGUF/Qwen3-0.6B-Q8_0.gguf") # 需要有模型文件
+response, history = guan.llama_chat(llm, '你好 /no_think')
+print()
+
+model, tokenizer = guan.load_modelscope_model(model_name="D:/models/Qwen/Qwen3-0.6B") # 需要有模型文件
+response, history = guan.modelscope_chat(model, tokenizer, '你好 /no_think')
diff --git a/tutorials/daily_scenarios/02_timing_log.py b/tutorials/daily_scenarios/02_timing_log.py
new file mode 100644
index 0000000..5d772d2
--- /dev/null
+++ b/tutorials/daily_scenarios/02_timing_log.py
@@ -0,0 +1,7 @@
+# 运行时间日志
+import guan
+import time
+guan.logging_with_day_and_time(content='start')
+for i in range(3):
+ time.sleep(5)
+ guan.logging_with_day_and_time(f'end_of_{i}')
diff --git a/tutorials/daily_scenarios/03_function_timer.py b/tutorials/daily_scenarios/03_function_timer.py
new file mode 100644
index 0000000..6ecc92b
--- /dev/null
+++ b/tutorials/daily_scenarios/03_function_timer.py
@@ -0,0 +1,25 @@
+# 函数计时器
+import guan
+
+@guan.timer_decorator
+def test1(a, b):
+ import time
+ print(a)
+ time.sleep(1)
+ print(b)
+ print('Run finished.')
+
+for _ in range(2):
+ test1(10, b=20)
+
+print()
+
+def test2(a, b):
+ import time
+ print(a)
+ time.sleep(1)
+ print(b)
+ print('Run finished.')
+
+for _ in range(2):
+ guan.timer(test2, 100, b=200)
diff --git a/tutorials/daily_scenarios/04_try_except.py b/tutorials/daily_scenarios/04_try_except.py
new file mode 100644
index 0000000..aaaf06c
--- /dev/null
+++ b/tutorials/daily_scenarios/04_try_except.py
@@ -0,0 +1,23 @@
+# try except 简写
+import guan
+
+@guan.try_decorator
+def test1(a, b):
+ print(a)
+ bug_code
+ print(b)
+ return 'return_message1'
+
+result1 = test1(10, b=20)
+print(result1)
+
+print()
+
+def test2(a, b):
+ print(a)
+ bug_code
+ print(b)
+ return 'return_message2'
+
+result2 = guan.try_except(test2, 100, b=200)
+print(result2)
diff --git a/tutorials/daily_scenarios/05_dump_and_load_data.py b/tutorials/daily_scenarios/05_dump_and_load_data.py
new file mode 100644
index 0000000..f62a898
--- /dev/null
+++ b/tutorials/daily_scenarios/05_dump_and_load_data.py
@@ -0,0 +1,7 @@
+# 变量写入文件
+import guan
+import numpy as np
+data = np.array([1, 2, 3])
+guan.dump_data(data, filename='a')
+loaded_data = guan.load_data(filename='a')
+print(loaded_data)
diff --git a/tutorials/daily_scenarios/06_print_array.py b/tutorials/daily_scenarios/06_print_array.py
new file mode 100644
index 0000000..cf5eb92
--- /dev/null
+++ b/tutorials/daily_scenarios/06_print_array.py
@@ -0,0 +1,4 @@
+# 打印数组
+import guan
+a = [1, 2, 3, 'a', 'b', 'c']
+guan.print_array(a)
diff --git a/tutorials/daily_scenarios/07_matrix_in_file.py b/tutorials/daily_scenarios/07_matrix_in_file.py
new file mode 100644
index 0000000..4e12b1c
--- /dev/null
+++ b/tutorials/daily_scenarios/07_matrix_in_file.py
@@ -0,0 +1,6 @@
+# 矩阵写入文件后查看
+import guan
+import numpy as np
+matrix = np.random.rand(5, 5)
+guan.write_matrix_in_markdown_format(matrix=matrix, filename='markdown_matrix')
+guan.write_matrix_in_latex_format(matrix=matrix, filename='latex_matrix')
diff --git a/tutorials/daily_scenarios/08_parallel_calculation.py b/tutorials/daily_scenarios/08_parallel_calculation.py
new file mode 100644
index 0000000..3547bbc
--- /dev/null
+++ b/tutorials/daily_scenarios/08_parallel_calculation.py
@@ -0,0 +1,15 @@
+# 并行计算
+import guan
+import time
+import os
+
+def run_proc(name):
+ start_time = time.time()
+ time.sleep(5)
+ end_time = time.time()
+ print ('Process id running on name %s = %s' % (name, os.getpid()), '; running time = %s' % (end_time-start_time))
+ return f'name_{name}'
+
+if __name__ == '__main__':
+ result_array = guan.parallel_calculation_with_multiprocessing_Pool(func=run_proc, args_list=range(32), show_time=1)
+ print(result_array)
diff --git a/tutorials/daily_scenarios/09_loop_calculation.py b/tutorials/daily_scenarios/09_loop_calculation.py
new file mode 100644
index 0000000..3f07579
--- /dev/null
+++ b/tutorials/daily_scenarios/09_loop_calculation.py
@@ -0,0 +1,33 @@
+# 循环参数计算
+
+import guan
+import numpy as np
+
+def test_1(x):
+ return 2*x
+
+x_array = np.arange(0, 5, 1)
+result_array = guan.loop_calculation_with_one_parameter(test_1, x_array)
+print(result_array)
+guan.plot(x_array, result_array)
+print()
+
+def test_2(x, y):
+ return x+y
+
+x_array = np.arange(0, 5, 1)
+y_array = np.arange(0, 3, 1)
+result_array = guan.loop_calculation_with_two_parameters(test_2, x_array, y_array)
+print(result_array)
+guan.plot_contour(x_array, y_array, result_array)
+print()
+
+def test_3(x, y, z):
+ return x+y+z
+
+x_array = np.arange(0, 5, 1)
+y_array = np.arange(0, 3, 1)
+z_array = np.arange(0, 2, 1)
+result_array = guan.loop_calculation_with_three_parameters(test_3, x_array, y_array, z_array)
+print(result_array)
+guan.plot_contour(y_array, z_array, result_array[:, :, 4])
diff --git a/tutorials/daily_scenarios/10_is_hermitian.py b/tutorials/daily_scenarios/10_is_hermitian.py
new file mode 100644
index 0000000..9f0a6f1
--- /dev/null
+++ b/tutorials/daily_scenarios/10_is_hermitian.py
@@ -0,0 +1,16 @@
+# 检查是否为厄米矩阵
+import guan
+
+matrix1 = [
+ [2, 1.00001-1j],
+ [1+1j, 1]
+]
+
+print(guan.is_hermitian(matrix1))
+
+matrix2 = [
+ [2, 1.00002-1j],
+ [1+1j, 1]
+]
+
+print(guan.is_hermitian(matrix2))
diff --git a/tutorials/daily_scenarios/11_split_parameters.py b/tutorials/daily_scenarios/11_split_parameters.py
new file mode 100644
index 0000000..00673c1
--- /dev/null
+++ b/tutorials/daily_scenarios/11_split_parameters.py
@@ -0,0 +1,9 @@
+# 数组分割
+import numpy as np
+import guan
+task_num = 4
+parameter_array_all = np.arange(0, 17, 1)
+for task_index in range(task_num):
+ parameter_array = guan.preprocess_for_parallel_calculations(parameter_array_all, task_num, task_index)
+ print(parameter_array)
+ print()
diff --git a/tutorials/physics_scenarios/01_pauli_matrices.py b/tutorials/physics_scenarios/01_pauli_matrices.py
new file mode 100644
index 0000000..910b87a
--- /dev/null
+++ b/tutorials/physics_scenarios/01_pauli_matrices.py
@@ -0,0 +1,4 @@
+# 泡利矩阵
+import guan
+sigma_x = guan.sigma_x()
+print(sigma_x)
diff --git a/tutorials/physics_scenarios/02_real_space_hamiltonian.py b/tutorials/physics_scenarios/02_real_space_hamiltonian.py
new file mode 100644
index 0000000..b12b409
--- /dev/null
+++ b/tutorials/physics_scenarios/02_real_space_hamiltonian.py
@@ -0,0 +1,5 @@
+# 实空间哈密顿量
+import guan
+print('\n', guan.hamiltonian_of_finite_size_system_along_one_direction(3), '\n')
+print(guan.hamiltonian_of_finite_size_system_along_two_directions_for_square_lattice(2, 2), '\n')
+print(guan.hamiltonian_of_finite_size_system_along_three_directions_for_cubic_lattice(2, 2, 2), '\n')
diff --git a/tutorials/physics_scenarios/03_band_structure.py b/tutorials/physics_scenarios/03_band_structure.py
new file mode 100644
index 0000000..0b964d4
--- /dev/null
+++ b/tutorials/physics_scenarios/03_band_structure.py
@@ -0,0 +1,14 @@
+# 能带图计算
+import guan
+import numpy as np
+k_array = np.linspace(-np.pi, np.pi, 100)
+ # one dimensional chain
+hamiltonian_function = guan.one_dimensional_fourier_transform_with_k(unit_cell=0, hopping=1)
+eigenvalue_array = guan.calculate_eigenvalue_with_one_parameter(k_array, hamiltonian_function)
+guan.plot(k_array, eigenvalue_array, xlabel='k', ylabel='E', style='-k', fontfamily=None)
+# square lattice ribbon
+eigenvalue_array = guan.calculate_eigenvalue_with_one_parameter(k_array, guan.hamiltonian_of_square_lattice_in_quasi_one_dimension)
+guan.plot(k_array, eigenvalue_array, xlabel='k', ylabel='E', style='-k', fontfamily=None)
+# graphene ribbon
+eigenvalue_array = guan.calculate_eigenvalue_with_one_parameter(k_array, guan.hamiltonian_of_graphene_with_zigzag_in_quasi_one_dimension)
+guan.plot(k_array, eigenvalue_array, xlabel='k', ylabel='E', style='-k', fontfamily=None)
diff --git a/tutorials/physics_scenarios/04_chern_number_and_wilson_loop.py b/tutorials/physics_scenarios/04_chern_number_and_wilson_loop.py
new file mode 100644
index 0000000..7fb7320
--- /dev/null
+++ b/tutorials/physics_scenarios/04_chern_number_and_wilson_loop.py
@@ -0,0 +1,9 @@
+# 陈数和Wilson loop计算
+import guan
+import numpy as np
+chern_number = guan.calculate_chern_number_for_square_lattice_with_efficient_method(guan.hamiltonian_of_one_QAH_model, precision=100)
+print('\nChern number=', chern_number, '\n')
+wilson_loop_array = guan.calculate_wilson_loop(guan.hamiltonian_of_ssh_model)
+print('Wilson loop =', wilson_loop_array)
+p = np.log(wilson_loop_array)/2/np.pi/1j
+print('\np =', p, '\n')
diff --git a/tutorials/physics_scenarios/05_density_of_states_with_green_function.py b/tutorials/physics_scenarios/05_density_of_states_with_green_function.py
new file mode 100644
index 0000000..74225d5
--- /dev/null
+++ b/tutorials/physics_scenarios/05_density_of_states_with_green_function.py
@@ -0,0 +1,34 @@
+# 使用格林函数计算态密度
+import guan
+import numpy as np
+
+hamiltonian = guan.hamiltonian_of_finite_size_system_along_two_directions_for_square_lattice(2,2)
+fermi_energy_array = np.linspace(-4, 4, 400)
+total_dos_array = guan.total_density_of_states_with_fermi_energy_array(fermi_energy_array, hamiltonian, broadening=0.1)
+guan.plot(fermi_energy_array, total_dos_array, xlabel='E', ylabel='Total DOS', style='-', fontfamily=None)
+
+fermi_energy = 0
+N1 = 3
+N2 = 4
+hamiltonian = guan.hamiltonian_of_finite_size_system_along_two_directions_for_square_lattice(N1,N2)
+LDOS = guan.local_density_of_states_for_square_lattice(fermi_energy, hamiltonian, N1=N1, N2=N2)
+print('square lattice:\n', LDOS, '\n')
+h00 = guan.hamiltonian_of_finite_size_system_along_one_direction(N2)
+h01 = np.identity(N2)
+LDOS = guan.local_density_of_states_for_square_lattice_using_dyson_equation(fermi_energy, h00=h00, h01=h01, N2=N2, N1=N1)
+print(LDOS, '\n\n')
+LDOS2 = guan.local_density_of_states_for_square_lattice_using_dyson_equation_with_second_method(fermi_energy, h00, h01, N2, N1, internal_degree=1, broadening=0.01)
+print(LDOS2, '\n\n')
+guan.plot_contour(range(N1), range(N2), LDOS, fontfamily=None)
+guan.plot_contour(range(N1), range(N2), LDOS2, fontfamily=None)
+
+N1 = 3
+N2 = 4
+N3 = 5
+hamiltonian = guan.hamiltonian_of_finite_size_system_along_three_directions_for_cubic_lattice(N1, N2, N3)
+LDOS = guan.local_density_of_states_for_cubic_lattice(fermi_energy, hamiltonian, N1=N1, N2=N2, N3=N3)
+print('cubic lattice:\n', LDOS, '\n')
+h00 = guan.hamiltonian_of_finite_size_system_along_two_directions_for_square_lattice(N2, N3)
+h01 = np.identity(N2*N3)
+LDOS = guan.local_density_of_states_for_cubic_lattice_using_dyson_equation(fermi_energy, h00, h01, N3=N3, N2=N2, N1=N1)
+print(LDOS)
diff --git a/tutorials/physics_scenarios/06_conductance_and_scattering_matrix.py b/tutorials/physics_scenarios/06_conductance_and_scattering_matrix.py
new file mode 100644
index 0000000..e545481
--- /dev/null
+++ b/tutorials/physics_scenarios/06_conductance_and_scattering_matrix.py
@@ -0,0 +1,12 @@
+# 电导和散射矩阵的计算
+import guan
+import numpy as np
+
+fermi_energy_array = np.linspace(-4, 4, 400)
+h00 = guan.hamiltonian_of_finite_size_system_along_one_direction(4)
+h01 = np.identity(4)
+conductance_array = guan.calculate_conductance_with_fermi_energy_array(fermi_energy_array, h00, h01)
+guan.plot(fermi_energy_array, conductance_array, xlabel='E', ylabel='Conductance', style='-', fontfamily=None)
+
+fermi_energy = 0
+guan.print_or_write_scattering_matrix(fermi_energy, h00, h01)
diff --git a/tutorials/physics_scenarios/07_wavefunction_gauge.py b/tutorials/physics_scenarios/07_wavefunction_gauge.py
new file mode 100644
index 0000000..6720489
--- /dev/null
+++ b/tutorials/physics_scenarios/07_wavefunction_gauge.py
@@ -0,0 +1,22 @@
+# 波函数规范的选取
+import numpy as np
+import cmath
+import guan
+
+# Fixed gauge example 1
+vector = np.array([np.sqrt(0.5), np.sqrt(0.5)])*cmath.exp(np.random.uniform(0, 1)*1j)
+print('\nExample 1\n', vector)
+print(np.dot(vector.transpose().conj(), vector), '\n')
+
+vector = guan.find_vector_with_fixed_gauge_by_making_one_component_real(vector)
+print(vector)
+print(np.dot(vector.transpose().conj(), vector), '\n')
+
+# Fixed gauge example 2
+vector = np.array([1, 0])*cmath.exp(np.random.uniform(0, 1)*1j)
+print('\nExample 2\n', vector)
+print(np.dot(vector.transpose().conj(), vector), '\n')
+
+vector = guan.find_vector_with_fixed_gauge_by_making_one_component_real(vector)
+print(vector)
+print(np.dot(vector.transpose().conj(), vector), '\n')
diff --git a/website/audit_site.py b/website/audit_site.py
new file mode 100644
index 0000000..8100e06
--- /dev/null
+++ b/website/audit_site.py
@@ -0,0 +1,279 @@
+"""审计生成的站点:链接、HTML 结构、SEO、可访问性。
+
+用法:
+ python website/audit_site.py [站点目录]
+默认审计 website/dist/site。
+"""
+
+from __future__ import annotations
+
+import html
+import json
+import re
+import sys
+from collections import Counter
+from pathlib import Path
+from urllib.parse import unquote, urlparse
+
+ROOT = Path(__file__).resolve().parent.parent
+SITE = Path(sys.argv[1]) if len(sys.argv) > 1 else ROOT / "website" / "dist" / "site"
+
+problems: list[str] = []
+notes: list[str] = []
+
+
+def report(kind: str, page: str, message: str) -> None:
+ problems.append(f"[{kind}] {page}: {message}")
+
+
+HTML_PAGES = sorted(SITE.rglob("*.html"))
+all_files = {p.relative_to(SITE).as_posix() for p in SITE.rglob("*") if p.is_file()}
+
+# ---------------------------------------------------------------------------
+# 1. 链接检查
+# ---------------------------------------------------------------------------
+ATTR_RE = re.compile(r"""\b(href|src)\s*=\s*(["'])(.*?)\2""", re.S | re.I)
+ID_RE = re.compile(r"""\bid\s*=\s*(["'])(.*?)\1""", re.S | re.I)
+
+page_ids: dict[str, set[str]] = {}
+for page in HTML_PAGES:
+ text = page.read_text(encoding="utf-8")
+ page_ids[page.relative_to(SITE).as_posix()] = {m.group(2) for m in ID_RE.finditer(text)}
+
+broken_links = 0
+external_links: Counter[str] = Counter()
+
+for page in HTML_PAGES:
+ rel = page.relative_to(SITE).as_posix()
+ text = page.read_text(encoding="utf-8")
+ for match in ATTR_RE.finditer(text):
+ attr, raw = match.group(1).lower(), match.group(3).strip()
+ if not raw or raw.startswith(("javascript:", "data:", "mailto:", "tel:", "#")):
+ if raw.startswith("#"):
+ anchor = unquote(raw[1:])
+ if anchor and anchor not in page_ids[rel]:
+ report("锚点", rel, f"指向本页不存在的 id: {raw}")
+ continue
+ parsed = urlparse(raw)
+ if parsed.scheme in ("http", "https"):
+ external_links[parsed.netloc] += 1
+ continue
+ if parsed.netloc:
+ report("链接", rel, f"未知协议/域名: {raw}")
+ continue
+ target = unquote(parsed.path)
+ if not target:
+ continue
+ base = page.parent
+ dest = (base / target).resolve()
+ try:
+ dest_rel = dest.relative_to(SITE.resolve())
+ except ValueError:
+ report("链接", rel, f"指向站点外部: {raw}")
+ continue
+ if target.endswith("/"):
+ dest = dest / "index.html"
+ if not dest.exists():
+ report("链接", rel, f"目标不存在: {raw}")
+ broken_links += 1
+ elif parsed.fragment:
+ frag = unquote(parsed.fragment)
+ dest_rel = dest_rel.as_posix()
+ if dest_rel in page_ids and frag not in page_ids[dest_rel]:
+ report("锚点", rel, f"{raw} -> 目标页无 id: {frag}")
+
+# ---------------------------------------------------------------------------
+# 2. HTML 结构检查
+# ---------------------------------------------------------------------------
+VOID = {"area", "base", "br", "col", "embed", "hr", "img", "input",
+ "link", "meta", "param", "source", "track", "wbr"}
+BLOCK = {"html", "head", "body", "div", "main", "header", "footer", "nav",
+ "section", "article", "aside", "ul", "ol", "li", "table", "tbody",
+ "thead", "tr", "td", "th", "form", "p", "h1", "h2", "h3", "h4", "h5",
+ "h6", "pre", "blockquote", "details", "summary", "figure", "picture",
+ "video", "audio", "dl", "dt", "dd", "hr", "fieldset", "option",
+ "select", "textarea", "button", "nav", "template", "svg", "canvas",
+ "iframe", "span", "label", "code", "a", "strong", "em", "b", "i",
+ "small", "sub", "sup", "br", "img", "table", "caption", "colgroup",
+ "style", "script", "noscript"}
+
+for page in HTML_PAGES:
+ rel = page.relative_to(SITE).as_posix()
+ text = page.read_text(encoding="utf-8")
+
+ # doctype
+ if not text.lstrip().lower().startswith("")
+
+ # lang 属性
+ m = re.search(r"]*)>", text, re.I)
+ if not m:
+ report("结构", rel, "缺少 标签")
+ elif not re.search(r"\blang\s*=", m.group(1), re.I):
+ report("SEO", rel, " 缺少 lang 属性")
+
+ # title
+ if not re.search(r"
.+?", text, re.S | re.I):
+ report("SEO", rel, "缺少非空 ")
+
+ # meta description
+ md = re.search(r' prev + 1:
+ report("结构", rel, f"标题层级跳跃 h{prev} -> h{cur}")
+
+ # 标签配对(简单栈式检查,忽略 void 与 script/style 内容)
+ stripped = re.sub(r"<(script|style)\b.*?\1>", "", text, flags=re.S | re.I)
+ stack: list[str] = []
+ for m in re.finditer(r"<(/?)([a-zA-Z][a-zA-Z0-9]*)\b[^>]*?(/?)>", stripped):
+ closing, tag, selfclose = m.group(1), m.group(2).lower(), m.group(3)
+ if tag in VOID or selfclose:
+ continue
+ if closing:
+ if not stack:
+ report("结构", rel, f"多余的 {tag}>")
+ elif stack[-1] != tag:
+ if tag in stack:
+ while stack and stack[-1] != tag:
+ report("结构", rel, f"标签未闭合: <{stack.pop()}>")
+ stack.pop()
+ else:
+ report("结构", rel, f"标签错配: {tag}> 对应 <{stack[-1]}>")
+ stack.pop()
+ else:
+ stack.pop()
+ else:
+ stack.append(tag)
+ for leftover in reversed(stack):
+ report("结构", rel, f"标签未闭合: <{leftover}>")
+
+ # 重复 id
+ ids = [m.group(2) for m in ID_RE.finditer(text)]
+ dupes = [i for i, c in Counter(ids).items() if c > 1]
+ if dupes:
+ report("结构", rel, f"重复 id: {dupes[:5]}")
+
+ # 图片 alt
+ for m in re.finditer(r"
]*>", text, re.I | re.S):
+ if not re.search(r"\balt\s*=", m.group(0), re.I):
+ report("可访问性", rel, f"img 缺少 alt: {m.group(0)[:70]}")
+
+ # 链接文本
+ for m in re.finditer(r"]*)>(.*?)", text, re.S | re.I):
+ attrs, inner = m.group(1), m.group(2)
+ if 'aria-label="' in attrs or "aria-label='" in attrs:
+ continue
+ text_only = re.sub(r"<[^>]+>", "", inner).strip()
+ if not text_only and not re.search(r"\bdownload\b", attrs, re.I):
+ report("可访问性", rel, f"空链接文本: {attrs[:70]}")
+
+ # 按钮缺 type
+ for m in re.finditer(r"