Path: csiph.com!fu-berlin.de!uni-berlin.de!not-for-mail From: Joel Goldstick Newsgroups: comp.lang.python Subject: Re: i'm a python newbie & wrote my first script, can someone critique it? Date: Fri, 10 Jun 2016 21:02:31 -0400 Lines: 228 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Trace: news.uni-berlin.de IFf5Uzvzqvw6JYsADdAdgQVQStNg6cXZTc5zsaOvXN1Q== Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'python,': 0.02; 'exercise': 0.03; 'configure': 0.04; 'string.': 0.04; '#if': 0.05; 'sys': 0.05; 'exit': 0.07; 'main()': 0.07; 'matches': 0.07; 'cc:addr:python-list': 0.09; '"in': 0.09; 'errno': 0.09; 'exception:': 0.09; 'globals': 0.09; 'logic': 0.09; 'oh,': 0.09; 'oop,': 0.09; 'oserror': 0.09; 'skip:# 30': 0.09; 'str)': 0.09; 'subject:script': 0.09; 'timestamp': 0.09; 'vba,': 0.09; 'worse': 0.09; 'received:209.85.218': 0.10; 'url:blog': 0.10; 'python': 0.10; 'python.': 0.11; 'skip:# 20': 0.13; 'syntax': 0.13; 'def': 0.13; 'appropriate': 0.14; 'subject:python': 0.14; 'things.': 0.15; 'variables': 0.15; '"),': 0.16; '"."': 0.16; '"python': 0.16; '"wrong': 0.16; '#python': 0.16; '(plain': 0.16; '0):': 0.16; '2016': 0.16; '6:52': 0.16; 'classes"': 0.16; 'complains': 0.16; 'disc': 0.16; 'doing,': 0.16; 'false:': 0.16; 'function?': 0.16; 'main():': 0.16; 'naming': 0.16; 'programmer,': 0.16; 'readable': 0.16; 'received:io': 0.16; 'received:psf.io': 0.16; 's[1:]': 0.16; 'scientist': 0.16; 'underscores': 0.16; 'unicode)': 0.16; 'uppercase': 0.16; 'why,': 0.16; 'wrote:': 0.16; 'case.': 0.18; 'try:': 0.18; 'all,': 0.20; 'cc:2**0': 0.20; 'cc:addr:python.org': 0.20; 'java': 0.22; '2.x': 0.22; 'code,': 0.23; 'this:': 0.23; 'import': 0.24; 'header:In-Reply-To:1': 0.24; 'wondering': 0.25; 'script': 0.25; 'example': 0.26; 'checking': 0.27; 'fri,': 0.27; 'message-id:@mail.gmail.com': 0.27; 'correct': 0.28; 'function': 0.28; 'idea': 0.28; 'values': 0.28; 'figured': 0.29; 'code:': 0.29; 'raise': 0.29; "i'm": 0.30; 'print': 0.30; 'url:mailman': 0.30; 'code': 0.30; 'version,': 0.30; 'probably': 0.31; 'skip:s 30': 0.31; 'post': 0.31; 'especially': 0.32; 'up.': 0.32; 'posting': 0.32; 'maybe': 0.33; 'run': 0.33; 'useful': 0.33; 'url:python': 0.33; 'done,': 0.33; 'url:listinfo': 0.34; 'changing': 0.34; 'except': 0.34; 'received:google.com': 0.35; 'could': 0.35; 'c++': 0.35; 'skip:e 40': 0.35; 'something': 0.35; 'but': 0.36; 'too': 0.36; 'should': 0.36; 'needed': 0.36; 'there': 0.36; 'url:org': 0.36; 'lines': 0.36; 'received:209.85': 0.36; 'subject:?': 0.36; 'pm,': 0.36; 'subject:: ': 0.37; 'really': 0.37; 'wanted': 0.37; 'things': 0.38; 'doing': 0.38; 'version': 0.38; 'received:209': 0.38; 'stuff': 0.38; 'wrong': 0.38; 'skip:o 20': 0.38; 'more': 0.63; 'sample': 0.63; 'information': 0.63; 'between': 0.65; 'better.': 0.66; 'here': 0.66; 'eyes': 0.70; 'url:info': 0.71; 'book,': 0.72; 'useful.': 0.72; 'subject: & ': 0.74; '250': 0.76; 'online,': 0.83; 'done:': 0.84; 'liking': 0.84; 'vba': 0.84; 'do:': 0.91; 'joel': 0.91; 'shocked': 0.91 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=3qway2HOpbptvgJoiTHRuvnXjfdD5IbiTX4Ncbzqj8Y=; b=OOKpRXcpT3lZYpAUU6DWreMJa+k5c/m49qNG1dlBIQC5pby4BQsa1PQChN8OIjF5C3 h48C5WhT5qEHkzVm7f/GPu53GzQBycAwhDCc+Legn5PztajYFkDj6STfPtr286M6RNn5 t0c91aanJguW/OGeZ6jF2qhpTR+97lqNt5j6vKeAkdwXay3N4s92ziAghsEIC0kU/5B4 1v+Yvl4SrpzyZSIHcF7SBvpWX+SX5VnQEcZtrzCrlZ+KYR6TF95vg3iorUlAGRMX4er7 9qCqc7LdpdJvWPBBpKovhMildwufAWCmzZ+lMNssxE0YDFYbiNL4+dI1maYontPOYN0u nPpw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=3qway2HOpbptvgJoiTHRuvnXjfdD5IbiTX4Ncbzqj8Y=; b=PCgMZp3U7vDC26HT7UZnqttrAjaIdPJ6sRx+dQMfiEN2Da4w+m//lza1sX96bhlY0U V8j0PuGzBwPotMoulNRMzNLYSG4SdGqbLYemequ7TLanaIgjCCuEbWWOlhCS3YBjrFDM tt4GhXWHkJXK9Hlf0H7HQUkIvdKKof5zQbfIJ/+o6uN2DxbaOkCWEY0mhbjVqDjiy6RC L+1jxVmBrOlTU+lb83Lfbw4vrGLmSEQF3W2zi4nl476qvlwolA6+/UYshcpebOvY1DQm uYEa4ldixT7xlUTrIW+ghY/4pmxuP+DPTJlVwMFOAvO9sFS0UEd5NutesMUghcRHLbTx IlWw== X-Gm-Message-State: ALyK8tK5nBt0CletR76UA520RmK//oUi6PBQQRtbTiC4lNrzcvQHpuWKp/IGFqiVFD4feKVa3lxPA7gtc6pXFg== X-Received: by 10.157.20.221 with SMTP id r29mr2941680otr.42.1465606951618; Fri, 10 Jun 2016 18:02:31 -0700 (PDT) In-Reply-To: X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Mailman-Original-Message-ID: X-Mailman-Original-References: Xref: csiph.com comp.lang.python:109809 On Fri, Jun 10, 2016 at 6:52 PM, mad scientist jr wrote: > Is this group appropriate for that kind of thing? > (If not sorry for posting this here.) > > So I wanted to start learning Python, and there is soooo much information= online, which is a little overwhelming. I really learn best from doing, es= pecially if it's something actually useful. I needed to create a bunch of e= mpty folders, so I figured it was a good exercise to start learning Python. > Now that it's done, I am wondering what kind of things I could do better. > Here is the code: > > # WELCOME TO MY FIRST PYTHON SCRIPT! > # FIRST OF ALL, IT ***WORKS***!!! YAY! > # I AM A VBA AND JAVASCRIPT PROGRAMMER, > # SO IT IS PROBABLY NOT VERY "PYTHONIC", > # SO PLEASE FEEL FREE TO TEAR THE SCRIPT A NEW ONE > # AFTER YOU ARE SHOCKED BY THIS BAD CODE, > # ALL I ASK IS THAT IF YOU THINK SOMETHING IS BAD, > # PLEASE POST AN EXAMPLE OF THE "CORRECT" WAY OF DOING IT > # COMING FROM VBA, I KNOW A LITTLE OOP, > # BUT NOT C++ C# JAVA STUFF LIKE "INTERFACES" AND "ABSTRACT BASE CLASSES" > # SO IF YOU GET INTO SUCH TERMINOLOGY MY EYES MIGHT START TO GLAZE OVER > # UNLESS YOU CARE TO EXPLAIN THAT TOO > > Ditch the uppercase comments. ##########################################################################= ###########################################################################= ####### > # GLOBAL VALUES > sForPythonVersion=3D"3" > #sFolderPathTemplate =3D "c:\\myscripts\\MP3 Disc " > sFolderPathTemplate =3D "c:\\temp\\MP3 Disc " > iFromCount =3D 1 > iToCount =3D 250 > iCountWidth =3D 3 > Python has guidelines for naming things. Don't use camel case. Use lower case and put underscores between words. Globals are a bad idea. If you don't know why, they are even a worse idea > #########################################################################= ###########################################################################= ############ > # SUPPORT FUNCTIONS > > # ///////////////////////////////////////////////////////////////////////= ///////////////////////////////////////////////////////////////////////////= //////////// > def is_string(myVar): # is_string IS MORE READABLE THAN isinstance (PLAIN= ENGLISH!) > #PYTHON 3 IS NOT LIKING THIS: return ( isinstance(myVar, str) or isin= stance(myVar, unicode) ) > #PYTHON 3 IS NOT LIKING THIS: return isinstance(myVar, basestr) > return isinstance(myVar, str) I'm not sure why you want to test for type. > > # ///////////////////////////////////////////////////////////////////////= ///////////////////////////////////////////////////////////////////////////= //////////// > # THIS IS SOME SAMPLE FUNCTION FROM A BOOK I AM READING "PYTHON IN EASY S= TEPS" > def strip_one_space(s): > if s.endswith(" "): s =3D s[:-1] > if s.startswith(" "): s =3D s[1:] > return s This may be from some book, but it could be done: s.strip() > > # ///////////////////////////////////////////////////////////////////////= ///////////////////////////////////////////////////////////////////////////= //////////// > def get_exact_python_version(): > import sys > sVersion =3D ".".join(map(str, sys.version_info[:3])) > sVersion =3D sVersion.strip() > return sVersion > > # ///////////////////////////////////////////////////////////////////////= ///////////////////////////////////////////////////////////////////////////= //////////// > # TO DO: RETURN TO THE LEFT OF FIRST "." > def get_python_version(): > sVersion =3D get_exact_python_version() > return sVersion[0:1] > > # ///////////////////////////////////////////////////////////////////////= ///////////////////////////////////////////////////////////////////////////= //////////// > # CHECK PYTHON VERSION, IF IT'S WRONG THEN GRACEFULLY EXIT BEFORE IT BLOW= S UP > # (DAMN, PYTHON 2.x STILL COMPLAINS WITH SYNTAX ERRORS!!) > # MAYBE THIS COULD STILL BE USEFUL FOR CHECKING THE SUB-VERSION, IN THAT = CASE > # TO DO: MORE GRANULAR CHECK, EG IF VERSION >=3D 3.5.0 > def exit_if_wrong_python_version(sRightVersion): > import os > sCurrentVersion =3D get_python_version() > if (sCurrentVersion !=3D sRightVersion): > print("" + > "Wrong Python version (" + > sCurrentVersion + > "), this script should be run using Python " + > sRightVersion + > ".x. Exiting..." > ) > os._exit(0) > > # ///////////////////////////////////////////////////////////////////////= ///////////////////////////////////////////////////////////////////////////= //////////// > def get_script_filename(): > import os > return os.path.basename(__file__) > > # ///////////////////////////////////////////////////////////////////////= ///////////////////////////////////////////////////////////////////////////= //////////// > def get_timestamp(): > import datetime > return datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d = %H:%M:%S') > > # ///////////////////////////////////////////////////////////////////////= ///////////////////////////////////////////////////////////////////////////= //////////// > > def create_folder(sPath): > import os > import errno > #if not os.path.exists(directory): > # os.makedirs(directory) > try: > os.makedirs(sPath, exist_ok=3DTrue) > except OSError as exception: > #if exception.errno !=3D errno.EEXIST: > print("ERROR #" + str(exception.errno) + "IN makedirs") > raise > > # ///////////////////////////////////////////////////////////////////////= ///////////////////////////////////////////////////////////////////////////= //////////// > > def create_folders(sFolderPathTemplate:str=3D"", iFromCount:int=3D1, iToC= ount:int=3D0, iCountWidth:int=3D0): > # MAKE SURE TEMPLATE'S A STRING. OH, IS THIS NOT "PYTHONIC"? WELL IT'= S MORE READABLE > if is_string(sFolderPathTemplate) =3D=3D False: > iFromCount =3D 1; iToCount =3D 0; > > sName =3D "" > sCount =3D "" > iLoop =3D iFromCount > while (iLoop <=3D iToCount) and (len(sFolderPathTemplate) > 0): > sCount =3D "{0}".format(iLoop) > if (iCountWidth > 0): > sCount =3D sCount.zfill(iCountWidth) > sName =3D sFolderPathTemplate.replace("", sCount) > create_folder(sName) > iLoop =3D iLoop + 1 > > #########################################################################= ###########################################################################= ######## > # MAIN LOGIC > > def main(): > # -------------------------------------------------------------------= ---------------------------------------------------------------------------= ------------------ > # MAKE SURE PYTHON VERSION IS CORRECT > exit_if_wrong_python_version(sForPythonVersion) > print("PYTHON VERSION (" + get_exact_python_version() + ") MATCHES RE= QUIRED VERSION (" + sForPythonVersion + ")") > #print("get_python_version returns \"" + get_python_version() = + "\"") > #print("get_exact_python_version returns \"" + get_exact_python_versi= on() + "\"") > > # -------------------------------------------------------------------= ---------------------------------------------------------------------------= ------------------ > # PRINT START TIMESTAMP > print("" + get_timestamp() + " " + get_script_filename() + " STARTED.= ") > > # -------------------------------------------------------------------= ---------------------------------------------------------------------------= ------------------ > # DO WHAT WE CAME TO DO > # IT'S PROBABLY BAD FORM TO REFERENCE GLOBAL VARIABLES INSIDE THE SCO= PE OF A FUNCTION? > # BUT I WANT TO MAKE IT EASY TO CONFIGURE THE SCRIPT JUST BY CHANGING= A COUPLE OF LINES > # AT THE TOP, WITHOUT HAVING TO SEARCH THROUGH THE CODE > create_folders( > sFolderPathTemplate, > iFromCount, > iToCount, > iCountWidth) > > # -------------------------------------------------------------------= ---------------------------------------------------------------------------= ------------------ > # NOW FINISH > print("" + get_timestamp() + " " + get_script_filename() + " FINISHED= .") > #import os > #os._exit(0) > > #########################################################################= ###########################################################################= ######## > > main() > -- > https://mail.python.org/mailman/listinfo/python-list I gave up. I'm happy you want to learn python, and have such enthusiasm, but you should practice some more --=20 Joel Goldstick http://joelgoldstick.com/blog http://cc-baseballstats.info/stats/birthdays