BustACode 15 Light Poster

First off, ignore my non-PEP-8 compliant coding, and just change them as needed.

I left your code intact up to and including line 13,
total_value = get_total(pennies, nickels, dimes, quarters)

I eliminated your get dollars and getcents functions, as you can get those with one short line using divmod. divmod gives you both the quotient and modulus (remainder) of the desired division. I recommend you study up on modulus and quotient, as they are very handy, and oft used. So oft used that Python introduced the combo keyword divmod.

I then switched out your last print lines to the new future compatible format.
{:,.2f} is to use comma separators and 2 significants after the decimal. {:,} is just use comma separators. See this link for more info on formatting:
https://www.daniweb.com/software-development/python/code/492854/another-visit-to-string-formatting-python

    pennies = int(input("Enter pennies:"))
    nickels = int(input("Enter nickels:"))
    dimes = int(input("Enter dimes:"))
    quarters = int(input("Enter quarters:"))

    print("You entered:")
    print("\tPennies:" , pennies)
    print("\tNickels:" , nickels)
    print("\tDimes:" , dimes)
    print("\tQuarters:" , quarters)
    total_value = get_total(pennies, nickels, dimes, quarters)

    v_Dollars, v_Cents = divmod(total_value, 1)

    print("Total = ${:,.2f}".format(total_value))
    print("You have {:,} dollar(s) and {:.2f} cent(s)".format(int(v_Dollars), v_Cents))

def get_total(pennies, nickels, dimes, quarters):
    pennies = (.01 * pennies);
    nickels = (.05 * nickels);
    dimes = (.10 * dimes);
    quarters = (.25 * quarters);
    total_value = pennies + nickels + dimes + quarters
    return total_value
BustACode 15 Light Poster

I had the same problem as you when I eliminated the semicolons--The object kept moving wildly around.

Turns out that one must be judicious in removing the semicolons on line 23, as the result may not--mine didn't--indent properly.

Once I preserved the proper indentation, all was well.

BustACode 15 Light Poster

I think the redesign of the site is a disaster.

