#๐Ÿ”’ Need help figuring out what I'm doing wrong (iterating over a string)

182 messages ยท Page 1 of 1 (latest)

spice niche
#
def check_palindrome(string):
    n=len(string)/2
    for i in string(0,n):
        if (i!=-i): 
            FLAG=False
            break 
        else: 
            FLAG=True
    return FLAG
    
    
print(check_palindrome("abcddcba")) ```
chrome adderBOT
#

@spice niche

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

spice niche
#

so I know for a fact that the variable name string isn't the issue because I made another function that used the same variable name as an argument and it worked fine

#

ah I forgot to add the error

shrewd arrow
#

In addition to the / operator, others exist.

#

When writing operators, it is often nice to place a space on either side, so tgat thry are visually seperated from the operands.

#

a + b vs a+b

spice niche
spice niche
#

(it doesn't even have arrow keys and I need so swtich b/w wasd and arrow keys)

shrewd arrow
#

Is there other code you've not shown?

verbal cosmos
#

The core of your problem is this expression:

string(0,n)

What should it do? A for-loop iterates over something, and this is the something.

shrewd arrow
#

I spotted that just before you posted. I was getting there, I was getting there.

spice niche
# shrewd arrow Is there other code you've not shown?
def word_count(string):
    return len(string)
    
def check_palindrome(string):
    n=len(string)/2
    for i in string(0,n):
        if (i!=-i): 
            FLAG=False
            break 
        else: 
            FLAG=True
    return FLAG
    
    
print(check_palindrome("abcddcba"))
#print(word_count("Hello World!"))```
verbal cosmos
#

The battle is not always to the string strong, nor the race to the swift.

spice niche
#

this is the full thing but the other function's not in use

shrewd arrow
#

!e py "abc"()

chrome adderBOT
# shrewd arrow !e ```py "abc"()```

:x: Your 3.14 eval job has completed with return code 1.

001 | /home/main.py:1: SyntaxWarning: 'str' object is not callable; perhaps you missed a comma?
002 |   "abc"()
003 | Traceback (most recent call last):
004 |   File "/home/main.py", line 1, in <module>
005 |     "abc"()
006 |     ~~~~~^^
007 | TypeError: 'str' object is not callable
spice niche
#

I thought you could iterate over a string w a for loop

shrewd arrow
#

You can.

shrewd arrow
#

That's not what you're attempting.

spice niche
#

how so?

verbal cosmos
#

Python doesn't have pointers per se.
You can iterate over a string; it gets you each letter as its own single character string:

for ch in string:

But that isn't what you wrote.

What did you intend to obtain from string(0,n) ?

shrewd arrow
#

Well, it's not what you've written.

spice niche
verbal cosmos
#

Likely. They're both iterables ๐Ÿ™‚

shrewd arrow
#

Start stop step.

spice niche
#

can I not specify how it moves thru the string without converting it to a list first

verbal cosmos
#

You can.

#

What should i itself be, in your mind?

spice niche
#

i should be a pointer that can be used to point at both the start and end of the string

#

so i and -i

verbal cosmos
#

Ok. Then in python, that means an index into the string. An integer. And you've got a function which produces those integers.

shrewd arrow
#

!e py print("abc"[0]) print("abc"[1]) print("abc"[2]) print("abc"[-1]) print("abc"[-2]) print("abc"[-3])

chrome adderBOT
spice niche
verbal cosmos
#

No. A for loop is what you want.

shrewd arrow
#

You could, but a for loop is going to be the better choice.

verbal cosmos
#

If i is an index to the string, an integer, what values should it take on for the loop iterations?

spice niche
verbal cosmos
#

That's ok. Let's take the first part.
What will produce the numbers 0, 1, 2 etc?

spice niche
#

a ranged for loop

verbal cosmos
#

Right, so write that bit now, here.

spice niche
#
for i in range len(string)(0,n)```
verbal cosmos
#

BTW, a "ranged for loop" is just a for-loop which iterates over the result of range(.......). it's nothing special - the iteration just comes from the range.

That's close. Have you used range before?

shrewd arrow
#

!e py (123)()

chrome adderBOT
# shrewd arrow !e ```py (123)()```

:x: Your 3.14 eval job has completed with return code 1.

001 | /home/main.py:1: SyntaxWarning: 'int' object is not callable; perhaps you missed a comma?
002 |   (123)()
003 | Traceback (most recent call last):
004 |   File "/home/main.py", line 1, in <module>
005 |     (123)()
006 |     ~~~~~^^
007 | TypeError: 'int' object is not callable
spice niche
#

ah-

verbal cosmos
#

If you've used range before, what did it look like?

spice niche
verbal cosmos
#

Right. That counts from 0 through to n-1. Which is what you want.

So inside the loop you've got i, the index of the left character. What gets you the left character itself?

spice niche
#
string[i]```
verbal cosmos
#

Correct.

#

Now, let's compute j, the index of the right character.

#

What would that be?

spice niche
#

can't I just use -i + 1 ?
or is there some advantage to using j as a separate pointer?

verbal cosmos
#

