SmartSet organizer - feedback?



  • Hi everyone!

    I just built my first "real" RoboFont-script: A little tool to activate or deactivate given SmartSets from an external folder. You can find the files and the sourcecode here: https://github.com/axani/RoboFont-SetOrganizer (The main file is SetOrganizer_basics.py)

    Since I´m quite new python-programming, I would appreciate some feedback (pitfalls, things I forgot etc.).

    There are still some issues I have to fix at the moment:

    • The activatet/deactivated SmartSets only get updated in the GUI of RoboFont when opening a new font window. If I understood Frederik correctly, there is no other way at the moment. Right?

    • I would like to show the SmartSet-query in a tooltip on checkbox-mouseover. Can you point me to a way to do that?

    • When a SmartSet in RoboFont is created, the SetOrganizer recognizes it. But when the name of a SmartSet contains letters outside the ASCII-range, RoboFont raises an UnicodeError. Is there a simple solution to fix this in my script?

    (Besides that: one main thing I don´t understand correctly yet, is when to use functions and when classes. But I think that´s a general programming question I need to learn.)

    Thanks for your great help so far!
    Philipp :-)



  • The way that your program is written right now, you could only be using functions. Classes are a way of creating objects that work as a kind of state machine. Usually they represent some kind of resource that your program has to work with and manipulate over the course of the script. What's helpful about classes is that they can store variables that are scoped to the class instance, and those variables can be accessible from other class functions.

    For instance, you currently have activateSet, deactivateSet, saveThisSet, and isExternal. All of these take a set as an argument and do something to it. That all of these functions manipulate the same resource is a good indication that it could be better expressed as a class.

    For example:

    class GlyphSet(object):
    
      def __init__(self, set):
        self.set = set
    
      def activate(self):
        addSmartSet(self.set)
        # ...
    
      def deactivate(self):
        # perform deactivation on self.set
    
      def save(self):
        # perform save on self.set
    
      def is_external(self):
        # check if self.set is 'external'
    
    for set in getSmartSets():
        glyph_set = GlyphSet(set)
        glyph_set.activate()
        if glyph_set.is_external():
          glyph_set.save()
        # etc...
    

    I'd recommend reading this chapter of Learn Python the Hard Way, which details how modules and classes work and what you can use them for: http://learnpythonthehardway.org/book/ex40.html

    As a general comment, your methods are pretty long. Breaking up your methods into logical chunks will help make it more readable and easier to maintain (since you can probably reuse them in other places).

    Frederik will have to help you with the other technical bits. :)



  • Hi Jack,

    thanks for your detailed answer! I will try to integrate your recommendation and report back next week. :-)