We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Update signature to Dict[floatScalar
https://github.com/adap/flower/blob/a8a7dd1fce957540b49c59e56221d5762a937f8d/src/py/flwr/server/strategy/fedavg.py#L106

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/py/flwr/server/strategy/fedavg.py`
Content:
```
1 # Copyright 2020 Adap GmbH. All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 # ==============================================================================
15 """Federated Averaging (FedAvg) [McMahan et al., 2016] strategy.
16 
17 Paper: https://arxiv.org/abs/1602.05629
18 """
19 
20 
21 from logging import WARNING
22 from typing import Callable, Dict, List, Optional, Tuple
23 
24 from flwr.common import (
25     EvaluateIns,
26     EvaluateRes,
27     FitIns,
28     FitRes,
29     Parameters,
30     Scalar,
31     Weights,
32     parameters_to_weights,
33     weights_to_parameters,
34 )
35 from flwr.common.logger import log
36 from flwr.server.client_manager import ClientManager
37 from flwr.server.client_proxy import ClientProxy
38 
39 from .aggregate import aggregate, weighted_loss_avg
40 from .strategy import Strategy
41 
42 DEPRECATION_WARNING = """
43 DEPRECATION WARNING: deprecated `eval_fn` return format
44 
45     loss, accuracy
46 
47 move to
48 
49     loss, {"accuracy": accuracy}
50 
51 instead. Note that compatibility with the deprecated return format will be
52 removed in a future release.
53 """
54 
55 DEPRECATION_WARNING_INITIAL_PARAMETERS = """
56 DEPRECATION WARNING: deprecated initial parameter type
57 
58     flwr.common.Weights (i.e., List[np.ndarray])
59 
60 will be removed in a future update, move to
61 
62     flwr.common.Parameters
63 
64 instead. Use
65 
66     parameters = flwr.common.weights_to_parameters(weights)
67 
68 to easily transform `Weights` to `Parameters`.
69 """
70 
71 
72 class FedAvg(Strategy):
73     """Configurable FedAvg strategy implementation."""
74 
75     # pylint: disable=too-many-arguments,too-many-instance-attributes
76     def __init__(
77         self,
78         fraction_fit: float = 0.1,
79         fraction_eval: float = 0.1,
80         min_fit_clients: int = 2,
81         min_eval_clients: int = 2,
82         min_available_clients: int = 2,
83         eval_fn: Optional[
84             Callable[[Weights], Optional[Tuple[float, Dict[str, Scalar]]]]
85         ] = None,
86         on_fit_config_fn: Optional[Callable[[int], Dict[str, Scalar]]] = None,
87         on_evaluate_config_fn: Optional[Callable[[int], Dict[str, Scalar]]] = None,
88         accept_failures: bool = True,
89         initial_parameters: Optional[Parameters] = None,
90     ) -> None:
91         """Federated Averaging strategy.
92 
93         Implementation based on https://arxiv.org/abs/1602.05629
94 
95         Args:
96             fraction_fit (float, optional): Fraction of clients used during
97                 training. Defaults to 0.1.
98             fraction_eval (float, optional): Fraction of clients used during
99                 validation. Defaults to 0.1.
100             min_fit_clients (int, optional): Minimum number of clients used
101                 during training. Defaults to 2.
102             min_eval_clients (int, optional): Minimum number of clients used
103                 during validation. Defaults to 2.
104             min_available_clients (int, optional): Minimum number of total
105                 clients in the system. Defaults to 2.
106             eval_fn (Callable[[Weights], Optional[Tuple[float, float]]], optional):
107                 Function used for validation. Defaults to None.
108             on_fit_config_fn (Callable[[int], Dict[str, Scalar]], optional):
109                 Function used to configure training. Defaults to None.
110             on_evaluate_config_fn (Callable[[int], Dict[str, Scalar]], optional):
111                 Function used to configure validation. Defaults to None.
112             accept_failures (bool, optional): Whether or not accept rounds
113                 containing failures. Defaults to True.
114             initial_parameters (Parameters, optional): Initial global model parameters.
115         """
116         super().__init__()
117         self.min_fit_clients = min_fit_clients
118         self.min_eval_clients = min_eval_clients
119         self.fraction_fit = fraction_fit
120         self.fraction_eval = fraction_eval
121         self.min_available_clients = min_available_clients
122         self.eval_fn = eval_fn
123         self.on_fit_config_fn = on_fit_config_fn
124         self.on_evaluate_config_fn = on_evaluate_config_fn
125         self.accept_failures = accept_failures
126         self.initial_parameters = initial_parameters
127 
128     def __repr__(self) -> str:
129         rep = f"FedAvg(accept_failures={self.accept_failures})"
130         return rep
131 
132     def num_fit_clients(self, num_available_clients: int) -> Tuple[int, int]:
133         """Return the sample size and the required number of available
134         clients."""
135         num_clients = int(num_available_clients * self.fraction_fit)
136         return max(num_clients, self.min_fit_clients), self.min_available_clients
137 
138     def num_evaluation_clients(self, num_available_clients: int) -> Tuple[int, int]:
139         """Use a fraction of available clients for evaluation."""
140         num_clients = int(num_available_clients * self.fraction_eval)
141         return max(num_clients, self.min_eval_clients), self.min_available_clients
142 
143     def initialize_parameters(
144         self, client_manager: ClientManager
145     ) -> Optional[Parameters]:
146         """Initialize global model parameters."""
147         initial_parameters = self.initial_parameters
148         self.initial_parameters = None  # Don't keep initial parameters in memory
149         if isinstance(initial_parameters, list):
150             log(WARNING, DEPRECATION_WARNING_INITIAL_PARAMETERS)
151             initial_parameters = weights_to_parameters(weights=initial_parameters)
152         return initial_parameters
153 
154     def evaluate(
155         self, parameters: Parameters
156     ) -> Optional[Tuple[float, Dict[str, Scalar]]]:
157         """Evaluate model parameters using an evaluation function."""
158         if self.eval_fn is None:
159             # No evaluation function provided
160             return None
161         weights = parameters_to_weights(parameters)
162         eval_res = self.eval_fn(weights)
163         if eval_res is None:
164             return None
165         loss, other = eval_res
166         if isinstance(other, float):
167             print(DEPRECATION_WARNING)
168             metrics = {"accuracy": other}
169         else:
170             metrics = other
171         return loss, metrics
172 
173     def configure_fit(
174         self, rnd: int, parameters: Parameters, client_manager: ClientManager
175     ) -> List[Tuple[ClientProxy, FitIns]]:
176         """Configure the next round of training."""
177         config = {}
178         if self.on_fit_config_fn is not None:
179             # Custom fit config function provided
180             config = self.on_fit_config_fn(rnd)
181         fit_ins = FitIns(parameters, config)
182 
183         # Sample clients
184         sample_size, min_num_clients = self.num_fit_clients(
185             client_manager.num_available()
186         )
187         clients = client_manager.sample(
188             num_clients=sample_size, min_num_clients=min_num_clients
189         )
190 
191         # Return client/config pairs
192         return [(client, fit_ins) for client in clients]
193 
194     def configure_evaluate(
195         self, rnd: int, parameters: Parameters, client_manager: ClientManager
196     ) -> List[Tuple[ClientProxy, EvaluateIns]]:
197         """Configure the next round of evaluation."""
198         # Do not configure federated evaluation if a centralized evaluation
199         # function is provided
200         if self.eval_fn is not None:
201             return []
202 
203         # Parameters and config
204         config = {}
205         if self.on_evaluate_config_fn is not None:
206             # Custom evaluation config function provided
207             config = self.on_evaluate_config_fn(rnd)
208         evaluate_ins = EvaluateIns(parameters, config)
209 
210         # Sample clients
211         if rnd >= 0:
212             sample_size, min_num_clients = self.num_evaluation_clients(
213                 client_manager.num_available()
214             )
215             clients = client_manager.sample(
216                 num_clients=sample_size, min_num_clients=min_num_clients
217             )
218         else:
219             clients = list(client_manager.all().values())
220 
221         # Return client/config pairs
222         return [(client, evaluate_ins) for client in clients]
223 
224     def aggregate_fit(
225         self,
226         rnd: int,
227         results: List[Tuple[ClientProxy, FitRes]],
228         failures: List[BaseException],
229     ) -> Tuple[Optional[Parameters], Dict[str, Scalar]]:
230         """Aggregate fit results using weighted average."""
231         if not results:
232             return None, {}
233         # Do not aggregate if there are failures and failures are not accepted
234         if not self.accept_failures and failures:
235             return None, {}
236         # Convert results
237         weights_results = [
238             (parameters_to_weights(fit_res.parameters), fit_res.num_examples)
239             for client, fit_res in results
240         ]
241         return weights_to_parameters(aggregate(weights_results)), {}
242 
243     def aggregate_evaluate(
244         self,
245         rnd: int,
246         results: List[Tuple[ClientProxy, EvaluateRes]],
247         failures: List[BaseException],
248     ) -> Tuple[Optional[float], Dict[str, Scalar]]:
249         """Aggregate evaluation losses using weighted average."""
250         if not results:
251             return None, {}
252         # Do not aggregate if there are failures and failures are not accepted
253         if not self.accept_failures and failures:
254             return None, {}
255         loss_aggregated = weighted_loss_avg(
256             [
257                 (
258                     evaluate_res.num_examples,
259                     evaluate_res.loss,
260                     evaluate_res.accuracy,
261                 )
262                 for _, evaluate_res in results
263             ]
264         )
265         return loss_aggregated, {}
266
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/py/flwr/server/strategy/fedavg.py b/src/py/flwr/server/strategy/fedavg.py
--- a/src/py/flwr/server/strategy/fedavg.py
+++ b/src/py/flwr/server/strategy/fedavg.py
@@ -92,26 +92,28 @@
 
         Implementation based on https://arxiv.org/abs/1602.05629
 
-        Args:
-            fraction_fit (float, optional): Fraction of clients used during
-                training. Defaults to 0.1.
-            fraction_eval (float, optional): Fraction of clients used during
-                validation. Defaults to 0.1.
-            min_fit_clients (int, optional): Minimum number of clients used
-                during training. Defaults to 2.
-            min_eval_clients (int, optional): Minimum number of clients used
-                during validation. Defaults to 2.
-            min_available_clients (int, optional): Minimum number of total
-                clients in the system. Defaults to 2.
-            eval_fn (Callable[[Weights], Optional[Tuple[float, float]]], optional):
-                Function used for validation. Defaults to None.
-            on_fit_config_fn (Callable[[int], Dict[str, Scalar]], optional):
-                Function used to configure training. Defaults to None.
-            on_evaluate_config_fn (Callable[[int], Dict[str, Scalar]], optional):
-                Function used to configure validation. Defaults to None.
-            accept_failures (bool, optional): Whether or not accept rounds
-                containing failures. Defaults to True.
-            initial_parameters (Parameters, optional): Initial global model parameters.
+        Parameters
+        ----------
+        fraction_fit : float, optional
+            Fraction of clients used during training. Defaults to 0.1.
+        fraction_eval : float, optional
+            Fraction of clients used during validation. Defaults to 0.1.
+        min_fit_clients : int, optional
+            Minimum number of clients used during training. Defaults to 2.
+        min_eval_clients : int, optional
+            Minimum number of clients used during validation. Defaults to 2.
+        min_available_clients : int, optional
+            Minimum number of total clients in the system. Defaults to 2.
+        eval_fn : Callable[[Weights], Optional[Tuple[float, Dict[str, Scalar]]]]
+            Optional function used for validation. Defaults to None.
+        on_fit_config_fn : Callable[[int], Dict[str, Scalar]], optional
+            Function used to configure training. Defaults to None.
+        on_evaluate_config_fn : Callable[[int], Dict[str, Scalar]], optional
+            Function used to configure validation. Defaults to None.
+        accept_failures : bool, optional
+            Whether or not accept rounds containing failures. Defaults to True.
+        initial_parameters : Parameters, optional
+            Initial global model parameters.
         """
         super().__init__()
         self.min_fit_clients = min_fit_clients

{"golden_diff": "diff --git a/src/py/flwr/server/strategy/fedavg.py b/src/py/flwr/server/strategy/fedavg.py\n--- a/src/py/flwr/server/strategy/fedavg.py\n+++ b/src/py/flwr/server/strategy/fedavg.py\n@@ -92,26 +92,28 @@\n \n         Implementation based on https://arxiv.org/abs/1602.05629\n \n-        Args:\n-            fraction_fit (float, optional): Fraction of clients used during\n-                training. Defaults to 0.1.\n-            fraction_eval (float, optional): Fraction of clients used during\n-                validation. Defaults to 0.1.\n-            min_fit_clients (int, optional): Minimum number of clients used\n-                during training. Defaults to 2.\n-            min_eval_clients (int, optional): Minimum number of clients used\n-                during validation. Defaults to 2.\n-            min_available_clients (int, optional): Minimum number of total\n-                clients in the system. Defaults to 2.\n-            eval_fn (Callable[[Weights], Optional[Tuple[float, float]]], optional):\n-                Function used for validation. Defaults to None.\n-            on_fit_config_fn (Callable[[int], Dict[str, Scalar]], optional):\n-                Function used to configure training. Defaults to None.\n-            on_evaluate_config_fn (Callable[[int], Dict[str, Scalar]], optional):\n-                Function used to configure validation. Defaults to None.\n-            accept_failures (bool, optional): Whether or not accept rounds\n-                containing failures. Defaults to True.\n-            initial_parameters (Parameters, optional): Initial global model parameters.\n+        Parameters\n+        ----------\n+        fraction_fit : float, optional\n+            Fraction of clients used during training. Defaults to 0.1.\n+        fraction_eval : float, optional\n+            Fraction of clients used during validation. Defaults to 0.1.\n+        min_fit_clients : int, optional\n+            Minimum number of clients used during training. Defaults to 2.\n+        min_eval_clients : int, optional\n+            Minimum number of clients used during validation. Defaults to 2.\n+        min_available_clients : int, optional\n+            Minimum number of total clients in the system. Defaults to 2.\n+        eval_fn : Callable[[Weights], Optional[Tuple[float, Dict[str, Scalar]]]]\n+            Optional function used for validation. Defaults to None.\n+        on_fit_config_fn : Callable[[int], Dict[str, Scalar]], optional\n+            Function used to configure training. Defaults to None.\n+        on_evaluate_config_fn : Callable[[int], Dict[str, Scalar]], optional\n+            Function used to configure validation. Defaults to None.\n+        accept_failures : bool, optional\n+            Whether or not accept rounds containing failures. Defaults to True.\n+        initial_parameters : Parameters, optional\n+            Initial global model parameters.\n         \"\"\"\n         super().__init__()\n         self.min_fit_clients = min_fit_clients\n", "issue": "Update signature to Dict[floatScalar\nhttps://github.com/adap/flower/blob/a8a7dd1fce957540b49c59e56221d5762a937f8d/src/py/flwr/server/strategy/fedavg.py#L106\n", "before_files": [{"content": "# Copyright 2020 Adap GmbH. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\n\"\"\"Federated Averaging (FedAvg) [McMahan et al., 2016] strategy.\n\nPaper: https://arxiv.org/abs/1602.05629\n\"\"\"\n\n\nfrom logging import WARNING\nfrom typing import Callable, Dict, List, Optional, Tuple\n\nfrom flwr.common import (\n    EvaluateIns,\n    EvaluateRes,\n    FitIns,\n    FitRes,\n    Parameters,\n    Scalar,\n    Weights,\n    parameters_to_weights,\n    weights_to_parameters,\n)\nfrom flwr.common.logger import log\nfrom flwr.server.client_manager import ClientManager\nfrom flwr.server.client_proxy import ClientProxy\n\nfrom .aggregate import aggregate, weighted_loss_avg\nfrom .strategy import Strategy\n\nDEPRECATION_WARNING = \"\"\"\nDEPRECATION WARNING: deprecated `eval_fn` return format\n\n    loss, accuracy\n\nmove to\n\n    loss, {\"accuracy\": accuracy}\n\ninstead. Note that compatibility with the deprecated return format will be\nremoved in a future release.\n\"\"\"\n\nDEPRECATION_WARNING_INITIAL_PARAMETERS = \"\"\"\nDEPRECATION WARNING: deprecated initial parameter type\n\n    flwr.common.Weights (i.e., List[np.ndarray])\n\nwill be removed in a future update, move to\n\n    flwr.common.Parameters\n\ninstead. Use\n\n    parameters = flwr.common.weights_to_parameters(weights)\n\nto easily transform `Weights` to `Parameters`.\n\"\"\"\n\n\nclass FedAvg(Strategy):\n    \"\"\"Configurable FedAvg strategy implementation.\"\"\"\n\n    # pylint: disable=too-many-arguments,too-many-instance-attributes\n    def __init__(\n        self,\n        fraction_fit: float = 0.1,\n        fraction_eval: float = 0.1,\n        min_fit_clients: int = 2,\n        min_eval_clients: int = 2,\n        min_available_clients: int = 2,\n        eval_fn: Optional[\n            Callable[[Weights], Optional[Tuple[float, Dict[str, Scalar]]]]\n        ] = None,\n        on_fit_config_fn: Optional[Callable[[int], Dict[str, Scalar]]] = None,\n        on_evaluate_config_fn: Optional[Callable[[int], Dict[str, Scalar]]] = None,\n        accept_failures: bool = True,\n        initial_parameters: Optional[Parameters] = None,\n    ) -> None:\n        \"\"\"Federated Averaging strategy.\n\n        Implementation based on https://arxiv.org/abs/1602.05629\n\n        Args:\n            fraction_fit (float, optional): Fraction of clients used during\n                training. Defaults to 0.1.\n            fraction_eval (float, optional): Fraction of clients used during\n                validation. Defaults to 0.1.\n            min_fit_clients (int, optional): Minimum number of clients used\n                during training. Defaults to 2.\n            min_eval_clients (int, optional): Minimum number of clients used\n                during validation. Defaults to 2.\n            min_available_clients (int, optional): Minimum number of total\n                clients in the system. Defaults to 2.\n            eval_fn (Callable[[Weights], Optional[Tuple[float, float]]], optional):\n                Function used for validation. Defaults to None.\n            on_fit_config_fn (Callable[[int], Dict[str, Scalar]], optional):\n                Function used to configure training. Defaults to None.\n            on_evaluate_config_fn (Callable[[int], Dict[str, Scalar]], optional):\n                Function used to configure validation. Defaults to None.\n            accept_failures (bool, optional): Whether or not accept rounds\n                containing failures. Defaults to True.\n            initial_parameters (Parameters, optional): Initial global model parameters.\n        \"\"\"\n        super().__init__()\n        self.min_fit_clients = min_fit_clients\n        self.min_eval_clients = min_eval_clients\n        self.fraction_fit = fraction_fit\n        self.fraction_eval = fraction_eval\n        self.min_available_clients = min_available_clients\n        self.eval_fn = eval_fn\n        self.on_fit_config_fn = on_fit_config_fn\n        self.on_evaluate_config_fn = on_evaluate_config_fn\n        self.accept_failures = accept_failures\n        self.initial_parameters = initial_parameters\n\n    def __repr__(self) -> str:\n        rep = f\"FedAvg(accept_failures={self.accept_failures})\"\n        return rep\n\n    def num_fit_clients(self, num_available_clients: int) -> Tuple[int, int]:\n        \"\"\"Return the sample size and the required number of available\n        clients.\"\"\"\n        num_clients = int(num_available_clients * self.fraction_fit)\n        return max(num_clients, self.min_fit_clients), self.min_available_clients\n\n    def num_evaluation_clients(self, num_available_clients: int) -> Tuple[int, int]:\n        \"\"\"Use a fraction of available clients for evaluation.\"\"\"\n        num_clients = int(num_available_clients * self.fraction_eval)\n        return max(num_clients, self.min_eval_clients), self.min_available_clients\n\n    def initialize_parameters(\n        self, client_manager: ClientManager\n    ) -> Optional[Parameters]:\n        \"\"\"Initialize global model parameters.\"\"\"\n        initial_parameters = self.initial_parameters\n        self.initial_parameters = None  # Don't keep initial parameters in memory\n        if isinstance(initial_parameters, list):\n            log(WARNING, DEPRECATION_WARNING_INITIAL_PARAMETERS)\n            initial_parameters = weights_to_parameters(weights=initial_parameters)\n        return initial_parameters\n\n    def evaluate(\n        self, parameters: Parameters\n    ) -> Optional[Tuple[float, Dict[str, Scalar]]]:\n        \"\"\"Evaluate model parameters using an evaluation function.\"\"\"\n        if self.eval_fn is None:\n            # No evaluation function provided\n            return None\n        weights = parameters_to_weights(parameters)\n        eval_res = self.eval_fn(weights)\n        if eval_res is None:\n            return None\n        loss, other = eval_res\n        if isinstance(other, float):\n            print(DEPRECATION_WARNING)\n            metrics = {\"accuracy\": other}\n        else:\n            metrics = other\n        return loss, metrics\n\n    def configure_fit(\n        self, rnd: int, parameters: Parameters, client_manager: ClientManager\n    ) -> List[Tuple[ClientProxy, FitIns]]:\n        \"\"\"Configure the next round of training.\"\"\"\n        config = {}\n        if self.on_fit_config_fn is not None:\n            # Custom fit config function provided\n            config = self.on_fit_config_fn(rnd)\n        fit_ins = FitIns(parameters, config)\n\n        # Sample clients\n        sample_size, min_num_clients = self.num_fit_clients(\n            client_manager.num_available()\n        )\n        clients = client_manager.sample(\n            num_clients=sample_size, min_num_clients=min_num_clients\n        )\n\n        # Return client/config pairs\n        return [(client, fit_ins) for client in clients]\n\n    def configure_evaluate(\n        self, rnd: int, parameters: Parameters, client_manager: ClientManager\n    ) -> List[Tuple[ClientProxy, EvaluateIns]]:\n        \"\"\"Configure the next round of evaluation.\"\"\"\n        # Do not configure federated evaluation if a centralized evaluation\n        # function is provided\n        if self.eval_fn is not None:\n            return []\n\n        # Parameters and config\n        config = {}\n        if self.on_evaluate_config_fn is not None:\n            # Custom evaluation config function provided\n            config = self.on_evaluate_config_fn(rnd)\n        evaluate_ins = EvaluateIns(parameters, config)\n\n        # Sample clients\n        if rnd >= 0:\n            sample_size, min_num_clients = self.num_evaluation_clients(\n                client_manager.num_available()\n            )\n            clients = client_manager.sample(\n                num_clients=sample_size, min_num_clients=min_num_clients\n            )\n        else:\n            clients = list(client_manager.all().values())\n\n        # Return client/config pairs\n        return [(client, evaluate_ins) for client in clients]\n\n    def aggregate_fit(\n        self,\n        rnd: int,\n        results: List[Tuple[ClientProxy, FitRes]],\n        failures: List[BaseException],\n    ) -> Tuple[Optional[Parameters], Dict[str, Scalar]]:\n        \"\"\"Aggregate fit results using weighted average.\"\"\"\n        if not results:\n            return None, {}\n        # Do not aggregate if there are failures and failures are not accepted\n        if not self.accept_failures and failures:\n            return None, {}\n        # Convert results\n        weights_results = [\n            (parameters_to_weights(fit_res.parameters), fit_res.num_examples)\n            for client, fit_res in results\n        ]\n        return weights_to_parameters(aggregate(weights_results)), {}\n\n    def aggregate_evaluate(\n        self,\n        rnd: int,\n        results: List[Tuple[ClientProxy, EvaluateRes]],\n        failures: List[BaseException],\n    ) -> Tuple[Optional[float], Dict[str, Scalar]]:\n        \"\"\"Aggregate evaluation losses using weighted average.\"\"\"\n        if not results:\n            return None, {}\n        # Do not aggregate if there are failures and failures are not accepted\n        if not self.accept_failures and failures:\n            return None, {}\n        loss_aggregated = weighted_loss_avg(\n            [\n                (\n                    evaluate_res.num_examples,\n                    evaluate_res.loss,\n                    evaluate_res.accuracy,\n                )\n                for _, evaluate_res in results\n            ]\n        )\n        return loss_aggregated, {}\n", "path": "src/py/flwr/server/strategy/fedavg.py"}], "after_files": [{"content": "# Copyright 2020 Adap GmbH. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\n\"\"\"Federated Averaging (FedAvg) [McMahan et al., 2016] strategy.\n\nPaper: https://arxiv.org/abs/1602.05629\n\"\"\"\n\n\nfrom logging import WARNING\nfrom typing import Callable, Dict, List, Optional, Tuple\n\nfrom flwr.common import (\n    EvaluateIns,\n    EvaluateRes,\n    FitIns,\n    FitRes,\n    Parameters,\n    Scalar,\n    Weights,\n    parameters_to_weights,\n    weights_to_parameters,\n)\nfrom flwr.common.logger import log\nfrom flwr.server.client_manager import ClientManager\nfrom flwr.server.client_proxy import ClientProxy\n\nfrom .aggregate import aggregate, weighted_loss_avg\nfrom .strategy import Strategy\n\nDEPRECATION_WARNING = \"\"\"\nDEPRECATION WARNING: deprecated `eval_fn` return format\n\n    loss, accuracy\n\nmove to\n\n    loss, {\"accuracy\": accuracy}\n\ninstead. Note that compatibility with the deprecated return format will be\nremoved in a future release.\n\"\"\"\n\nDEPRECATION_WARNING_INITIAL_PARAMETERS = \"\"\"\nDEPRECATION WARNING: deprecated initial parameter type\n\n    flwr.common.Weights (i.e., List[np.ndarray])\n\nwill be removed in a future update, move to\n\n    flwr.common.Parameters\n\ninstead. Use\n\n    parameters = flwr.common.weights_to_parameters(weights)\n\nto easily transform `Weights` to `Parameters`.\n\"\"\"\n\n\nclass FedAvg(Strategy):\n    \"\"\"Configurable FedAvg strategy implementation.\"\"\"\n\n    # pylint: disable=too-many-arguments,too-many-instance-attributes\n    def __init__(\n        self,\n        fraction_fit: float = 0.1,\n        fraction_eval: float = 0.1,\n        min_fit_clients: int = 2,\n        min_eval_clients: int = 2,\n        min_available_clients: int = 2,\n        eval_fn: Optional[\n            Callable[[Weights], Optional[Tuple[float, Dict[str, Scalar]]]]\n        ] = None,\n        on_fit_config_fn: Optional[Callable[[int], Dict[str, Scalar]]] = None,\n        on_evaluate_config_fn: Optional[Callable[[int], Dict[str, Scalar]]] = None,\n        accept_failures: bool = True,\n        initial_parameters: Optional[Parameters] = None,\n    ) -> None:\n        \"\"\"Federated Averaging strategy.\n\n        Implementation based on https://arxiv.org/abs/1602.05629\n\n        Parameters\n        ----------\n        fraction_fit : float, optional\n            Fraction of clients used during training. Defaults to 0.1.\n        fraction_eval : float, optional\n            Fraction of clients used during validation. Defaults to 0.1.\n        min_fit_clients : int, optional\n            Minimum number of clients used during training. Defaults to 2.\n        min_eval_clients : int, optional\n            Minimum number of clients used during validation. Defaults to 2.\n        min_available_clients : int, optional\n            Minimum number of total clients in the system. Defaults to 2.\n        eval_fn : Callable[[Weights], Optional[Tuple[float, Dict[str, Scalar]]]]\n            Optional function used for validation. Defaults to None.\n        on_fit_config_fn : Callable[[int], Dict[str, Scalar]], optional\n            Function used to configure training. Defaults to None.\n        on_evaluate_config_fn : Callable[[int], Dict[str, Scalar]], optional\n            Function used to configure validation. Defaults to None.\n        accept_failures : bool, optional\n            Whether or not accept rounds containing failures. Defaults to True.\n        initial_parameters : Parameters, optional\n            Initial global model parameters.\n        \"\"\"\n        super().__init__()\n        self.min_fit_clients = min_fit_clients\n        self.min_eval_clients = min_eval_clients\n        self.fraction_fit = fraction_fit\n        self.fraction_eval = fraction_eval\n        self.min_available_clients = min_available_clients\n        self.eval_fn = eval_fn\n        self.on_fit_config_fn = on_fit_config_fn\n        self.on_evaluate_config_fn = on_evaluate_config_fn\n        self.accept_failures = accept_failures\n        self.initial_parameters = initial_parameters\n\n    def __repr__(self) -> str:\n        rep = f\"FedAvg(accept_failures={self.accept_failures})\"\n        return rep\n\n    def num_fit_clients(self, num_available_clients: int) -> Tuple[int, int]:\n        \"\"\"Return the sample size and the required number of available\n        clients.\"\"\"\n        num_clients = int(num_available_clients * self.fraction_fit)\n        return max(num_clients, self.min_fit_clients), self.min_available_clients\n\n    def num_evaluation_clients(self, num_available_clients: int) -> Tuple[int, int]:\n        \"\"\"Use a fraction of available clients for evaluation.\"\"\"\n        num_clients = int(num_available_clients * self.fraction_eval)\n        return max(num_clients, self.min_eval_clients), self.min_available_clients\n\n    def initialize_parameters(\n        self, client_manager: ClientManager\n    ) -> Optional[Parameters]:\n        \"\"\"Initialize global model parameters.\"\"\"\n        initial_parameters = self.initial_parameters\n        self.initial_parameters = None  # Don't keep initial parameters in memory\n        if isinstance(initial_parameters, list):\n            log(WARNING, DEPRECATION_WARNING_INITIAL_PARAMETERS)\n            initial_parameters = weights_to_parameters(weights=initial_parameters)\n        return initial_parameters\n\n    def evaluate(\n        self, parameters: Parameters\n    ) -> Optional[Tuple[float, Dict[str, Scalar]]]:\n        \"\"\"Evaluate model parameters using an evaluation function.\"\"\"\n        if self.eval_fn is None:\n            # No evaluation function provided\n            return None\n        weights = parameters_to_weights(parameters)\n        eval_res = self.eval_fn(weights)\n        if eval_res is None:\n            return None\n        loss, other = eval_res\n        if isinstance(other, float):\n            print(DEPRECATION_WARNING)\n            metrics = {\"accuracy\": other}\n        else:\n            metrics = other\n        return loss, metrics\n\n    def configure_fit(\n        self, rnd: int, parameters: Parameters, client_manager: ClientManager\n    ) -> List[Tuple[ClientProxy, FitIns]]:\n        \"\"\"Configure the next round of training.\"\"\"\n        config = {}\n        if self.on_fit_config_fn is not None:\n            # Custom fit config function provided\n            config = self.on_fit_config_fn(rnd)\n        fit_ins = FitIns(parameters, config)\n\n        # Sample clients\n        sample_size, min_num_clients = self.num_fit_clients(\n            client_manager.num_available()\n        )\n        clients = client_manager.sample(\n            num_clients=sample_size, min_num_clients=min_num_clients\n        )\n\n        # Return client/config pairs\n        return [(client, fit_ins) for client in clients]\n\n    def configure_evaluate(\n        self, rnd: int, parameters: Parameters, client_manager: ClientManager\n    ) -> List[Tuple[ClientProxy, EvaluateIns]]:\n        \"\"\"Configure the next round of evaluation.\"\"\"\n        # Do not configure federated evaluation if a centralized evaluation\n        # function is provided\n        if self.eval_fn is not None:\n            return []\n\n        # Parameters and config\n        config = {}\n        if self.on_evaluate_config_fn is not None:\n            # Custom evaluation config function provided\n            config = self.on_evaluate_config_fn(rnd)\n        evaluate_ins = EvaluateIns(parameters, config)\n\n        # Sample clients\n        if rnd >= 0:\n            sample_size, min_num_clients = self.num_evaluation_clients(\n                client_manager.num_available()\n            )\n            clients = client_manager.sample(\n                num_clients=sample_size, min_num_clients=min_num_clients\n            )\n        else:\n            clients = list(client_manager.all().values())\n\n        # Return client/config pairs\n        return [(client, evaluate_ins) for client in clients]\n\n    def aggregate_fit(\n        self,\n        rnd: int,\n        results: List[Tuple[ClientProxy, FitRes]],\n        failures: List[BaseException],\n    ) -> Tuple[Optional[Parameters], Dict[str, Scalar]]:\n        \"\"\"Aggregate fit results using weighted average.\"\"\"\n        if not results:\n            return None, {}\n        # Do not aggregate if there are failures and failures are not accepted\n        if not self.accept_failures and failures:\n            return None, {}\n        # Convert results\n        weights_results = [\n            (parameters_to_weights(fit_res.parameters), fit_res.num_examples)\n            for client, fit_res in results\n        ]\n        return weights_to_parameters(aggregate(weights_results)), {}\n\n    def aggregate_evaluate(\n        self,\n        rnd: int,\n        results: List[Tuple[ClientProxy, EvaluateRes]],\n        failures: List[BaseException],\n    ) -> Tuple[Optional[float], Dict[str, Scalar]]:\n        \"\"\"Aggregate evaluation losses using weighted average.\"\"\"\n        if not results:\n            return None, {}\n        # Do not aggregate if there are failures and failures are not accepted\n        if not self.accept_failures and failures:\n            return None, {}\n        loss_aggregated = weighted_loss_avg(\n            [\n                (\n                    evaluate_res.num_examples,\n                    evaluate_res.loss,\n                    evaluate_res.accuracy,\n                )\n                for _, evaluate_res in results\n            ]\n        )\n        return loss_aggregated, {}\n", "path": "src/py/flwr/server/strategy/fedavg.py"}]}