# How to calculate the length of a non-ASCII string for a curses app?

**URL:** https://discuss.python.org/t/how-to-calculate-the-length-of-a-non-ascii-string-for-a-curses-app/56116
**Category:** Python Help
**Created:** [June 19, 2024, 12:56am UTC](https://discuss.python.org/t/how-to-calculate-the-length-of-a-non-ascii-string-for-a-curses-app/56116 "2024-06-19T00:56:11Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![FelixFourcolor](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/felixfourcolor/32/13104_2.png) [@FelixFourcolor](https://discuss.python.org/u/FelixFourcolor)
#### Post date: [June 19, 2024, 12:56am UTC](https://discuss.python.org/t/how-to-calculate-the-length-of-a-non-ascii-string-for-a-curses-app/56116/1 "2024-06-19T00:56:11Z")

</div>

I’m learning to write a TUI app with curses, something along the line of a text editor (but much simpler). To handle horizontal scroll and word wrap I need to measure how long a string is, so that I could compare it to how wide the terminal is and do appropriate calculations.

The problem is `len` is not accurate for non-ASCII characters. In particular, I need emojis to work. For example, `len("🙂")` is 1, but it actually takes up 2 spaces in the terminal.

My current solution is using the `emoji` library to detect whether a character is an emoji, if so count its length as 2. It sort of works, but it feels hacky. Surely there must be a more natural solution? Also I’m not sure that all emojis take up 2 spaces, it just seems to me that most do.

Am I approaching the word wrap problem the right way (or is this an XY problem)? If this is the right approach, what’s the best way to solve this? Thank you.

---

<div class="post-metadata">

### Author: ![blhsing](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/blhsing/32/25812_2.png) [@blhsing](https://discuss.python.org/u/blhsing)
#### Post date: [June 19, 2024, 1:39am UTC](https://discuss.python.org/t/how-to-calculate-the-length-of-a-non-ascii-string-for-a-curses-app/56116/2 "2024-06-19T01:39:49Z")

</div>

You can use [`unicodedata.east_asian_width`](https://docs.python.org/3/library/unicodedata.html#unicodedata.east_asian_width) to determine the width of a unicode character. If it returns `'F'` or `'W'`, it should have a display width of 2.

In particular, for emoji characters like the one in your question the function should return `'W'`, according to the [Unicode® Standard Annex #11](https://www.unicode.org/reports/tr11/#ED4):

> _**[ED4](https://www.unicode.org/reports/tr11/#ED4).** East Asian Wide (W)_ : All other characters that are _always_ wide. These characters occur only in the context of East Asian typography where they are wide characters (such as the Unified Han Ideographs or Squared Katakana Symbols). This category includes characters that have explicit halfwidth counterparts, along with characters that have the [[UTS51](https://www.unicode.org/reports/tr41/tr41-32.html#UTS51)] property _Emoji\_Presentation_ , with the exception of characters that have the [[UCD](https://www.unicode.org/reports/tr41/tr41-32.html#UCD)] property _Regional\_Indicator_

---

<div class="post-metadata">

### Author: ![kknechtel](https://avatars.discourse-cdn.com/v4/letter/k/e47c2d/32.png) [@kknechtel](https://discuss.python.org/u/kknechtel)
#### Post date: [June 19, 2024, 2:06am UTC](https://discuss.python.org/t/how-to-calculate-the-length-of-a-non-ascii-string-for-a-curses-app/56116/3 "2024-06-19T02:06:08Z")

</div>

Keep in mind that you’ll _also_ have the _opposite_ problem: for example,

```python
>>> len('é')
2

```

That’s a different representation, as two distinct characters, of the same _grapheme_:

```python
>>> len('é')
1

```

There [are a ton of corner cases in this. Text is hard.](https://langdev.stackexchange.com/questions/71) You really need a third-party library for this.

---

<div class="post-metadata">

### Author: ![FelixFourcolor](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/felixfourcolor/32/13104_2.png) [@FelixFourcolor](https://discuss.python.org/u/FelixFourcolor)
#### Post date: [June 19, 2024, 4:17am UTC](https://discuss.python.org/t/how-to-calculate-the-length-of-a-non-ascii-string-for-a-curses-app/56116/4 "2024-06-19T04:17:00Z")

</div>

Which library do you recommend for this?

---

<div class="post-metadata">

### Author: ![blhsing](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/blhsing/32/25812_2.png) [@blhsing](https://discuss.python.org/u/blhsing)
#### Post date: [June 19, 2024, 7:40am UTC](https://discuss.python.org/t/how-to-calculate-the-length-of-a-non-ascii-string-for-a-curses-app/56116/5 "2024-06-19T07:40:34Z")

</div>

I’d recommend [`wcwidth.wcswidth`](https://pypi.org/project/wcwidth/):

```python
from wcwidth import wcswidth

for c in "🙂", "é", "각":
    print(len(c), wcswidth(c))

```

This outputs:

```plaintext
1 2
2 1
3 2

```