I thought that the first moringing it was up, and still do. Seems it was designed by someone that does not know, and/or understand the Web desing mantra of "Don't make them think." Site navigation here has sort of become like navigating the "The Cube" ('97).

There is still a lot of community and well meaning people here, but they are lost behind a wall of confusion.

Just my 2 cents--worth a dollar in 1913.

BustACode 15 Light Poster

Also, to get the "Cancel" button in the dialog to work insert between lines 70 and 71 this:

elif result == None:
    to_exit()
BustACode 15 Light Poster

Great stuff thanks. I'm running 2.7

I had to change quit() on line 54 to:

    root.destroy()
    sys.exit()

Otherwise my run of it would hang on cancel.

Also in 2.7, I had to change some of the imports, and line 72, because several Tkinter modules have been change in 3.+ from 2.7 as follows:

2.73.+
Tkinter → tkinter
tkMessageBox → tkinter.messagebox
tkColorChooser → tkinter.colorchooser
tkFileDialog → tkinter.filedialog
tkCommonDialog → tkinter.commondialog
tkSimpleDialog → tkinter.simpledialog
tkFont → tkinter.font
Tkdnd → tkinter.dnd
ScrolledText → tkinter.scrolledtext
Tix → tkinter.tix
ttk → tkinter.ttk
Ref: https://stackoverflow.com/questions/673174/file-dialogs-of-tkinter-in-python-3

So if the reader is not running 3.+, make the appropriate changes from the above list, and all should be good to go.

ddanbe commented: helpful +15
BustACode 15 Light Poster

You can do it with images as well:

    from Tkinter import *
    root=Tk()
    c=Button(root,justify = LEFT, command = lambda: c.config(text="False", image = io_LEDRedOff) if c.config('text')[-1] == 'True' else c.config(text="True", image = io_LEDRedOn))
    io_LEDRedOn=PhotoImage(file="LED-Red-On.gif")
    io_LEDRedOff=PhotoImage(file="LED-Red-Off.gif")
    c.config(text = "False", image=io_LEDRedOff, width="15",height="15")
    c.pack(side=RIGHT)

    root.mainloop()

NOTE: Images in code are here: http://i.imgur.com/uMzb0g9.gif
http://i.imgur.com/bFo9AtY.gif

BustACode 15 Light Poster

This can be accomplised in one line using "lambda" and a one line "if/else" statement:

t_btn = tk.Button(root, text="True", width=12, command = lambda: t_btn.config(text="False") if t_btn.config('text')[-1] == 'True' else t_btn.config(text="True"))

BustACode 15 Light Poster

I found that one can use dictionaries to hold Tkinter widget config and display parameters. This then permits one to have these dictionaries elsewhere in the code for easy modification instead of buried within the code for each widget.

I particularly like to place these dictionaries toward the top of my Tkinter code for easy access and modification. I no longer have to search through a long display of widget code, and then over to the pertinent parameter to modify what I need. I now just find the pertinent dictionary in the area of focus--congfig. or display--and modify it. "Easy peasy."

I included a working example.

So now you know; You can use dictionaries to set parameters in Tkinter widgets.

BustACode 15 Light Poster

I have been learning NumPy arrays/matrices in Python.

As I worked, I found that I desired a more readable form of 3d matrices. So I figured that writing one would be a good goal and learning exercise. The goal was to create a function that would print 3d NumPy matrices out in a more readable 'tower' form, but without altering the original matrix or duplicating it . I accomplished the goal, and learned much about NumPy, and output formatting.

If you too desire to have 3d matrices displayed in a more readable form, then this should do the trick.

Enjoy.

Note: Yes, I am not PEP-8 compliant. The code rows are longer than 80 chars. with the comments. Please adjust/modify as needed.

BustACode 15 Light Poster

Note: In Python 2.7 use: from __future__ import print_function to use examples.

In Python, by default, the key and value pairs in a dictionary are stored as hashes, therefore dictionaries do not retain the order in which values were added, and cannot be ordered.

v_Dict ={}
v_Dict["First"] = 99
v_Dict["Second"] = 45
v_Dict["Third"] = 234
print(v_Dict) ## {'Second': 45, 'Third': 234, 'First': 99}

No order at all.

To maintain an ordered dictionary one must use the collection module's "OrderedDict()."
Normally one would declare a dictionary to be ordered like so:

from collections import OrderedDict
v_Dict = OrderedDict()
v_Dict["First"] = 99
v_Dict["Second"] = 45
v_Dict["Third"] = 234
print(v_Dict) ## OrderedDict([('First', 99), ('Second', 45), ('Third', 234)])

An OrderedDict() maintains the order pairs were added.

However, from time to time I find that OrderedDict() is not up to the task. Like here with zip:

from collections import OrderedDict
d_Dict = OrderedDict()
v_Keys = [45, 50, 20]
v_Values = [3.0, 5.0, 2.0]
d_Dict = dict(zip(v_Keys, v_Values))
print(d_Dict) ## {50: 5.0, 20: 2.0, 45: 3.0}

Order is lost again.

To get order back, one must sort the dictionary on the pairs from within OrderedDict(). Like so:

from collections import OrderedDict
v_Keys = [45, 50, 20]
v_Values = [3.0, 5.0, 2.0]
d_Dict = dict(zip(v_Keys, v_Values))
d_Dict = OrderedDict(sorted(d_Dict.items()))
print(d_Dict) ## OrderedDict([(20, 2.0), (45, 3.0), (50, 5.0)])

Order is restored.

I hope someone finds this beneficial.

BustACode 15 Light Poster

By the way, you can split on more than one entry pattern to allow for mistakes by the user. I do this for my factoring program, as I always seemed to enter the wrong pattern, and so just found how to except them all.

nums = input("Please enter different numbers seperated by comma, star, or space: ").replace("*", ",").replace(" ", ",").split(',')

replace does that for each spacer type, putting in a comma for each. Then split does away with the commas. You can add, or subtract "replace" statements as needed.

BustACode 15 Light Poster

Use an initialized list variable, ListTotal = [] then use append in your loop: ListTotal.append(int(i)) to put each newly converted int number in the list.

Instead of running another loop to sum things, do it as you go with another initialized variable: v_Sum = 0 and then after the list append do this: v_Sum = v_Sum + int(i)

You can then forgo the other function/loop.

The the resulting code could then be packed into a function if needed.

I hope this helped.

BustACode 15 Light Poster

Coincidentally how to do a multi-input was rattling around my head for the past two weeks. Tonight, I click on turtorials for S & G, and bam!, there's the answer.

Thanks.

BustACode 15 Light Poster

Needed a func to convert base 2 into 10, and back. Found the referenced code in this func for moving between three bases, and generalized it to between bases 2 and 62, and all in between.

Upconvert a number, then down convert, then upconvert again. Go wild, have fun.

BustACode 15 Light Poster

I, and many others, desired a "switch" keyword in Python. For me it was to a desire to make some of my code more compact and readable, as I often have many user selected options for the code to weed through. So I set off on a journey to figure out how to create a "switch" like statement. When I returned home, I was much enlightened and more thoroughly up to speed with Python. Great journey.

What I settled on was a simple dictionary setup that returns strings that are then immediately evaluated/run with the "exec" keyword. Now "exec" can be dangerous, but my use here is within a closed "match or toss" setup. I.e. the user doesn't enter the code to be run in the "exec."

As you can see, the strings returned can contain multiple statements and expressions, and even call other functions. Just use "\n" between each statement or expression.

Enjoy.

BustACode 15 Light Poster

I know that you are still learning, but you may want to get into the habit of using more descriptive variables. Doing so will make your life much easier later when debugging or months from now when you are trying to figure out how something you wrote works. I know, cause it happened to me--"What the hell is "b," and where did "c" come from?"

As for functions, you should learn about, and how to use those as soon as possible. As you write your code, try to identify code that is repeated, and then move that code into a function. You will like it Sam I Am.

Good luck and happy coding.

BustACode 15 Light Poster

In my quest to learn more regarding programming in Python, I "dissect" a lot of other people's code.
While doing this, or writing my own code, I end up with 10's of debug print lines.

Things like this: if v_Debug == 1: print("DEBUG - ".format()) # DEBUG

If I decide to keep the code for future use, those debug lines must eventually be removed, and that's not very fun at all.

So I decided to use what I had learned about writing self-modding code and create a module that would read thru
the calling module and delete those lines, and then save the altered file.

The code is the whole importable module. To use it, import your module of it, then call f_RemoveDEBUGLines()
with your pattern. The default pattern is "DEBUG". It will read the calling module's file and delete ALL the lines
that have the matching pattern.

Make sure you have a BACKUP of the original file, as you cannot undo what it does.

Note: I only share these snippets as a way to pay forward what I have gained from so many others.
My hope is that some will find these snippets and know what can be done, and how, like I so often
have and still do from other's efforts and posts.

Feel free to modify to your liking.

Enjoy

BustACode 15 Light Poster

I needed a random color selector. I found one here. I rewrote it to make it more general purpose.
"f_GenRandomColor" is the picker. The output is in list form, which should make it suitable for most general applications.
"f_HTMLRandomColorChart" is just a way to create an HTML table to test the output from.

Thanks to the original author.

BustACode 15 Light Poster

When recursion won't do, then memoizaton will.

BustACode 15 Light Poster

Allows multiple entries using raw_input.

I often have to enter multiple items in my Python programs. I desired an easier way than using a loop(s). Today I discovered a way, and with a few mods made it happen.

BustACode 15 Light Poster

I just love generators in Python.

One of the cool things I found out from this site was that one could send in a value when calling on an active generator.

To do so one uses the send() method and a yield like so: "x = yield".

The send with a value will assign the sent value to the variable associated with the yield.

I used this once to iterate through my generator once with one set of values, and then later with a different set.

Cool stuff.

BustACode 15 Light Poster

Looks great, but having followed Micro$oft since the late 80s, I quiver at any mention of them and anything good, or that I love, in the same sentence. And I do love Python.

I have seen M$ buy or get involved with technologies or products only to see those technologies or products wither and die as a result. They are the "Red Horse" of technology.

Best thing that ever happened to open-source, especially Linux, was that M$ tried to kill it, and not "help" or "cooperate" with it.

Also, relying on any product by Micro$oft means also suffering biennial user interface changes that will boggle the mind, as any Office user will attest to--Menu, "ribbon" or whatever 2013's is?

Then there is the "little" matter of their fun with grenades EULs.

I will eat green eggs, and ham. In the rain, or even on a train. I will not eat Micro$oft green eggs, and ham. Not in the rain, or even on a train.

BustACode 15 Light Poster

Very nice. Thanks. I would, will, add a reciprocal key.

BustACode 15 Light Poster

Great stuff.
I went through it and saved it for future reference. Great cheat sheet.

Thanks

BustACode 15 Light Poster

What has helped me a lot is researching in areas of Python that I do not currently need. I didn't need to use generators, but I pushed to learn how to create and use them, and now I do use them. Also, while learning generators, I began to learn comprehensions (still haven't mastered them).

