We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Unnecessary string formatting when saving the model
https://github.com/mozilla/bugbug/blob/ab007344c5c799c08739b2d56f334afcaf242919/bugbug/model.py#L111 is not needed, we can use the variable directly.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `bugbug/model.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 # This Source Code Form is subject to the terms of the Mozilla Public
3 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
4 # You can obtain one at http://mozilla.org/MPL/2.0/.
5 
6 import numpy as np
7 import shap
8 from imblearn.metrics import classification_report_imbalanced
9 from imblearn.under_sampling import RandomUnderSampler
10 from sklearn import metrics
11 from sklearn.externals import joblib
12 from sklearn.feature_extraction.text import TfidfVectorizer
13 from sklearn.model_selection import cross_val_score
14 from sklearn.model_selection import train_test_split
15 
16 from bugbug import bugzilla
17 from bugbug.nlp import SpacyVectorizer
18 
19 
20 class Model():
21     def __init__(self, lemmatization=False):
22         if lemmatization:
23             self.text_vectorizer = SpacyVectorizer
24         else:
25             self.text_vectorizer = TfidfVectorizer
26 
27         self.undersampling_enabled = True
28         self.cross_validation_enabled = True
29 
30     def get_feature_names(self):
31         return []
32 
33     def train(self):
34         classes = self.get_labels()
35         class_names = sorted(list(set(classes.values())), reverse=True)
36 
37         # Get bugs, filtering out those for which we have no labels.
38         def bugs():
39             return (bug for bug in bugzilla.get_bugs() if bug['id'] in classes)
40 
41         # Calculate labels.
42         y = np.array([classes[bug['id']] for bug in bugs()])
43 
44         # Extract features from the bugs.
45         X = self.extraction_pipeline.fit_transform(bugs())
46 
47         print(f'X: {X.shape}, y: {y.shape}')
48 
49         # Split dataset in training and test.
50         X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=0)
51 
52         if self.undersampling_enabled:
53             # Under-sample the majority classes, as the datasets are imbalanced.
54             X_train, y_train = RandomUnderSampler(random_state=0).fit_sample(X_train, y_train)
55 
56         print(f'X_train: {X_train.shape}, y_train: {y_train.shape}')
57         print(f'X_test: {X_test.shape}, y_test: {y_test.shape}')
58 
59         # Use k-fold cross validation to evaluate results.
60         if self.cross_validation_enabled:
61             scores = cross_val_score(self.clf, X_train, y_train, cv=5)
62             print(f'CV Accuracy: f{scores.mean()} (+/- {scores.std() * 2})')
63 
64         # Evaluate results on the test set.
65         self.clf.fit(X_train, y_train)
66 
67         feature_names = self.get_feature_names()
68         if len(feature_names):
69             explainer = shap.TreeExplainer(self.clf)
70             shap_values = explainer.shap_values(X_train)
71 
72             print('Feature ranking (top 20 features):')
73             # Calculate the values that represent the fraction of the model output variability attributable
74             # to each feature across the whole dataset.
75             shap_sums = np.abs(shap_values).sum(0)
76             rel_shap_sums = shap_sums / shap_sums.sum()
77             indices = np.argsort(rel_shap_sums)[::-1][:20]
78             for i, index in enumerate(indices):
79                 print(f'{i + 1}. \'{feature_names[index]}\' ({rel_shap_sums[index]})')
80 
81         y_pred = self.clf.predict(X_test)
82 
83         print(f'No confidence threshold - {len(y_test)} classified')
84         print(metrics.confusion_matrix(y_test, y_pred, labels=class_names))
85         print(classification_report_imbalanced(y_test, y_pred, labels=class_names))
86 
87         # Evaluate results on the test set for some confidence thresholds.
88         for confidence_threshold in [0.6, 0.7, 0.8, 0.9]:
89             y_pred_probas = self.clf.predict_proba(X_test)
90 
91             y_test_filter = []
92             y_pred_filter = []
93             for i in range(0, len(y_test)):
94                 argmax = np.argmax(y_pred_probas[i])
95                 if y_pred_probas[i][argmax] < confidence_threshold:
96                     continue
97 
98                 y_test_filter.append(y_test[i])
99                 y_pred_filter.append(argmax)
100 
101             y_pred_filter = self.clf._le.inverse_transform(y_pred_filter)
102 
103             print(f'\nConfidence threshold > {confidence_threshold} - {len(y_test_filter)} classified')
104             print(metrics.confusion_matrix(y_test_filter, y_pred_filter, labels=class_names))
105             print(classification_report_imbalanced(y_test_filter, y_pred_filter, labels=class_names))
106 
107         joblib.dump(self, f'{self.__class__.__name__.lower()}')
108 
109     @staticmethod
110     def load(model_file_name):
111         return joblib.load(model_file_name)
112 
113     def overwrite_classes(self, bugs, classes, probabilities):
114         return classes
115 
116     def classify(self, bugs, probabilities=False, importances=False):
117         assert bugs is not None
118         assert self.extraction_pipeline is not None and self.clf is not None, 'The module needs to be initialized first'
119 
120         if not isinstance(bugs, list):
121             bugs = [bugs]
122 
123         assert isinstance(bugs[0], dict)
124 
125         X = self.extraction_pipeline.transform(bugs)
126         if probabilities:
127             classes = self.clf.predict_proba(X)
128         else:
129             classes = self.clf.predict(X)
130 
131         classes = self.overwrite_classes(bugs, classes, probabilities)
132 
133         if importances:
134             explainer = shap.TreeExplainer(self.clf)
135             shap_values = explainer.shap_values(X)
136 
137             shap_sums = shap_values.sum(0)
138             abs_shap_sums = np.abs(shap_sums)
139             rel_shap_sums = abs_shap_sums / abs_shap_sums.sum()
140             indices = np.argsort(abs_shap_sums)[::-1]
141             importances = [(index, shap_sums[index] > 0, rel_shap_sums[index]) for index in indices]
142 
143             return classes, importances
144 
145         return classes
146
```
--- 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/bugbug/model.py b/bugbug/model.py
--- a/bugbug/model.py
+++ b/bugbug/model.py
@@ -104,7 +104,7 @@
             print(metrics.confusion_matrix(y_test_filter, y_pred_filter, labels=class_names))
             print(classification_report_imbalanced(y_test_filter, y_pred_filter, labels=class_names))
 
-        joblib.dump(self, f'{self.__class__.__name__.lower()}')
+        joblib.dump(self, self.__class__.__name__.lower())
 
     @staticmethod
     def load(model_file_name):

{"golden_diff": "diff --git a/bugbug/model.py b/bugbug/model.py\n--- a/bugbug/model.py\n+++ b/bugbug/model.py\n@@ -104,7 +104,7 @@\n             print(metrics.confusion_matrix(y_test_filter, y_pred_filter, labels=class_names))\n             print(classification_report_imbalanced(y_test_filter, y_pred_filter, labels=class_names))\n \n-        joblib.dump(self, f'{self.__class__.__name__.lower()}')\n+        joblib.dump(self, self.__class__.__name__.lower())\n \n     @staticmethod\n     def load(model_file_name):\n", "issue": "Unnecessary string formatting when saving the model\nhttps://github.com/mozilla/bugbug/blob/ab007344c5c799c08739b2d56f334afcaf242919/bugbug/model.py#L111 is not needed, we can use the variable directly.\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n# This Source Code Form is subject to the terms of the Mozilla Public\n# License, v. 2.0. If a copy of the MPL was not distributed with this file,\n# You can obtain one at http://mozilla.org/MPL/2.0/.\n\nimport numpy as np\nimport shap\nfrom imblearn.metrics import classification_report_imbalanced\nfrom imblearn.under_sampling import RandomUnderSampler\nfrom sklearn import metrics\nfrom sklearn.externals import joblib\nfrom sklearn.feature_extraction.text import TfidfVectorizer\nfrom sklearn.model_selection import cross_val_score\nfrom sklearn.model_selection import train_test_split\n\nfrom bugbug import bugzilla\nfrom bugbug.nlp import SpacyVectorizer\n\n\nclass Model():\n    def __init__(self, lemmatization=False):\n        if lemmatization:\n            self.text_vectorizer = SpacyVectorizer\n        else:\n            self.text_vectorizer = TfidfVectorizer\n\n        self.undersampling_enabled = True\n        self.cross_validation_enabled = True\n\n    def get_feature_names(self):\n        return []\n\n    def train(self):\n        classes = self.get_labels()\n        class_names = sorted(list(set(classes.values())), reverse=True)\n\n        # Get bugs, filtering out those for which we have no labels.\n        def bugs():\n            return (bug for bug in bugzilla.get_bugs() if bug['id'] in classes)\n\n        # Calculate labels.\n        y = np.array([classes[bug['id']] for bug in bugs()])\n\n        # Extract features from the bugs.\n        X = self.extraction_pipeline.fit_transform(bugs())\n\n        print(f'X: {X.shape}, y: {y.shape}')\n\n        # Split dataset in training and test.\n        X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=0)\n\n        if self.undersampling_enabled:\n            # Under-sample the majority classes, as the datasets are imbalanced.\n            X_train, y_train = RandomUnderSampler(random_state=0).fit_sample(X_train, y_train)\n\n        print(f'X_train: {X_train.shape}, y_train: {y_train.shape}')\n        print(f'X_test: {X_test.shape}, y_test: {y_test.shape}')\n\n        # Use k-fold cross validation to evaluate results.\n        if self.cross_validation_enabled:\n            scores = cross_val_score(self.clf, X_train, y_train, cv=5)\n            print(f'CV Accuracy: f{scores.mean()} (+/- {scores.std() * 2})')\n\n        # Evaluate results on the test set.\n        self.clf.fit(X_train, y_train)\n\n        feature_names = self.get_feature_names()\n        if len(feature_names):\n            explainer = shap.TreeExplainer(self.clf)\n            shap_values = explainer.shap_values(X_train)\n\n            print('Feature ranking (top 20 features):')\n            # Calculate the values that represent the fraction of the model output variability attributable\n            # to each feature across the whole dataset.\n            shap_sums = np.abs(shap_values).sum(0)\n            rel_shap_sums = shap_sums / shap_sums.sum()\n            indices = np.argsort(rel_shap_sums)[::-1][:20]\n            for i, index in enumerate(indices):\n                print(f'{i + 1}. \\'{feature_names[index]}\\' ({rel_shap_sums[index]})')\n\n        y_pred = self.clf.predict(X_test)\n\n        print(f'No confidence threshold - {len(y_test)} classified')\n        print(metrics.confusion_matrix(y_test, y_pred, labels=class_names))\n        print(classification_report_imbalanced(y_test, y_pred, labels=class_names))\n\n        # Evaluate results on the test set for some confidence thresholds.\n        for confidence_threshold in [0.6, 0.7, 0.8, 0.9]:\n            y_pred_probas = self.clf.predict_proba(X_test)\n\n            y_test_filter = []\n            y_pred_filter = []\n            for i in range(0, len(y_test)):\n                argmax = np.argmax(y_pred_probas[i])\n                if y_pred_probas[i][argmax] < confidence_threshold:\n                    continue\n\n                y_test_filter.append(y_test[i])\n                y_pred_filter.append(argmax)\n\n            y_pred_filter = self.clf._le.inverse_transform(y_pred_filter)\n\n            print(f'\\nConfidence threshold > {confidence_threshold} - {len(y_test_filter)} classified')\n            print(metrics.confusion_matrix(y_test_filter, y_pred_filter, labels=class_names))\n            print(classification_report_imbalanced(y_test_filter, y_pred_filter, labels=class_names))\n\n        joblib.dump(self, f'{self.__class__.__name__.lower()}')\n\n    @staticmethod\n    def load(model_file_name):\n        return joblib.load(model_file_name)\n\n    def overwrite_classes(self, bugs, classes, probabilities):\n        return classes\n\n    def classify(self, bugs, probabilities=False, importances=False):\n        assert bugs is not None\n        assert self.extraction_pipeline is not None and self.clf is not None, 'The module needs to be initialized first'\n\n        if not isinstance(bugs, list):\n            bugs = [bugs]\n\n        assert isinstance(bugs[0], dict)\n\n        X = self.extraction_pipeline.transform(bugs)\n        if probabilities:\n            classes = self.clf.predict_proba(X)\n        else:\n            classes = self.clf.predict(X)\n\n        classes = self.overwrite_classes(bugs, classes, probabilities)\n\n        if importances:\n            explainer = shap.TreeExplainer(self.clf)\n            shap_values = explainer.shap_values(X)\n\n            shap_sums = shap_values.sum(0)\n            abs_shap_sums = np.abs(shap_sums)\n            rel_shap_sums = abs_shap_sums / abs_shap_sums.sum()\n            indices = np.argsort(abs_shap_sums)[::-1]\n            importances = [(index, shap_sums[index] > 0, rel_shap_sums[index]) for index in indices]\n\n            return classes, importances\n\n        return classes\n", "path": "bugbug/model.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n# This Source Code Form is subject to the terms of the Mozilla Public\n# License, v. 2.0. If a copy of the MPL was not distributed with this file,\n# You can obtain one at http://mozilla.org/MPL/2.0/.\n\nimport numpy as np\nimport shap\nfrom imblearn.metrics import classification_report_imbalanced\nfrom imblearn.under_sampling import RandomUnderSampler\nfrom sklearn import metrics\nfrom sklearn.externals import joblib\nfrom sklearn.feature_extraction.text import TfidfVectorizer\nfrom sklearn.model_selection import cross_val_score\nfrom sklearn.model_selection import train_test_split\n\nfrom bugbug import bugzilla\nfrom bugbug.nlp import SpacyVectorizer\n\n\nclass Model():\n    def __init__(self, lemmatization=False):\n        if lemmatization:\n            self.text_vectorizer = SpacyVectorizer\n        else:\n            self.text_vectorizer = TfidfVectorizer\n\n        self.undersampling_enabled = True\n        self.cross_validation_enabled = True\n\n    def get_feature_names(self):\n        return []\n\n    def train(self):\n        classes = self.get_labels()\n        class_names = sorted(list(set(classes.values())), reverse=True)\n\n        # Get bugs, filtering out those for which we have no labels.\n        def bugs():\n            return (bug for bug in bugzilla.get_bugs() if bug['id'] in classes)\n\n        # Calculate labels.\n        y = np.array([classes[bug['id']] for bug in bugs()])\n\n        # Extract features from the bugs.\n        X = self.extraction_pipeline.fit_transform(bugs())\n\n        print(f'X: {X.shape}, y: {y.shape}')\n\n        # Split dataset in training and test.\n        X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=0)\n\n        if self.undersampling_enabled:\n            # Under-sample the majority classes, as the datasets are imbalanced.\n            X_train, y_train = RandomUnderSampler(random_state=0).fit_sample(X_train, y_train)\n\n        print(f'X_train: {X_train.shape}, y_train: {y_train.shape}')\n        print(f'X_test: {X_test.shape}, y_test: {y_test.shape}')\n\n        # Use k-fold cross validation to evaluate results.\n        if self.cross_validation_enabled:\n            scores = cross_val_score(self.clf, X_train, y_train, cv=5)\n            print(f'CV Accuracy: f{scores.mean()} (+/- {scores.std() * 2})')\n\n        # Evaluate results on the test set.\n        self.clf.fit(X_train, y_train)\n\n        feature_names = self.get_feature_names()\n        if len(feature_names):\n            explainer = shap.TreeExplainer(self.clf)\n            shap_values = explainer.shap_values(X_train)\n\n            print('Feature ranking (top 20 features):')\n            # Calculate the values that represent the fraction of the model output variability attributable\n            # to each feature across the whole dataset.\n            shap_sums = np.abs(shap_values).sum(0)\n            rel_shap_sums = shap_sums / shap_sums.sum()\n            indices = np.argsort(rel_shap_sums)[::-1][:20]\n            for i, index in enumerate(indices):\n                print(f'{i + 1}. \\'{feature_names[index]}\\' ({rel_shap_sums[index]})')\n\n        y_pred = self.clf.predict(X_test)\n\n        print(f'No confidence threshold - {len(y_test)} classified')\n        print(metrics.confusion_matrix(y_test, y_pred, labels=class_names))\n        print(classification_report_imbalanced(y_test, y_pred, labels=class_names))\n\n        # Evaluate results on the test set for some confidence thresholds.\n        for confidence_threshold in [0.6, 0.7, 0.8, 0.9]:\n            y_pred_probas = self.clf.predict_proba(X_test)\n\n            y_test_filter = []\n            y_pred_filter = []\n            for i in range(0, len(y_test)):\n                argmax = np.argmax(y_pred_probas[i])\n                if y_pred_probas[i][argmax] < confidence_threshold:\n                    continue\n\n                y_test_filter.append(y_test[i])\n                y_pred_filter.append(argmax)\n\n            y_pred_filter = self.clf._le.inverse_transform(y_pred_filter)\n\n            print(f'\\nConfidence threshold > {confidence_threshold} - {len(y_test_filter)} classified')\n            print(metrics.confusion_matrix(y_test_filter, y_pred_filter, labels=class_names))\n            print(classification_report_imbalanced(y_test_filter, y_pred_filter, labels=class_names))\n\n        joblib.dump(self, self.__class__.__name__.lower())\n\n    @staticmethod\n    def load(model_file_name):\n        return joblib.load(model_file_name)\n\n    def overwrite_classes(self, bugs, classes, probabilities):\n        return classes\n\n    def classify(self, bugs, probabilities=False, importances=False):\n        assert bugs is not None\n        assert self.extraction_pipeline is not None and self.clf is not None, 'The module needs to be initialized first'\n\n        if not isinstance(bugs, list):\n            bugs = [bugs]\n\n        assert isinstance(bugs[0], dict)\n\n        X = self.extraction_pipeline.transform(bugs)\n        if probabilities:\n            classes = self.clf.predict_proba(X)\n        else:\n            classes = self.clf.predict(X)\n\n        classes = self.overwrite_classes(bugs, classes, probabilities)\n\n        if importances:\n            explainer = shap.TreeExplainer(self.clf)\n            shap_values = explainer.shap_values(X)\n\n            shap_sums = shap_values.sum(0)\n            abs_shap_sums = np.abs(shap_sums)\n            rel_shap_sums = abs_shap_sums / abs_shap_sums.sum()\n            indices = np.argsort(abs_shap_sums)[::-1]\n            importances = [(index, shap_sums[index] > 0, rel_shap_sums[index]) for index in indices]\n\n            return classes, importances\n\n        return classes\n", "path": "bugbug/model.py"}]}