prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Add python 3.12 to CI
  ## 🚀 Feature
  
  Add python 3.12 to CI: https://github.com/pytorch/ignite/blob/master/.github/workflows/unit-tests.yml
  
  
  </issue>
  <code>
  [start of examples/mnist/mnist.py]
  1 from argparse import ArgumentParser
  2 
  3 import torch
  4 import torch.nn.functional as F
  5 from torch import nn
  6 from torch.optim import SGD
  7 from torch.utils.data import DataLoader
  8 from torchvision.datasets import MNIST
  9 from torchvision.transforms import Compose, Normalize, ToTensor
  10 from tqdm import tqdm
  11 
  12 from ignite.engine import create_supervised_evaluator, create_supervised_trainer, Events
  13 from ignite.metrics import Accuracy, Loss
  14 from ignite.utils import setup_logger
  15 
  16 
  17 class Net(nn.Module):
  18     def __init__(self):
  19         super(Net, self).__init__()
  20         self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
  21         self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
  22         self.conv2_drop = nn.Dropout2d()
  23         self.fc1 = nn.Linear(320, 50)
  24         self.fc2 = nn.Linear(50, 10)
  25 
  26     def forward(self, x):
  27         x = F.relu(F.max_pool2d(self.conv1(x), 2))
  28         x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))
  29         x = x.view(-1, 320)
  30         x = F.relu(self.fc1(x))
  31         x = F.dropout(x, training=self.training)
  32         x = self.fc2(x)
  33         return F.log_softmax(x, dim=-1)
  34 
  35 
  36 def get_data_loaders(train_batch_size, val_batch_size):
  37     data_transform = Compose([ToTensor(), Normalize((0.1307,), (0.3081,))])
  38 
  39     train_loader = DataLoader(
  40         MNIST(download=True, root=".", transform=data_transform, train=True), batch_size=train_batch_size, shuffle=True
  41     )
  42 
  43     val_loader = DataLoader(
  44         MNIST(download=False, root=".", transform=data_transform, train=False), batch_size=val_batch_size, shuffle=False
  45     )
  46     return train_loader, val_loader
  47 
  48 
  49 def run(train_batch_size, val_batch_size, epochs, lr, momentum, log_interval):
  50     train_loader, val_loader = get_data_loaders(train_batch_size, val_batch_size)
  51     model = Net()
  52     device = "cpu"
  53 
  54     if torch.cuda.is_available():
  55         device = "cuda"
  56 
  57     model.to(device)  # Move model before creating optimizer
  58     optimizer = SGD(model.parameters(), lr=lr, momentum=momentum)
  59     criterion = nn.NLLLoss()
  60     trainer = create_supervised_trainer(model, optimizer, criterion, device=device)
  61     trainer.logger = setup_logger("trainer")
  62 
  63     val_metrics = {"accuracy": Accuracy(), "nll": Loss(criterion)}
  64     evaluator = create_supervised_evaluator(model, metrics=val_metrics, device=device)
  65     evaluator.logger = setup_logger("evaluator")
  66 
  67     pbar = tqdm(initial=0, leave=False, total=len(train_loader), desc=f"ITERATION - loss: {0:.2f}")
  68 
  69     @trainer.on(Events.ITERATION_COMPLETED(every=log_interval))
  70     def log_training_loss(engine):
  71         pbar.desc = f"ITERATION - loss: {engine.state.output:.2f}"
  72         pbar.update(log_interval)
  73 
  74     @trainer.on(Events.EPOCH_COMPLETED)
  75     def log_training_results(engine):
  76         pbar.refresh()
  77         evaluator.run(train_loader)
  78         metrics = evaluator.state.metrics
  79         avg_accuracy = metrics["accuracy"]
  80         avg_nll = metrics["nll"]
  81         tqdm.write(
  82             f"Training Results - Epoch: {engine.state.epoch} Avg accuracy: {avg_accuracy:.2f} Avg loss: {avg_nll:.2f}"
  83         )
  84 
  85     @trainer.on(Events.EPOCH_COMPLETED)
  86     def log_validation_results(engine):
  87         evaluator.run(val_loader)
  88         metrics = evaluator.state.metrics
  89         avg_accuracy = metrics["accuracy"]
  90         avg_nll = metrics["nll"]
  91         tqdm.write(
  92             f"Validation Results - Epoch: {engine.state.epoch} Avg accuracy: {avg_accuracy:.2f} Avg loss: {avg_nll:.2f}"
  93         )
  94 
  95         pbar.n = pbar.last_print_n = 0
  96 
  97     @trainer.on(Events.EPOCH_COMPLETED | Events.COMPLETED)
  98     def log_time(engine):
  99         tqdm.write(f"{trainer.last_event_name.name} took { trainer.state.times[trainer.last_event_name.name]} seconds")
  100 
  101     trainer.run(train_loader, max_epochs=epochs)
  102     pbar.close()
  103 
  104 
  105 if __name__ == "__main__":
  106     parser = ArgumentParser()
  107     parser.add_argument("--batch_size", type=int, default=64, help="input batch size for training (default: 64)")
  108     parser.add_argument(
  109         "--val_batch_size", type=int, default=1000, help="input batch size for validation (default: 1000)"
  110     )
  111     parser.add_argument("--epochs", type=int, default=10, help="number of epochs to train (default: 10)")
  112     parser.add_argument("--lr", type=float, default=0.01, help="learning rate (default: 0.01)")
  113     parser.add_argument("--momentum", type=float, default=0.5, help="SGD momentum (default: 0.5)")
  114     parser.add_argument(
  115         "--log_interval", type=int, default=10, help="how many batches to wait before logging training status"
  116     )
  117 
  118     args = parser.parse_args()
  119 
  120     run(args.batch_size, args.val_batch_size, args.epochs, args.lr, args.momentum, args.log_interval)
  121
  [end of examples/mnist/mnist.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/examples/mnist/mnist.py b/examples/mnist/mnist.py
  --- a/examples/mnist/mnist.py
  +++ b/examples/mnist/mnist.py
  @@ -96,7 +96,7 @@
   
       @trainer.on(Events.EPOCH_COMPLETED | Events.COMPLETED)
       def log_time(engine):
  -        tqdm.write(f"{trainer.last_event_name.name} took { trainer.state.times[trainer.last_event_name.name]} seconds")
  +        tqdm.write(f"{trainer.last_event_name.name} took {trainer.state.times[trainer.last_event_name.name]} seconds")
   
       trainer.run(train_loader, max_epochs=epochs)
       pbar.close()
  
verification_info: {"golden_diff": "diff --git a/examples/mnist/mnist.py b/examples/mnist/mnist.py\n--- a/examples/mnist/mnist.py\n+++ b/examples/mnist/mnist.py\n@@ -96,7 +96,7 @@\n \n     @trainer.on(Events.EPOCH_COMPLETED | Events.COMPLETED)\n     def log_time(engine):\n-        tqdm.write(f\"{trainer.last_event_name.name} took { trainer.state.times[trainer.last_event_name.name]} seconds\")\n+        tqdm.write(f\"{trainer.last_event_name.name} took {trainer.state.times[trainer.last_event_name.name]} seconds\")\n \n     trainer.run(train_loader, max_epochs=epochs)\n     pbar.close()\n", "issue": "Add python 3.12 to CI\n## \ud83d\ude80 Feature\r\n\r\nAdd python 3.12 to CI: https://github.com/pytorch/ignite/blob/master/.github/workflows/unit-tests.yml\r\n\n", "before_files": [{"content": "from argparse import ArgumentParser\n\nimport torch\nimport torch.nn.functional as F\nfrom torch import nn\nfrom torch.optim import SGD\nfrom torch.utils.data import DataLoader\nfrom torchvision.datasets import MNIST\nfrom torchvision.transforms import Compose, Normalize, ToTensor\nfrom tqdm import tqdm\n\nfrom ignite.engine import create_supervised_evaluator, create_supervised_trainer, Events\nfrom ignite.metrics import Accuracy, Loss\nfrom ignite.utils import setup_logger\n\n\nclass Net(nn.Module):\n    def __init__(self):\n        super(Net, self).__init__()\n        self.conv1 = nn.Conv2d(1, 10, kernel_size=5)\n        self.conv2 = nn.Conv2d(10, 20, kernel_size=5)\n        self.conv2_drop = nn.Dropout2d()\n        self.fc1 = nn.Linear(320, 50)\n        self.fc2 = nn.Linear(50, 10)\n\n    def forward(self, x):\n        x = F.relu(F.max_pool2d(self.conv1(x), 2))\n        x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))\n        x = x.view(-1, 320)\n        x = F.relu(self.fc1(x))\n        x = F.dropout(x, training=self.training)\n        x = self.fc2(x)\n        return F.log_softmax(x, dim=-1)\n\n\ndef get_data_loaders(train_batch_size, val_batch_size):\n    data_transform = Compose([ToTensor(), Normalize((0.1307,), (0.3081,))])\n\n    train_loader = DataLoader(\n        MNIST(download=True, root=\".\", transform=data_transform, train=True), batch_size=train_batch_size, shuffle=True\n    )\n\n    val_loader = DataLoader(\n        MNIST(download=False, root=\".\", transform=data_transform, train=False), batch_size=val_batch_size, shuffle=False\n    )\n    return train_loader, val_loader\n\n\ndef run(train_batch_size, val_batch_size, epochs, lr, momentum, log_interval):\n    train_loader, val_loader = get_data_loaders(train_batch_size, val_batch_size)\n    model = Net()\n    device = \"cpu\"\n\n    if torch.cuda.is_available():\n        device = \"cuda\"\n\n    model.to(device)  # Move model before creating optimizer\n    optimizer = SGD(model.parameters(), lr=lr, momentum=momentum)\n    criterion = nn.NLLLoss()\n    trainer = create_supervised_trainer(model, optimizer, criterion, device=device)\n    trainer.logger = setup_logger(\"trainer\")\n\n    val_metrics = {\"accuracy\": Accuracy(), \"nll\": Loss(criterion)}\n    evaluator = create_supervised_evaluator(model, metrics=val_metrics, device=device)\n    evaluator.logger = setup_logger(\"evaluator\")\n\n    pbar = tqdm(initial=0, leave=False, total=len(train_loader), desc=f\"ITERATION - loss: {0:.2f}\")\n\n    @trainer.on(Events.ITERATION_COMPLETED(every=log_interval))\n    def log_training_loss(engine):\n        pbar.desc = f\"ITERATION - loss: {engine.state.output:.2f}\"\n        pbar.update(log_interval)\n\n    @trainer.on(Events.EPOCH_COMPLETED)\n    def log_training_results(engine):\n        pbar.refresh()\n        evaluator.run(train_loader)\n        metrics = evaluator.state.metrics\n        avg_accuracy = metrics[\"accuracy\"]\n        avg_nll = metrics[\"nll\"]\n        tqdm.write(\n            f\"Training Results - Epoch: {engine.state.epoch} Avg accuracy: {avg_accuracy:.2f} Avg loss: {avg_nll:.2f}\"\n        )\n\n    @trainer.on(Events.EPOCH_COMPLETED)\n    def log_validation_results(engine):\n        evaluator.run(val_loader)\n        metrics = evaluator.state.metrics\n        avg_accuracy = metrics[\"accuracy\"]\n        avg_nll = metrics[\"nll\"]\n        tqdm.write(\n            f\"Validation Results - Epoch: {engine.state.epoch} Avg accuracy: {avg_accuracy:.2f} Avg loss: {avg_nll:.2f}\"\n        )\n\n        pbar.n = pbar.last_print_n = 0\n\n    @trainer.on(Events.EPOCH_COMPLETED | Events.COMPLETED)\n    def log_time(engine):\n        tqdm.write(f\"{trainer.last_event_name.name} took { trainer.state.times[trainer.last_event_name.name]} seconds\")\n\n    trainer.run(train_loader, max_epochs=epochs)\n    pbar.close()\n\n\nif __name__ == \"__main__\":\n    parser = ArgumentParser()\n    parser.add_argument(\"--batch_size\", type=int, default=64, help=\"input batch size for training (default: 64)\")\n    parser.add_argument(\n        \"--val_batch_size\", type=int, default=1000, help=\"input batch size for validation (default: 1000)\"\n    )\n    parser.add_argument(\"--epochs\", type=int, default=10, help=\"number of epochs to train (default: 10)\")\n    parser.add_argument(\"--lr\", type=float, default=0.01, help=\"learning rate (default: 0.01)\")\n    parser.add_argument(\"--momentum\", type=float, default=0.5, help=\"SGD momentum (default: 0.5)\")\n    parser.add_argument(\n        \"--log_interval\", type=int, default=10, help=\"how many batches to wait before logging training status\"\n    )\n\n    args = parser.parse_args()\n\n    run(args.batch_size, args.val_batch_size, args.epochs, args.lr, args.momentum, args.log_interval)\n", "path": "examples/mnist/mnist.py"}]}