---
id: 69a890af247de743333bd4d2
title: "Challenge 229: Truncate the Text 2"
challengeType: 29
dashedName: challenge-229
---

# --description--

Given a string, return a new string that is truncated so that the total width of the characters does not exceed 50 units.

Each character has a specific width:

| Letters | Width |
| - | - |
| `"ilI"` | 1 |
| `"fjrt"` | 2 |
| `"abcdeghkmnopqrstuvwxyzJL"` | 3 |
| `"ABCDEFGHKMNOPQRSTUVWXYZ"` | 4 |

The table above includes all upper and lower case letters. Additionally:

- Spaces (`" "`) have a width of 2
- Periods (`"."`) have a width of 1

- If the given string is 50 units or less, return the string as-is, otherwise
- Truncate the string and add three periods at the end (`"..."`) so it's total width, including the three periods, is as close as possible to 60 units without going over.

# --hints--

`truncate_text("The quick brown fox")` should return `"The quick brown f..."`.

```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(truncate_text("The quick brown fox"), "The quick brown f...")`)
}})
```

`truncate_text("The silky smooth sloth")` should return `truncate_text("The silky smooth sloth")`.

```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(truncate_text("The silky smooth sloth"), truncate_text("The silky smooth sloth"))`)
}})
```

`truncate_text("THE LOUD BRIGHT BIRD")` should return `"THE LOUD BRIG..."`.

```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(truncate_text("THE LOUD BRIGHT BIRD"), "THE LOUD BRIG...")`)
}})
```

`truncate_text("The fast striped zebra")` should return `"The fast striped z..."`.

```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(truncate_text("The fast striped zebra"), "The fast striped z...")`)
}})
```

`truncate_text("The big black bear")` should return `"The big black bear"`.

```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(truncate_text("The big black bear"), "The big black bear")`)
}})
```

# --seed--

## --seed-contents--

```py
def truncate_text(s):

    return s
```

# --solutions--

```py
def truncate_text(s):
    MAX_WIDTH = 50
    ELLIPSIS = "..."
    ELLIPSIS_WIDTH = 3
    TRUNCATE_LIMIT = MAX_WIDTH - ELLIPSIS_WIDTH

    char_groups = {
        "ilI.": 1,
        "fjrt ": 2,
        "abcdeghkmnopqrstuvwxyzJL": 3,
        "ABCDEFGHKMNOPQRSTUVWXYZ": 4
    }

    def get_char_width(char):
        for key, width in char_groups.items():
            if char in key:
                return width
        return 3

    def string_width(string):
        total = 0
        for char in string:
            total += get_char_width(char)
        return total

    if string_width(s) <= MAX_WIDTH:
        return s

    result = ""
    total_width = 0

    for char in s:
        char_width = get_char_width(char)

        if total_width + char_width > TRUNCATE_LIMIT:
            break

        result += char
        total_width += char_width

    return result + ELLIPSIS
```