Then of course one should always be learning how to manipulate and present strings. Much of what I learned from learning string manipulation and presentation has helped me with Regular Expressions.

Learn Regular Expressions now, as it is painful to have to learn them under pressure when you are trying to complete a project.

BustACode 15 Light Poster

Also because of my work in number theory, I often need to have the root floor and root ceing of a number.

This is my function for computing those two numbers from a target number.

BustACode 15 Light Poster

As a result of my research in number theory I find that I often need to break a number down into its numerical parts while stepping through one divisor to another.

I call this process "break factoring," as I am just breaking a number down into parts, and not necessarily factoring it.
A "break factor" result has three columns of numbers: A multiplier (M), the quotient (Q), and the remainder (R). For each level of the results: (M * Q) + R = Number

This function returns the printed table.

Also not earth shattering, but hey, someone might want to use it.

BustACode 15 Light Poster

I do a lot of work in number theory, especially with factors.
I often need just the two middle factors from a very long factor list/result, so I created a function that takes a factor list and returns just the middle two, or one, factors.

Nothing earth shattering, but I use it a lot, and thought that I would share it.

And those with better ways to offer, offer away. I am always interested.

BustACode 15 Light Poster

One day I got to wondering if it was possible to get a Python script to modify itself. After a few searches I found this solution that I present here. I did not write this code, but feel that it should be "paid forward" so others know that it is possible, and how to accomplish it. Basically the script reads itself into a variable, then REs the timestamp line which is then replaces with a new one. Next the modified code is saved back down. I could actually see a genetic algo modding itself as it goes so that it writes an optimal version of itself at the end. Pretty cool.