1: you can't just use -i + 1 because it's not quite correct. We'll get there.
2: we're using j just to keep each step separated out so that we can talk about it.

spice niche
#

got it

verbal cosmos
#

So you're advocating using j = -i + 1 above.
Sorry, -i, I mistyped.

spice niche
#

ahhh-

verbal cosmos
#

If i=0, and string is "abc" like Opal example earlier. What does that make?

spice niche
#

if we go by what I said earlier that would make j = 1

verbal cosmos
#

Yeah. But what is the index of c ?

spice niche
#

the index of c is -1 or 2

verbal cosmos
#

Ok. So since we're counting backwards, we're subtracting i from some rightmost position.
If i=0 s the rightmost, then we want 2 (for the c).
Or -1, either will do.
So the starting (rightmost) position is when i=0 (meaning we can drop i when thinking about it).

This means the starting rightmost poition is -1, or 2. And we subtract i from that?

So write a j = for that.

spice niche
#

-# sorry, gimme a moment, I gotta afk rq

verbal cosmos
#

Me too. back in a few minutes.

spice niche
#

I'm back

spice niche
spice niche
#

-# omg, I completely forgot that the start value in the range function was optional and that if you only pass one argument it assumes that that's the stop value :")

#

-# I should get something to eat cause my empty stomach isn't helping my empty head

verbal cosmos
safe gust
#

(it might help to verify the current state of the code?)

verbal cosmos
#

We're building the for loop from scratch. No need yet.

#

So far we've got a for loop, i the left index, and we're computing j, the right index.

spice niche
#

-# I'm back from eating some food :p

spice niche
verbal cosmos
#

I was hoping to compute j directly from each i instead of setting it at the start and adjusting it. Both work, but I want you to think about an expression for j

verbal cosmos
#

Ok that makes j = -1 when i=0, and counts down. That will be fine.

#

So now you have an index for the left char and the right char. To compare those 2 characters, what do you do?

spice niche
#
if (i != j):
  FLAG = False
  break
