Iconphoto values

Looking at my code closely I found something I don’t know what it does. In line 'root.icon… It’s the ‘False’ that I’m curious about. I tested it with True and saw no difference. What does it do? If nothing why there? I know this is trivial, but got my attention, because everything we input should be aiding our code job.

import tkinter as tk
root = tk.Tk()

root.geometry("200x200")
root.iconphoto(False, tk.PhotoImage(file='C:\\Users\\Pc\\Desktop\\icon.png'))

root.mainloop()

Thanks. This sure is a great forum!! Real help!

By Leonard Dye via Discussions on Python.org at 15Sep2022 22:57:

Looking at my code closely I found something I don’t know what it does.
In line 'root.icon… It’s the ‘False’ that I’m curious about. I
tested it with True and saw no difference. What does it do? If nothing
why there? I know this is trivial, but got my attention, because
everything we input should be aiding our code job.

import tkinter as tk
root = tk.Tk()

root.geometry("200x200")
root.iconphoto(False, tk.PhotoImage(file='C:\\Users\\Pc\\Desktop\\icon.png'))

root.mainloop()

Did you know that you can ask methods and functions about themselves?
Observe:

 Python 3.10.6 (main, Aug 11 2022, 13:47:18) [Clang 12.0.0 (clang-1200.0.32.29)] on darwin
 Type "help", "copyright", "credits" or "license" for more information.
 >>> import tkinter as tk
 >>> root = tk.Tk()
 >>> help(root.iconphoto)
 Help on method wm_iconphoto in module tkinter:

 wm_iconphoto(default=False, *args) method of tkinter.Tk instance
     Sets the titlebar icon for this window based on the named photo
     images passed through args. If default is True, this is applied to
     all future created toplevels as well.

     The data in the images is taken as a snapshot at the time of
     invocation. If the images are later changed, this is not reflected
     to the titlebar icons. Multiple images are accepted to allow
     different images sizes to be provided. The window manager may scale
     provided icons to an appropriate size.

     On Windows, the images are packed into a Windows icon structure.
     This will override an icon specified to wm_iconbitmap, and vice
     versa.

     On X, the images are arranged into the _NET_WM_ICON X property,
     which most modern window managers support. An icon specified by
     wm_iconbitmap may exist simultaneously.

     On Macintosh, this currently does nothing.

So. this sets the window manager icon to the image you specify. If
default is true, this setting will apply for all future top level
windows as well so that you could do this once at the start of your app,
and have your preferred icon for all app windows without further work.

In this case default is set to False, so the icon setting only
applies to your root top level window, not any later ones you might
create.

Cheers,
Cameron Simpson cs@cskk.id.au

1 Like

No, I did not know that. But it solves a lot of problems, I have been having. I enjoy working things out and understanding what I’m doing. You have given me another tool rich in information.
Thanks again for your patience and knowledge.

By Leonard Dye via Discussions on Python.org at 16Sep2022 00:40:

No, I did not know that. But it solves a lot of problems, I have been
having. I enjoy working things out and understanding what I’m doing.
You have given me another tool rich in information.

Those docs do depend on some diligence on the part of whoever wrote the
library you’re using. The help() builtin function looks are the
“docstring” of whatever object you’ve given it. You can provide that
when you define a class or function: if the first expression of the
class or function body is a constant string it gets saved saved as the
“docstring”. Example:

 def square(x):
     ''' Return the square of the value in x.
     '''
     return x * x