import sys, os, importlib, inspect, locale, time, re, inspect, datetime
from datetime import datetime
locale.setlocale(locale.LC_ALL, '') # Set the locale for your system 'en_US.UTF-8'
    # Main #
def main():
        # Main Code
            # Print the time it is last run
    lastrun = 'Tue Mar  3 03:17:46 2015'
    print("This program was last run at: <<%s>>.") %(lastrun)

            # Read in the source code of itself
    srcfile = inspect.getsourcefile(sys.modules[__name__]) ## Gets module name and path then extracts and stores file name and path.
    print("DEBUG srcfile: %s") %(srcfile) # DEBUG
    f = open(srcfile, 'r') ## Open connections to source file in "r" mode and stores connection in "f".
    src = f.read() ## Reads source file code into "src" variable.
    f.close() ## Closes file connection.

            # modify the embedded timestamp
    timestamp = datetime.ctime(datetime.now())
    match = re.search("lastrun = '(.*)'", src)
    if match:
BustACode 15 Light Poster

@Gribouillis: That's cool. I may use that in the future, as one can just pop. a list and then dynamically print it out in multicolumns. Useful. Thanks.

BustACode 15 Light Poster

Instead of using letters as substitutes for playing card suits, I came up with a way to use unicodes to produce the common suits. The following creates the coded needed, makes the deck, and then prints the deck. The printing was the hard part. Is 2.7, and should be 3.0+ compat.

