Editing Russ Python Tips and Techniques

Jump to navigation Jump to search

Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.

Latest revision Your text
Line 1: Line 1:
 
= What =
 
= What =
 
These are Tips and Techniques I have found useful in my Python programming [[User:Russ_hensel]].  I would be interested in your feedback.  Let me know if you think the tip is useful/wrong/something everyone knows.  A good set of this material relates to applications with a GUI.  They are often not beginner techniques, but neither are they all advanced ones.
 
These are Tips and Techniques I have found useful in my Python programming [[User:Russ_hensel]].  I would be interested in your feedback.  Let me know if you think the tip is useful/wrong/something everyone knows.  A good set of this material relates to applications with a GUI.  They are often not beginner techniques, but neither are they all advanced ones.
Just starting Feb 2017 check history tab above to see if progress is being made.  If you find a tip not finished or working feel free to contact me.
+
Just starting Feb 2017 check history to see if progress is being made.  If you find a tip not finished or working feel free to contact me.
  
 
== Ones Still To Be Written ==
 
== Ones Still To Be Written ==
Line 7: Line 7:
 
* when division by 0 is useful
 
* when division by 0 is useful
 
* code is multiple files - scratch file
 
* code is multiple files - scratch file
 +
* msg, print( msg )
 
* moving to 3.6 use fstrings
 
* moving to 3.6 use fstrings
 
* example files with functions  [[Python Example Code]]
 
* example files with functions  [[Python Example Code]]
Line 12: Line 13:
 
* dict based case statements
 
* dict based case statements
 
* choose names for cut and paste
 
* choose names for cut and paste
 +
* saving your place in editor
 +
* spyder using comments for navigation
 
* mark your code with unusual string  * zzz in your code  
 
* mark your code with unusual string  * zzz in your code  
 +
* make your names searchable
  
  
=== Move these to a good place in the outline ===
 
  
==== Python Installation ====
+
[[Programming Tips]]
 
 
I have a separate page [[Category:Python Installation]] about installation an maintenance, the first part is of general interest, the second on particular issues I have encountered.  It may be useful to get some of my projects running [[Category:Python Projects]].
 
 
 
 
 
==== FStrings ====
 
 
 
 
 
FStrings are incredibly nice. New in 3.6, use it ( or 3.7.... ) They also are reputed to be really fast.  Use them.  At a later time I may have a bunch of examples, but for now just the basic statement:
 
 
 
