MIL-005: Screenshot, wiki and finish #30
@@ -15,9 +15,14 @@ keeps the names of the lectures (`data`, `temperatures`, `temp_list`, `data_dict
|
|||||||
`average_temp`, `monday`, `to_dict`, `to_list`, `mean`, `max`, `to_csv`) so that you
|
`average_temp`, `monday`, `to_dict`, `to_list`, `mean`, `max`, `to_csv`) so that you
|
||||||
can compare it with your own solution.
|
can compare it with your own solution.
|
||||||
|
|
||||||
> **Status:** in progress. The project foundation (configuration, constants,
|

|
||||||
> documentation settings and continuous integration) is in place; the readers and
|
|
||||||
> the analysis follow in the next milestones, see `docs/project-plan.md`.
|
*`python -m weather` in a terminal: the csv part first, then the pandas part.*
|
||||||
|
|
||||||
|
> **Status:** finished. The `csv` reader, the `pandas` analysis, the creation and
|
||||||
|
> export of a `DataFrame` and the program that prints the results are done. A short
|
||||||
|
> description in English, Danish and Bahasa Melayu is on the wiki of the repository
|
||||||
|
> (the pages are in `wiki/`).
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
@@ -81,14 +86,46 @@ To install only what the `csv` part needs, leave out the extras:
|
|||||||
|
|
||||||
## Run
|
## Run
|
||||||
|
|
||||||
With the virtual environment active, the program that prints the results of the
|
With the virtual environment active, print the results of the lectures:
|
||||||
lectures is added in a later milestone (`python -m weather`); until then the
|
|
||||||
package can be imported:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python -c "from weather import constants; print(constants.DATA_FILE)"
|
python -m weather
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The program prints, in the order of the lectures:
|
||||||
|
|
||||||
|
1. the rows of `weather_data.csv` and the temperatures as whole numbers, read with
|
||||||
|
the `csv` library (no `pandas` needed);
|
||||||
|
2. the same file read with `pandas` as a `DataFrame`, converted to a dictionary and
|
||||||
|
a list;
|
||||||
|
3. the average temperature, computed by hand and with `mean`, and the maximum;
|
||||||
|
4. the row of Monday, the row of the hottest day, and Monday in Fahrenheit;
|
||||||
|
5. a `DataFrame` created from a dictionary of students and scores.
|
||||||
|
|
||||||
|
Nothing is written to disk unless you ask for it. To also export the scores table
|
||||||
|
to a CSV file, give a path:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python -m weather --export new_data.csv
|
||||||
|
```
|
||||||
|
|
||||||
|
If `pandas` is not installed the `csv` part is still printed, a message names the
|
||||||
|
extra to install, and the exit code is 1.
|
||||||
|
|
||||||
|
The functions can also be used from your own code:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from weather.csv_reader import read_temperatures
|
||||||
|
from weather.analysis import read_data, average_temp, max_temp
|
||||||
|
|
||||||
|
temperatures = read_temperatures() # [12, 14, 15, 14, 21, 22, 24]
|
||||||
|
data = read_data() # a pandas DataFrame
|
||||||
|
print(average_temp(data), max_temp(data))
|
||||||
|
```
|
||||||
|
|
||||||
|
The default data file is the `weather_data.csv` inside the package, so the
|
||||||
|
functions work from any folder; pass a `path` to read another file.
|
||||||
|
|
||||||
## Run the tests
|
## Run the tests
|
||||||
|
|
||||||
The tests write only into temporary folders.
|
The tests write only into temporary folders.
|
||||||
@@ -134,12 +171,18 @@ The HTML is written to `build/doxygen/index.html`. A warning fails the build.
|
|||||||
```text
|
```text
|
||||||
.
|
.
|
||||||
├── .gitea/workflows/ci.yml continuous integration (Gitea Actions)
|
├── .gitea/workflows/ci.yml continuous integration (Gitea Actions)
|
||||||
├── docs/ business case, plan, milestones, reviews
|
├── docs/ business case, plan, milestones, reviews, screenshot
|
||||||
├── src/weather/ the package
|
├── src/weather/ the package
|
||||||
│ ├── __init__.py
|
│ ├── __init__.py
|
||||||
│ └── constants.py every constant of the lectures
|
│ ├── __main__.py prints the results: python -m weather
|
||||||
|
│ ├── analysis.py read_data, average_temp, max_temp, row selection (pandas)
|
||||||
|
│ ├── constants.py every constant of the lectures
|
||||||
|
│ ├── csv_reader.py read_rows and read_temperatures (csv library)
|
||||||
|
│ ├── export.py create_scores_frame and export_frame (pandas)
|
||||||
|
│ └── weather_data.csv the weather data of the lecture
|
||||||
├── tests/ pytest tests (conftest.py runs every test in a
|
├── tests/ pytest tests (conftest.py runs every test in a
|
||||||
│ temporary folder)
|
│ temporary folder)
|
||||||
|
├── wiki/ wiki pages in English, Danish and Bahasa Melayu
|
||||||
├── Doxyfile source documentation settings
|
├── Doxyfile source documentation settings
|
||||||
├── LICENSE
|
├── LICENSE
|
||||||
├── pyproject.toml project configuration
|
├── pyproject.toml project configuration
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ document of a type. `Primary File` may contain a glob (e.g.
|
|||||||
| PP | Project Plan | docs/project-plan.md | 002 |
|
| PP | Project Plan | docs/project-plan.md | 002 |
|
||||||
| MIL | Milestone / Gateway | docs/milestones/*.md | 006 |
|
| MIL | Milestone / Gateway | docs/milestones/*.md | 006 |
|
||||||
| DICT | Domain Dictionary | docs/dictionary.md | 002 |
|
| DICT | Domain Dictionary | docs/dictionary.md | 002 |
|
||||||
| RC | SQA Review Record | docs/sqa/reviews/rc-*.md | 013 |
|
| RC | SQA Review Record | docs/sqa/reviews/rc-*.md | 014 |
|
||||||
|
|
||||||
## Languages
|
## Languages
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
@@ -0,0 +1,61 @@
|
|||||||
|
# RC-013: Code review of MIL-005 (screenshot, README, wiki; no Python file changed)
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
| Key | Value |
|
||||||
|
| --- | --- |
|
||||||
|
| ID | RC-013 |
|
||||||
|
| CrossReference | [MIL-005], [QC-PY-001] |
|
||||||
|
|
||||||
|
## Version History
|
||||||
|
| Date | Status | Author | Reviewer | Change | Commit |
|
||||||
|
| --- | --- | --- | --- | --- | --- |
|
||||||
|
| 2026-10-13 | Proposed | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [deaed38] |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Artifact Under Review
|
||||||
|
|
||||||
|
- Instance reviewed: the source and tests that [MIL-005] delivers (screenshot, README, wiki; no Python file changed)
|
||||||
|
- Checklist used: [QC-PY-001]
|
||||||
|
- Scope: full review of the files changed on the branch of the milestone
|
||||||
|
- Language and domain: n/a
|
||||||
|
- Language reviewer: none
|
||||||
|
- Mode: autonomous, not independent (the reviewer is `AI as stand-in for S01`; the assistant also wrote the code; the review of the files was done by the `python-developer` agent of the session)
|
||||||
|
|
||||||
|
## Checklist Results
|
||||||
|
|
||||||
|
| # | Criterion | Status | Evidence/Notes |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| 1 | Packages, modules, functions, variables, classes and constants follow PEP 8 casing (`snake_case`, `PascalCase`, `UPPER_SNAKE`) | N-A | MIL-005 changes no Python file (`git diff main --stat -- src tests` is empty); the files are a PNG, `README.md` and `wiki/`. |
|
||||||
|
| 2 | Names state purpose in the domain's language; no unexplained abbreviations, no single-letter names outside tiny scopes | N-A | No Python file changed. |
|
||||||
|
| 3 | Code is produced by the project's formatter and passes its linter with no unexplained suppressions | Pass | `ruff check` and `ruff format --check` still exit 0 on the unchanged `src` and `tests`, checked in a fresh clone of the branch. |
|
||||||
|
| 4 | Every function and method signature is type-annotated, including `-> None` | N-A | No Python file changed. |
|
||||||
|
| 5 | No bare `except:`, no swallowed exceptions; specific exceptions are raised and the cause is kept (`raise ... from`) | N-A | No Python file changed. |
|
||||||
|
| 6 | No mutable default arguments and no shadowed builtins | N-A | No Python file changed. |
|
||||||
|
| 7 | Files, locks and connections are managed with context managers | N-A | No Python file changed. |
|
||||||
|
| 8 | Public modules, classes and functions have docstrings that say what, not how | Pass | `doxygen Doxyfile` exits 0 with no warnings in the fresh clone. |
|
||||||
|
| 9 | Logging uses `logging`, not `print`; no secrets or personal data in log output | N-A | No Python file changed. |
|
||||||
|
| 10 | Classes and operations trace to the Design Class Diagram they implement; deviations are recorded | N-A | No Python file changed. |
|
||||||
|
| 11 | Tests exist for new behaviour, are named for the behaviour, and do not depend on order or the network | Pass | In a fresh clone of the branch, following the README on Windows PowerShell (`python -m venv .venv`, `python -m pip install --upgrade pip`, `python -m pip install -e ".[dev]"`), `pytest` reports 39 passed and `python -m weather` exits 0 and prints the results of the lectures. |
|
||||||
|
| 12 | Type checker runs in strict mode without errors; `Any` is justified in a comment | Pass | `python -m mypy` runs with `strict = true`: no issues in 12 source files in the fresh clone. |
|
||||||
|
| 13 | Dependencies are declared and pinned in the project's dependency file, none unused | N-A | No dependency change. |
|
||||||
|
| 14 | Each piece of knowledge (a business rule, constant, format, validation or query) is defined in one place; code is merged only where it expresses the same knowledge, not where it merely looks alike | N-A | No Python file changed. |
|
||||||
|
| 15 | Imports point inward: business-rule modules import no framework, database, UI or delivery-mechanism code, and there are no import cycles | N-A | No Python file changed. |
|
||||||
|
| 16 | SOLID holds: a class or module has one reason to change; new behaviour is added by extension, not by editing a type test in several places; subclasses honour the contract of their base; protocols are narrow; high-level code depends on protocols or abstract types and receives its implementations | N-A | No Python file changed. |
|
||||||
|
|
||||||
|
## Overall Verdict
|
||||||
|
|
||||||
|
Go — all Mandatory criteria pass or are not applicable. Assessed on 2026-10-13 by the assistant that wrote the code, as stand-in for S01 in autonomous mode. Mode: autonomous, not independent. The pull request is the second look. The deliverables of [MIL-005] that are not code were checked against its Go/No-Go list: the screenshot is a capture of a real console window that ran `python -m weather` (taken once with a one-off script outside the repository, not part of the change; the capture was cropped to the window so that no neighbouring window shows); the README and the three wiki pages show it; the wiki has `Home`, `Home.da`, `Home.ms` and `_Sidebar`; the marker `wiki/.publish` is added (a small addition to the task list: it is what makes the instance's workflow publish the pages). The address of the image on `main` and the publication of the wiki are checked after the merge and reported in the run summary.
|
||||||
|
|
||||||
|
## Action Items
|
||||||
|
|
||||||
|
| Action | Owner | Due |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Challenge this `Go` in the run summary or on the pull request if the stand-in decision is not wanted | S01 | 2026-10-23 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
[MIL-005]: ../../milestones/mil-005-screenshot-wiki-and-finish.md
|
||||||
|
[QC-PY-001]: ../../../framework/qc/code/qc-programming-python.md
|
||||||
|
[PP-001]: ../../project-plan.md
|
||||||
|
[deaed38]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-weather/commit/deaed3899c379d04d6df00d616086f46aefea029
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
> Denne side er genereret fra README.md og wiki/. Ændringer her bliver overskrevet, næste gang wikien udgives.
|
||||||
|
|
||||||
|
> Den engelske side er den gældende; denne oversættelse følger den.
|
||||||
|
|
||||||
|
[English](Home) | Dansk | [Bahasa Melayu](Home.ms)
|
||||||
|
|
||||||
|
# Vejrdata (dag 25)
|
||||||
|
|
||||||
|
At læse CSV-vejrdata i Python. Det er opgaven fra dag 25 i Udemys *100 Days of Code: The Complete Python Pro Bootcamp*. Lektionerne læser en uges vejr fra `weather_data.csv` med Pythons indbyggede `csv`-bibliotek og samler temperaturerne som hele tal, og viser derefter, hvordan biblioteket `pandas` gør det samme på én linje. En tabel er en `DataFrame`, og en kolonne i den er en `Series`; begge kan omdannes til en ordbog og en liste, gennemsnits- og maksimumtemperaturen kan beregnes, rækker kan udvælges ud fra en betingelse, og en `DataFrame` kan oprettes ud fra en ordbog og eksporteres til en CSV-fil.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
*`python -m weather` i en terminal: først csv-delen, derefter pandas-delen.*
|
||||||
|
|
||||||
|
## Hvad programmet skriver
|
||||||
|
|
||||||
|
| Del | Resultat |
|
||||||
|
| --- | --- |
|
||||||
|
| `csv`-biblioteket | Filens rækker og temperaturerne `[12, 14, 15, 14, 21, 22, 24]` |
|
||||||
|
| `pandas` | `DataFrame`, ordbogen og listen med temperaturer |
|
||||||
|
| Statistik | Gennemsnit 17,43 (i hånden og med `mean`) og maksimum 24 |
|
||||||
|
| Rækkeudvælgelse | Mandagens række, den varmeste dags række (søndag), mandag i Fahrenheit (53,6) |
|
||||||
|
| Opret og eksportér | En `DataFrame` med elever og point lavet ud fra en ordbog; skrives kun til en fil med `--export` |
|
||||||
|
|
||||||
|
## Funktioner
|
||||||
|
|
||||||
|
| Funktion | Modul | Lektion |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `read_rows`, `read_temperatures` | `weather.csv_reader` | Læsning med `csv`-biblioteket |
|
||||||
|
| `read_data` | `weather.analysis` | `pandas.read_csv` |
|
||||||
|
| `to_data_dict`, `to_temp_list` | `weather.analysis` | `to_dict`, `to_list` |
|
||||||
|
| `average_temp`, `average_temp_mean`, `max_temp` | `weather.analysis` | Sum og længde, `mean`, `max` |
|
||||||
|
| `row_for_day`, `hottest_row`, `day_in_fahrenheit` | `weather.analysis` | Udvælgelse af rækker |
|
||||||
|
| `create_scores_frame`, `export_frame` | `weather.export` | `DataFrame` ud fra en ordbog, `to_csv` |
|
||||||
|
|
||||||
|
## Kør programmet
|
||||||
|
|
||||||
|
Der skal bruges Python 3.13 eller nyere. `csv`-delen har ingen afhængigheder ved kørsel; `pandas` er et valgfrit tilvalg, som `dev`-tilvalget installerer.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-weather.git
|
||||||
|
cd 025-weather
|
||||||
|
python -m venv .venv
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
python -m pip install -e ".[dev]"
|
||||||
|
python -m weather
|
||||||
|
```
|
||||||
|
|
||||||
|
Tilføj `--export new_data.csv` for også at skrive tabellen med point til en fil. Repositoriets README har den fulde opsætning til Windows, Linux og macOS.
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
> This page is generated from README.md and wiki/. Changes made here are overwritten the next time the wiki is published.
|
||||||
|
|
||||||
|
English | [Dansk](Home.da) | [Bahasa Melayu](Home.ms)
|
||||||
|
|
||||||
|
# Weather Data (Day 25)
|
||||||
|
|
||||||
|
Reading CSV weather data in Python. It is the day-25 assignment of Udemy's *100 Days of Code: The Complete Python Pro Bootcamp*. The lectures read the weather of one week from `weather_data.csv` with Python's built-in `csv` library and collect the temperatures as whole numbers, and then show how the `pandas` library does the same in one line. A table is a `DataFrame` and a column of it is a `Series`; both can be converted to a dictionary and a list, the average and the maximum temperature can be computed, rows can be selected by a condition, and a `DataFrame` can be created from a dictionary and exported to a CSV file.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
*`python -m weather` in a terminal: the csv part first, then the pandas part.*
|
||||||
|
|
||||||
|
## What the program prints
|
||||||
|
|
||||||
|
| Part | Result |
|
||||||
|
| --- | --- |
|
||||||
|
| `csv` library | The rows of the file and the temperatures `[12, 14, 15, 14, 21, 22, 24]` |
|
||||||
|
| `pandas` | The `DataFrame`, the dictionary and the list of temperatures |
|
||||||
|
| Statistics | Average 17.43 (by hand and with `mean`) and maximum 24 |
|
||||||
|
| Row selection | The row of Monday, the row of the hottest day (Sunday), Monday in Fahrenheit (53.6) |
|
||||||
|
| Create and export | A `DataFrame` of students and scores made from a dictionary; written to a file only with `--export` |
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
|
||||||
|
| Function | Module | Lecture |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `read_rows`, `read_temperatures` | `weather.csv_reader` | Reading with the `csv` library |
|
||||||
|
| `read_data` | `weather.analysis` | `pandas.read_csv` |
|
||||||
|
| `to_data_dict`, `to_temp_list` | `weather.analysis` | `to_dict`, `to_list` |
|
||||||
|
| `average_temp`, `average_temp_mean`, `max_temp` | `weather.analysis` | Sum and length, `mean`, `max` |
|
||||||
|
| `row_for_day`, `hottest_row`, `day_in_fahrenheit` | `weather.analysis` | Selecting rows |
|
||||||
|
| `create_scores_frame`, `export_frame` | `weather.export` | `DataFrame` from a dictionary, `to_csv` |
|
||||||
|
|
||||||
|
## Run
|
||||||
|
|
||||||
|
Python 3.13 or newer is needed. The `csv` part has no runtime dependencies; `pandas` is an optional extra that the `dev` extra installs.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-weather.git
|
||||||
|
cd 025-weather
|
||||||
|
python -m venv .venv
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
python -m pip install -e ".[dev]"
|
||||||
|
python -m weather
|
||||||
|
```
|
||||||
|
|
||||||
|
Add `--export new_data.csv` to also write the scores table to a file. The README of the repository has the full set-up for Windows, Linux and macOS.
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
> Halaman ini dijana daripada README.md dan wiki/. Perubahan di sini akan ditimpa apabila wiki diterbitkan lagi.
|
||||||
|
|
||||||
|
> Halaman Bahasa Inggeris adalah yang rasmi; terjemahan ini mengikutinya.
|
||||||
|
|
||||||
|
[English](Home) | [Dansk](Home.da) | Bahasa Melayu
|
||||||
|
|
||||||
|
# Data Cuaca (hari 25)
|
||||||
|
|
||||||
|
Membaca data cuaca CSV dalam Python. Ia ialah tugasan hari ke-25 dalam *100 Days of Code: The Complete Python Pro Bootcamp* di Udemy. Pelajaran membaca cuaca satu minggu daripada `weather_data.csv` dengan pustaka `csv` terbina dalam Python dan mengumpul suhu sebagai nombor bulat, kemudian menunjukkan bagaimana pustaka `pandas` melakukan perkara yang sama dalam satu baris. Satu jadual ialah `DataFrame` dan satu lajur daripadanya ialah `Series`; kedua-duanya boleh ditukar kepada kamus dan senarai, suhu purata dan suhu maksimum boleh dikira, baris boleh dipilih mengikut syarat, dan `DataFrame` boleh dicipta daripada kamus serta dieksport ke fail CSV.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
*`python -m weather` dalam terminal: bahagian csv dahulu, kemudian bahagian pandas.*
|
||||||
|
|
||||||
|
## Apa yang dipaparkan oleh program
|
||||||
|
|
||||||
|
| Bahagian | Hasil |
|
||||||
|
| --- | --- |
|
||||||
|
| Pustaka `csv` | Baris fail dan suhu `[12, 14, 15, 14, 21, 22, 24]` |
|
||||||
|
| `pandas` | `DataFrame`, kamus dan senarai suhu |
|
||||||
|
| Statistik | Purata 17.43 (secara manual dan dengan `mean`) dan maksimum 24 |
|
||||||
|
| Pemilihan baris | Baris hari Isnin, baris hari terpanas (Ahad), Isnin dalam Fahrenheit (53.6) |
|
||||||
|
| Cipta dan eksport | `DataFrame` pelajar dan skor yang dibuat daripada kamus; ditulis ke fail hanya dengan `--export` |
|
||||||
|
|
||||||
|
## Fungsi
|
||||||
|
|
||||||
|
| Fungsi | Modul | Pelajaran |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `read_rows`, `read_temperatures` | `weather.csv_reader` | Membaca dengan pustaka `csv` |
|
||||||
|
| `read_data` | `weather.analysis` | `pandas.read_csv` |
|
||||||
|
| `to_data_dict`, `to_temp_list` | `weather.analysis` | `to_dict`, `to_list` |
|
||||||
|
| `average_temp`, `average_temp_mean`, `max_temp` | `weather.analysis` | Jumlah dan panjang, `mean`, `max` |
|
||||||
|
| `row_for_day`, `hottest_row`, `day_in_fahrenheit` | `weather.analysis` | Memilih baris |
|
||||||
|
| `create_scores_frame`, `export_frame` | `weather.export` | `DataFrame` daripada kamus, `to_csv` |
|
||||||
|
|
||||||
|
## Jalankan
|
||||||
|
|
||||||
|
Python 3.13 atau lebih baharu diperlukan. Bahagian `csv` tiada kebergantungan semasa dijalankan; `pandas` ialah tambahan pilihan yang dipasang oleh tambahan `dev`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-weather.git
|
||||||
|
cd 025-weather
|
||||||
|
python -m venv .venv
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
python -m pip install -e ".[dev]"
|
||||||
|
python -m weather
|
||||||
|
```
|
||||||
|
|
||||||
|
Tambah `--export new_data.csv` untuk turut menulis jadual skor ke fail. README repositori mempunyai persediaan penuh untuk Windows, Linux dan macOS.
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
**Weather Data (Day 25)**
|
||||||
|
|
||||||
|
English
|
||||||
|
|
||||||
|
- [Home](Home)
|
||||||
|
|
||||||
|
Dansk
|
||||||
|
|
||||||
|
- [Hjem](Home.da)
|
||||||
|
|
||||||
|
Bahasa Melayu
|
||||||
|
|
||||||
|
- [Utama](Home.ms)
|
||||||
Reference in New Issue
Block a user