Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support indexing and slicing #35

Open
rsalmei opened this issue Sep 4, 2019 · 16 comments
Open

Support indexing and slicing #35

rsalmei opened this issue Sep 4, 2019 · 16 comments

Comments

@rsalmei
Copy link

rsalmei commented Sep 4, 2019

Hello,

You say in the readme that:

It correctly supports all str() methods including len().

But it seems it does not support basic indexing or slicing:

image

Could you please fix or implement it?
I need this kind of functionality to be able to support colors in my progress bar project. I was wondering if I'd implement colorizing and len and indexing and slicing myself, but thankfully found this project of yours, it is missing little to fit my need perfectly. Thanks.

My project is in: https://github.com/rsalmei/alive-progress
alive-progress

@timofurrer
Copy link
Owner

Good catch! Give me a day or two to find some spare time! If you'd want to implement it by yourself - I'm happy to review PRs 🎉

@rsalmei
Copy link
Author

rsalmei commented Sep 4, 2019

Great, thanks!

Do you realize it's not that easy to implement?
Imagine in my example, a red Hello and an orange World. The char at index 1 should be a red e. And a slice between 4:7 should be a red o, a space and an orange W, and etc. All slices should maintain the styling...

I'm currently busy with my progress bar, but I will contribute in another time, thank you!

@timofurrer
Copy link
Owner

Yeah, that's what I figured ... let's see if that's possible some how ;)

@timofurrer
Copy link
Owner

I've just released an alpha release v0.6.0a1 which supports the basics of indexing and slicing.
There are some limitations though: see the README changes

Could you please verify if that implementation if enough for your project?

@rsalmei
Copy link
Author

rsalmei commented Sep 5, 2019

Wow, that was fast! Thank you.
I'll verify and report back to you!

@rsalmei
Copy link
Author

rsalmei commented Sep 5, 2019

Hey, it seems to be working real nice!
It just broke with unicode characters, but should be easy to fix:

In [30]: colorful.red('♫♬')
Out[30]: <colorful.core.ColorfulString at 0x10e403a10>

In [31]: print(_)
♫♬

In [32]: _[1]
---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
<ipython-input-32-ac1337140e92> in <module>()
----> 1 _[1]

/Users/rogerio/.pyenv/versions/2.7.15/lib/python2.7/site-packages/colorful/core.pyc in __getitem__(self, item)
    357                 else:
    358                     if start <= current_orig_string_idx < stop:
--> 359                         sliced_styled_string += self.orig_string[current_orig_string_idx]
    360                         step_counter = step - 1
    361

UnicodeDecodeError: 'ascii' codec can't decode byte 0x99 in position 0: ordinal not in range(128)

@rsalmei
Copy link
Author

rsalmei commented Sep 5, 2019

I got another of the same error with disable:

In [34]: colorful.disable()

In [35]: print(_30)
---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
<ipython-input-35-16e467c1c773> in <module>()
----> 1 print(_30)

/Users/rogerio/.pyenv/versions/2.7.15/lib/python2.7/site-packages/colorful/core.pyc in __str__(self)
    238         def __str__(self):
    239             if self.colorful_ctx.colormode == terminal.NO_COLORS:
--> 240                 return self.orig_string.encode(DEFAULT_ENCODING)
    241             else:
    242                 return self.styled_string.encode(DEFAULT_ENCODING)

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 0: ordinal not in range(128)

ps.: testing with python 2.7 to be more restrictive, it probably works in 3.7.

@timofurrer
Copy link
Owner

Are you sure that's a bug in colorful? The string with the unicode char is that really a Python 2 unicode string? Try using the u"" string literal of import unicode_literals from __future__.

image

@timofurrer
Copy link
Owner

image

@rsalmei
Copy link
Author

rsalmei commented Sep 6, 2019

Oh yes, my mistake! I'm sorry for that.
It does work for these cases!

Unfortunately it is still missing something, but I'm not sure what.
I'm my progress bar, I need to generate some cool lines like these:

In [17]: blank = ' '; gap = 2; block_size = 10; content = 'abc'

In [18]: ''.join(chain.from_iterable(zip(repeat(blank * gap),
    ...:                                 map(lambda c: c * block_size, content))))
Out[18]: '  aaaaaaaaaa  bbbbbbbbbb  cccccccccc'

So, I've generated blocks of each character, with a certain gap between them.

But with a colorful string, I get:

In [19]: content = colorful.red('♫♬')

In [20]: ''.join(chain.from_iterable(zip(repeat(blank * gap),
    ...:                                 map(lambda c: c * block_size, content))))
Out[20]: '  \x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b  [[[[[[[[[[  3333333333  8888888888  ;;;;;;;;;;  2222222222  ;;;;;;;;;;  2222222222  5555555555  5555555555  ;;;;;;;;;;  0000000000  ;;;;;;;;;;  0000000000  mmmmmmmmmm  ♫♫♫♫♫♫♫♫♫♫  ♬♬♬♬♬♬♬♬♬♬  \x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b  [[[[[[[[[[  3333333333  9999999999  mmmmmmmmmm'

So maybe the __iter__ would have to return colored chars too.

@rsalmei
Copy link
Author

rsalmei commented Sep 6, 2019

Also, I think I need object.reversed, as I use reversed() in some computations.
Look:

In [24]: content = reversed(colorful.red('♫♬'))

In [25]: ''.join(chain.from_iterable(zip(repeat(blank * gap),
    ...:                                 map(lambda c: c * block_size, content))))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-25-8facd9412722> in <module>
      1 ''.join(chain.from_iterable(zip(repeat(blank * gap),
----> 2                                 map(lambda c: c * block_size, content))))

TypeError: sequence item 1: expected str instance, ColorfulString found

I don't really get where or why this error was triggered...
Actually I do! The reverse protocol knows how to handle strings, any other objects has to implement the support via the reversed method...

@timofurrer
Copy link
Owner

I'll have a look at the first problem.

Also, I think I need object.reversed, as I use reversed() in some computations.

Reversing the string could be a little harder ... Do you need the coloring there? If not you could just access the original string of the ColorfulString object and reverse that - as a workaround at least.

@rsalmei
Copy link
Author

rsalmei commented Sep 10, 2019

Hey, yes I do need color in reverse strings...
I have a plethora of factory methods to generate the various animations, and if one calls for a different scrolling direction, I need to reverse the original string, including colors. So if we have: red a yellow b reset, I'd expect the reverse to return yellow b red a reset.

Regarding the first issue, I think it's just the iter missing, which should return red a reset, and yellow b reset.
Actually, it should respect the len protocol, if the object has len=2, it should return 2 iterations in iter.

Do you think it's doable?

@github-actions
Copy link

github-actions bot commented Nov 9, 2019

This Issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days

@github-actions github-actions bot added the stale label Nov 9, 2019
@timofurrer timofurrer reopened this Nov 16, 2019
@timofurrer timofurrer removed the stale label Nov 16, 2019
@rsalmei
Copy link
Author

rsalmei commented Jul 18, 2020

Hello @timofurrer, how are you?

Hey, there's someone interested in helping me with this coloring, maybe he could help you here too!
I'm going to link this issue there, thank you for all the help you already did!

@rsalmei
Copy link
Author

rsalmei commented Jul 18, 2020

As I explained in my issue there:

The problem lies on having to have string-like objects that support: len, indexing, slicing, concatenation and reverse without losing color information!! 😨

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants