We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Typo in ratiotile.py
https://github.com/qtile/qtile/blob/95919912b11eabedb59ad3215747544c48c522f9/libqtile/layout/ratiotile.py#L307

cmd_upn -> cmd_up

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `libqtile/layout/ratiotile.py`
Content:
```
1 # -*- coding:utf-8 -*-
2 # Copyright (c) 2011 Florian Mounier
3 # Copyright (c) 2012-2013, 2015 Tycho Andersen
4 # Copyright (c) 2013 Björn Lindström
5 # Copyright (c) 2013 Tao Sauvage
6 # Copyright (c) 2014 ramnes
7 # Copyright (c) 2014 Sean Vig
8 # Copyright (c) 2014 dmpayton
9 # Copyright (c) 2014 dequis
10 # Copyright (c) 2017 Dirk Hartmann
11 #
12 # Permission is hereby granted, free of charge, to any person obtaining a copy
13 # of this software and associated documentation files (the "Software"), to deal
14 # in the Software without restriction, including without limitation the rights
15 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 # copies of the Software, and to permit persons to whom the Software is
17 # furnished to do so, subject to the following conditions:
18 #
19 # The above copyright notice and this permission notice shall be included in
20 # all copies or substantial portions of the Software.
21 #
22 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 # SOFTWARE.
29 
30 from __future__ import division
31 
32 import math
33 
34 from .base import _SimpleLayoutBase
35 
36 
37 ROWCOL = 1  # do rows at a time left to right top down
38 COLROW = 2  # do cols top to bottom, left to right
39 
40 GOLDEN_RATIO = 1.618
41 
42 
43 class GridInfo(object):
44     """
45     Calculates sizes for grids
46     >>> gi = GridInfo(.5, 5, 600, 480)
47     >>> gi.calc()
48     (1, 5, 1)
49     >>> gi.get_sizes()
50     [(0, 0, 120, 480), (120, 0, 120, 480), (240, 0, 120, 480), (360, 0, 120, 480), (480, 0, 120, 480)]
51     >>> gi = GridInfo(6, 5, 600, 480)
52     >>> gi.get_sizes()
53     [(0, 0, 600, 96), (0, 96, 600, 96), (0, 192, 600, 96), (0, 288, 600, 96), (0, 384, 600, 96)]
54     >>> gi = GridInfo(1, 5, 600, 480)
55     >>> gi.get_sizes()
56     [(0, 0, 200, 240), (200, 0, 200, 240), (400, 0, 200, 240), (0, 240, 300, 240), (200, 240, 200, 240)]
57 
58     >>> foo = GridInfo(1.6, 7, 400,370)
59     >>> foo.get_sizes(500,580)
60 
61 
62     """
63     def __init__(self, ratio, num_windows, width, height):
64         self.ratio = ratio
65         self.num_windows = num_windows
66         self.width = width
67         self.height = height
68         self.num_rows = 0
69         self.num_cols = 0
70 
71     def calc(self, num_windows, width, height):
72         """returns (rows, cols, orientation) tuple given input"""
73         best_ratio = None
74         best_rows_cols_orientation = None
75         for rows, cols, orientation in self._possible_grids(num_windows):
76 
77             sample_width = width / cols
78             sample_height = height / rows
79             sample_ratio = sample_width / sample_height
80             diff = abs(sample_ratio - self.ratio)
81             if best_ratio is None or diff < best_ratio:
82                 best_ratio = diff
83                 best_rows_cols_orientation = (rows, cols, orientation)
84 
85         return best_rows_cols_orientation
86 
87     def _possible_grids(self, num_windows):
88         """
89         iterates over possible grids given a number of windows
90         """
91         if num_windows < 2:
92             end = 2
93         else:
94             end = num_windows // 2 + 1
95         for rows in range(1, end):
96             cols = int(math.ceil(num_windows / rows))
97             yield (rows, cols, ROWCOL)
98             if rows != cols:
99                 # also want the reverse test
100                 yield (cols, rows, COLROW)
101 
102     def get_sizes_advanced(self, total_width, total_height,
103                            xoffset=0, yoffset=0):
104         """after every row/column recalculate remaining area"""
105         results = []
106         width = total_width
107         height = total_height
108         while len(results) < self.num_windows:
109             remaining = self.num_windows - len(results)
110             orien, sizes = self._get_row_or_col(
111                 remaining, width, height, xoffset, yoffset
112             )
113             results.extend(sizes)
114             if orien == ROWCOL:
115                 # adjust height/yoffset
116                 height -= sizes[-1][-1]
117                 yoffset += sizes[-1][-1]
118             else:
119                 width -= sizes[-1][-2]
120                 xoffset += sizes[-1][-2]
121 
122         return results
123 
124     def _get_row_or_col(self, num_windows, width, height, xoffset, yoffset):
125         """process one row (or col) at a time"""
126         rows, cols, orientation = self.calc(num_windows, width, height)
127         results = []
128         if orientation == ROWCOL:
129             x = 0
130             y = 0
131             for i, col in enumerate(range(cols)):
132                 w_width = width // cols
133                 w_height = height // rows
134                 if i == cols - 1:
135                     w_width = width - x
136                 results.append((x + xoffset, y + yoffset, w_width, w_height))
137                 x += w_width
138         elif orientation == COLROW:
139             x = 0
140             y = 0
141             for i, col in enumerate(range(rows)):
142                 w_width = width // cols
143                 w_height = height // rows
144                 if i == rows - 1:
145                     w_height = height - y
146                 results.append((x + xoffset, y + yoffset, w_width, w_height))
147                 y += w_height
148         return orientation, results
149 
150     def get_sizes(self, total_width, total_height, xoffset=0, yoffset=0):
151         width = 0
152         height = 0
153         results = []
154         rows, cols, orientation = self.calc(
155             self.num_windows, total_width, total_height
156         )
157         if orientation == ROWCOL:
158             y = 0
159             for i, row in enumerate(range(rows)):
160                 x = 0
161                 width = total_width // cols
162                 for j, col in enumerate(range(cols)):
163                     height = total_height // rows
164                     if i == rows - 1 and j == 0:
165                         # last row
166                         remaining = self.num_windows - len(results)
167                         width = total_width // remaining
168                     elif j == cols - 1 or len(results) + 1 == self.num_windows:
169                         # since we are dealing with integers,
170                         # make last column (or item) take up remaining space
171                         width = total_width - x
172 
173                     results.append((
174                         x + xoffset,
175                         y + yoffset,
176                         width,
177                         height
178                     ))
179                     if len(results) == self.num_windows:
180                         return results
181                     x += width
182                 y += height
183         else:
184             x = 0
185             for i, col in enumerate(range(cols)):
186                 y = 0
187                 height = total_height // rows
188                 for j, row in enumerate(range(rows)):
189                     width = total_width // cols
190                     # down first
191                     if i == cols - 1 and j == 0:
192                         remaining = self.num_windows - len(results)
193                         height = total_height // remaining
194                     elif j == rows - 1 or len(results) + 1 == self.num_windows:
195                         height = total_height - y
196                     results.append((
197                         x + xoffset,  # i * width + xoffset,
198                         y + yoffset,  # j * height + yoffset,
199                         width,
200                         height
201                     ))
202                     if len(results) == self.num_windows:
203                         return results
204                     y += height
205                 x += width
206 
207         return results
208 
209 
210 class RatioTile(_SimpleLayoutBase):
211     """Tries to tile all windows in the width/height ratio passed in"""
212     defaults = [
213         ("border_focus", "#0000ff", "Border colour for the focused window."),
214         ("border_normal", "#000000", "Border colour for un-focused windows."),
215         ("border_width", 1, "Border width."),
216         ("name", "ratiotile", "Name of this layout."),
217         ("margin", 0, "Margin of the layout"),
218         ("ratio", GOLDEN_RATIO, "Ratio of the tiles"),
219         ("ratio_increment", 0.1, "Amount to increment per ratio increment"),
220         ("fancy", False, "Use a different method to calculate window sizes."),
221     ]
222 
223     def __init__(self, **config):
224         _SimpleLayoutBase.__init__(self, **config)
225         self.add_defaults(RatioTile.defaults)
226         self.dirty = True  # need to recalculate
227         self.layout_info = []
228         self.last_size = None
229         self.last_screen = None
230 
231     def clone(self, group):
232         return _SimpleLayoutBase.clone(self, group)
233 
234     def add(self, w):
235         self.dirty = True
236         self.clients.appendHead(w)
237 
238     def remove(self, w):
239         self.dirty = True
240         return _SimpleLayoutBase.remove(self, w)
241 
242     def configure(self, win, screen):
243         # force recalc
244         if not self.last_screen or self.last_screen != screen:
245             self.last_screen = screen
246             self.dirty = True
247         if self.last_size and not self.dirty:
248             if screen.width != self.last_size[0] or \
249                     screen.height != self.last_size[1]:
250                 self.dirty = True
251         if self.dirty:
252             gi = GridInfo(
253                 self.ratio,
254                 len(self.clients),
255                 screen.width,
256                 screen.height
257             )
258             self.last_size = (screen.width, screen.height)
259             if self.fancy:
260                 method = gi.get_sizes_advanced
261             else:
262                 method = gi.get_sizes
263 
264             self.layout_info = method(
265                 screen.width,
266                 screen.height,
267                 screen.x,
268                 screen.y
269             )
270 
271             self.dirty = False
272         try:
273             idx = self.clients.index(win)
274         except ValueError:
275             win.hide()
276             return
277         x, y, w, h = self.layout_info[idx]
278         if win.has_focus:
279             bc = self.group.qtile.colorPixel(self.border_focus)
280         else:
281             bc = self.group.qtile.colorPixel(self.border_normal)
282         win.place(
283             x,
284             y,
285             w - self.border_width * 2,
286             h - self.border_width * 2,
287             self.border_width,
288             bc,
289             margin=self.margin,
290         )
291         win.unhide()
292 
293     def info(self):
294         d = _SimpleLayoutBase.info(self)
295         focused = self.clients.current_client
296         d['ratio'] = self.ratio,
297         d['focused'] = focused.name if focused else None,
298         d['layout_info'] = self.layout_info
299         return d
300 
301     def shuffle(self, function):
302         if self.clients:
303             function(self.clients)
304             self.group.layoutAll()
305 
306     cmd_down = _SimpleLayoutBase.previous
307     cmd_upn = _SimpleLayoutBase.next
308 
309     cmd_previous = _SimpleLayoutBase.previous
310     cmd_next = _SimpleLayoutBase.next
311 
312     def cmd_shuffle_down(self):
313         if self.clients:
314             self.clients.rotate_up()
315             self.self.group.layoutAll()
316 
317     def cmd_shuffle_up(self):
318         if self.clients:
319             self.clients.rotate_down()
320             self.self.group.layoutAll()
321 
322     def cmd_decrease_ratio(self):
323         new_ratio = self.ratio - self.ratio_increment
324         if new_ratio < 0:
325             return
326         self.ratio = new_ratio
327         self.group.layoutAll()
328 
329     def cmd_increase_ratio(self):
330         self.ratio += self.ratio_increment
331         self.group.layoutAll()
332
```
--- 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/libqtile/layout/ratiotile.py b/libqtile/layout/ratiotile.py
--- a/libqtile/layout/ratiotile.py
+++ b/libqtile/layout/ratiotile.py
@@ -304,7 +304,7 @@
             self.group.layoutAll()
 
     cmd_down = _SimpleLayoutBase.previous
