Add Strange Grid problem explanation and interactive tutorial#281
Conversation
✅ Deploy Preview for algorithm-datastructures-math-studies ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
📝 WalkthroughSummary by CodeRabbit
WalkthroughStrange Grid Again の解説教材を追加:問題解析と導出、定式化 f(r,c)=10×floor((r−1)/2)+2×(c−1)+((r−1) mod 2) を使った O(1) 算術解法の説明、複数の Python 実装、対話式ステップ表示・可視化・フローチャート・検証表を備えた自己完結型 HTML と対応する Markdown を公開ディレクトリへ追加し、サイトインデックス生成ロジックを一部整理しました。 Changes
Sequence Diagram(s)(該当なし) Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
public/index.html (1)
419-440:⚠️ Potential issue | 🟠 Majorpublic/index.html の直接編集は不可です
このファイルは自動生成対象のため、変更は
python generate_index.py側で行い再生成してください。現状の直接編集はリリース前に差し戻しが必要です。As per coding guidelines, Do not directly edit
public/index.html- it is auto-generated bypython generate_index.pyAlso applies to: 589-590, 768-768, 788-790
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@public/index.html` around lines 419 - 440, Do not edit public/index.html directly; instead update the generator script python generate_index.py so the generated HTML uses the new site subtitle, search input placeholder/attributes, and tab buttons/content shown in the diff. Modify the generator logic that creates the header/site-subtitle, the search container (elements with id="searchInput", id="searchCount", id="searchClear"), and the tab rendering code that outputs the container with id="categoryTabs" and button elements with class="tab-button" (ensure data-category, data-tab-target, tab-icon and tab-count values match the diff). Regenerate the file with python generate_index.py and verify the output matches the provided snippet.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@Mathematics/Fundamentals/HackerRank/Claude/Easy/Strange` Grid
Again/Strange_Grid_Again.md:
- Around line 175-183: Update the flowchart and the edge-case table to use the
correct column offset formula and expected value: change the CalcCol node
formula from "2 × c - 1" to "2 × (c - 1)" to match the text and use the correct
computation in CalcBase/CalcRow/Sum; then correct the test case for r=100, c=1
in the edge-case table from 490 to 491 so the expected output matches the actual
calculation. Ensure all instances (including nodes CalcBase, CalcCol, CalcRow,
and Sum) and the duplicate section noted (lines ~380-390) are updated
consistently.
- Around line 283-331: The function docstring for strangeGrid is misindented and
the module entry guard is malformed; move the triple-quoted docstring so it is
indented inside the strangeGrid function body (same indentation as the code that
follows it), replace the invalid `if **name** == "**main**":` with the correct
`if __name__ == "__main__":`, and indent everything under that guard (fptr =
open(...), input parsing, call to strangeGrid, fptr.write, fptr.close) so they
are inside the if block; verify names like strangeGrid and fptr remain
unchanged.
In `@public/Mathematics/Fundamentals/HackerRank/Claude/Easy/Strange` Grid
Again/Strange_Grid_Again.html:
- Around line 1047-1443: The code builds HTML via innerHTML for elements
ov-grid, edge-tbody, step-list and vis-content (see the IIFEs that generate the
overview grid and edge cases, and functions renderList and renderVis), which
violates the public/*.html guideline; replace each innerHTML assignment by
constructing nodes with DocumentFragment + document.createElement, set text via
textContent, set classes/attributes via className/setAttribute, and append
children, then append the fragment to the target element; for STEPS[].render
either return a DocumentFragment (or take a container argument) instead of an
HTML string so renderVis can append the fragment to vis-content, and update
renderList to build the step buttons with createElement, set dataset and click
listeners directly rather than injecting HTML. Ensure edge-tbody is built using
tr/td elements created via createElement and populated with textContent.
---
Outside diff comments:
In `@public/index.html`:
- Around line 419-440: Do not edit public/index.html directly; instead update
the generator script python generate_index.py so the generated HTML uses the new
site subtitle, search input placeholder/attributes, and tab buttons/content
shown in the diff. Modify the generator logic that creates the
header/site-subtitle, the search container (elements with id="searchInput",
id="searchCount", id="searchClear"), and the tab rendering code that outputs the
container with id="categoryTabs" and button elements with class="tab-button"
(ensure data-category, data-tab-target, tab-icon and tab-count values match the
diff). Regenerate the file with python generate_index.py and verify the output
matches the provided snippet.
---
Duplicate comments:
In `@Mathematics/Fundamentals/HackerRank/Claude/Easy/Strange` Grid
Again/Strange_Grid_Again.html:
- Around line 1047-1443: The code builds HTML via string concatenation and
assigns it with innerHTML in multiple places (the IIFEs that set 'ov-grid' and
'edge-tbody', the STEPS[].render functions, renderList, and renderVis), which
repeats the public-review concern about XSS and brittle DOM generation; update
these sites to create DOM nodes programmatically instead of building HTML
strings (use document.createElement, element.classList, element.textContent,
appendChild, and dataset for attributes) for the functions/blocks: the top
overview IIFE (that fills ov-grid), the edge cases IIFE (edge-tbody), the STEPS
array render functions, renderList (buttons with .step-btn and data-n), and
renderVis (vis-content), and adjust the cpbtn handler to set button textContent
rather than replacing innerHTML; ensure semantics and classes remain identical
while avoiding innerHTML assignments.
…dy into dev-from-macmini
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
generate_index.py (1)
895-910:⚠️ Potential issue | 🟠 Major
css_catがhtml.escape()されずに HTML 属性値として直接埋め込まれており、コーディングガイドライン違反かつ XSS リスクです
css_cat = category.lower()(Line 895)はエスケープされないままdata-category="{css_cat}"属性(Line 898・905)に埋め込まれています。カテゴリ名はファイルシステムのディレクトリ名から取得されるため、"や<、>を含むディレクトリ名が存在した場合、属性の引用符が崩れるか XSS が成立します。safe_category(Line 896)は正しくhtml.escape(category, quote=True)でエスケープされているため、同様にcss_catもエスケープが必要です。🛡️ 修正案
- css_cat = category.lower() - safe_category = html.escape(category, quote=True) + safe_category = html.escape(category, quote=True) + css_cat = html.escape(category.lower(), quote=True)As per coding guidelines, "Template strings in
generate_index.pymust usehtml.escape()to prevent XSS attacks when embedding user-generated strings in HTML output".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@generate_index.py` around lines 895 - 910, The data-category attribute currently embeds css_cat (set via css_cat = category.lower()) without escaping, introducing an XSS risk; change code to escape the category when used in HTML attributes (e.g., create safe_css_cat = html.escape(category.lower(), quote=True) or reassign css_cat = html.escape(css_cat, quote=True)) and then use safe_css_cat in the template attributes instead of css_cat—update the occurrences in the tab button (data-category on the tab-button in the string built for tabs_html) and the list item (data-category in item_html used for file_list_html/all_files_html) so all attribute insertions are passed through html.escape(..., quote=True).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@generate_index.py`:
- Line 627: The template literal for the clear-search button uses the
multiplication sign "×" which triggers Ruff RUF001; locate the string that
renders the button (look for the HTML fragment containing id="searchClear" and
class="search-clear") and replace the literal "×" with a non-ambiguous
representation — either the HTML entity "×" or the Python Unicode escape
"\u00D7" inside the Python string — ensuring proper quoting/escaping so the
rendered HTML shows the same glyph without the ambiguous character.
In `@Mathematics/Fundamentals/HackerRank/Claude/Easy/Strange` Grid
Again/Strange_Grid_Again.html:
- Around line 1142-1162: The string assigned to the variable code inside the
cpbtn click handler spans multiple lines using single quotes which causes a JS
SyntaxError; change the assignment to use a template literal (replace the
surrounding single quotes with backticks) or join each line with + so the Python
source is a valid single-line JS string—update the code variable in the
document.getElementById('cpbtn').addEventListener(...) block accordingly.
In `@Mathematics/Fundamentals/HackerRank/Claude/Easy/Strange` Grid
Again/Strange_Grid_Again.md:
- Around line 208-209: 説明文の偶奇が逆になっています: 変数名 row_offset と計算式 row_offset = (r-1) %
2 を参照して、現在「各グループの偶数行目が row_offset=0、奇数行目が row_offset=1」と記載されている箇所を修正し、「奇数行 (r
が奇数) が row_offset=0、偶数行 (r が偶数) が row_offset=1」と書き換えてください(参照シンボル: row_offset, r,
row_offset = (r-1) % 2)。
In `@public/index.html`:
- Around line 419-420: public/index.html is auto-generated and must not be
edited directly; instead update the generator script generate_index.py to change
the subtitle (the content that produces the <p class="site-subtitle"> element)
and then re-run the generator to produce a new public/index.html; ensure the
change is made in generate_index.py (the template/data that writes the
site-subtitle) and commit the regenerated file rather than hand-editing
public/index.html.
In `@public/Mathematics/Fundamentals/HackerRank/Claude/Easy/Strange` Grid
Again/Strange_Grid_Again.html:
- Around line 1142-1162: The JS string assigned to variable "code" inside the
'cpbtn' click listener contains literal newlines but is wrapped in single
quotes, causing a SyntaxError; replace the single-quoted multiline string with a
template literal (backticks) so the Python code block can contain newlines, then
ensure navigator.clipboard.writeText(code) still receives that string unchanged.
---
Outside diff comments:
In `@generate_index.py`:
- Around line 895-910: The data-category attribute currently embeds css_cat (set
via css_cat = category.lower()) without escaping, introducing an XSS risk;
change code to escape the category when used in HTML attributes (e.g., create
safe_css_cat = html.escape(category.lower(), quote=True) or reassign css_cat =
html.escape(css_cat, quote=True)) and then use safe_css_cat in the template
attributes instead of css_cat—update the occurrences in the tab button
(data-category on the tab-button in the string built for tabs_html) and the list
item (data-category in item_html used for file_list_html/all_files_html) so all
attribute insertions are passed through html.escape(..., quote=True).
---
Duplicate comments:
In `@Mathematics/Fundamentals/HackerRank/Claude/Easy/Strange` Grid
Again/Strange_Grid_Again.md:
- Around line 215-220:
データフロー図の式表記が曖昧なので、ノードラベルを本文の公式表記に合わせて明示的な括弧を使うよう修正してください(例:G のラベルを "g = floor((r
- 1) / 2)" に、CO のラベルを "col_offset = 2 × (c - 1)" に変更し、必要なら RO や B
の表記も本文と同じ形式に揃えてください);対象は Mermaid ノード識別子 G, CO, RO, B, R, C です。
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
generate_index.py (1)
179-183: 🧹 Nitpick | 🔵 Trivialカテゴリ順が非決定的になっています
Line 179-183 で
sorted_categoriesを作成していますが、Line 896 のstructure.items()では未使用のためos.walkの順序に依存します。生成HTMLの差分安定化のため、ソート済みカテゴリで描画してください。🔧 修正案
- def render_category_files(structure): + def render_category_files(structure, categories): tabs_html_list = [] files_html_sections = [] all_files_html_list = [] # Renamed to avoid conflict with outer scope all_files_html - - for category, files in structure.items(): + for category in categories: + files = structure[category] css_cat = html.escape(category.lower(), quote=True) safe_category = html.escape(category, quote=True) icon = category_icons.get(category, '📁') # Default icon if not found @@ - tabs_html, tab_contents_html, all_files_html = render_category_files(structure) + tabs_html, tab_contents_html, all_files_html = render_category_files(structure, sorted_categories)Also applies to: 891-926
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@generate_index.py` around lines 179 - 183, sorted_categories is computed but never used, causing category iteration to depend on os.walk order; update the rendering/iteration that currently loops over structure (e.g., the block that calls structure.items() to build/generate HTML) to instead iterate over sorted_categories and use structure[cat] for each category, and ensure files within each category are sorted (structure[cat].sort) before rendering; apply the same change to the other rendering loop referenced (the code covering the range around the second instance) so both outputs use deterministic sorted_categories rather than structure iteration order.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@Mathematics/Fundamentals/HackerRank/Claude/Easy/Strange` Grid
Again/Strange_Grid_Again.html:
- Around line 391-408: The .cpbtn style lacks a keyboard focus state, so add a
:focus and/or :focus-visible rule for .cpbtn (in addition to the existing
.cpbtn:hover) that provides a visible, high-contrast focus indicator (e.g., an
outline or box-shadow that respects border-radius) and retains the transition
and cursor behavior; ensure the focus style is clearly visible against the
button background (use a contrasting color or thicker ring) and include
:focus-visible to avoid showing the ring on mouse clicks while preserving
keyboard accessibility.
- Around line 807-812: フローチャートの説明文で使われている "base = 10g" 表記が SVG の "base = 10 × g"
と不一致なので、説明文内の該当テキスト(現在 "base = 10g" と書かれている箇所)を "base = 10 × g"
に変更して表記を統一してください(または逆に SVG を変更する場合は SVG 内の "base = 10 × g" を "base = 10g"
に揃えるなど、同一セクション内でどちらかの表記に統一すること)。
- Around line 1181-1253: The render logic that builds the header, rows and cells
is duplicated across the three render functions; extract a single helper (e.g.,
buildGridFragment or createGridPreview) that accepts COLS, rows and the cellVal
accessor and returns the DocumentFragment (or wrapper element) containing the
header, gp-row rows, rl labels, cell elements with class 'cell' + ca/cb logic
and the legend, then replace each render implementation to call that helper
(pass the same COLS and the local cellVal closure or a cell-value callback) so
all header generation, row labeling and class assignment (g =
Math.floor((r-1)/2); g % 2 === 0 ? 'ca' : 'cb') is centralized.
- Around line 1037-1039: Update the footer text: locate the <footer> element
that currently contains the string "Python CPython 3.13.3" and change it to
"Python CPython 3.12.4" so the displayed HackerRank Python version matches the
judge environment.
- Around line 1147-1173: The click handler on element 'cpbtn' assumes
navigator.clipboard exists and never handles errors or cancels prior timeouts;
update the event listener for 'cpbtn' to first verify navigator.clipboard and
that writeText is a function, then call
navigator.clipboard.writeText(code).then(...) and append a .catch(...) to set an
error state (change button text to a failure message) and optionally log the
error; introduce a module-scoped timeoutId (e.g., let copyTimeoutId: number |
null = null) used by the handler to clearTimeout(copyTimeoutId) before
scheduling setTimeout to revert the button text so repeated clicks won't stack
timers; ensure you reference the existing symbols (cpbtn element, the inline
click handler, navigator.clipboard.writeText, and the setTimeout used to revert
the button text) when making these changes.
In `@Mathematics/Fundamentals/HackerRank/Claude/Easy/Strange` Grid
Again/Strange_Grid_Again.md:
- Around line 138-142: ドキュメントの「各グループの先頭値(列 c=1, 偶数行)」の説明が row_offset=0
と矛盾しているので、「偶数行」を「奇数行(下行)」に修正してください;対象の箇所は式 base = 10 · g とその直前の row_offset=0
の説明に関連する文言を更新し、"列 c=1, 奇数行(下行)" のように表記を一致させてください。
---
Outside diff comments:
In `@generate_index.py`:
- Around line 179-183: sorted_categories is computed but never used, causing
category iteration to depend on os.walk order; update the rendering/iteration
that currently loops over structure (e.g., the block that calls
structure.items() to build/generate HTML) to instead iterate over
sorted_categories and use structure[cat] for each category, and ensure files
within each category are sorted (structure[cat].sort) before rendering; apply
the same change to the other rendering loop referenced (the code covering the
range around the second instance) so both outputs use deterministic
sorted_categories rather than structure iteration order.
---
Duplicate comments:
In `@Mathematics/Fundamentals/HackerRank/Claude/Easy/Strange` Grid
Again/Strange_Grid_Again.html:
- Around line 1147-1173: The template literal fix is already applied inside the
click handler attached to document.getElementById('cpbtn') (the backticked code
variable), but the review comment contains a leftover "[duplicate_comment]"
marker; remove that stray marker from the comment/content so the review is clean
and only acknowledges the applied fix.
…in and index generation
…dy into dev-from-macmini
|
Note Docstrings generation - SUCCESS |
Docstrings generation was requested by @myoshi2891. * #281 (comment) The following files were modified: * `generate_index.py`
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@Mathematics/Fundamentals/HackerRank/Claude/Easy/Strange` Grid
Again/Strange_Grid_Again.html:
- Around line 409-416: The CSS contains duplicate rules for the selectors
.cpbtn:focus and .cpbtn:focus-visible (the identical blocks shown twice); remove
one of the duplicated rule blocks so each selector pair is defined only once,
keeping the remaining block with outline: 2px solid var(--gd); outline-offset:
2px to preserve the intended styling.
- Around line 1185-1277: There are two identical definitions of
buildGridFragment which is a copy-paste duplicate; remove one of them so only a
single buildGridFragment function remains (e.g., delete the earlier duplicate
block) and keep the other intact, ensuring any external callers still reference
the single remaining buildGridFragment.
In `@Mathematics/Fundamentals/HackerRank/Claude/Easy/Strange` Grid
Again/Strange_Grid_Again.md:
- Around line 107-112: The overview grid in the summary has rows within each
2-row group reversed, causing a mismatch with the defined function f(r,c) =
10*((r-1)//2) + 2*(c-1) + (r-1)%2; update the table so Row 6 contains 21, Row 5
contains 20 (and likewise Row 4=11, Row 3=10, etc.) to match f(r,c) and the
example r=6,c=3 -> 25; ensure the displayed rows follow the same ordering logic
used by f(r,c) throughout the document.
---
Duplicate comments:
In `@Mathematics/Fundamentals/HackerRank/Claude/Easy/Strange` Grid
Again/Strange_Grid_Again.html:
- Around line 1154-1181: The clipboard handler for the element with id 'cpbtn'
needs to guard against navigator.clipboard being undefined, add error handling,
and prevent stacked timeouts: check if navigator.clipboard and
navigator.clipboard.writeText exist and if not fall back to creating a temporary
textarea and document.execCommand('copy'); call
navigator.clipboard.writeText(...).then(...) and add .catch(...) to set an error
message (e.g., 'コピー失敗' or similar) so the user gets feedback on permission
denial; also store the setTimeout id in a variable (e.g., copyTimeout) and
clearTimeout(copyTimeout) before setting a new timeout so repeated clicks don’t
accumulate, and ensure you update the button text in both success and failure
branches.
In `@public/index.html`:
- Around line 419-420: The generated site subtitle in the <p
class="site-subtitle"> element is correct and matches the counts produced by
generate_index.py (84 + 6 + 35 + 11 + 13 + 3 = 152), so no code change is
required; leave public/index.html as-is and keep the regeneration flow from
generate_index.py intact.
📝 Add docstrings to `dev-from-macmini`
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@generate_index.py`:
- Around line 928-930: item_html is built using backslash line-continuation
which triggers Ruff ISC002; change it to use a single parenthesized f-string
expression instead of backslashes. Locate the item_html assignment and replace
the chained string with a parenthesized expression like item_html =
(f'...{encoded_path}...' f'...{icon}...' f'...{safe_title}...'
f'...{safe_github_path}...') so the concatenation is explicit and Ruff ISC002 is
satisfied.
- Around line 913-930: The icon variable is inserted into HTML without escaping;
create a escaped version (e.g., safe_icon = html.escape(icon)) and use safe_icon
wherever icon is embedded in the templates (references: the
tabs_html_list.append call that uses '<span class="tab-icon">{icon}</span>' and
the item_html construction that uses '<span class="card-icon">{icon}</span>'),
ensuring all usages of icon in generate_index.py are replaced with the escaped
safe_icon to satisfy the HTML-escaping guideline.
- Line 891: render_category_files が外部変数 category_icons を暗黙参照しており戻り型注釈がないため Ruff
ANN202 を引いています。render_category_files に戻り型アノテーションを追加し(例: -> None
または適切な型)、category_icons
を関数シグネチャに明示的な引数として追加し、関数内で直接その引数を参照するように修正してから、この関数を呼んでいる箇所すべてを更新して現在の暗黙の外部変数ではなく新しい
category_icons 引数を渡すようにしてください。
| file_list_html += '</ul>' | ||
|
|
||
| tab_contents_html += f'<div id="{safe_category}" class="tab-content">\n{file_list_html}\n<div class="no-results"><span class="no-results-icon">\U0001F50E</span>No results found</div>\n</div>\n' | ||
| def render_category_files(structure, sorted_categories): |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
render_category_files に戻り型アノテーションを追加し、category_icons の依存を明示してください
Ruff ANN202 警告が出ています。また、この関数はパラメータに宣言されていない外部スコープの category_icons を暗黙的に参照(クロージャー)しています。将来この関数をメソッドやモジュールレベルの関数に昇格させる際に問題になりえます。
♻️ 修正案
- def render_category_files(structure, sorted_categories):
+ def render_category_files(
+ structure: Dict[str, List[Tuple[str, str]]],
+ sorted_categories: List[str],
+ icons: Dict[str, str] | None = None,
+ ) -> Tuple[str, str, str]:
"""
Builds HTML fragments for category tabs, per-category file lists, and an aggregated all-files list.
...
"""
+ if icons is None:
+ icons = category_icons呼び出し側:
- tabs_html, tab_contents_html, all_files_html = render_category_files(structure, sorted_categories)
+ tabs_html, tab_contents_html, all_files_html = render_category_files(structure, sorted_categories, category_icons)🧰 Tools
🪛 Ruff (0.15.1)
[warning] 891-891: Missing return type annotation for private function render_category_files
(ANN202)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@generate_index.py` at line 891, render_category_files が外部変数 category_icons
を暗黙参照しており戻り型注釈がないため Ruff ANN202 を引いています。render_category_files に戻り型アノテーションを追加し(例:
-> None または適切な型)、category_icons
を関数シグネチャに明示的な引数として追加し、関数内で直接その引数を参照するように修正してから、この関数を呼んでいる箇所すべてを更新して現在の暗黙の外部変数ではなく新しい
category_icons 引数を渡すようにしてください。
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Create a GitHub issue for the review comment about render_category_files
gh issue create \
--repo myoshi2891/Algorithm-DataStructures-Math-SQL \
--title "generate_index.py: render_category_files に戻り型アノテーションを追加し category_icons の依存を明示" \
--body "## 概要
\`generate_index.py\` の \`render_category_files\` 関数に以下の問題があります:
1. **Ruff ANN202 警告**: 戻り型アノテーションが欠落しています
2. **暗黙的なクロージャー参照**: 関数が外部スコープの \`category_icons\` を暗黙的に参照しており、将来この関数をメソッドやモジュールレベルの関数に昇格させる際に問題になりえます
## 対応内容
- \`render_category_files\` に適切な戻り型アノテーション (\`-> Tuple[str, str, str]\`) を追加
- \`category_icons\` を関数の明示的な引数として追加
- 関数呼び出し箇所を更新して \`category_icons\` を引数として渡すように修正
## 関連リンク
- PR: https://github.com/myoshi2891/Algorithm-DataStructures-Math-SQL/pull/281
- レビューコメント: https://github.com/myoshi2891/Algorithm-DataStructures-Math-SQL/pull/281#discussion_r2835742513
- 報告者: `@myoshi2891`" \
--assignee myoshi2891
Length of output: 74
@myoshi2891, issue を作成しました! 🎫
Issue #283: generate_index.py: render_category_files に戻り型アノテーションを追加し category_icons の依存を明示
| icon = category_icons.get(category, '📁') # Default icon if not found | ||
|
|
||
| tabs_html_list.append(f'<button class="tab-button" data-category="{css_cat}" data-tab-target="{safe_category}">' | ||
| f'<span class="tab-icon">{icon}</span> {safe_category} ' | ||
| f'<span class="tab-count">{len(files)}</span></button>\n') | ||
|
|
||
| file_list_html = '<ul class="file-list">\n' | ||
| category_files = [] | ||
| for title, path in files: | ||
| encoded_path = urllib.parse.quote(path) | ||
| # Use standard GitHub-style path (assuming 'path' is already relative or suitable) | ||
| github_path = path # Assuming 'path' is already the desired relative path | ||
| safe_title = html.escape(title) | ||
| safe_github_path = html.escape(github_path) # Escape path for display | ||
|
|
||
| item_html = f'<li class="file-item" data-category="{css_cat}"><a class="file-link" href="{encoded_path}">' \ | ||
| f'<span class="card-header"><span class="card-icon">{icon}</span>' \ | ||
| f'<span class="card-title">{safe_title}</span></span><span class="file-path">{safe_github_path}</span></a></li>\n' |
There was a problem hiding this comment.
icon 変数を html.escape() でエスケープしてください(コーディングガイドライン違反)
icon(行 916・929)は HTML エスケープなしで直接テンプレートに埋め込まれています。現在の値は全て絵文字(HTML 特殊文字なし)なので実害はありませんが、ガイドラインでは「HTML 出力に埋め込む文字列は html.escape() を使用すること」が義務付けられています。
🛡️ 修正案
icon = category_icons.get(category, '📁') # Default icon if not found
+ safe_icon = html.escape(icon)
tabs_html_list.append(f'<button class="tab-button" data-category="{css_cat}" data-tab-target="{safe_category}">'
- f'<span class="tab-icon">{icon}</span> {safe_category} '
+ f'<span class="tab-icon">{safe_icon}</span> {safe_category} '
f'<span class="tab-count">{len(files)}</span></button>\n')
...
item_html = f'<li class="file-item" data-category="{css_cat}"><a class="file-link" href="{encoded_path}">' \
- f'<span class="card-header"><span class="card-icon">{icon}</span>' \
+ f'<span class="card-header"><span class="card-icon">{safe_icon}</span>' \
f'<span class="card-title">{safe_title}</span></span><span class="file-path">{safe_github_path}</span></a></li>\n'Based on learnings: "Applies to generate_index.py : Template strings in generate_index.py must use html.escape() to prevent XSS attacks when embedding user-generated strings in HTML output"
🧰 Tools
🪛 Ruff (0.15.1)
[warning] 928-929: Implicitly concatenated string literals over multiple lines
(ISC002)
[warning] 929-930: Implicitly concatenated string literals over multiple lines
(ISC002)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@generate_index.py` around lines 913 - 930, The icon variable is inserted into
HTML without escaping; create a escaped version (e.g., safe_icon =
html.escape(icon)) and use safe_icon wherever icon is embedded in the templates
(references: the tabs_html_list.append call that uses '<span
class="tab-icon">{icon}</span>' and the item_html construction that uses '<span
class="card-icon">{icon}</span>'), ensuring all usages of icon in
generate_index.py are replaced with the escaped safe_icon to satisfy the
HTML-escaping guideline.
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Create a GitHub issue for the HTML escaping guideline violation
gh issue create \
--repo myoshi2891/Algorithm-DataStructures-Math-SQL \
--title "generate_index.py: icon変数のHTMLエスケープ処理が必要" \
--body "## 概要
\`generate_index.py\` 内の \`icon\` 変数が HTML エスケープなしで直接テンプレートに埋め込まれています。
## 詳細
現在の実装では、\`icon\` 変数(絵文字)が \`html.escape()\` を通さずに HTML テンプレートに挿入されています。現状では全て絵文字のため実害はありませんが、コーディングガイドラインでは「HTML 出力に埋め込む文字列は \`html.escape()\` を使用すること」が義務付けられています。
## 影響範囲
- 行 916, 929 付近
- \`tabs_html_list.append()\` 呼び出し内の \`<span class=\"tab-icon\">{icon}</span>\`
- \`item_html\` 構築内の \`<span class=\"card-icon\">{icon}</span>\`
## 参照
- PR: https://github.com/myoshi2891/Algorithm-DataStructures-Math-SQL/pull/281
- コメント: https://github.com/myoshi2891/Algorithm-DataStructures-Math-SQL/pull/281#discussion_r2835742517
- 報告者: `@myoshi2891`" \
--assignee myoshi2891
Length of output: 74
@myoshi2891 さん、イシューを作成しました!
📋 Issue #284: generate_index.py: icon変数のHTMLエスケープ処理が必要
このイシューには以下が含まれています:
- 問題の概要と詳細
- 影響範囲(行番号と該当箇所)
- このPRとコメントへのバックリンク
- 担当者としてあなたを設定
後続のPRで対応していただけます 🙌
🧠 Learnings used
Learnt from: CR
Repo: myoshi2891/Algorithm-DataStructures-Math-SQL PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-20T07:21:45.802Z
Learning: Applies to generate_index.py : Template strings in `generate_index.py` must use `html.escape()` to prevent XSS attacks when embedding user-generated strings in HTML output
| item_html = f'<li class="file-item" data-category="{css_cat}"><a class="file-link" href="{encoded_path}">' \ | ||
| f'<span class="card-header"><span class="card-icon">{icon}</span>' \ | ||
| f'<span class="card-title">{safe_title}</span></span><span class="file-path">{safe_github_path}</span></a></li>\n' |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
暗黙的な文字列連結を括弧で囲んでください(Ruff ISC002)
バックスラッシュによる暗黙的な複数行文字列連結は Ruff ISC002 警告の対象です。括弧を使った明示的な記法に変更してください。
♻️ 修正案
- item_html = f'<li class="file-item" data-category="{css_cat}"><a class="file-link" href="{encoded_path}">' \
- f'<span class="card-header"><span class="card-icon">{icon}</span>' \
- f'<span class="card-title">{safe_title}</span></span><span class="file-path">{safe_github_path}</span></a></li>\n'
+ item_html = (
+ f'<li class="file-item" data-category="{css_cat}"><a class="file-link" href="{encoded_path}">'
+ f'<span class="card-header"><span class="card-icon">{icon}</span>'
+ f'<span class="card-title">{safe_title}</span></span><span class="file-path">{safe_github_path}</span></a></li>\n'
+ )🧰 Tools
🪛 Ruff (0.15.1)
[warning] 928-929: Implicitly concatenated string literals over multiple lines
(ISC002)
[warning] 929-930: Implicitly concatenated string literals over multiple lines
(ISC002)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@generate_index.py` around lines 928 - 930, item_html is built using backslash
line-continuation which triggers Ruff ISC002; change it to use a single
parenthesized f-string expression instead of backslashes. Locate the item_html
assignment and replace the chained string with a parenthesized expression like
item_html = (f'...{encoded_path}...' f'...{icon}...' f'...{safe_title}...'
f'...{safe_github_path}...') so the concatenation is explicit and Ruff ISC002 is
satisfied.
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Create GitHub issue for Ruff ISC002 warning
gh issue create \
--title "generate_index.py の暗黙的な文字列連結を修正 (Ruff ISC002)" \
--body "## 概要
\`generate_index.py\` の928-930行目で、バックスラッシュによる暗黙的な複数行文字列連結が使用されており、Ruff ISC002 警告が発生しています。括弧を使った明示的な記法に変更する必要があります。
## 関連リンク
- プルリクエスト: https://github.com/myoshi2891/Algorithm-DataStructures-Math-SQL/pull/281
- コメント: https://github.com/myoshi2891/Algorithm-DataStructures-Math-SQL/pull/281#discussion_r2835742520
## 対象箇所
ファイル: \`generate_index.py\`
行: 928-930
\`item_html\` の構築において、バックスラッシュによる行継続ではなく、括弧で囲んだ明示的な文字列連結に変更してください。
---
_リクエスト者: `@myoshi2891_`" \
--assignee myoshi2891
Length of output: 74
@myoshi2891 issueを作成しました!
Ruff ISC002 警告に関する issue はこちらです:
#285
generate_index.py の暗黙的な文字列連結を括弧を使った明示的な記法に修正する内容で、あなたにアサインしました。
…dy into dev-from-macmini
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@Mathematics/Fundamentals/HackerRank/Claude/Easy/Strange` Grid
Again/Strange_Grid_Again.md:
- Around line 1-22: The file starts with an H2 ("## 問題分析") while the H1 ("#
Strange Grid - 無限グリッドの座標値算出") appears later, breaking Markdown hierarchy; fix by
moving or adding an H1 at the top—either promote the existing "## 問題分析" to "#
問題分析" or insert an appropriate H1 (e.g., "# Strange Grid - 無限グリッドの座標値算出") before
"## 問題分析" so the document begins with a single top-level heading and preserves
proper nesting.
In `@public/index.html`:
- Line 589: Update the HTML title in the source file Strange_Grid_Again.html so
it includes "Again" (e.g., change the <title> text to "Strange Grid Again 解説" or
an equivalent Japanese title containing "Again"); this ensures generate_index.py
extracts the correct display title and the entry rendered by public/index.html
will show "Strange Grid Again 解説".
In `@public/Mathematics/Fundamentals/HackerRank/Claude/Easy/Strange` Grid
Again/Strange_Grid_Again.html:
- Around line 201-293: The .step-btn and button.ctrl controls lack keyboard
focus styles; add :focus and :focus-visible rules for .step-btn and for
button.ctrl (and optionally for .step-btn.active) that mirror the existing
.cpbtn focus behavior (use a clear outline/box-shadow and slight transform) so
keyboard users get a visible focus indicator consistent with .cpbtn and WCAG
2.4.7; update the CSS rules near the .step-btn and button.ctrl definitions to
include these focus selectors and ensure they are not applied when :disabled.
- Around line 1052-1098: The IIFE that builds the overview grid duplicates the
same header/row/cell generation logic already refactored into buildGridFragment;
remove the duplicated code inside the IIFE and call buildGridFragment(...)
instead (pass the same parameters or adapt its signature if needed) so the
overview uses the shared implementation; locate the anonymous self-invoking
function around the overview grid (the block that reads rows = [6,5,4,3,2,1],
cols = [1,2,3,4,5] and appends to element 'ov-grid') and replace its internal
logic with a call to buildGridFragment/append the returned fragment, ensuring
any styling or class names (gp-row, rl, cell, ca, cb) remain consistent with
STEPS.render uses.
---
Duplicate comments:
In `@Mathematics/Fundamentals/HackerRank/Claude/Easy/Strange` Grid
Again/Strange_Grid_Again.html:
- Around line 201-223: The .step-btn and button.ctrl selectors are missing
:focus-visible styles; update the CSS to add matching :focus-visible rules for
.step-btn:focus-visible and button.ctrl:focus-visible (consistent with the
existing .cpbtn:focus-visible in the public copy) so keyboard focus shows the
same outline/border/box-shadow behavior as .cpbtn; ensure the styles mirror the
public file's diff (include border-color/box-shadow/outline adjustments and any
focus-visible-specific background or transform) and keep them grouped with the
existing .step-btn and button.ctrl rules to maintain consistency.
- Around line 1052-1098: The inline IIFE that builds the overview grid
duplicates the logic in buildGridFragment; remove that IIFE and replace it with
a single call to the shared buildGridFragment helper (passing the same rows and
cols arrays and the cellVal accessor) to produce the fragment, then clear and
append it to the 'ov-grid' element. Specifically: remove the entire (function ()
{ ... })(); block, define rows = [6,5,4,3,2,1] and cols = [1,2,3,4,5] as before,
call var frag = buildGridFragment(rows, cols, cellVal), then do
target.textContent = '' and target.appendChild(frag); ensure references to
cellVal and class names (gp-row, rl, cell, ca, cb) remain handled inside
buildGridFragment.
In `@public/index.html`:
- Around line 419-420: This HTML fragment is from an autogenerated file so do
not modify it manually; confirm the p element with class "site-subtitle" is
produced by the regeneration script and, if changes are needed, update the
generator (update_index.sh) and re-run it to regenerate public/index.html rather
than editing p.site-subtitle directly; revert any manual edits in this PR and
add a short PR note stating the file is autogenerated to avoid duplicate
comments.
| ## 問題分析 | ||
|
|
||
| グリッドのパターンを観察します: | ||
|
|
||
| | Row | c=1 | c=2 | c=3 | c=4 | c=5 | | ||
| | --- | --- | --- | --- | --- | --- | | ||
| | 1 | 0 | 2 | 4 | 6 | 8 | | ||
| | 2 | 1 | 3 | 5 | 7 | 9 | | ||
| | 3 | 10 | 12 | 14 | 16 | 18 | | ||
| | 4 | 11 | 13 | 15 | 17 | 19 | | ||
| | 5 | 20 | 22 | 24 | 26 | 28 | | ||
| | 6 | 21 | 23 | 25 | 27 | 29 | | ||
|
|
||
| **法則:** | ||
|
|
||
| - 行は2行1組のグループ `g = (r-1) // 2`(0-indexed)を形成 | ||
| - グループ内の基底値: `base = 10 * g` | ||
| - 列のオフセット: `2 * (c-1)`(各列は偶数ステップ) | ||
| - グループ内の行オフセット: `(r-1) % 2`(1行目=0, 2行目=1) | ||
|
|
||
| **計算式:** `answer = 10 * ((r-1) // 2) + 2 * (c-1) + (r-1) % 2` | ||
|
|
There was a problem hiding this comment.
ファイル冒頭の見出し階層が不正です
ファイルが ## 問題分析(H2)から始まり、対応する H1 見出しが line 79 の # Strange Grid - 無限グリッドの座標値算出 まで登場しません。標準的な Markdown 階層では H2 は H1 の子要素であり、GitHub ビューや各種 Markdown レンダラーで見出しツリーが崩れます。
lines 1-77 のセクションに H1 タイトルを追加するか、このセクションを H1 の後に移動することを検討してください。
💡 修正案(H1 を先頭に追加)
+# Strange Grid — 問題分析と実装
+
## 問題分析🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@Mathematics/Fundamentals/HackerRank/Claude/Easy/Strange` Grid
Again/Strange_Grid_Again.md around lines 1 - 22, The file starts with an H2 ("##
問題分析") while the H1 ("# Strange Grid - 無限グリッドの座標値算出") appears later, breaking
Markdown hierarchy; fix by moving or adding an H1 at the top—either promote the
existing "## 問題分析" to "# 問題分析" or insert an appropriate H1 (e.g., "# Strange
Grid - 無限グリッドの座標値算出") before "## 問題分析" so the document begins with a single
top-level heading and preserves proper nesting.
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Create a GitHub issue for the Markdown heading hierarchy problem
gh issue create \
--title "Strange_Grid_Again.md: Markdown見出し階層の修正が必要" \
--body "## 問題
\`Mathematics/Fundamentals/HackerRank/Claude/Easy/Strange Grid Again/Strange_Grid_Again.md\` ファイルが H2 見出し (\`## 問題分析\`) から始まっており、対応する H1 見出しが後方(79行目)に登場します。
標準的な Markdown 階層では H2 は H1 の子要素であり、GitHub ビューや各種 Markdown レンダラーで見出しツリーが崩れる可能性があります。
## 修正方針
以下のいずれかの対応を検討してください:
1. ファイル冒頭に H1 タイトルを追加
2. 既存の H1 をファイル先頭に移動
3. 冒頭の \`## 問題分析\` を H1 に昇格
## 関連情報
- PR: https://github.com/myoshi2891/Algorithm-DataStructures-Math-SQL/pull/281
- コメント: https://github.com/myoshi2891/Algorithm-DataStructures-Math-SQL/pull/281#discussion_r2835766478
- 報告者: `@myoshi2891`" \
--assignee myoshi2891
Length of output: 74
@myoshi2891 承知しました!Markdown見出し階層の問題について issue を作成しました:
Issue #286: Strange_Grid_Again.md: Markdown見出し階層の修正が必要
このissueには修正方針と関連情報(PR・コメントへのリンク)を含めています。
| <li class="file-item" data-category="mathematics"><a class="file-link" href="Mathematics/Palindrome/leetcode/9.%20Palindrome%20Number/claud%20sonnet%204.5/README_react.html"><span class="card-header"><span class="card-icon">📐</span><span class="card-title">LeetCode 9: Palindrome Number - 数値反転による回文判定</span></span><span class="file-path">Mathematics/Palindrome/leetcode/9. Palindrome Number/claud sonnet 4.5/README_react.html</span></a></li> | ||
| <li class="file-item" data-category="mathematics"><a class="file-link" href="Mathematics/Fundamentals/HackerRank/Claude/Easy/moving-tiles-visualization.html"><span class="card-header"><span class="card-icon">📐</span><span class="card-title">Moving Tiles - 重なり面積の時間逆算</span></span><span class="file-path">Mathematics/Fundamentals/HackerRank/Claude/Easy/moving-tiles-visualization.html</span></a></li> | ||
| <li class="file-item" data-category="mathematics"><a class="file-link" href="Mathematics/Combination%20Calculation/leetcode/62.%20Unique%20Paths/Claude/README.html"><span class="card-header"><span class="card-icon">📐</span><span class="card-title">Robot Unique Paths - 技術解説</span></span><span class="file-path">Mathematics/Combination Calculation/leetcode/62. Unique Paths/Claude/README.html</span></a></li> | ||
| <li class="file-item" data-category="mathematics"><a class="file-link" href="Mathematics/Fundamentals/HackerRank/Claude/Easy/Strange%20Grid%20Again/Strange_Grid_Again.html"><span class="card-header"><span class="card-icon">📐</span><span class="card-title">Strange Grid 解説</span></span><span class="file-path">Mathematics/Fundamentals/HackerRank/Claude/Easy/Strange Grid Again/Strange_Grid_Again.html</span></a></li> |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
fd "Strange_Grid_Again.html" --exec sh -c 'echo "=== File: {} ===" && head -100 "{}" | grep -E "<title|<h1" && echo "---" && tail -50 "{}"'Repository: myoshi2891/Algorithm-DataStructures-Math-SQL
Length of output: 3852
🏁 Script executed:
find . -name "generate_index.py" -type fRepository: myoshi2891/Algorithm-DataStructures-Math-SQL
Length of output: 107
🏁 Script executed:
cat generate_index.py | head -100Repository: myoshi2891/Algorithm-DataStructures-Math-SQL
Length of output: 5335
Strange_Grid_Again.html のタイトルに「Again」を追加してください
Strange_Grid_Again.html の <title> タグが現在 Strange Grid 解説 となっており、問題名の Again が欠落しています。generate_index.py は各ソース HTML の <title> タグから表示タイトルを抽出するため、ソース HTML のタイトルを修正する必要があります。
<title>Strange Grid Again 解説</title> のように「Again」を含めるか、適切な日本語タイトルに修正してください。修正すると、自動生成される public/index.html のカードタイトルも正しく更新されます。
Also applies to: 768-768
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@public/index.html` at line 589, Update the HTML title in the source file
Strange_Grid_Again.html so it includes "Again" (e.g., change the <title> text to
"Strange Grid Again 解説" or an equivalent Japanese title containing "Again");
this ensures generate_index.py extracts the correct display title and the entry
rendered by public/index.html will show "Strange Grid Again 解説".
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Create GitHub issue for the missing "Again" in Strange_Grid_Again.html title
gh issue create \
--title "Strange_Grid_Again.html のタイトルに「Again」が欠落" \
--body "## 問題
\`Strange_Grid_Again.html\` の \`<title>\` タグが現在「Strange Grid 解説」となっており、問題名の **Again** が欠落しています。
\`generate_index.py\` は各ソース HTML の \`<title>\` タグから表示タイトルを抽出するため、ソース HTML のタイトルを修正する必要があります。
## 関連
- PR: https://github.com/myoshi2891/Algorithm-DataStructures-Math-SQL/pull/281
- コメント: https://github.com/myoshi2891/Algorithm-DataStructures-Math-SQL/pull/281#discussion_r2835766480
## 期待される動作
\`<title>Strange Grid Again 解説</title>\` のように「Again」を含むタイトルに修正することで、自動生成される \`public/index.html\` のカードタイトルも正しく「Strange Grid Again 解説」と表示されるようになります。
## 対象ファイル
- \`Mathematics/Fundamentals/HackerRank/Claude/Easy/Strange Grid Again/Strange_Grid_Again.html\`
---
_Issue created by `@coderabbitai` based on review comment by `@myoshi2891_`" \
--assignee myoshi2891
Length of output: 74
@myoshi2891 Issue を作成しました!
Issue #287: Strange_Grid_Again.html のタイトルに「Again」が欠落
| .step-btn { | ||
| width: 100%; | ||
| text-align: left; | ||
| border-radius: 0.9rem; | ||
| border: 2px solid #e2e8f0; | ||
| background: #fff; | ||
| padding: 0.8rem 1rem; | ||
| cursor: pointer; | ||
| transition: all 0.18s; | ||
| font-family: inherit; | ||
| margin-bottom: 6px; | ||
| display: block; | ||
| } | ||
| .step-btn:hover { | ||
| border-color: var(--green); | ||
| transform: translateX(3px); | ||
| box-shadow: 0 4px 12px rgba(0, 200, 150, 0.15); | ||
| } | ||
| .step-btn.active { | ||
| background: linear-gradient(135deg, #d1fae5, #a7f3d0); | ||
| border-color: var(--green); | ||
| box-shadow: 0 4px 14px rgba(0, 200, 150, 0.22); | ||
| } | ||
| .step-n { | ||
| font-weight: 700; | ||
| font-size: 0.85rem; | ||
| color: #1e293b; | ||
| margin-bottom: 2px; | ||
| } | ||
| .step-btn.active .step-n { | ||
| color: #065f46; | ||
| } | ||
| .step-s { | ||
| font-size: 0.73rem; | ||
| color: #94a3b8; | ||
| } | ||
| .vis-box { | ||
| background: linear-gradient(135deg, #ecfdf5, #f0f9ff); | ||
| border-radius: 1rem; | ||
| border: 2px solid #d1fae5; | ||
| padding: 1.1rem 1.3rem; | ||
| margin-bottom: 1rem; | ||
| } | ||
| .vis-t { | ||
| font-weight: 800; | ||
| font-size: 1rem; | ||
| color: #065f46; | ||
| } | ||
| .vis-d { | ||
| color: #475569; | ||
| font-size: 0.87rem; | ||
| line-height: 1.75; | ||
| margin-top: 4px; | ||
| } | ||
| .controls { | ||
| display: flex; | ||
| gap: 8px; | ||
| margin-top: 14px; | ||
| flex-wrap: wrap; | ||
| justify-content: center; | ||
| } | ||
| button.ctrl { | ||
| padding: 0.58rem 1.25rem; | ||
| border-radius: 0.7rem; | ||
| font-weight: 700; | ||
| font-size: 0.87rem; | ||
| cursor: pointer; | ||
| border: none; | ||
| transition: all 0.18s; | ||
| font-family: inherit; | ||
| } | ||
| button.ctrl:disabled { | ||
| opacity: 0.4; | ||
| cursor: not-allowed; | ||
| } | ||
| .cp { | ||
| background: linear-gradient(135deg, #00c896, #059669); | ||
| color: #fff; | ||
| box-shadow: 0 3px 10px rgba(0, 200, 150, 0.3); | ||
| } | ||
| .cp:hover:not(:disabled) { | ||
| transform: translateY(-2px); | ||
| box-shadow: 0 6px 18px rgba(0, 200, 150, 0.35); | ||
| } | ||
| .cs { | ||
| background: #f1f5f9; | ||
| color: var(--ink2); | ||
| border: 1.5px solid #e2e8f0; | ||
| } | ||
| .cs:hover:not(:disabled) { | ||
| background: #e2e8f0; | ||
| transform: translateY(-2px); | ||
| } |
There was a problem hiding this comment.
.step-btn と button.ctrl にキーボードフォーカス表示スタイルがありません
.cpbtn には :focus, :focus-visible ルールが追加されていますが(lines 409-413)、.step-btn(ステップボタン)と button.ctrl(Play/Prev/Next/Reset)には対応するルールがありません。キーボード操作でこれらのボタンにフォーカスが当たっても視覚的インジケーターがなく、WCAG 2.1 SC 2.4.7(フォーカスの可視性)に対して .cpbtn と一貫していません。
♿ 修正案
.step-btn:hover {
border-color: var(--green);
transform: translateX(3px);
box-shadow: 0 4px 12px rgba(0, 200, 150, 0.15);
}
+ .step-btn:focus-visible {
+ outline: 2px solid var(--gd);
+ outline-offset: 2px;
+ border-color: var(--green);
+ } button.ctrl:disabled {
opacity: 0.4;
cursor: not-allowed;
}
+ button.ctrl:focus-visible {
+ outline: 2px solid var(--gd);
+ outline-offset: 2px;
+ }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@public/Mathematics/Fundamentals/HackerRank/Claude/Easy/Strange` Grid
Again/Strange_Grid_Again.html around lines 201 - 293, The .step-btn and
button.ctrl controls lack keyboard focus styles; add :focus and :focus-visible
rules for .step-btn and for button.ctrl (and optionally for .step-btn.active)
that mirror the existing .cpbtn focus behavior (use a clear outline/box-shadow
and slight transform) so keyboard users get a visible focus indicator consistent
with .cpbtn and WCAG 2.4.7; update the CSS rules near the .step-btn and
button.ctrl definitions to include these focus selectors and ensure they are not
applied when :disabled.
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Create a GitHub issue for the keyboard focus accessibility concern
gh issue create \
--repo myoshi2891/Algorithm-DataStructures-Math-SQL \
--title "Strange_Grid_Again.html: .step-btn と button.ctrl にキーボードフォーカススタイルが不足" \
--body "## 概要
\`Strange_Grid_Again.html\` 内の \`.step-btn\`(ステップボタン)と \`button.ctrl\`(Play/Prev/Next/Resetコントロール)にキーボードフォーカス時の視覚的インジケーターが不足しています。
## 詳細
- \`.cpbtn\` には \`:focus\` と \`:focus-visible\` のスタイルが実装されていますが、\`.step-btn\` と \`button.ctrl\` には対応するルールがありません
- キーボード操作でこれらのボタンにフォーカスが当たっても視覚的な表示がないため、WCAG 2.1 SC 2.4.7(フォーカスの可視性)への準拠に問題があります
- アクセシビリティ向上のため、\`.cpbtn\` と一貫したフォーカススタイル(outline や box-shadow)の追加が必要です
## 対象ファイル
\`public/Mathematics/Fundamentals/HackerRank/Claude/Easy/Strange Grid Again/Strange_Grid_Again.html\`
## 関連
- PR `#281`: ${PR_URL}
- コメント: ${COMMENT_URL}
- 報告者: `@myoshi2891`" \
--assignee myoshi2891
Length of output: 74
@myoshi2891, イシューを作成しました!
Issue #288: Strange_Grid_Again.html: .step-btn と button.ctrl にキーボードフォーカススタイルが不足
キーボードフォーカスのアクセシビリティ改善について、後続の作業で対応できるようにイシューとして記録しました。
| /* Overview grid */ | ||
| (function () { | ||
| var rows = [6, 5, 4, 3, 2, 1], | ||
| cols = [1, 2, 3, 4, 5]; | ||
| var frag = document.createDocumentFragment(); | ||
| var wrap = document.createElement('div'); | ||
| wrap.style.display = 'inline-block'; | ||
|
|
||
| var headerDiv = document.createElement('div'); | ||
| headerDiv.style.cssText = | ||
| 'display:flex;gap:4px;margin-bottom:4px;margin-left:48px;'; | ||
| cols.forEach(function (c) { | ||
| var cellDiv = document.createElement('div'); | ||
| cellDiv.style.cssText = | ||
| 'width:52px;text-align:center;font-size:.72rem;font-weight:700;color:#64748b;'; | ||
| cellDiv.textContent = 'c=' + c; | ||
| headerDiv.appendChild(cellDiv); | ||
| }); | ||
| wrap.appendChild(headerDiv); | ||
|
|
||
| rows.forEach(function (r) { | ||
| var gpRow = document.createElement('div'); | ||
| gpRow.className = 'gp-row'; | ||
|
|
||
| var rl = document.createElement('div'); | ||
| rl.className = 'rl'; | ||
| rl.textContent = 'r=' + r; | ||
| gpRow.appendChild(rl); | ||
|
|
||
| var cellContainer = document.createElement('div'); | ||
| cellContainer.style.cssText = 'display:flex;gap:4px;'; | ||
|
|
||
| cols.forEach(function (c) { | ||
| var g = Math.floor((r - 1) / 2); | ||
| var cell = document.createElement('div'); | ||
| cell.className = 'cell ' + (g % 2 === 0 ? 'ca' : 'cb'); | ||
| cell.textContent = cellVal(r, c); | ||
| cellContainer.appendChild(cell); | ||
| }); | ||
| gpRow.appendChild(cellContainer); | ||
| wrap.appendChild(gpRow); | ||
| }); | ||
| frag.appendChild(wrap); | ||
| var target = document.getElementById('ov-grid'); | ||
| target.textContent = ''; | ||
| target.appendChild(frag); | ||
| })(); |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
概要グリッドの IIFE が buildGridFragment と同一ロジックを重複しています
buildGridFragment ヘルパーへのリファクタは STEPS.render 三箇所に適用されましたが、概要グリッドの IIFE(lines 1052-1098)は同一のヘッダー・行・セル生成ロジックをそのまま保持しています。buildGridFragment は関数宣言であるため巻き上げ(ホイスト)が有効で、IIFE 内から呼び出し可能です。
♻️ 提案リファクタ
- (function () {
- var rows = [6, 5, 4, 3, 2, 1],
- cols = [1, 2, 3, 4, 5];
- var frag = document.createDocumentFragment();
- var wrap = document.createElement('div');
- wrap.style.display = 'inline-block';
-
- var headerDiv = document.createElement('div');
- headerDiv.style.cssText =
- 'display:flex;gap:4px;margin-bottom:4px;margin-left:48px;';
- cols.forEach(function (c) {
- var cellDiv = document.createElement('div');
- cellDiv.style.cssText =
- 'width:52px;text-align:center;font-size:.72rem;font-weight:700;color:`#64748b`;';
- cellDiv.textContent = 'c=' + c;
- headerDiv.appendChild(cellDiv);
- });
- wrap.appendChild(headerDiv);
-
- rows.forEach(function (r) {
- var gpRow = document.createElement('div');
- gpRow.className = 'gp-row';
-
- var rl = document.createElement('div');
- rl.className = 'rl';
- rl.textContent = 'r=' + r;
- gpRow.appendChild(rl);
-
- var cellContainer = document.createElement('div');
- cellContainer.style.cssText = 'display:flex;gap:4px;';
-
- cols.forEach(function (c) {
- var g = Math.floor((r - 1) / 2);
- var cell = document.createElement('div');
- cell.className = 'cell ' + (g % 2 === 0 ? 'ca' : 'cb');
- cell.textContent = cellVal(r, c);
- cellContainer.appendChild(cell);
- });
- gpRow.appendChild(cellContainer);
- wrap.appendChild(gpRow);
- });
- frag.appendChild(wrap);
- var target = document.getElementById('ov-grid');
- target.textContent = '';
- target.appendChild(frag);
- })();
+ (function () {
+ var rows = [6, 5, 4, 3, 2, 1];
+ var cols = [1, 2, 3, 4, 5];
+ // buildGridFragment は関数宣言のためホイスト済み
+ var frag = buildGridFragment(cols, rows, cellVal, null);
+ var target = document.getElementById('ov-grid');
+ target.textContent = '';
+ target.appendChild(frag);
+ })();🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@public/Mathematics/Fundamentals/HackerRank/Claude/Easy/Strange` Grid
Again/Strange_Grid_Again.html around lines 1052 - 1098, The IIFE that builds the
overview grid duplicates the same header/row/cell generation logic already
refactored into buildGridFragment; remove the duplicated code inside the IIFE
and call buildGridFragment(...) instead (pass the same parameters or adapt its
signature if needed) so the overview uses the shared implementation; locate the
anonymous self-invoking function around the overview grid (the block that reads
rows = [6,5,4,3,2,1], cols = [1,2,3,4,5] and appends to element 'ov-grid') and
replace its internal logic with a call to buildGridFragment/append the returned
fragment, ensuring any styling or class names (gp-row, rl, cell, ca, cb) remain
consistent with STEPS.render uses.
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Create GitHub issue for the overview grid refactoring suggestion
gh issue create \
--repo myoshi2891/Algorithm-DataStructures-Math-SQL \
--title "Strange Grid 解説: 概要グリッドの重複コードをリファクタリング" \
--body "## 概要
Strange_Grid_Again.html の概要グリッド生成 IIFE(lines 1052-1098)が、既存の \`buildGridFragment\` ヘルパー関数と同一のロジックを重複して実装しています。
## 詳細
\`buildGridFragment\` ヘルパーは STEPS.render の三箇所で使用されていますが、概要グリッドの IIFE は同じヘッダー・行・セル生成ロジックを独自に実装しています。関数宣言はホイストされるため、IIFE 内から \`buildGridFragment\` を呼び出すことが可能です。
## 対応内容
概要グリッドの IIFE 内の重複コードを削除し、\`buildGridFragment\` を呼び出すように変更してください。
## 関連情報
- Pull Request: https://github.com/myoshi2891/Algorithm-DataStructures-Math-SQL/pull/281
- コメント: https://github.com/myoshi2891/Algorithm-DataStructures-Math-SQL/pull/281#discussion_r2835766482
- 報告者: `@myoshi2891`" \
--assignee myoshi2891 \
--label enhancement
Length of output: 74
@myoshi2891, Issue を作成しました:
#289 Strange Grid 解説: 概要グリッドの重複コードをリファクタリング
概要グリッド生成の重複コードを buildGridFragment ヘルパーに統一するリファクタリングタスクとして記録されています。
対応した内容は以下の通りです:
Strange_Grid_Again.html(.cpbtnのスタイル):cpbtnに:focusと:focus-visibleのスタイルを追加し、キーボードフォーカスが視覚的にわかりやすくなるようにしました(outline: 2px solid var(--gd)を指定)。Strange_Grid_Again.html(説明文の統一): base値の表記を、図のSVG表記に合わせて"base = 10g"から"base = 10 × g"に統一しました。Strange_Grid_Again.html(レンダー処理のリファクタ): 3箇所のSTEPS.render内で重複していた「表・セルのHTML構築処理」を一本化し、buildGridFragmentヘルパー関数として抽出・共通化しました。Strange_Grid_Again.html(フッターのバージョン):Python CPython 3.13.3となっていた箇所をPython CPython 3.12.4に修正しました。Strange_Grid_Again.html(クリップボードAPIの堅牢化): copy時のクリックハンドラ処理を見直し、navigator.clipboardの存在確認、.catchによるエラーハンドリング(および『コピー失敗』の表示)、タイムアウトIDを保持してのclearTimeout実行など、より堅牢な実装に改良しました。generate_index.py(カテゴリソート): ループ処理でstructure.items()ではなくsorted_categoriesを基準に回すよう変更し、カテゴリの出力順序を決定論的に(OSの走査順に依存しないように)しました。Strange_Grid_Again.md(説明文の矛盾解消): base値の説明箇所で「偶数行」となっていたテキストを、実際のオフセット式に合致する「奇数行(下行)」に正しました。上記修正を加え、ローカルで
update_index.shによる再生成を行い、正しく結果がpublic以下にも反映された状態でコミットを作成しています。