#๐ Need help figuring out what I'm doing wrong (iterating over a string)
182 messages ยท Page 1 of 1 (latest)
@spice niche
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.
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
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
I'm using a shitty 60% keyboard rn until my other one arrives so yea, I apologise for that
(it doesn't even have arrow keys and I need so swtich b/w wasd and arrow keys)
Is there other code you've not shown?
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.
I spotted that just before you posted. I was getting there, I was getting there.
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!"))```
The battle is not always to the string strong, nor the race to the swift.
this is the full thing but the other function's not in use
!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 [35m"/home/main.py"[0m, line [35m1[0m, in [35m<module>[0m
005 | [31m"abc"[0m[1;31m()[0m
006 | [31m~~~~~[0m[1;31m^^[0m
007 | [1;35mTypeError[0m: [35m'str' object is not callable[0m
um?
I use i as a pointer to parse thru string and check the first against the last, second against the second last (n so forth)
I thought you could iterate over a string w a for loop
You can.
how so?
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) ?
Well, it's not what you've written.
I think I'm mixing the for i in iterable with for i in range(first value, limit, increment)
Likely. They're both iterables ๐
Start stop step.
can I not specify how it moves thru the string without converting it to a list first
i should be a pointer that can be used to point at both the start and end of the string
so i and -i
Ok. Then in python, that means an index into the string. An integer. And you've got a function which produces those integers.
!e py print("abc"[0]) print("abc"[1]) print("abc"[2]) print("abc"[-1]) print("abc"[-2]) print("abc"[-3])
:white_check_mark: Your 3.14 eval job has completed with return code 0.
001 | a
002 | b
003 | c
004 | c
005 | b
006 | a
so do I use a while loop instead?
No. A for loop is what you want.
You could, but a for loop is going to be the better choice.
If i is an index to the string, an integer, what values should it take on for the loop iterations?
i should be 0, 1, 2... and -i should be -1, -2, -3...
except.. I can't use -i, I'd need to compare it with -i + 1
That's ok. Let's take the first part.
What will produce the numbers 0, 1, 2 etc?
a ranged for loop
Right, so write that bit now, here.
for i in range len(string)(0,n)```
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?
!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 [35m"/home/main.py"[0m, line [35m1[0m, in [35m<module>[0m
005 | [31m(123)[0m[1;31m()[0m
006 | [31m~~~~~[0m[1;31m^^[0m
007 | [1;35mTypeError[0m: [35m'int' object is not callable[0m
ah-
If you've used range before, what did it look like?
for i in range (0,n)```
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?
string[i]```
Correct.
Now, let's compute j, the index of the right character.
What would that be?
can't I just use -i + 1 ?
or is there some advantage to using j as a separate pointer?
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.
got it
So you're advocating using j = -i + 1 above.
Sorry, -i, I mistyped.
ahhh-
If i=0, and string is "abc" like Opal example earlier. What does that make?
if we go by what I said earlier that would make j = 1
Yeah. But what is the index of c ?
the index of c is -1 or 2
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.
-# sorry, gimme a moment, I gotta afk rq
Me too. back in a few minutes.
I'm back
j would be i - 1
also tyt~
-# 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
I just ate.
So: i - 1. This has a positive i in the expression. So as i goes up (index 1, index 2 etc) will j go up or down?
Also, you're starting from 2. Write the expression with 2 and things involving i (because i starts at 0 so it should just be 2 the first time around the loop).
(it might help to verify the current state of the code?)
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.
-# I'm back from eating some food :p
j goes down as i goes up, we can add a j -= 1 right b4 the loop repeats
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
we could write j as j = -i - 1
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?
if (i != j):
FLAG = False
break
else: FLAG = True```
oh wait yea @.@
if string[i] != string[j]:
FLAG = False
break
else: FLAG = True```
Looks good. Let's see the entire function then.
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
Up? Why up?
cause we'd need the range for i to be long enough to cover the full string no?
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)
:white_check_mark: Your 3.14 eval job has completed with return code 0.
001 | 2.5
002 | 2
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!!
So: is your function correct?
I was just gonna check it loll
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
looks like it works
So first: why does that happen?
cause we're trying to floor divide len(string) by two and that returns 0 which isn't iterable
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?
it doesn't
Right. AKA zero times.
And where is FLAG defined? Inisde the loop.
Describe to me your human logic for checking the palindrome.
No. Why would that help? (What's your thinking here?)
if the n = 0 then we could return "invalid string input" instead of returning the flag value
But an empty string isn't invalid.
that way the loop never runs unless it can
What about "a". That also shows the same behaviour, and it also is not invalid.
could return True instead then
-# ~~ had to look up what a palindrome is again :")~~
Right. That's one approach: "early return" (before the end of the function) for the trivial case.
cause both "a" and "" are read the same way front and back
But we don't need to. let's back up.
As a human, how do you decide if a string is a palindrome.
if it is read the same way forward or back
And how do you check that. As a human.
Or more to the point, when you wrote this loop how were you thinking?
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
Test data: https://www.youtube.com/watch?v=eIty7RqbF9o
โ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...
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.
maybe this is a simpler way to think about it: what is the definition of a palindrome?
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.
np
but it's a good question to ask again after the code works.
@spice niche still with us? Or listening to the video?
I'm here
So: does the idea of having a theory that this string is a plaindrome, then discoveing it isn't work for your thinking?
yeah, that works
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.
that is pretty helpful :0
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...
will 100% read thru these
tysm for the help and the patience!~
I really appreciate it
np, that's why we're here
@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
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).
I'm still here, just stepped away from the computer
!e py print("abc"[::-1])Here is a quick shorthand for a slice that reverses.
:white_check_mark: Your 3.14 eval job has completed with return code 0.
cba
This is effectively py "abc"[None:None:-1]
I'll leave you to ponder how you might choose to take advantage of this.
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
Strictly speaking, you need write no loops.
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.
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.