-    cmd_upn = _SimpleLayoutBase.next
+    cmd_up = _SimpleLayoutBase.next
 
     cmd_previous = _SimpleLayoutBase.previous
     cmd_next = _SimpleLayoutBase.next

{"golden_diff": "diff --git a/libqtile/layout/ratiotile.py b/libqtile/layout/ratiotile.py\n--- a/libqtile/layout/ratiotile.py\n+++ b/libqtile/layout/ratiotile.py\n@@ -304,7 +304,7 @@\n             self.group.layoutAll()\n \n     cmd_down = _SimpleLayoutBase.previous\n-    cmd_upn = _SimpleLayoutBase.next\n+    cmd_up = _SimpleLayoutBase.next\n \n     cmd_previous = _SimpleLayoutBase.previous\n     cmd_next = _SimpleLayoutBase.next\n", "issue": "Typo in ratiotile.py\nhttps://github.com/qtile/qtile/blob/95919912b11eabedb59ad3215747544c48c522f9/libqtile/layout/ratiotile.py#L307\r\n\r\ncmd_upn -> cmd_up\n", "before_files": [{"content": "# -*- coding:utf-8 -*-\n# Copyright (c) 2011 Florian Mounier\n# Copyright (c) 2012-2013, 2015 Tycho Andersen\n# Copyright (c) 2013 Bj\u00f6rn Lindstr\u00f6m\n# Copyright (c) 2013 Tao Sauvage\n# Copyright (c) 2014 ramnes\n# Copyright (c) 2014 Sean Vig\n# Copyright (c) 2014 dmpayton\n# Copyright (c) 2014 dequis\n# Copyright (c) 2017 Dirk Hartmann\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\nfrom __future__ import division\n\nimport math\n\nfrom .base import _SimpleLayoutBase\n\n\nROWCOL = 1  # do rows at a time left to right top down\nCOLROW = 2  # do cols top to bottom, left to right\n\nGOLDEN_RATIO = 1.618\n\n\nclass GridInfo(object):\n    \"\"\"\n    Calculates sizes for grids\n    >>> gi = GridInfo(.5, 5, 600, 480)\n    >>> gi.calc()\n    (1, 5, 1)\n    >>> gi.get_sizes()\n    [(0, 0, 120, 480), (120, 0, 120, 480), (240, 0, 120, 480), (360, 0, 120, 480), (480, 0, 120, 480)]\n    >>> gi = GridInfo(6, 5, 600, 480)\n    >>> gi.get_sizes()\n    [(0, 0, 600, 96), (0, 96, 600, 96), (0, 192, 600, 96), (0, 288, 600, 96), (0, 384, 600, 96)]\n    >>> gi = GridInfo(1, 5, 600, 480)\n    >>> gi.get_sizes()\n    [(0, 0, 200, 240), (200, 0, 200, 240), (400, 0, 200, 240), (0, 240, 300, 240), (200, 240, 200, 240)]\n\n    >>> foo = GridInfo(1.6, 7, 400,370)\n    >>> foo.get_sizes(500,580)\n\n\n    \"\"\"\n    def __init__(self, ratio, num_windows, width, height):\n        self.ratio = ratio\n        self.num_windows = num_windows\n        self.width = width\n        self.height = height\n        self.num_rows = 0\n        self.num_cols = 0\n\n    def calc(self, num_windows, width, height):\n        \"\"\"returns (rows, cols, orientation) tuple given input\"\"\"\n        best_ratio = None\n        best_rows_cols_orientation = None\n        for rows, cols, orientation in self._possible_grids(num_windows):\n\n            sample_width = width / cols\n            sample_height = height / rows\n            sample_ratio = sample_width / sample_height\n            diff = abs(sample_ratio - self.ratio)\n            if best_ratio is None or diff < best_ratio:\n                best_ratio = diff\n                best_rows_cols_orientation = (rows, cols, orientation)\n\n        return best_rows_cols_orientation\n\n    def _possible_grids(self, num_windows):\n        \"\"\"\n        iterates over possible grids given a number of windows\n        \"\"\"\n        if num_windows < 2:\n            end = 2\n        else:\n            end = num_windows // 2 + 1\n        for rows in range(1, end):\n            cols = int(math.ceil(num_windows / rows))\n            yield (rows, cols, ROWCOL)\n            if rows != cols:\n                # also want the reverse test\n                yield (cols, rows, COLROW)\n\n    def get_sizes_advanced(self, total_width, total_height,\n                           xoffset=0, yoffset=0):\n        \"\"\"after every row/column recalculate remaining area\"\"\"\n        results = []\n        width = total_width\n        height = total_height\n        while len(results) < self.num_windows:\n            remaining = self.num_windows - len(results)\n            orien, sizes = self._get_row_or_col(\n                remaining, width, height, xoffset, yoffset\n            )\n            results.extend(sizes)\n            if orien == ROWCOL:\n                # adjust height/yoffset\n                height -= sizes[-1][-1]\n                yoffset += sizes[-1][-1]\n            else:\n                width -= sizes[-1][-2]\n                xoffset += sizes[-1][-2]\n\n        return results\n\n    def _get_row_or_col(self, num_windows, width, height, xoffset, yoffset):\n        \"\"\"process one row (or col) at a time\"\"\"\n        rows, cols, orientation = self.calc(num_windows, width, height)\n        results = []\n        if orientation == ROWCOL:\n            x = 0\n            y = 0\n            for i, col in enumerate(range(cols)):\n                w_width = width // cols\n                w_height = height // rows\n                if i == cols - 1:\n                    w_width = width - x\n                results.append((x + xoffset, y + yoffset, w_width, w_height))\n                x += w_width\n        elif orientation == COLROW:\n            x = 0\n            y = 0\n            for i, col in enumerate(range(rows)):\n                w_width = width // cols\n                w_height = height // rows\n                if i == rows - 1:\n                    w_height = height - y\n                results.append((x + xoffset, y + yoffset, w_width, w_height))\n                y += w_height\n        return orientation, results\n\n    def get_sizes(self, total_width, total_height, xoffset=0, yoffset=0):\n        width = 0\n        height = 0\n        results = []\n        rows, cols, orientation = self.calc(\n            self.num_windows, total_width, total_height\n        )\n        if orientation == ROWCOL:\n            y = 0\n            for i, row in enumerate(range(rows)):\n                x = 0\n                width = total_width // cols\n                for j, col in enumerate(range(cols)):\n                    height = total_height // rows\n                    if i == rows - 1 and j == 0:\n                        # last row\n                        remaining = self.num_windows - len(results)\n                        width = total_width // remaining\n                    elif j == cols - 1 or len(results) + 1 == self.num_windows:\n                        # since we are dealing with integers,\n                        # make last column (or item) take up remaining space\n                        width = total_width - x\n\n                    results.append((\n                        x + xoffset,\n                        y + yoffset,\n                        width,\n                        height\n                    ))\n                    if len(results) == self.num_windows:\n                        return results\n                    x += width\n                y += height\n        else:\n            x = 0\n            for i, col in enumerate(range(cols)):\n                y = 0\n                height = total_height // rows\n                for j, row in enumerate(range(rows)):\n                    width = total_width // cols\n                    # down first\n                    if i == cols - 1 and j == 0:\n                        remaining = self.num_windows - len(results)\n                        height = total_height // remaining\n                    elif j == rows - 1 or len(results) + 1 == self.num_windows:\n                        height = total_height - y\n                    results.append((\n                        x + xoffset,  # i * width + xoffset,\n                        y + yoffset,  # j * height + yoffset,\n                        width,\n                        height\n                    ))\n                    if len(results) == self.num_windows:\n                        return results\n                    y += height\n                x += width\n\n        return results\n\n\nclass RatioTile(_SimpleLayoutBase):\n    \"\"\"Tries to tile all windows in the width/height ratio passed in\"\"\"\n    defaults = [\n        (\"border_focus\", \"#0000ff\", \"Border colour for the focused window.\"),\n        (\"border_normal\", \"#000000\", \"Border colour for un-focused windows.\"),\n        (\"border_width\", 1, \"Border width.\"),\n        (\"name\", \"ratiotile\", \"Name of this layout.\"),\n        (\"margin\", 0, \"Margin of the layout\"),\n        (\"ratio\", GOLDEN_RATIO, \"Ratio of the tiles\"),\n        (\"ratio_increment\", 0.1, \"Amount to increment per ratio increment\"),\n        (\"fancy\", False, \"Use a different method to calculate window sizes.\"),\n    ]\n\n    def __init__(self, **config):\n        _SimpleLayoutBase.__init__(self, **config)\n        self.add_defaults(RatioTile.defaults)\n        self.dirty = True  # need to recalculate\n        self.layout_info = []\n        self.last_size = None\n        self.last_screen = None\n\n    def clone(self, group):\n        return _SimpleLayoutBase.clone(self, group)\n\n    def add(self, w):\n        self.dirty = True\n        self.clients.appendHead(w)\n\n    def remove(self, w):\n        self.dirty = True\n        return _SimpleLayoutBase.remove(self, w)\n\n    def configure(self, win, screen):\n        # force recalc\n        if not self.last_screen or self.last_screen != screen:\n            self.last_screen = screen\n            self.dirty = True\n        if self.last_size and not self.dirty:\n            if screen.width != self.last_size[0] or \\\n                    screen.height != self.last_size[1]:\n                self.dirty = True\n        if self.dirty:\n            gi = GridInfo(\n                self.ratio,\n                len(self.clients),\n                screen.width,\n                screen.height\n            )\n            self.last_size = (screen.width, screen.height)\n            if self.fancy:\n                method = gi.get_sizes_advanced\n            else:\n                method = gi.get_sizes\n\n            self.layout_info = method(\n                screen.width,\n                screen.height,\n                screen.x,\n                screen.y\n            )\n\n            self.dirty = False\n        try:\n            idx = self.clients.index(win)\n        except ValueError:\n            win.hide()\n            return\n        x, y, w, h = self.layout_info[idx]\n        if win.has_focus:\n            bc = self.group.qtile.colorPixel(self.border_focus)\n        else:\n            bc = self.group.qtile.colorPixel(self.border_normal)\n        win.place(\n            x,\n            y,\n            w - self.border_width * 2,\n            h - self.border_width * 2,\n            self.border_width,\n            bc,\n            margin=self.margin,\n        )\n        win.unhide()\n\n    def info(self):\n        d = _SimpleLayoutBase.info(self)\n        focused = self.clients.current_client\n        d['ratio'] = self.ratio,\n        d['focused'] = focused.name if focused else None,\n        d['layout_info'] = self.layout_info\n        return d\n\n    def shuffle(self, function):\n        if self.clients:\n            function(self.clients)\n            self.group.layoutAll()\n\n    cmd_down = _SimpleLayoutBase.previous\n    cmd_upn = _SimpleLayoutBase.next\n\n    cmd_previous = _SimpleLayoutBase.previous\n    cmd_next = _SimpleLayoutBase.next\n\n    def cmd_shuffle_down(self):\n        if self.clients:\n            self.clients.rotate_up()\n            self.self.group.layoutAll()\n\n    def cmd_shuffle_up(self):\n        if self.clients:\n            self.clients.rotate_down()\n            self.self.group.layoutAll()\n\n    def cmd_decrease_ratio(self):\n        new_ratio = self.ratio - self.ratio_increment\n        if new_ratio < 0:\n            return\n        self.ratio = new_ratio\n        self.group.layoutAll()\n\n    def cmd_increase_ratio(self):\n        self.ratio += self.ratio_increment\n        self.group.layoutAll()\n", "path": "libqtile/layout/ratiotile.py"}], "after_files": [{"content": "# -*- coding:utf-8 -*-\n# Copyright (c) 2011 Florian Mounier\n# Copyright (c) 2012-2013, 2015 Tycho Andersen\n# Copyright (c) 2013 Bj\u00f6rn Lindstr\u00f6m\n# Copyright (c) 2013 Tao Sauvage\n# Copyright (c) 2014 ramnes\n# Copyright (c) 2014 Sean Vig\n# Copyright (c) 2014 dmpayton\n# Copyright (c) 2014 dequis\n# Copyright (c) 2017 Dirk Hartmann\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\nfrom __future__ import division\n\nimport math\n\nfrom .base import _SimpleLayoutBase\n\n\nROWCOL = 1  # do rows at a time left to right top down\nCOLROW = 2  # do cols top to bottom, left to right\n\nGOLDEN_RATIO = 1.618\n\n\nclass GridInfo(object):\n    \"\"\"\n    Calculates sizes for grids\n    >>> gi = GridInfo(.5, 5, 600, 480)\n    >>> gi.calc()\n    (1, 5, 1)\n    >>> gi.get_sizes()\n    [(0, 0, 120, 480), (120, 0, 120, 480), (240, 0, 120, 480), (360, 0, 120, 480), (480, 0, 120, 480)]\n    >>> gi = GridInfo(6, 5, 600, 480)\n    >>> gi.get_sizes()\n    [(0, 0, 600, 96), (0, 96, 600, 96), (0, 192, 600, 96), (0, 288, 600, 96), (0, 384, 600, 96)]\n    >>> gi = GridInfo(1, 5, 600, 480)\n    >>> gi.get_sizes()\n    [(0, 0, 200, 240), (200, 0, 200, 240), (400, 0, 200, 240), (0, 240, 300, 240), (200, 240, 200, 240)]\n\n    >>> foo = GridInfo(1.6, 7, 400,370)\n    >>> foo.get_sizes(500,580)\n\n\n    \"\"\"\n    def __init__(self, ratio, num_windows, width, height):\n        self.ratio = ratio\n        self.num_windows = num_windows\n        self.width = width\n        self.height = height\n        self.num_rows = 0\n        self.num_cols = 0\n\n    def calc(self, num_windows, width, height):\n        \"\"\"returns (rows, cols, orientation) tuple given input\"\"\"\n        best_ratio = None\n        best_rows_cols_orientation = None\n        for rows, cols, orientation in self._possible_grids(num_windows):\n\n            sample_width = width / cols\n            sample_height = height / rows\n            sample_ratio = sample_width / sample_height\n            diff = abs(sample_ratio - self.ratio)\n            if best_ratio is None or diff < best_ratio:\n                best_ratio = diff\n                best_rows_cols_orientation = (rows, cols, orientation)\n\n        return best_rows_cols_orientation\n\n    def _possible_grids(self, num_windows):\n        \"\"\"\n        iterates over possible grids given a number of windows\n        \"\"\"\n        if num_windows < 2:\n            end = 2\n        else:\n            end = num_windows // 2 + 1\n        for rows in range(1, end):\n            cols = int(math.ceil(num_windows / rows))\n            yield (rows, cols, ROWCOL)\n            if rows != cols:\n                # also want the reverse test\n                yield (cols, rows, COLROW)\n\n    def get_sizes_advanced(self, total_width, total_height,\n                           xoffset=0, yoffset=0):\n        \"\"\"after every row/column recalculate remaining area\"\"\"\n        results = []\n        width = total_width\n        height = total_height\n        while len(results) < self.num_windows:\n            remaining = self.num_windows - len(results)\n            orien, sizes = self._get_row_or_col(\n                remaining, width, height, xoffset, yoffset\n            )\n            results.extend(sizes)\n            if orien == ROWCOL:\n                # adjust height/yoffset\n                height -= sizes[-1][-1]\n                yoffset += sizes[-1][-1]\n            else:\n                width -= sizes[-1][-2]\n                xoffset += sizes[-1][-2]\n\n        return results\n\n    def _get_row_or_col(self, num_windows, width, height, xoffset, yoffset):\n        \"\"\"process one row (or col) at a time\"\"\"\n        rows, cols, orientation = self.calc(num_windows, width, height)\n        results = []\n        if orientation == ROWCOL:\n            x = 0\n            y = 0\n            for i, col in enumerate(range(cols)):\n                w_width = width // cols\n                w_height = height // rows\n                if i == cols - 1:\n                    w_width = width - x\n                results.append((x + xoffset, y + yoffset, w_width, w_height))\n                x += w_width\n        elif orientation == COLROW:\n            x = 0\n            y = 0\n            for i, col in enumerate(range(rows)):\n                w_width = width // cols\n                w_height = height // rows\n                if i == rows - 1:\n                    w_height = height - y\n                results.append((x + xoffset, y + yoffset, w_width, w_height))\n                y += w_height\n        return orientation, results\n\n    def get_sizes(self, total_width, total_height, xoffset=0, yoffset=0):\n        width = 0\n        height = 0\n        results = []\n        rows, cols, orientation = self.calc(\n            self.num_windows, total_width, total_height\n        )\n        if orientation == ROWCOL:\n            y = 0\n            for i, row in enumerate(range(rows)):\n                x = 0\n                width = total_width // cols\n                for j, col in enumerate(range(cols)):\n                    height = total_height // rows\n                    if i == rows - 1 and j == 0:\n                        # last row\n                        remaining = self.num_windows - len(results)\n                        width = total_width // remaining\n                    elif j == cols - 1 or len(results) + 1 == self.num_windows:\n                        # since we are dealing with integers,\n                        # make last column (or item) take up remaining space\n                        width = total_width - x\n\n                    results.append((\n                        x + xoffset,\n                        y + yoffset,\n                        width,\n                        height\n                    ))\n                    if len(results) == self.num_windows:\n                        return results\n                    x += width\n                y += height\n        else:\n            x = 0\n            for i, col in enumerate(range(cols)):\n                y = 0\n                height = total_height // rows\n                for j, row in enumerate(range(rows)):\n                    width = total_width // cols\n                    # down first\n                    if i == cols - 1 and j == 0:\n                        remaining = self.num_windows - len(results)\n                        height = total_height // remaining\n                    elif j == rows - 1 or len(results) + 1 == self.num_windows:\n                        height = total_height - y\n                    results.append((\n                        x + xoffset,  # i * width + xoffset,\n                        y + yoffset,  # j * height + yoffset,\n                        width,\n                        height\n                    ))\n                    if len(results) == self.num_windows:\n                        return results\n                    y += height\n                x += width\n\n        return results\n\n\nclass RatioTile(_SimpleLayoutBase):\n    \"\"\"Tries to tile all windows in the width/height ratio passed in\"\"\"\n    defaults = [\n        (\"border_focus\", \"#0000ff\", \"Border colour for the focused window.\"),\n        (\"border_normal\", \"#000000\", \"Border colour for un-focused windows.\"),\n        (\"border_width\", 1, \"Border width.\"),\n        (\"name\", \"ratiotile\", \"Name of this layout.\"),\n        (\"margin\", 0, \"Margin of the layout\"),\n        (\"ratio\", GOLDEN_RATIO, \"Ratio of the tiles\"),\n        (\"ratio_increment\", 0.1, \"Amount to increment per ratio increment\"),\n        (\"fancy\", False, \"Use a different method to calculate window sizes.\"),\n    ]\n\n    def __init__(self, **config):\n        _SimpleLayoutBase.__init__(self, **config)\n        self.add_defaults(RatioTile.defaults)\n        self.dirty = True  # need to recalculate\n        self.layout_info = []\n        self.last_size = None\n        self.last_screen = None\n\n    def clone(self, group):\n        return _SimpleLayoutBase.clone(self, group)\n\n    def add(self, w):\n        self.dirty = True\n        self.clients.appendHead(w)\n\n    def remove(self, w):\n        self.dirty = True\n        return _SimpleLayoutBase.remove(self, w)\n\n    def configure(self, win, screen):\n        # force recalc\n        if not self.last_screen or self.last_screen != screen:\n            self.last_screen = screen\n            self.dirty = True\n        if self.last_size and not self.dirty:\n            if screen.width != self.last_size[0] or \\\n                    screen.height != self.last_size[1]:\n                self.dirty = True\n        if self.dirty:\n            gi = GridInfo(\n                self.ratio,\n                len(self.clients),\n                screen.width,\n                screen.height\n            )\n            self.last_size = (screen.width, screen.height)\n            if self.fancy:\n                method = gi.get_sizes_advanced\n            else:\n                method = gi.get_sizes\n\n            self.layout_info = method(\n                screen.width,\n                screen.height,\n                screen.x,\n                screen.y\n            )\n\n            self.dirty = False\n        try:\n            idx = self.clients.index(win)\n        except ValueError:\n            win.hide()\n            return\n        x, y, w, h = self.layout_info[idx]\n        if win.has_focus:\n            bc = self.group.qtile.colorPixel(self.border_focus)\n        else:\n            bc = self.group.qtile.colorPixel(self.border_normal)\n        win.place(\n            x,\n            y,\n            w - self.border_width * 2,\n            h - self.border_width * 2,\n            self.border_width,\n            bc,\n            margin=self.margin,\n        )\n        win.unhide()\n\n    def info(self):\n        d = _SimpleLayoutBase.info(self)\n        focused = self.clients.current_client\n        d['ratio'] = self.ratio,\n        d['focused'] = focused.name if focused else None,\n        d['layout_info'] = self.layout_info\n        return d\n\n    def shuffle(self, function):\n        if self.clients:\n            function(self.clients)\n            self.group.layoutAll()\n\n    cmd_down = _SimpleLayoutBase.previous\n    cmd_up = _SimpleLayoutBase.next\n\n    cmd_previous = _SimpleLayoutBase.previous\n    cmd_next = _SimpleLayoutBase.next\n\n    def cmd_shuffle_down(self):\n        if self.clients:\n            self.clients.rotate_up()\n            self.self.group.layoutAll()\n\n    def cmd_shuffle_up(self):\n        if self.clients:\n            self.clients.rotate_down()\n            self.self.group.layoutAll()\n\n    def cmd_decrease_ratio(self):\n        new_ratio = self.ratio - self.ratio_increment\n        if new_ratio < 0:\n            return\n        self.ratio = new_ratio\n        self.group.layoutAll()\n\n    def cmd_increase_ratio(self):\n        self.ratio += self.ratio_increment\n        self.group.layoutAll()\n", "path": "libqtile/layout/ratiotile.py"}]}