[Tutor] Directory permission and ACLs
I am new to python and wanted to write a program that looks at directory permissions and ext3 ACLs and also change them if needed. What modules would I be looking at for those functions? Thank you. Pat ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] python-ldap
I am new to python and fairly new to programming. I have written some ldap scripts in perl and am trying to learn how to do that in python. I found some code on the net using the python-ldap module (the unaltered code is at the bottom of this email) and have adapted it to my needs, the code works fine. I want to learn what some of the things in the code are. The two things I don't understand are ldap.SCOPE_SUBTREE and ldap.RES_SEARCH_ENTRY when I print those out I get integers 2 and 100 respectively, I am not sure if they change but that is what they start out at. I am figuring other modules use similar things (variables?), can someone point me to where I can understand what more about what these are. The help documentation didn't really explain about these. Thanks Pat code: import ldap ## first you must open a connection to the server try: l = ldap.open("127.0.0.1") ## searching doesn't require a bind in LDAP V3. If you're using LDAP v2, set the next line appropriately ## and do a bind as shown in the above example. # you can also set this to ldap.VERSION2 if you're using a v2 directory # you should set the next option to ldap.VERSION2 if you're using a v2 directory l.protocol_version = ldap.VERSION3 except ldap.LDAPError, e: print e # handle error however you like ## The next lines will also need to be changed to support your search requirements and directory baseDN = "ou=Customers, ou=Sales, o=anydomain.com" searchScope = ldap.SCOPE_SUBTREE ## retrieve all attributes - again adjust to your needs - see documentation for more options retrieveAttributes = None searchFilter = "cn=*jack*" try: ldap_result_id = l.search(baseDN, searchScope, searchFilter, retrieveAttributes) result_set = [] while 1: result_type, result_data = l.result(ldap_result_id, 0) if (result_data == []): break else: ## here you don't have to append to a list ## you could do whatever you want with the individual entry ## The appending to list is just for illustration. if result_type == ldap.RES_SEARCH_ENTRY: result_set.append(result_data) print result_set except ldap.LDAPError, e: print e ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] Life after beginner
Hello,I have been reading about and playing with programming in python for awhile now. I have most of the basics down. I know what a tuple is, I know how to load modules, and I understand a fair amount of beginning programming theory. I have written some scripts for both home and work and have become fairly proficient at reading python code. My question is, what next? Is there some intermediate tutorials or books out there that I can start learning some real meat in the language? Things that just writing a simple script I might miss. I really want to learn about in depth programming and programming style but I am far from an expert. But with all the languages I have learned (really touched on) C, C++ perl, and python I seem to get to this point and then I am not sure where to go from here. I want to be able to write large projects in python and carry that experience over to the other languages as well. So any insight would be welcome. Thank you.Pat ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] Locking a file in linux with Python
Hello,I am trying to find on the web how to lock a file with python in Linux. I am trying to process a group of files that are continually being written to and when I am working on one file I would like to be able to lock it. Can anyone point me in the right direction for that. Thanks-- Pat Martin ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Locking a file in linux with Python
> I am trying to find on the web how to lock a file with python in Linux.> I am trying to process a group of files that are continually being > written to and when I am working on one file I would like to be able to> lock it. Can anyone point me in the right direction for that.Hi Pat,Take a look at the 'portalocker' recipe in the Python Cookbook: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65203Does this address your question?Good luck to you! I had actually looked at that site, but when I do the commandstestfile = open('testlock', 'a+')fcntl.flock(mboxfile.fileno(), fcntl.LOCK_EX)in the interpreter and then try to access the file in another terminal (I leave the interpreter open) I can write to the file just fine with vi. So I am not thinking it is working. Unless I am missing something... Thanks again.Pat Martin ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Locking a file in linux with Python
On 2/22/06, Pat Martin <[EMAIL PROTECTED]> wrote: > I am trying to find on the web how to lock a file with python in Linux. > I am trying to process a group of files that are continually being > written to and when I am working on one file I would like to be able to> lock it. Can anyone point me in the right direction for that.Hi Pat,Take a look at the 'portalocker' recipe in the Python Cookbook: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65203 Does this address your question?Good luck to you! I had actually looked at that site, but when I do the commandstestfile = open('testlock', 'a+')fcntl.flock(mboxfile.fileno(), fcntl.LOCK_EX)in the interpreter and then try to access the file in another terminal (I leave the interpreter open) I can write to the file just fine with vi. So I am not thinking it is working. Unless I am missing something... Thanks again.Pat Martin Ooops the commands I am running are actually mboxfile = open('testlock', 'a+')fcntl.flock(mboxfile.fileno(), fcntl.LOCK_EX)and it is not working. The two filenames do match, sorry for that typo earlier. -- Pat Martin ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Locking a file in linux with Python
Danny and Hugo,Thanks that really explains it better on what was going on. I may try renaming the file to see if I can get around it that way. -- Pat Martin ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] usernames and uid in linux
Hello all,I seem to be having a problem finding the right tool in python. Given a username I want to find the uid for it. I can do the reverse very easily with:pwd.getpwuid(2012)This returns a tuple of data from the passwd file. But I want to do something like: command(username) And get something that returns the uid (the number).Thanks-- Pat Martin ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] usernames and uid in linux
You're close:import pwdpw = pwd.getpwnam('username') Bill--INTERNET: [EMAIL PROTECTED] Bill Campbell; Celestial Systems, Inc.URL: http://www.celestial.com/ PO Box 820; 6641 E. Mercer Way FAX:(206) 232-9186 Mercer Island, WA 98040-0820; (206) 236-1676There is no distinctly native American criminal class save Congress-- Mark Twain___ Tutor maillist - Tutor@python.orghttp://mail.python.org/mailman/listinfo/tutorI completely missed that. Thank you so much. -- Pat Martin ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] Assigning a variable to an FTP directory listing
Hello, I am writing a program that needs to pull all of the files from a specific directory. I have a few lines written that give me the list of files but when I try to assign it to a variable the variable ends up equaling "226 Directory send Ok", this is a snippet of my code. ftp=FTP(ftpserver) ftp.login(user=username,passwd=password) ftp.cwd(remoteworkdir) listoffiles = ftp.retrlines('NLST') print listoffiles ftp.quit() The output I get is: sampleone samplethree sampletwo 226 Directory send OK. The list of files I get is just from running the ftp.retrlines command it isn't because of the variable printing. If I do it without the assignment of the listoffiles variable it just lists the files from running that command and the Directory send OK isn't there. Any ideas on how I can assign just the list of files to a variable that I can do a for loop to go through and download? Thank you, Pat ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Assigning a variable to an FTP directory listing
Below is what worked for me, thank you. I had a feeling it had to do with the callback but have never dealt with callbacks before so wasn't sure. Time to do more reading. For those asking about alternatives to FTP, its for a vendor who only uses FTP so no choice in that. Thanks all for the help. On Wed, Dec 11, 2013 at 4:22 PM, Steven D'Aprano wrote: > On Wed, Dec 11, 2013 at 03:55:50PM -0800, Pat Martin wrote: >> Hello, >> >> I am writing a program that needs to pull all of the files from a >> specific directory. I have a few lines written that give me the list >> of files but when I try to assign it to a variable the variable ends >> up equaling "226 Directory send Ok", this is a snippet of my code. > > I don't have an FTP server to test this against, but try this instead: > > from ftplib import FTP > ftp = FTP(ftpserver) > ftp.login(user=username, passwd=password) > ftp.cwd(remoteworkdir) > listoffiles = [] > status = ftp.retrlines('NLST', callback=listoffiles.append) > ftp.quit() > if status != "226 Directory send OK." > # An error? > print status > for filename in listoffiles: > print filename > > > > -- > Steven > ___ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Select a string
Hello all, I am trying to write a program for a programming class that finds the number of a specific string (bob) in a string of characters. I am using one of the sample strings they give me and it should find 2 instances of bob but my script returns 0. Since they want it to find 2 from the bobob in the string using "bob in s" doesn't work (it only returns 1). My eyes are crossing looking at the code, can someone give me a hint on what I am missing that causes this to not give me the correct answer of 2. #!/usr/bin/env python3 s = 'azcbobobegghakl' count = 0 theo = False firstb = False for i in s: if i == 'b': firstb == True if (i == 'b') and (theo == True): count += 1 if (i =='o') and (firstb == True): theo = True if (i != 'b') and (i != 'o'): theo = False firstb = False print(count) Thanks, Pat ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Select a string
I knew it was an assignment I just couldn't see it no matter how hard I looked at the code. Thanks for the tips on printing the variables, I was printing them right after the if statements not at the beginning and ending of the loop. I will remember that about True/False and comparisons thanks for that as well. The reason I haven't used regex/methods/etc is it hasn't been covered yet, we have only covered basic types, for, while and if statements. On Wed, Sep 6, 2017 at 1:54 AM, Alan Gauld via Tutor wrote: > On 06/09/17 06:34, Pat Martin wrote: > > > but my script returns 0. Since they want it to find 2 from the bobob in > the > > string using "bob in s" doesn't work (it only returns 1). > > Your code has bugs and Cameron has addressed those along > with general advice on how to debug your code in future. > However there are other string methods that could save > you some work. > > At the >>> prompt use dir(str) to see a list of all > the methods available. Then use help(str.methodName) > to find out what each one does. > (Or just browse the string documentation on the web site!) > > In this case you might find some of the following methods useful: > > str.count > str.find > str.index > str.startswith > > and of course you can use string slicing to access a > substring. Combining slicing with the parameters of > find or index should make your task easier. > > Finally, if you want to carry on with your loop approach > you might find that enumerate is useful here since it > gives you the index as well as the character. That > will allow you to look-ahead to see if the next two > characters are 'ob'... That should simplify things. > > -- > 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@python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Select a string
I got it working for all the tests, but the code is ugly. I think regex or using string methods would have been easier and neater but like I said we hadn't covered it in the class yet so didn't think I should use it. I am embarrassed by how bad the code looks to me. I am self taught and have written a couple useful scripts but still very much a beginner and there are definite holes in my knowledge. Hoping this class fills in some of the holes. Thanks again all for the suggestions and the tips. On Wed, Sep 6, 2017 at 8:01 AM, Pat Martin wrote: > I knew it was an assignment I just couldn't see it no matter how hard I > looked at the code. Thanks for the tips on printing the variables, I was > printing them right after the if statements not at the beginning and ending > of the loop. I will remember that about True/False and comparisons thanks > for that as well. > > The reason I haven't used regex/methods/etc is it hasn't been covered yet, > we have only covered basic types, for, while and if statements. > > On Wed, Sep 6, 2017 at 1:54 AM, Alan Gauld via Tutor > wrote: > >> On 06/09/17 06:34, Pat Martin wrote: >> >> > but my script returns 0. Since they want it to find 2 from the bobob in >> the >> > string using "bob in s" doesn't work (it only returns 1). >> >> Your code has bugs and Cameron has addressed those along >> with general advice on how to debug your code in future. >> However there are other string methods that could save >> you some work. >> >> At the >>> prompt use dir(str) to see a list of all >> the methods available. Then use help(str.methodName) >> to find out what each one does. >> (Or just browse the string documentation on the web site!) >> >> In this case you might find some of the following methods useful: >> >> str.count >> str.find >> str.index >> str.startswith >> >> and of course you can use string slicing to access a >> substring. Combining slicing with the parameters of >> find or index should make your task easier. >> >> Finally, if you want to carry on with your loop approach >> you might find that enumerate is useful here since it >> gives you the index as well as the character. That >> will allow you to look-ahead to see if the next two >> characters are 'ob'... That should simplify things. >> >> -- >> 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@python.org >> To unsubscribe or change subscription options: >> https://mail.python.org/mailman/listinfo/tutor >> > > ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Graphical/web program
Hello, I have recently written a program to add switches and hosts to my ssh config file, I use argparse for some switches like user name and such and it has been working pretty well. I was thinking of turning this into a web app (one that is just run on my local machine) something like have a form with text box, checkbox and radio buttons for the options/flags. My question is, is something like that practical? Will I be able to write to a local file (home/user/.ssh/config) with say a flask app? I don't know flask but am willing to learn it and thought this might be a good program for it. Thanks in advance for any thoughts or ideas. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] pythonic
Hello all, I have written the following program. It generates a template for Pelican web site static generator. It works just fine, it generates the template and then I put the info in it to customize. But I was wondering, is this the "right" way to do it in python? #!/usr/bin/env python3 """Generate a Pelican markdown base page.""" import argparse import datetime def Main(): """Run if run as a program.""" parser = argparse.ArgumentParser() parser.add_argument("-T", "--title", type=str, required=True, help='Title for site, also generates the slug', metavar="") parser.add_argument("-c", "--category", required=True, help='Category or categories of post', metavar="") parser.add_argument("-t", "--tags", type=str, required=True, help="Tags for post", metavar="") parser.add_argument("-a", "--author", type=str, default="Pat Martin", help="Author of post", metavar="") args = parser.parse_args() now = datetime.datetime.now() slug = args.title.replace(" ", "-").lower() with open("{}.md".format(slug), 'w') as f: f.write("Title: {}\n".format(args.title)) f.write("Date: {}-{}-{} {}:{}\n".format(now.year, now.month, now.day, now.hour, now.minute)) f.write("Modified: {}-{}-{} {}:{}\n".format(now.year, now.month, now.day, now.hour, now.minute)) f.write("Category: {}\n".format(args.category)) f.write("Slug: {}\n".format(slug)) f.write("Authors: {}\n".format(args.author)) f.write("Summary: \n") if __name__ == "__main__": Main() Thanks for any input. WP ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pythonic
Thank you all for the ideas and comments, it is appreciated. I have some refactoring to do now. On Fri, Mar 30, 2018 at 2:22 AM, Peter Otten <__pete...@web.de> wrote: > Pat Martin wrote: > > > I have written the following program. It generates a template for Pelican > > web site static generator. It works just fine, it generates the template > > and then I put the info in it to customize. But I was wondering, is this > > the "right" way to do it in python? > > You may rewrite the code creating the output as a loop: > > now_str = now.replace(microsecond=0).isoformat(" ") > with open("{}.md".format(slug), 'w') as f: > for name, value in [ > ("Title", args.title), > ("Date", now_str), > ("Modified", now_str), > ("Category", args.category), > ("Slug", slug), > ("Authors", args.author), > ("Summary", ""), > ]: > print(name, value, sep=": ", file=f) > > > If you want to format more than one date the same way you should put the > code into a function, no matter whether you pick your, my, or Alan's much > more common way to implement it > > def format_time(dt): >return ... > > ... > ("Date", format_time(now)), > ("Modified", format_time(modified)), > ... > > The idea behind my suggestions is the DRY (don't repeat yourself) principle > which applies to code written in any language. > > > #!/usr/bin/env python3 > > """Generate a Pelican markdown base page.""" > > > > import argparse > > import datetime > > > > > > def Main(): > > """Run if run as a program.""" > > parser = argparse.ArgumentParser() > > parser.add_argument("-T", "--title", type=str, required=True, > > help='Title for site, also generates the slug', > > metavar="") > > parser.add_argument("-c", "--category", required=True, > > help='Category or categories of post', > metavar="") > > parser.add_argument("-t", "--tags", type=str, required=True, > > help="Tags for post", metavar="") > > parser.add_argument("-a", "--author", type=str, default="Pat Martin", > > help="Author of post", metavar="") > > args = parser.parse_args() > > > > now = datetime.datetime.now() > > slug = args.title.replace(" ", "-").lower() > > > > with open("{}.md".format(slug), 'w') as f: > > f.write("Title: {}\n".format(args.title)) > > f.write("Date: {}-{}-{} {}:{}\n".format(now.year, > > now.month, > > now.day, > > now.hour, > > now.minute)) > > f.write("Modified: {}-{}-{} {}:{}\n".format(now.year, > > now.month, > > now.day, > > now.hour, > > now.minute)) > > f.write("Category: {}\n".format(args.category)) > > f.write("Slug: {}\n".format(slug)) > > f.write("Authors: {}\n".format(args.author)) > > f.write("Summary: \n") > > > > > > if __name__ == "__main__": > > Main() > > > ___ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Storing passwords and version control
Hello all, I am writing a script that will be using an API to connect to some systems to pull info for a search. Since it will be a script I will be running through cron I won't be able to type the password at time of running. I also am going to be putting this in source control, using git specifically. The process I am currently thinking of using is having a separate file with the username and password in it and just having that ignored by source control. That of course doesn't solve the problem of the password sitting in a file on the system unencrypted. Is there a better or more accepted way to do this in python? Thanks ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] (no subject)
TLDR; How do you figure out if code is inefficient (if it isn't necessarily obvious) and how do you find a more efficient solution? I use code wars sometimes to get some practice with Python, there was a challenge to compare two strings and if string1 had enough characters to be rearranged to make string2 return True, otherwise return False. I wrote a script that was like this: for i in string1: if i not in string2: return False string2.replace(i,"",1) return True This worked but I kept getting that my function was too inefficient and it took too long. I did a search for the problem and found someone was using collections.Counter. This basically takes the string and returns the number of times each character occurs in it. Then just compare the count of one string to another to see if there is enough of each letter to make the other string. This seems like an elegant way to do it. My question is, how do I know something is inefficient and more importantly how do I go about finding a more efficient solution? I have just discovered dir() and it has really helped in finding methods for items but that doesn't help when finding actual packages especially if I don't know exactly what I am looking for. Sorry about the long email, not sure if there is even an answer to this question except maybe write more code and get more experience? Pat ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] How to find optimisations for code
Sorry my first email didn't have a subject line TLDR; How do you figure out if code is inefficient (if it isn't necessarily obvious) and how do you find a more efficient solution? I use code wars sometimes to get some practice with Python, there was a challenge to compare two strings and if string1 had enough characters to be rearranged to make string2 return True, otherwise return False. I wrote a script that was like this: for i in string1: if i not in string2: return False string2.replace(i,"",1) return True This worked but I kept getting that my function was too inefficient and it took too long. I did a search for the problem and found someone was using collections.Counter. This basically takes the string and returns the number of times each character occurs in it. Then just compare the count of one string to another to see if there is enough of each letter to make the other string. This seems like an elegant way to do it. My question is, how do I know something is inefficient and more importantly how do I go about finding a more efficient solution? I have just discovered dir() and it has really helped in finding methods for items but that doesn't help when finding actual packages especially if I don't know exactly what I am looking for. Sorry about the long email, not sure if there is even an answer to this question except maybe write more code and get more experience? Pat ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to find optimisations for code
That's correct sorry, I reassigned with replace back to string2, I forgot that in my retyping of the snippet. That makes sense, when it comes to strings and it taking so long. Thanks for explaining that. On Fri, Oct 19, 2018 at 10:09 AM Peter Otten <__pete...@web.de> wrote: > Mats Wichmann wrote: > > > On 10/19/2018 10:12 AM, Pat Martin wrote: > >> Sorry my first email didn't have a subject line > >> > >> TLDR; How do you figure out if code is inefficient (if it isn't > >> necessarily obvious) and how do you find a more efficient solution? > > > > I think you've hit it in your last sentence ("except maybe write more > > code and get more experience"): experience will let you recognize > > patterns. > > > >> I use code wars sometimes to get some practice with Python, there was a > >> challenge to compare two strings and if string1 had enough characters to > >> be rearranged to make string2 return True, otherwise return False. > >> > >> I wrote a script that was like this: > >> > >> for i in string1: > >> if i not in string2: > >> return False > >> string2.replace(i,"",1) > >> return True > >> > >> This worked but I kept getting that my function was too inefficient and > >> it took too long. I did a search for the problem and found someone was > >> using collections.Counter. This basically takes the string and returns > >> the number of times each character occurs in it. Then just compare the > >> count of one string to another to see if there is enough of each letter > >> to make the other string. This seems like an elegant way to do it. > > > > notwithstanding that the challenge is a little contrived... here's > > something you will come to recognize. You use the string replace > > method, which is described thus, pasting from the official docs: > > > > """ > > str.replace(old, new[, count]) > > > > Return a copy of the string with all occurrences of substring old > > replaced by new. If the optional argument count is given, only the first > > count occurrences are replaced. > > """ > > > > Strings are not modifiable, so there is no replace-in-place. Each time > > you call string2.replace you build a new string... and then do nothing > > with that string, as you never assign a name to it. So that line clearly > > makes your code inefficient - you do some work that is just thrown away. > > And it's not clear what the purpose of this replacement is, anyway. > > This is probably retyped from memory. If the line were > > string2 = string2.replace(i,"",1) > > it would address your concern below about repeated chars. > > >>> def contains(s, t): > ... for c in s: > ... if c not in t: return False > ... t = t.replace(c, "", 1) # remove one occurence of c from t > ... return True > ... > >>> contains("ata", "attax") > True > >>> contains("tata", "attax") > True > >>> contains("tatat", "attax") # not enough 't's > False > > > Further it's not clear that you have the right answer. What if string1 > > contains one 'r' and string2 contains three? For the one 'r', the test > > that it is also in string2 succeeds... but nowhere do you find out that > > you actually needed to have three in order to be able to "rearrange to > > make string2". > > > > Solving this problem might benefit from thinking about tests first: if > > you write a test where you know the answer is going to be negative, a > > second where it is going to be positive, and a third that is a > > non-trivial instance of positive (like the multiple-letter count), then > > you have something to code your solution against. After it works, you > > can then think about refactoring: is there a better way? This will kind > > of naturally lead you to thinking in terms of efficiency. > > > > Lesson 2: for very many tasks, someone has already done it, and you can > > benefit by using some existing code, from the standard library or a > > module installed separately. That's often the difference between a > > programming challenge, which may want you to code it yourself to show > > you can, and real-world problem solving, where you are rewarded (in > > time) by efficiently reusing existing code. > > > > > > > > ___ > > Tutor maillist - Tutor@python.org > > To unsubscribe or change subscription options: > > https://mail.python.org/mailman/listinfo/tutor > > > ___ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to find optimisations for code
So should we always use sets or dictionaries if possible? Are these more efficient because of not keeping track of their position? On Fri, Oct 19, 2018 at 10:47 AM Pat Martin wrote: > That's correct sorry, I reassigned with replace back to string2, I forgot > that in my retyping of the snippet. > > That makes sense, when it comes to strings and it taking so long. Thanks > for explaining that. > > On Fri, Oct 19, 2018 at 10:09 AM Peter Otten <__pete...@web.de> wrote: > >> Mats Wichmann wrote: >> >> > On 10/19/2018 10:12 AM, Pat Martin wrote: >> >> Sorry my first email didn't have a subject line >> >> >> >> TLDR; How do you figure out if code is inefficient (if it isn't >> >> necessarily obvious) and how do you find a more efficient solution? >> > >> > I think you've hit it in your last sentence ("except maybe write more >> > code and get more experience"): experience will let you recognize >> > patterns. >> > >> >> I use code wars sometimes to get some practice with Python, there was a >> >> challenge to compare two strings and if string1 had enough characters >> to >> >> be rearranged to make string2 return True, otherwise return False. >> >> >> >> I wrote a script that was like this: >> >> >> >> for i in string1: >> >> if i not in string2: >> >> return False >> >> string2.replace(i,"",1) >> >> return True >> >> >> >> This worked but I kept getting that my function was too inefficient and >> >> it took too long. I did a search for the problem and found someone was >> >> using collections.Counter. This basically takes the string and returns >> >> the number of times each character occurs in it. Then just compare the >> >> count of one string to another to see if there is enough of each letter >> >> to make the other string. This seems like an elegant way to do it. >> > >> > notwithstanding that the challenge is a little contrived... here's >> > something you will come to recognize. You use the string replace >> > method, which is described thus, pasting from the official docs: >> > >> > """ >> > str.replace(old, new[, count]) >> > >> > Return a copy of the string with all occurrences of substring old >> > replaced by new. If the optional argument count is given, only the first >> > count occurrences are replaced. >> > """ >> > >> > Strings are not modifiable, so there is no replace-in-place. Each time >> > you call string2.replace you build a new string... and then do nothing >> > with that string, as you never assign a name to it. So that line clearly >> > makes your code inefficient - you do some work that is just thrown away. >> > And it's not clear what the purpose of this replacement is, anyway. >> >> This is probably retyped from memory. If the line were >> >> string2 = string2.replace(i,"",1) >> >> it would address your concern below about repeated chars. >> >> >>> def contains(s, t): >> ... for c in s: >> ... if c not in t: return False >> ... t = t.replace(c, "", 1) # remove one occurence of c from t >> ... return True >> ... >> >>> contains("ata", "attax") >> True >> >>> contains("tata", "attax") >> True >> >>> contains("tatat", "attax") # not enough 't's >> False >> >> > Further it's not clear that you have the right answer. What if string1 >> > contains one 'r' and string2 contains three? For the one 'r', the test >> > that it is also in string2 succeeds... but nowhere do you find out that >> > you actually needed to have three in order to be able to "rearrange to >> > make string2". >> > >> > Solving this problem might benefit from thinking about tests first: if >> > you write a test where you know the answer is going to be negative, a >> > second where it is going to be positive, and a third that is a >> > non-trivial instance of positive (like the multiple-letter count), then >> > you have something to code your solution against. After it works, you >> > can then think about refactoring: is there a better way? This will kind >> > of naturally lead you to th