That saves the string “Return the square of the value in x.” as the
function docstring, which help(square) would print. By using triple
quotes (''') you can write a multiline docstring if you desire.

You can also get at this string directly (that’s all help() is doing):

 print("The docstring is", square.__doc__)

Cheers,
Cameron Simpson cs@cskk.id.au

1 Like

That explains why we make sure that we use doc strings with classes. It needs to be more than just a single line. If we have variables in the class they need to be noted. Then it can be looked at by help() and know what variables are available as arguments. That makes the doc string as important as the comments which serve as clarifacation of why something is done. Doc string are not restating the comments as I had thought.

AS a side note, I’m starting to look at classes. I still have a lot to learn. :slight_smile: But Python is starting to make sense, it is a beautiful language.

1 Like

I found this example of ‘docstrings’. This means that our code is to end up being more verbose than the code itself. Why is this, if Python is written Pythonic style, it’s good pseudocode on it’s own. Just seems like over kill, since most of the Python code I have seen have little or no docstrings. Is this how it is really to be done in the real world? I’m looking for a correct concept for my standard for programming. Are docstrings put in at the end when the code has been tested and works?
Thanks again.

class Animal:
    """
    A class used to represent an Animal

    ...

    Attributes
    ----------
    says_str : str
        a formatted string to print out what the animal says
    name : str
        the name of the animal
    sound : str
        the sound that the animal makes
    num_legs : int
        the number of legs the animal has (default 4)

    Methods
    -------
    says(sound=None)
        Prints the animals name and what sound it makes
    """

    says_str = "A {name} says {sound}"

    def __init__(self, name, sound, num_legs=4):
        """
        Parameters
        ----------
        name : str
            The name of the animal
        sound : str
            The sound the animal makes
        num_legs : int, optional
            The number of legs the animal (default is 4)
        """

        self.name = name
        self.sound = sound
        self.num_legs = num_legs

    def says(self, sound=None):
        """Prints what the animals name is and what sound it makes.

        If the argument `sound` isn't passed in, the default Animal
        sound is used.

        Parameters
        ----------
        sound : str, optional
            The sound the animal makes (default is None)

        Raises
        ------
        NotImplementedError
            If no sound is set for the animal or passed in as a
            parameter.
        """

        if self.sound is None and sound is None:
            raise NotImplementedError("Silent Animals are not supported!")

        out_sound = self.sound if sound is None else sound
        print(self.says_str.format(name=self.name, sound=out_sound))

By Leonard Dye via Discussions on Python.org at 16Sep2022 23:33:

I found this example of ‘docstrings’. This means that our code is to
end up being more verbose than the code itself. Why is this, if Python
is written Pythonic style, it’s good pseudocode on it’s own.

Well, if one follows the precepts of Literate Programming, that can be a
good thing: Literate programming - Wikipedia

Anyway, what you’ve got below is pretty wordy. I’ll show what I would
write by comparison. Remembering that this is a matter of taste and
inclination in some degree.

There’s a section in the Python docs about docstrings too:
https://docs.python.org/3/tutorial/controlflow.html#tut-docstrings

Just seems like over kill, since most of the Python code I have seen
have little or no docstrings. Is this how it is really to be done in
the real world? I’m looking for a correct concept for my standard for
programming. Are docstrings put in at the end when the code has been
tested and works?

A docstring should help the user use the code, telling them what
parameters it accepts and their meaning, and what the outcomes are. If
pertinent, some discussion about limitations or bugs. For a lot of small
things, little is needed.

But the code is how the function implements things. (a) the
docstring should help someone who doesn’t have ready access to the code,
or if the code is difficult and (b) the docstring should describe what
the user can expect of the code in terms of outcomes. How that’s done
internally isn’t relevant. And of course the implementation might
change.

Docstrings, like opening comments (they often displace opening comments
either fully or partially), are often, perhaps preferably, written
before the code is written, if the code is nontrivial. FOr myself,
writing a docstring for a tricky function helps me get clear in my mind
what has to be done. If I can’t write a docstring, the precise operation
of the function is often unclear.

If I’m in prototype mode, where I know what I’m trying to solve but
still mucking around with how I’m going to solve it, I’d likely write a
1 line docstring, if any, until the function is stable.

And for genuinely trivial stuff I write the docstring later, often. My
linters whinge about missing docstrings :slight_smile:

Let’s look at your example. I like MarkDown myself:
https://daringfireball.net/projects/markdown/syntax
It is pretty succinct, and it’s also the markup we use on the Discourse
forums :slight_smile: I tend to use GitHub flavoured MarkDown, when the dialect
matters: GitHub Flavored Markdown Spec

So, to your example:

class Animal:
“”"
A class used to represent an Animal

Attributes

says_str : str
a formatted string to print out what the animal says
name : str
the name of the animal
sound : str
the sound that the animal makes
num_legs : int
the number of legs the animal has (default 4)

Happy days. What the class is for, what public attributes it provides.
I’d write this in markdown like this:

 class Animal:
     ''' A class used to represent an Animal.

         Attributess:
         * `says_str`: a formatted string to print out what the animal says
         * `name`: the name of the animal
         * `sound`: the sound that the animal makes
         * `num_legs`: the number of legs the animal has, default `4`
     '''

Methods

says(sound=None)
Prints the animals name and what sound it makes
“”"

I’d omit this entirely because each method will also have its own
docstring. But the leading section might have explainatory text or
examples if the class has significant complexity.

def init(self, name, sound, num_legs=4):
“”"
Parameters
----------
name : str
The name of the animal
sound : str
The sound the animal makes
num_legs : int, optional
The number of legs the animal (default is 4)
“”"

Again, I’d write:

 def __init__(self, name, sound, num_legs=4):
     ''' Initialise the `Animal`.

         Parameters:
         * `name`: the name of the animal
         * `sound`: the sound the animal makes
         * `num_legs`: optional `int`, default `4`: the number of legs the animal
     '''

Their says() docstring:

def says(self, sound=None):
“”"Prints what the animals name is and what sound it makes.

   If the argument `sound` isn't passed in, the default Animal
   sound is used.

   Parameters
   ----------
   sound : str, optional
       The sound the animal makes (default is None)

   Raises
   ------
   NotImplementedError
       If no sound is set for the animal or passed in as a
       parameter.
   """

I’d write:

 def says(self, sound=None):
     ''' Print what the animal's name is and what sound it makes.

         Parameters:
         * `sound`: optional `str`, default `None`:
           the sound the animal makes

         If `sound` is provided and no sound is set for the animal 
         this method will raise `NotImplementedError`.
     '''

You don’t even need to have a separate section for the parameters; I do
it when there’s more than a few. If I can put the relevant detail in the
opening sentence/paragraph, no need for something distinct. Example:

 @typechecked
 def deduce_type_bigendianness(typecode: str) -> bool:
   ''' Deduce the native endianness for `typecode`,
       an array/struct typecode character.
   '''

The type annotations (:str, ->bool) already describe the types of
the parameters and the return, and the function does something very
simple.

Here’s another function whose docstring embeds the parameters in the
opening sentence, but elaborates on the meaning of the unit parameter:

 def as_datetime64s(times, unit='s', utcoffset=0):
   ''' Return a Numpy array of `datetime64` values
       computed from an iterable of `int`/`float` UNIX timestamp values.

       The optional `unit` parameter (default `'s'`) may be one of:
       - `'s'`: seconds
       - `'ms'`: milliseconds
       - `'us'`: microseconds
       - `'ns'`: nanoseconds
       and represents the precision to preserve in the source time
       when converting to a `datetime64`.
       Less precision gives greater time range.
   '''

Now, the builtin help() Python function doesn’t do anything very
complicated with the docstrings, but it does bundle up the class
docstring with all the method docstrings. Example:

 >>> import cs.timeseries
 >>> help(cs.timeseries.TypeCode)
 Help on class TypeCode in module cs.timeseries:

 class TypeCode(builtins.str)
  >  TypeCode(t)
  >
  >  A valid `array` typecode with convenience methods.
  >
  >  Method resolution order:
  >      TypeCode
  >      builtins.str
  >      builtins.object
  >
  >  Methods defined here:
  >
  >  struct_format(self, bigendian)
  >      Return a `struct` format string for the supplied big endianness.
  >
  >  ----------------------------------------------------------------------
  >  Class methods defined here:
  >
  >  promote(t) from builtins.type
  >      Promote `t` to a `TypeCode`.

and so on.

And various documentation tools will gather all this stuff up for you. I
cobbled together something to produce README.md files for my modules
built from their docstrings. As a bonus, the README.md also gets
presented in PyPI.

So to continue the extended example with cs.timeseries:

It isn’t beautiful, but it is at least fairly effective. The
cs.timeseries module is fairly long, and a lot of the docstrings are
verbose to get things straight in my own head.

The smaller your code, the less verbosity you will usually need.

Cheers,
Cameron Simpson cs@cskk.id.au

1 Like

Just an additional example, from the same module. Here’s a range(start,stop) method whose implementation is 4 lines of code. But the docstring is huge, because it warrants discussion of limitations on how it can be used:

Some of that discussion was for my own reference so that i could remember how to use it reliably and how not to use it.

Cheers,
Cameron

Python docstrings should use RST (ReStructured Text) to better integrate with documentation generator tools like sphinx.

Which is fine, RST is great, except that inline code uses double backticks rather than single, which makes me sad :frowning:

There are also about thirty bazillion different, slightly incompatible, versions of Markdown :slight_smile: so as soon as you try to do something more complicated than bold or italic you run into trouble :frowning:

(Reddit is a good example of that. The subreddits… pages and the subreddits… pages use different styles of markdown.)

Aye. I find RST tedious and verbose. For long form documentation it is a good thing - arguably a great thing, with its rich support for links and references and roles etc. But for my own modules, no thanks.

If I get to making some RST docs, for example for readthedocs or for a large package, I probably will go with RST, and may well take the time to translate some RST from (still) markdown docstrings (probably in some targeted fashion). But those docs will likely reference the code docstrings rather than being derived from it.

As I mentioned, I lean to github flavoured markdown in terms of dialect.

I’m not a reddit person. I understand it to be a time sink of even greater menace than an unbounded wikipedia browse.

I’m of the opinion that having docstrings is very desirable, and RST gets in the way of my motivation, not to mention how… rich in vertical space it is, particularly for parameter lists. I’m for concise and low friction, which MarkDown gives me.

Cheers,
Cameron