[Tutor] How to manipulate a user's input twice in one statement

ThreeBlindQuarks threesomequarks at proton.me
Wed May 17 20:24:14 EDT 2023


Goran,

As you learn, you have to make distinctions.

A function defined with def is not associated with a class and indeed there is no concept of a self.

A class you created yourself can have instance methods that are given a copy of the self when invoked properly on an instance of that object. Just to be confusing, you can make methods associated with the class that pretty much act like a regular function in a sort of namespace of the class like math.sin() ...

But the class holding str objects is not created by you and has only the methods you can get by typing:

>>> dir(str)
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'removeprefix', 'removesuffix', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

So it does seem to be there.

And the following works fine for me:

>>> input("text ").removesuffix(".avi")
text xyz.avi
'xyz'

What I am wondering is if what you want is not to remove a fixed suffix but anything starting with a period near the end. In the old days, a suffix was up to three characters but no longer. So the way to do it is NOT necessarily to ask for a suffix, or to look at the last few letters but perhaps other ways.

One way is to search back from the end of the string till you find a period and then just copy everything before it.

Lots of modules can be used, such as this one:

>>> import os.path
>>> os.path.splitext("abc.defg")
('abc', '.defg')
>>> os.path.splitext("abc.defg")[0]
'abc'

And of course there are regular expressions where you ask to greedily match everything and save it as \1 followed by a period and anything and then replace it with just \1.

If you have an assignment that asks you to use a particular tool, fine. If not, your method is only helpful if you are sure of the length of the suffix and in that case, you can use a subset at the end of the string to remove the end. Still, it is perhaps easier to use just the subset BEFORE and throw away the rest.






Sent with Proton Mail secure email.

------- Original Message -------
On Wednesday, May 17th, 2023 at 4:29 PM, Alan Gauld via Tutor <tutor at python.org> wrote:


> On 17/05/2023 15:24, Goran Ikac wrote:
> 
> > Aha! So, "removesuffix" can be used as a method applied to an object (the
> > instance of <class 'str'>), but not as a function with a string as the
> > first argument. The first argument must be "self".
> 
> 
> Correct. self is the string instance in the method definition but when
> you use it the string instance is the prefix object. The difference
> between a function and a method is that Pyhthon automatically converts
> 
> object.method(args)
> to
> method(object, args)
> 
> behind the scenes. (It does a bit more than that but from
> a users perspective it's close enough)
> 
> > > > > input().removesuffix(input()[1:])
> > 
> > ... and it didn't work as I expected.
> 
> 
> I guess that's what I'm confused about.
> input() is a function like any other. It returns a string obtained from
> stdin(usually the user but it could be from another program or file)
> 
> And you call input() twice here, so lets unpick how Python sees this.
> 
> First it sees the first input and recognizes that it must return
> a string, so it calls it and grabs the string returned. It then
> calls the removesuffix() method of that string object.
> 
> But removesuffix() takes a string as an argument and to get that
> string Python must call the second input() function invocation.
> That returns another string object which Python then passes
> to removesuffix.
> 
> After removing the suffix Python gets handed yet another
> string object as a result which it then displays.
> 
> So Python converts your code into:
> 
> print( first_string.removesuffix(second_string) )
> 
> I'm not sure what you expected it to do?
> 
> > > > > result = 3 * (2 + int(input('Please, type a number: '))
> 
> 
> This is the same but you only call input() once.
> But Python processes it in the same way.
> 
> It sees result = 3 * (2 + int(some_string))
> 
> and some_string is obtained by calling input()
> 
> The only difference is that you had two calls to input() in
> the first case but only one in the second example.
> 
> There is nothing magic about input() that would make
> Python remember its previous result any more than it
> remembers the earlier result from, say pow()
> 
> So if you type:
> 
> hyp = pow(pow(x,2) + pow(y,2), 0.5)
> 
> pow() is called three times each completely independent
> of the others. It's the same with input(), it is just a
> function like any other.
> 
> > ... worked, and I guessed if I can make the method work like a function or
> > an operator would.
> > Obviously, I need to learn better about classes and methods.
> 
> 
> I'm not sure that's the problem here. Apart from the fact
> that removesuffix() is a method of a string rather than a
> stand-alone function it doesn't change how it interacts
> with input()
> 
> In fact you could create a function that would do the
> same job and it would have the same effect:
> 
> def remove_suffix(aString, aSuffix):
> return aString.removesuffix(aSuffix)
> 
> now you could try calling it with input():
> 
> remove_suffix(input(),input())
> 
> You would still get the same double call to input()
> If you wanted to use the same result(and slice it you
> could use the walrus operator:
> 
> remove_suffix(s := input(), s[1:])
> 
> but that still requires a variable it just keeps it
> inside the line(but it is still available afterwards too!).
> 
> I hope that makes sense.
> 
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.amazon.com/author/alan_gauld
> Follow my photo-blog on Flickr at:
> http://www.flickr.com/photos/alangauldphotos
> 
> 
> 
> _______________________________________________
> Tutor maillist - Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor


More information about the Tutor mailing list