Python Forum
"Slicing and dicing strings" - - PyBite #105
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
"Slicing and dicing strings" - - PyBite #105
#7
Hi @knackwurstbagel: Thank you for your feedback. I ran your code. Here is the output: objectsytoo:)bites. The ‘!.’ has been stripped, as you explained.

I’ve made more progress. I’ve achieved half the task, or so it appears to me.

This is my desired output: ['objects', 'y', 'too', ':)', 'bites']

This is my actual output: ['objects', 'y', 'too', ':)', 'bites']

You people are going to laugh when you see how inelegant my code turned out. Here is the script now, in full:

from string import ascii_lowercase

text = """
One really nice feature of Python is polymorphism: using the same operation
on different types of objects.
Let's talk about an elegant feature: slicing.
You can use this on a string as well as a list for example
'pybites'[0:2] gives 'py'.
The first value is inclusive and the last one is exclusive so
here we grab indexes 0 and 1, the letter p and y.
When you have a 0 index you can leave it out so can write this as 'pybites'[:2]
but here is the kicker: you can use this on a list too!
['pybites', 'teaches', 'you', 'Python'][-2:] would gives ['you', 'Python']
and now you know about slicing from the end as well :)
keep enjoying our bites!
"""
results = []
stripped = text.strip()
splitted = stripped.split("\n")
for line in splitted:
   line.lstrip(' ')
   line.rstrip(' ')
   if line[0].islower():
       new_line_split = line.split()
       last_word = new_line_split[-1]
       results.extend(last_word)
       results_as_string = ''.join(results)
print(results_as_string)
w = results_as_string.replace(".", "zzz")
print(w)
x = w.rstrip('!')
print(x)
y = x.replace("!", "zzz")
z = y[:-5] + "zzz" + y[-5:]
print(z)
a = z.split('zzz')
print(a)
I suppose it ‘works’ but it's ugly.

Here is my code refactored into a function:

from string import ascii_lowercase

def slice_and_dice(text):
    ''' 
    First task for this exercises
    '''
    results = []
    stripped = text.strip()
    splitted = stripped.split("\n")
    for line in splitted:
        line.lstrip(' ')
        line.rstrip(' ')
        if line[0].islower():
            new_line_split = line.split()
            last_word = new_line_split[-1]
            results.extend(last_word)
            results_as_string = ''.join(results)
    w = results_as_string.replace(".", "zzz")
    x = w.rstrip('!')
    y = x.replace("!", "zzz")
    z = y[:-5] + "zzz" + y[-5:]
    a = z.split('zzz')
    return a
Here is the test script:

from slicing_basic6 import text, slice_and_dice

another_text = """
Take the block of text provided and strip() off the whitespace at the ends.
Split the whole block up by newline (\n).
if the first character is lowercase, split it into words and add the last word
of that line to the results list.
Strip the trailing dot (.) and exclamation mark (!) from the word first.
 finally return the results list!
"""


def test_slice_and_dice_default_text():
   expected = ['objects', 'y', 'too', ':)', 'bites']
   assert slice_and_dice(text) == expected


def test_slice_and_dice_other_text():
   expected = ['word', 'list', 'list']
   assert slice_and_dice(another_text) == expected
When I run the test, here is the output:

 $ python -m pytest test_slicing.py
================================= test session starts ==================================
platform linux -- Python 3.8.3, pytest-5.4.3, py-1.8.1, pluggy-0.13.1
rootdir: /home/gnull/dev/projects/python/2018-and-2020/bitesofpy/Intro-freebies-101-110/inprogress/Bite 105 - Slice and dice
collected 2 items                                                                      

test_slicing.py .F                                                               [100%]

======================================= FAILURES =======================================
____________________________ test_slice_and_dice_other_text ____________________________

    def test_slice_and_dice_other_text():
        expected = ['word', 'list', 'list']
>       assert slice_and_dice(another_text) == expected
E       AssertionError: assert ['li', 'st', ''] == ['word', 'list', 'list']
E         At index 0 diff: 'li' != 'word'
E         Use -v to get the full diff

test_slicing.py:20: AssertionError
--------------------------------- Captured stdout call ---------------------------------
list.
listzzz
listzzz
lizzzstzzz
=============================== short test summary info ================================
FAILED test_slicing.py::test_slice_and_dice_other_text - AssertionError: assert ['li'...
============================= 1 failed, 1 passed in 0.05s ==============================
As you can see, it passes the first test. Hooray! But I have no clue how to re-write my code so that it automatically returns ['word', 'list', 'list'] based on the secondary text string declared in the test script.




Here is the solution provided by the course instructor:

from string import ascii_lowercase


text = """
One really nice feature of Python is polymorphism: using the same operation
on different types of objects.
Let's talk about an elegant feature: slicing.
You can use this on a string as well as a list for example
'pybites'[0:2] gives 'py'.
The first value is inclusive and the last one is exclusive so
here we grab indexes 0 and 1, the letter p and y.
When you have a 0 index you can leave it out so can write this as 'pybites'[:2]
but here is the kicker: you can use this on a list too!
['pybites', 'teaches', 'you', 'Python'][-2:] would gives ['you', 'Python']
  and now you know about slicing from the end as well :)
keep enjoying our bites!
"""

def slice_and_dice(text: str = text) -> list:
    """Get a list of words from the passed in text.
       See the Bite description for step by step instructions"""
    results = []
    for line in text.strip().splitlines():
        line = line.lstrip()

        if line[0] not in ascii_lowercase:
            continue

        words = line.split()
        last_word_stripped = words[-1].rstrip('!.')
        results.append(last_word_stripped)

    return results
I don’t completely understand. Here is my best attempt at transcribing the python code into english writing:

Quote:19 name function as slice_and_dice passin the text
20 doc string
21 doc string
22 declare results variable as empty list
23 split the lines and strip the text for every line
24 declare a variable as line with the left most character of the string and strip it ( but only if it is a space)
25 white space
26 if the first character of line is not a-z, then:
27 continue with the loop
28 white space
29 for the words variable, define it as every line but splitted
30 if the last word ends with ‘!.’, the strip it
31 append the last word to the results variable
32 white space
33 return the results

Would someone be able to add to or correct my understanding? Is there a better explanation for some of the lines I am struggling to understand?

At line 19, the function parameter is: text: str = text. How does this work? The variable text makes sense, but how and why does the string class method equal text? Also: What does -> list do?
Reply


Messages In This Thread
RE: "Slicing and dicing strings" - - PyBite #105 - by Drone4four - Jun-11-2020, 02:49 PM

Possibly Related Threads…
Thread Author Replies Views Last Post
  Dictionary lookups exercise (PyBite #109) Drone4four 14 6,311 Aug-10-2020, 06:41 PM
Last Post: Intr0spective
  Type conversion and exception handling (PyBite #110) Drone4four 5 39,509 Jul-27-2020, 11:33 AM
Last Post: DeaD_EyE
  Iterating over dictionaries with the namedtuple function (PyBite #108) Drone4four 7 5,027 Jul-15-2020, 04:23 AM
Last Post: ndc85430
  Strings inside other strings - substrings OmarSinno 2 3,783 Oct-06-2017, 09:58 AM
Last Post: gruntfutuk

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020