else: FLAG = True```
verbal cosmos
#

That compares the indices. Not the characters.

#

(And you don't need the brackets.)

spice niche
#

oh wait yea @.@

spice niche
verbal cosmos
#

Looks good. Let's see the entire function then.

spice niche
#
def check_palindrome(string):
    n=len(string)/2
    for i in range(n):
        j = -i - 1
        if (string[i] != string[j]): 
            FLAG=False
            break 
        else: 
            FLAG=True
    return FLAG
#

the only issue would be if len(string) is an odd number, then we'd need to round up the divident

verbal cosmos
#

Up? Why up?

spice niche
#

cause we'd need the range for i to be long enough to cover the full string no?

verbal cosmos
#

But won't that be comparing the middle character... with itself? Always equal I'd hope.

#

SO it would work. But it would be unnecessary.

#

!e
So really, you can round down. Let me introduce you to the // operator:

print(5 / 2)
print(5 // 2)
chrome adderBOT
spice niche
#

oh wait yea, since the middle character's well.. in the middle it's obv equal to itself and doesn't need to be checked :")

#

but TYSM for being patient w me!!

verbal cosmos
#

So: is your function correct?

spice niche
#

I was just gonna check it loll

verbal cosmos
#

There are 2 ways to check:

  • run it with various strings, look for mistakes
  • eyeball its logic and ddecide if it makes sense
#

The second is faster for finding bugs, if they're there and if you recognise them.

#

The first is only as good as your test data.

#

Beware of bugs in the above code; I have only proved it correct, not tried it.

  • Donald E. Knuth
verbal cosmos
#

Try the trivial case: ""

#

And the next trivial case "a"

spice niche
#

ah :")

verbal cosmos
#

So first: why does that happen?

spice niche
verbal cosmos
#

No.

#

Number are not (whoops) iterable, and range(0) does work, though it produces no numbers.

#

But if range(0) produces no numbers, how many times does the loop run?

spice niche
#

it doesn't

verbal cosmos
#

Right. AKA zero times.

And where is FLAG defined? Inisde the loop.

spice niche
#

Rightt-

#

so I could fix it with another elif

verbal cosmos
#

Describe to me your human logic for checking the palindrome.

verbal cosmos
spice niche
verbal cosmos
#

But an empty string isn't invalid.

spice niche
#

that way the loop never runs unless it can

verbal cosmos
#

What about "a". That also shows the same behaviour, and it also is not invalid.

spice niche
#

could return True instead then

#

-# ~~ had to look up what a palindrome is again :")~~

verbal cosmos
#

Right. That's one approach: "early return" (before the end of the function) for the trivial case.

spice niche
#

cause both "a" and "" are read the same way front and back

verbal cosmos
#

But we don't need to. let's back up.

#

As a human, how do you decide if a string is a palindrome.

spice niche
verbal cosmos
#

And how do you check that. As a human.

#

Or more to the point, when you wrote this loop how were you thinking?

spice niche
#

I personally flip between a few ways, either read it left to right and then right to left, or the way I wrote the code

verbal cosmos
#

โ€œBobโ€ by โ€œWeird Alโ€ Yankovic - HD Version

Listen to โ€œWeird Alโ€ Yankovic: https://weirdalyankovic.lnk.to/listenYD
Subscribe to the official โ€œWeird Alโ€ Yankovic YouTube channel: https://weirdalyankovic.lnk.to/subscribeYD
Watch more โ€œWeird Alโ€ Yankovic videos: https://weirdalyankovic.lnk.to/listenYC/youtube

Follow โ€œWeird Al...

โ–ถ Play video
#

Ok, doing the left to right version, we can cast this as a theory, to be falsified or not, in the style of Karl Popper.

Theory: this string is a palindrome. Look along it, and if you find it isn't, it's false and you stop.

safe gust
#

maybe this is a simpler way to think about it: what is the definition of a palindrome?

verbal cosmos
#

No, we've got that. And we've got a function to test it.

#

I'm chasing down the thought process which leads to reliably defining FLAG.

#

Thus the theory falsification approach.

safe gust
#

oh, I thought you were about to jump ahead from that :)

#

my mistake

verbal cosmos
#

np

safe gust
#

but it's a good question to ask again after the code works.

verbal cosmos
#

@spice niche still with us? Or listening to the video?

verbal cosmos
#

So: does the idea of having a theory that this string is a plaindrome, then discoveing it isn't work for your thinking?

spice niche
#

yeah, that works

verbal cosmos
#

So, FLAG is the result of testing the theory.

#

If that's our theory, can we work with:

FLAG = True # maybe this is a palindrome
for ......
    if the characters don't match:
        FLAG = False # it's not a palindrome!
        break
return FLAG
#

The difference here is that FLAG is always set. Then corrected if it was wrong.
But regardless of how many times the loop runs, FLAG has a value.

#

Lot of things are written this way: set some initial values, then work on them. You had the set-the-value inside the loop, so it might not happen at all with a short string.
This one unconditionally sets the value before the loop.

spice niche
#

that is pretty helpful :0

verbal cosmos
#

Article about the song above, which is all palindromes: https://en.wikipedia.org/wiki/Bob_("Weird_Al"_Yankovic_song)
This "falsification" approach is describe here for science:
https://en.wikipedia.org/wiki/Falsifiability
and was introduced by Karl Popper:
https://en.wikipedia.org/wiki/Karl_Popper

Worth a read.

"Bob" is a song by "Weird Al" Yankovic from the 2003 album Poodle Hat. The song is a parody sung in the style of Bob Dylan, and each line of the lyrics is a palindrome, as is the title. For example, the song's first line is "I, man, am regalโ€”a German am I".
The song did not chart at the time of its release, but later became the subject of crit...

Falsifiability is a standard of evaluation of scientific statements, including theories and hypotheses. A statement is falsifiable if it belongs to a language or logical structure capable of describing an empirical observation that contradicts it.
In the case of a theory, falsifiability requires that, given an initial condition, the theory must...

Sir Karl Raimund Popper (28 July 1902 โ€“ 17 September 1994) was an Austrianโ€“British philosopher, academic and social commentator. One of the 20th century's most influential philosophers of science, Popper is known for his rejection of the classical inductivist views on the scientific method in favour of empirical falsification made possible b...

spice niche
#

tysm for the help and the patience!~

#

I really appreciate it

verbal cosmos
#

np, that's why we're here

shrewd arrow
#

@spice niche I would like to show you a thing.

#

Are you still around?

#

First, here's a link to the slice documentation.

#

!d slice

chrome adderBOT
#

class slice(stop, /)``````py

class slice(start, stop, step=None, /)```
Return a [slice](https://docs.python.org/3/glossary.html#term-slice) object representing the set of indices specified by `range(start, stop, step)`. The *start* and *step* arguments default to `None`.

Slice objects are also generated when [slicing syntax](https://docs.python.org/3/reference/expressions.html#slicings) is used. For example: `a[start:stop:step]` or `a[start:stop, i]`.

See [`itertools.islice()`](https://docs.python.org/3/library/itertools.html#itertools.islice) for an alternate version that returns an [iterator](https://docs.python.org/3/glossary.html#term-iterator).
spice niche
shrewd arrow
#

!e py print("abc"[::-1])Here is a quick shorthand for a slice that reverses.

chrome adderBOT
shrewd arrow
#

This is effectively py "abc"[None:None:-1]

#

I'll leave you to ponder how you might choose to take advantage of this.

spice niche
#

Ooooo~
I had the idea to slice the string in half, flip the latter half n compare but that seemed a little overcomplicated but I never thought of doing this (like this)

#

I also did think of flipping the string and comparing the og and the flipped string but didn't want too many loop statements by doing it the conventional way

#

I did end up doing just that tho

shrewd arrow
#

Strictly speaking, you need write no loops.

spice niche
#

yeahh

#

this is neat tho, Ima have to remember this

shrewd arrow
#

Definitely play around with slicing. It can be a pain in the arse, especially when going in reverse if you need something more specific than this.

#

But it's worth knowing about.

chrome adderBOT
#
Python help channel closed for inactivity

This help channel has been closed. Feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.