<pre>
 
    joe  = "Joe Smith Jones Norton"
 
    msg  = f"Joe's name is actually {joe}"
 
    print( msg 0
 
</pre>
 
 
 
==== Comments for Navigation ====
 
 
 
Spyder has a nice feature for code navigation: the "Outline Tab".  This tab outlines the code nesting classes, methods.... and expands and contracts the tree much like the code folding show in the editor.  The outline tab works both to help you navigate to a place in the code, or to show you where in the code the cursor currently lies.  What is less obvious is that comments can also mark a section.  I have not found documentation for this but here is what I have found.  A comment like "# ------ frame building methods  --" will create an outline section whose indentation in the outline depends on indentation of the comment.  The space and the "-" characters are important.  Start by using exactly what is shown here, and experiment to see how much you can change it before it disappears from the outline.  I often use this to group a large number of similar methods that can then be folded out of view.
 
 
 
==== msg ====
 
 
 
A name I use over and over again for messages, often like:
 
 
 
<pre>
 
msg  = "this is a message"
 
print( msg )
 
</pre>
 
 
 
Why two lines instead of one?  Because I often change it to include logging or sending to the GUI.  It might then become:
 
 
 
<pre>
 
msg  = "this is a message"
 
print( msg )
 
AppGlobal.logger.debug( msg )
 
</pre>
 
 
 
I find this a nice way to manage code.
 
 
 
 
 
==== #rint ====
 
 
 
 
 
If you use print for debugging you may want to scan your code of "print" to remove unwanted statements.  I do not delete them because sometimes I want them again for more debugging.  I change "print" to "#rint"
 
to comment out the print but to stop it form showing up on searches.
 
 
 
 
 
==== Make Code Searchable ====
 
 
 
I like generic names to enable cut and paste but this runs against the idea of searchable code.  The idea is that unusual names are easy to search for.  It also helps if names are descriptive.  Why searchable? So you can find the code you want to work on.  One way to be both searchable and generic is to take instance references and make local ( or the reverse )  For example consider this tkinter code:
 
 
 
 
 
<pre>
 
        a_list    = list(self.sort_order_dict.keys())
 
        a_widget  =  ttk.Combobox( a_frame, values = a_list,  state='readonly')
 
        a_widget.grid( row = lrow + 1, column = lcol, rowspan = 1, columnspan = 3,  sticky = E + W + N + S )
 
        a_widget.set( a_list[0] )
 
        self.sort_order_widget = a_widget
 
        lcol  += 3
 
</pre>
 
 
 
The name a_widget is generic, but to see what it "really" is you have the none generic name "self.sort_order_widget"
 
 
 
If you do not see an easy way to do this with names use a comment.  Using zzzz.... is a short term way of doing this.
 
 
 
==== Dict Based Case Statements ====
 
 
 
 
 
Python does not have a case statement, but it does have if....elif which can be used and is only a little more verbose.  However if you have more than a few cases it can be cumbersome.  Using a dict gives a very compact and fast case statement.  Suppose you want to have a case statement based on strings:
 
 
 
 
 
<pre>
 
    # set up, ideally only done onece, perhaps at module or class level
 
    dispatch_dict  = { "one":    print_one,
 
                        "two":    print_two,
 
                        "three":  print_three,
 
                        }
 
 
 
    # set a case for an example call:
 
    key = "two"
 
 
 
    # the slightly verbose case statement
 
    function      = dispatch_dict[ key ]
 
    function()
 
</pre>
 
  
 
= Parameters for Applications =
 
= Parameters for Applications =
Line 163: Line 82:
 
= Names =
 
= Names =
  
I have heard it said that proper naming is the hardest problem in programming.  Not sure if true, but it is not easy.  So here is my take:
 
 
* Of course be consistent.  It may help to make a vocabulary list of the terms you prefer.  I have found that the values often come in pairs:
 
 
  start_date / stop_date  or low_temp / high_temp ( or hi_temp ) or start_date / end_date
 
  then some style are:
 
  date_start / date_stop
 
 
Note that the stop_date and end_date is an easy place for confusion.  So decide on your style and stick to it.
 
 
* Do not be afraid of long names but consistent abbreviations are fine ( keep a list ).
 
* I generally think that methods should be named with verb like names: os_open_file.
 
* I find that people use the name '''file''' for both the '''file name''' ( often string like ) and for the '''file handle''' ( the thing you get when you open a file ), so my variables for file names are like:
 
 
  input_file_name ( sometimes input_fn )
 
 
 
* Lists and other iteratables often get a name to indicate that: so a list of names might be called something like student_names
 
 
* Sometimes generic names are preferable especially if there scope is just a few lines.  I am willing to iterate over a list of numbers with i, but I prefer ix and even then I fell lazy.  If I have a list of names as above I might itterate with the singular, but usually i prefix it with i_ so:
 
 
    for i_name in student_names
 
        print( i_name )
 
  
 
= Comments =
 
= Comments =
Line 206: Line 102:
  
 
= Copy and Paste =
 
= Copy and Paste =
some content may move to [[Copy and Paste Is Good]] or not
 
 
  
 
There are lots of arguments against copy and paste, but used carefully I think that it is extremely useful.  But used carefully.
 
There are lots of arguments against copy and paste, but used carefully I think that it is extremely useful.  But used carefully.
Line 221: Line 115:
 
** I own the results, if it does not work properly I am to blame
 
** I own the results, if it does not work properly I am to blame
 
** I write code in a generic way to make it easy to copy and paste.
 
** I write code in a generic way to make it easy to copy and paste.
 
* Refactoring:
 
** Of course when I refactor I use copy and paste, because basically your are just rearranging code you already have that works.
 
** Many people use git to make sure they do not loose stuff in translation.  I just use file copies, I have my own methods
 
** Sleep that is zzzzzzz: I put zzzz or similar around the place where I am making changes.  It throws a quick syntax method if I foolishly try to run the code and is easy to find as zzzz is not anything I would normally use in code.  Sometimes I copy a lot of junk in between a pair of zzz so I have all the names I need in easy view.  Then I do the new code, remove the junk and finally the pair of zzzz'a.
 
  
 
* Other peoples code:
 
* Other peoples code:

Please note that all contributions to OpenCircuits may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see OpenCircuits:Copyrights for details). Do not submit copyrighted work without permission!

Cancel Editing help (opens in new window)