BustACode 15 Light Poster

Recently I started teaching teens programming. I use Python for them.

An adult approached me and asked if I would teach her. The problem is that she's in her 40s, and hasn't had to think logically or algorithmically since high school, if ever. Scratch/Snap is too basic, and Python, in my opinion, would be too advanced.

I decided to use Small Basic. Great choice, as it introduces things in a workable, but small-step format. I particularly liked how it teaches loops with "goto," and then loops later. Doing so shows how loops can be constructed from a "goto" routine. I.e. you can construct loops with "goto" and have the student see the mechanics of how loops work. Ditto subroutines.

Though Small Basic is not quite legacy, it does utilize Basic, and can be a good choice for those just starting out.

BustACode 15 Light Poster

For an IDE, I use PyScripter for my Python coding. Just the right mix of highlighting, etc. that I need for my rather basic programs/script. I like the ability to add keyboard shortcuts for code templates. So, as I learn how to do certain things, I add that code as a template and then invoke it as needed. Other IDEs have this, but PyScripter makes it easy to create and invoke.

As for learning, I used TutorialPoint's great site and info. Some of it is a little dated, but great foundation to build upon. Afterwards I moved to investing in books.

BustACode 15 Light Poster

Good stuff, and ideas. Thanks.

I am not a "spammer," but I do eat Spam. Does that make me a spammee?

BustACode 15 Light Poster

My code and funcs for printing to columns in 2.7 and 3.0+ using print(). I had to relearn column formatting as I moved to using the print() function, and so the follwing is a result. Inspired and partially copied from discussion on StackOverflow

def main():
        # Main Code
    v_Data = [['a', 'b', 'c'], ['a', 'b', 'c'], ['a', 'bbbbbbbbbbbbbbbbbbb', 'c'], ['k', 'k', 'l'], ['a', 'b', 'c']] ## Each bracketed item is a 'row', non-bracketed ithems are broken into seprate rows
    f_PrintToFixedColumns(v_Data)
    print()

    print("Var Cols")
    f_PrintToVarColumns(v_Data)


def f_PrintToFixedColumns(v_Data):
    """Syntax: (list); Returns: (print);
    Desc.: Takes a list and finds longest data item, then prints in columns
    formated to width of that max width.
    Test: f_PrintToColumns(v_Data) [See main for test data.]"""
    v_ColWidth = max(len(word) for row in v_Data for word in row) + 2  # paddingGet max length 'word' from 'word' per 'row'
    for j, row in enumerate(v_Data):
        print("".join(word.ljust(v_ColWidth) for word in row))

def f_PrintToVarColumns(v_Data):
    """Syntax: (list); Returns: (print);
    Desc.: Takes a list and prints each column to width of longest member.
    Test: f_PrintToVarColumns(v_Data) [See main for test data.]"""
    widths = [max(map(len, col)) for col in zip(*v_Data)]
    for row in v_Data:
        print("  ".join((val.ljust(width) for val, width in zip(row, widths))))
BustACode 15 Light Poster

Great stuff. I did't know that that capability was availble. Thanks.