From 3811ccd5fa1bdc5e86a3ec5266610b7e5c1b5db3 Mon Sep 17 00:00:00 2001 From: Thomas Li Date: Thu, 12 Dec 2019 06:49:11 -0800 Subject: [PATCH 1/2] CLN: replace str.format() and !r --- pandas/io/formats/css.py | 20 +++++------ pandas/io/formats/excel.py | 20 +++++------ pandas/io/formats/style.py | 68 ++++++++++++++------------------------ 3 files changed, 42 insertions(+), 66 deletions(-) diff --git a/pandas/io/formats/css.py b/pandas/io/formats/css.py index cd58ef51d1b65..8d910128b5f81 100644 --- a/pandas/io/formats/css.py +++ b/pandas/io/formats/css.py @@ -17,10 +17,7 @@ def expand(self, prop, value): try: mapping = self.SIDE_SHORTHANDS[len(tokens)] except KeyError: - warnings.warn( - 'Could not expand "{prop}: {val}"'.format(prop=prop, val=value), - CSSWarning, - ) + warnings.warn(f"Could not expand '{prop}: {value}'", CSSWarning) return for key, idx in zip(self.SIDES, mapping): yield prop_fmt.format(key), tokens[idx] @@ -110,14 +107,14 @@ def __call__(self, declarations_str, inherited=None): # 3. TODO: resolve other font-relative units for side in self.SIDES: - prop = "border-{side}-width".format(side=side) + prop = f"border-{side}-width" if prop in props: props[prop] = self.size_to_pt( props[prop], em_pt=font_size, conversions=self.BORDER_WIDTH_RATIOS ) for prop in [ - "margin-{side}".format(side=side), - "padding-{side}".format(side=side), + f"margin-{side}", + f"padding-{side}", ]: if prop in props: # TODO: support % @@ -173,7 +170,7 @@ def __call__(self, declarations_str, inherited=None): def size_to_pt(self, in_val, em_pt=None, conversions=UNIT_RATIOS): def _error(): - warnings.warn("Unhandled size: {val!r}".format(val=in_val), CSSWarning) + warnings.warn(f"Unhandled size: {repr(in_val)}", CSSWarning) return self.size_to_pt("1!!default", conversions=conversions) try: @@ -206,9 +203,9 @@ def _error(): val = round(val, 5) if int(val) == val: - size_fmt = "{fmt:d}pt".format(fmt=int(val)) + size_fmt = f"{int(val):d}pt" else: - size_fmt = "{fmt:f}pt".format(fmt=val) + size_fmt = f"{val:f}pt" return size_fmt def atomize(self, declarations): @@ -252,7 +249,6 @@ def parse(self, declarations_str): yield prop, val else: warnings.warn( - "Ill-formatted attribute: expected a colon " - "in {decl!r}".format(decl=decl), + "Ill-formatted attribute: expected a colon " f"in {repr(decl)}", CSSWarning, ) diff --git a/pandas/io/formats/excel.py b/pandas/io/formats/excel.py index 0413dcf18d04a..0755617d42431 100644 --- a/pandas/io/formats/excel.py +++ b/pandas/io/formats/excel.py @@ -132,12 +132,10 @@ def build_border(self, props): return { side: { "style": self._border_style( - props.get("border-{side}-style".format(side=side)), - props.get("border-{side}-width".format(side=side)), - ), - "color": self.color_to_excel( - props.get("border-{side}-color".format(side=side)) + props.get(f"border-{side}-style"), + props.get(f"border-{side}-width"), ), + "color": self.color_to_excel(props.get(f"border-{side}-color")), } for side in ["top", "right", "bottom", "left"] } @@ -321,7 +319,7 @@ def color_to_excel(self, val): try: return self.NAMED_COLORS[val] except KeyError: - warnings.warn("Unhandled color format: {val!r}".format(val=val), CSSWarning) + warnings.warn(f"Unhandled color format: {repr(val)}", CSSWarning) def build_number_format(self, props): return {"format_code": props.get("number-format")} @@ -427,7 +425,7 @@ def _format_value(self, val): if missing.isposinf_scalar(val): val = self.inf_rep elif missing.isneginf_scalar(val): - val = "-{inf}".format(inf=self.inf_rep) + val = f"-{self.inf_rep}" elif self.float_format is not None: val = float(self.float_format % val) if getattr(val, "tzinfo", None) is not None: @@ -509,8 +507,8 @@ def _format_header_regular(self): if has_aliases: if len(self.header) != len(self.columns): raise ValueError( - "Writing {cols} cols but got {alias} " - "aliases".format(cols=len(self.columns), alias=len(self.header)) + f"Writing {len(self.columns)} cols but got {len(self.header)} " + "aliases" ) else: colnames = self.header @@ -718,8 +716,8 @@ def write( if num_rows > self.max_rows or num_cols > self.max_cols: raise ValueError( "This sheet is too large! Your sheet size is: " - + "{}, {} ".format(num_rows, num_cols) - + "Max sheet size is: {}, {}".format(self.max_rows, self.max_cols) + + f"{num_rows}, {num_cols} " + + f"Max sheet size is: {self.max_rows}, {self.max_cols}" ) if isinstance(writer, ExcelWriter): diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index ebe86a7f535cb..14bca490d3714 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -28,7 +28,6 @@ jinja2 = import_optional_dependency("jinja2", extra="DataFrame.style requires jinja2.") - try: import matplotlib.pyplot as plt from matplotlib import colors @@ -165,7 +164,7 @@ def default_display_func(x): if self.na_rep is not None and pd.isna(x): return self.na_rep elif is_float(x): - display_format = "{0:.{precision}f}".format(x, precision=self.precision) + display_format = f"{x:.{self.precision}f}" return display_format else: return x @@ -293,7 +292,7 @@ def format_attr(pair): name = self.data.columns.names[r] cs = [ BLANK_CLASS if name is None else INDEX_NAME_CLASS, - "level{lvl}".format(lvl=r), + f"level{r}", ] name = BLANK_VALUE if name is None else name row_es.append( @@ -310,8 +309,8 @@ def format_attr(pair): for c, value in enumerate(clabels[r]): cs = [ COL_HEADING_CLASS, - "level{lvl}".format(lvl=r), - "col{col}".format(col=c), + f"level{r}", + f"col{c}", ] cs.extend( cell_context.get("col_headings", {}).get(r, {}).get(c, []) @@ -339,7 +338,7 @@ def format_attr(pair): index_header_row = [] for c, name in enumerate(self.data.index.names): - cs = [INDEX_NAME_CLASS, "level{lvl}".format(lvl=c)] + cs = [INDEX_NAME_CLASS, f"level{c}"] name = "" if name is None else name index_header_row.append( {"type": "th", "value": name, "class": " ".join(cs)} @@ -358,8 +357,8 @@ def format_attr(pair): for c, value in enumerate(rlabels[r]): rid = [ ROW_HEADING_CLASS, - "level{lvl}".format(lvl=c), - "row{row}".format(row=r), + f"level{c}", + f"row{r}", ] es = { "type": "th", @@ -377,7 +376,7 @@ def format_attr(pair): row_es.append(es) for c, col in enumerate(self.data.columns): - cs = [DATA_CLASS, "row{row}".format(row=r), "col{col}".format(col=c)] + cs = [DATA_CLASS, f"row{r}", f"col{c}"] cs.extend(cell_context.get("data", {}).get(r, {}).get(c, [])) formatter = self._display_funcs[(r, c)] value = self.data.iloc[r, c] @@ -399,12 +398,7 @@ def format_attr(pair): props.append(x.split(":")) else: props.append(["", ""]) - cellstyle.append( - { - "props": props, - "selector": "row{row}_col{col}".format(row=r, col=c), - } - ) + cellstyle.append({"props": props, "selector": f"row{r}_col{c}"}) body.append(row_es) table_attr = self.table_attributes @@ -627,15 +621,15 @@ def _apply(self, func, axis=0, subset=None, **kwargs): result = func(data, **kwargs) if not isinstance(result, pd.DataFrame): raise TypeError( - "Function {func!r} must return a DataFrame when " - "passed to `Styler.apply` with axis=None".format(func=func) + f"Function {repr(func)} must return a DataFrame when " + "passed to `Styler.apply` with axis=None" ) if not ( result.index.equals(data.index) and result.columns.equals(data.columns) ): msg = ( - "Result of {func!r} must have identical index and " - "columns as the input".format(func=func) + f"Result of {repr(func)} must have identical index and " + "columns as the input" ) raise ValueError(msg) @@ -643,11 +637,9 @@ def _apply(self, func, axis=0, subset=None, **kwargs): expected_shape = self.data.loc[subset].shape if result_shape != expected_shape: msg = ( - "Function {func!r} returned the wrong shape.\n" - "Result has shape: {res}\n" - "Expected shape: {expect}".format( - func=func, res=result.shape, expect=expected_shape - ) + f"Function {repr(func)} returned the wrong shape.\n" + "Result has shape: {result.shape}\n" + "Expected shape: {expected_shape}" ) raise ValueError(msg) self._update_ctx(result) @@ -975,9 +967,7 @@ def hide_columns(self, subset): @staticmethod def _highlight_null(v, null_color): - return ( - "background-color: {color}".format(color=null_color) if pd.isna(v) else "" - ) + return f"background-color: {null_color}" if pd.isna(v) else "" def highlight_null(self, null_color="red"): """ @@ -1130,9 +1120,7 @@ def relative_luminance(rgba): def css(rgba): dark = relative_luminance(rgba) < text_color_threshold text_color = "#f1f1f1" if dark else "#000000" - return "background-color: {b};color: {c};".format( - b=colors.rgb2hex(rgba), c=text_color - ) + return f"background-color: {colors.rgb2hex(rgba)};color: {text_color};" if s.ndim == 1: return [css(rgba) for rgba in rgbas] @@ -1164,7 +1152,7 @@ def set_properties(self, subset=None, **kwargs): >>> df.style.set_properties(color="white", align="right") >>> df.style.set_properties(**{'background-color': 'yellow'}) """ - values = ";".join("{p}: {v}".format(p=p, v=v) for p, v in kwargs.items()) + values = ";".join(f"{p}: {v}" for p, v in kwargs.items()) f = lambda x: values return self.applymap(f, subset=subset) @@ -1195,12 +1183,9 @@ def css_bar(start, end, color): if end > start: css += "background: linear-gradient(90deg," if start > 0: - css += " transparent {s:.1f}%, {c} {s:.1f}%, ".format( - s=start, c=color - ) - css += "{c} {e:.1f}%, transparent {e:.1f}%)".format( - e=min(end, width), c=color - ) + css += f" transparent {start:.1f}%, {color} {start:.1f}%, " + e = min(end, width) + css += f"{color} {e:.1f}%, transparent {e:.1f}%)" return css def css(x): @@ -1362,7 +1347,7 @@ def _highlight_extrema(data, color="yellow", max_=True): """ Highlight the min or max in a Series or DataFrame. """ - attr = "background-color: {0}".format(color) + attr = f"background-color: {color}" if max_: extrema = data == np.nanmax(data.to_numpy()) @@ -1532,10 +1517,7 @@ def _maybe_wrap_formatter(formatter, na_rep: Optional[str]): elif callable(formatter): formatter_func = formatter else: - msg = ( - "Expected a template string or callable, got {formatter} " - "instead".format(formatter=formatter) - ) + msg = f"Expected a template string or callable, got {formatter} " "instead" raise TypeError(msg) if na_rep is None: @@ -1543,5 +1525,5 @@ def _maybe_wrap_formatter(formatter, na_rep: Optional[str]): elif isinstance(na_rep, str): return lambda x: na_rep if pd.isna(x) else formatter_func(x) else: - msg = "Expected a string, got {na_rep} instead".format(na_rep=na_rep) + msg = f"Expected a string, got {na_rep} instead" raise TypeError(msg) From 6ed6828a5911458e20e43f5d31ab71a710de765a Mon Sep 17 00:00:00 2001 From: Thomas Li <47963215+lithomas1@users.noreply.github.com> Date: Thu, 12 Dec 2019 15:52:18 -0800 Subject: [PATCH 2/2] Apply suggestions from code review Co-Authored-By: Simon Hawkins --- pandas/io/formats/excel.py | 4 ++-- pandas/io/formats/style.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/io/formats/excel.py b/pandas/io/formats/excel.py index 0755617d42431..ed59a7d8a908b 100644 --- a/pandas/io/formats/excel.py +++ b/pandas/io/formats/excel.py @@ -716,8 +716,8 @@ def write( if num_rows > self.max_rows or num_cols > self.max_cols: raise ValueError( "This sheet is too large! Your sheet size is: " - + f"{num_rows}, {num_cols} " - + f"Max sheet size is: {self.max_rows}, {self.max_cols}" + f"{num_rows}, {num_cols} " + f"Max sheet size is: {self.max_rows}, {self.max_cols}" ) if isinstance(writer, ExcelWriter): diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index 246de05e46a7c..f578cb05e5530 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -1515,7 +1515,7 @@ def _maybe_wrap_formatter(formatter, na_rep: Optional[str]): elif callable(formatter): formatter_func = formatter else: - msg = f"Expected a template string or callable, got {formatter} " "instead" + msg = f"Expected a template string or callable, got {formatter} instead" raise TypeError(msg) if na_rep is None: