Screenshot instructions:
Windows
Mac
Red Hat Linux
Ubuntu
Click URL instructions:
Right-click on ad, choose "Copy Link", then paste here →
(This may not be possible with some types of ads)
From: Brian Matherly <brian@gr...> - 2010-01-10 22:41:25
|
As part of GEP008, I'm trying to figure out what to do with the DateDisplay and NameDisplay classes. Here is my suggestion: 1) Create a new directory in gen called "display". This directory will be for code that facilitates the formatting of data for display (like DateDisplay and NameDisplay) Initially, we will have gen.display.date and gen.display.name. But I can imagine that eventually we will have displayers for other objects. I already know of some code in a random "utils" file somewhere that formats Places for display. That code could ultimately find a home in gen.display.place. 2) Create a DisplayerFactory class which can do the work of figuring out the right displayer to use. Right now, most code accesses the global BasicUtils.name_displayer and DateHandler.displayer objects. This is bad programming practice. With the new factories, you can call: gen.display.factory.get_displayer("Date") and the factory will make sure that you get the right displayer for the current locale and user preferences. Similarly, calling: gen.display.factory.get_displayer("Name") would return a NameDisplay object properly initialized to the current user settings. This way, the Displayer classes themselves would not depend on config and we could remove code like this: global WITH_GRAMP_CONFIG self.name_formats = {} self.set_name_format(self.STANDARD_FORMATS) if WITH_GRAMPS_CONFIG: self.default_format = config.get('preferences.name-format') if self.default_format == 0: self.default_format = Name.LNFN config.set('preferences.name-format', self.default_format) else: self.default_format = 1 I would appreciate you comments. If I can move forward with this scheme, I'll add it to the GEP008 wiki page. ~Brian |
From: Doug Blank <doug.blank@gm...> - 2010-01-11 02:03:25
Attachments:
Message as HTML
|
On Sun, Jan 10, 2010 at 5:41 PM, Brian Matherly <brian@...>wrote: > As part of GEP008, I'm trying to figure out what to do with the DateDisplay > and NameDisplay classes. > > Here is my suggestion: > > 1) Create a new directory in gen called "display". This directory will be > for code that facilitates the formatting of data for display (like > DateDisplay and NameDisplay) > > Initially, we will have gen.display.date and gen.display.name. But I can > imagine that eventually we will have displayers for other objects. I already > know of some code in a random "utils" file somewhere that formats Places for > display. That code could ultimately find a home in gen.display.place. > > 2) Create a DisplayerFactory class which can do the work of figuring out > the right displayer to use. Right now, most code accesses the global > BasicUtils.name_displayer and DateHandler.displayer objects. This is bad > programming practice. With the new factories, you can call: > gen.display.factory.get_displayer("Date") > and the factory will make sure that you get the right displayer for the > current locale and user preferences. > Similarly, calling: > gen.display.factory.get_displayer("Name") > would return a NameDisplay object properly initialized to the current user > settings. > This way, the Displayer classes themselves would not depend on config and > we could remove code like this: > global WITH_GRAMP_CONFIG > self.name_formats = {} > self.set_name_format(self.STANDARD_FORMATS) > > if WITH_GRAMPS_CONFIG: > self.default_format = config.get('preferences.name-format') > if self.default_format == 0: > self.default_format = Name.LNFN > config.set('preferences.name-format', self.default_format) > else: > self.default_format = 1 > > I would appreciate you comments. If I can move forward with this scheme, > I'll add it to the GEP008 wiki page. > > I don't really have an an opinion on where this code would go, but it seems that displaying a name or date should be as simple as: >>> str(person.get_primary_name()) "Surname, Givenname Middle" >>> str(person.get_birth_date()) "about January 3, 1956" If you need more API, I'd put it on the objects that it belongs to. But I like OOP :) This could be related to the Engine idea for gen.lib. -Doug ~Brian > > > ------------------------------------------------------------------------------ > This SF.Net email is sponsored by the Verizon Developer Community > Take advantage of Verizon's best-in-class app development support > A streamlined, 14 day to market process makes app distribution fast and > easy > Join now and get one step closer to millions of Verizon customers > http://p.sf.net/sfu/verizon-dev2dev > _______________________________________________ > Gramps-devel mailing list > Gramps-devel@... > https://lists.sourceforge.net/lists/listinfo/gramps-devel > |
From: Benny Malengier <benny.malengier@gm...> - 2010-01-11 08:24:21
|
2010/1/10 Brian Matherly <brian@...>: > As part of GEP008, I'm trying to figure out what to do with the DateDisplay and NameDisplay classes. > > Here is my suggestion: > > 1) Create a new directory in gen called "display". This directory will be for code that facilitates the formatting of data for display (like DateDisplay and NameDisplay) > > Initially, we will have gen.display.date and gen.display.name. But I can imagine that eventually we will have displayers for other objects. I already know of some code in a random "utils" file somewhere that formats Places for display. That code could ultimately find a home in gen.display.place. > > 2) Create a DisplayerFactory class which can do the work of figuring out the right displayer to use. Right now, most code accesses the global BasicUtils.name_displayer and DateHandler.displayer objects. This is bad programming practice. With the new factories, you can call: > gen.display.factory.get_displayer("Date") > and the factory will make sure that you get the right displayer for the current locale and user preferences. > Similarly, calling: > gen.display.factory.get_displayer("Name") > would return a NameDisplay object properly initialized to the current user settings. > This way, the Displayer classes themselves would not depend on config and we could remove code like this: > global WITH_GRAMP_CONFIG > self.name_formats = {} > self.set_name_format(self.STANDARD_FORMATS) > > if WITH_GRAMPS_CONFIG: > self.default_format = config.get('preferences.name-format') > if self.default_format == 0: > self.default_format = Name.LNFN > config.set('preferences.name-format', self.default_format) > else: > self.default_format = 1 > > I would appreciate you comments. If I can move forward with this scheme, I'll add it to the GEP008 wiki page. If I understand correctly, factory will depend on config, and call displayer with correct settings? For me your suggestion sound ok. The idea of Doug with str is nice, but what we do is a bit more versatile than just giving a nice str reprensation of an object, so I would stick with specific display classes, with str in the object being more low level. Benny |
From: Brian Matherly <brian@gr...> - 2010-01-11 14:04:36
|
Benny, > > As part of GEP008, I'm trying to figure out what to do > with the DateDisplay and NameDisplay classes. > > > > Here is my suggestion: > > > > 1) Create a new directory in gen called "display". > This directory will be for code that facilitates the > formatting of data for display (like DateDisplay and > NameDisplay) > > > > Initially, we will have gen.display.date and > gen.display.name. But I can imagine that eventually we will > have displayers for other objects. I already know of some > code in a random "utils" file somewhere that formats Places > for display. That code could ultimately find a home in > gen.display.place. > > > > 2) Create a DisplayerFactory class which can do the > work of figuring out the right displayer to use. Right now, > most code accesses the global BasicUtils.name_displayer and > DateHandler.displayer objects. This is bad programming > practice. With the new factories, you can call: > > gen.display.factory.get_displayer("Date") > > and the factory will make sure that you get the right > displayer for the current locale and user preferences. > > Similarly, calling: > > gen.display.factory.get_displayer("Name") > > would return a NameDisplay object properly initialized > to the current user settings. > > This way, the Displayer classes themselves would not > depend on config and we could remove code like this: > > global WITH_GRAMP_CONFIG > > self.name_formats = {} > > > self.set_name_format(self.STANDARD_FORMATS) > > > > if WITH_GRAMPS_CONFIG: > > self.default_format = > config.get('preferences.name-format') > > if self.default_format == 0: > > self.default_format = > Name.LNFN > > > config.set('preferences.name-format', > self.default_format) > > else: > > self.default_format = 1 > > > > I would appreciate you comments. If I can move forward > with this scheme, I'll add it to the GEP008 wiki page. > > If I understand correctly, factory will depend on config, > and call > displayer with correct settings? Yes. Displayer will not have any dependency on config. > For me your suggestion sound ok. The idea of Doug with str > is nice, > but what we do is a bit more versatile than just giving a > nice str > reprensation of an object, so I would stick with specific > display > classes, with str in the object being more low level. Doug's idea would make gen.lib bloated because name.py and date.py would have all the logic for displaying and they would have to depend on config (they might already, I don't know). Date.py would have to know about the plugin system to choose the correct localized date displayer. So it would make those already large classes even larger. I'll proceed with my plan. ~Brian |
From: Doug Blank <doug.blank@gm...> - 2010-01-11 14:59:39
Attachments:
Message as HTML
|
On Mon, Jan 11, 2010 at 8:37 AM, Brian Matherly <brian@...>wrote: > Benny, > > > > As part of GEP008, I'm trying to figure out what to do > > with the DateDisplay and NameDisplay classes. > > > > > > Here is my suggestion: > > > > > > 1) Create a new directory in gen called "display". > > This directory will be for code that facilitates the > > formatting of data for display (like DateDisplay and > > NameDisplay) > > > > > > Initially, we will have gen.display.date and > > gen.display.name. But I can imagine that eventually we will > > have displayers for other objects. I already know of some > > code in a random "utils" file somewhere that formats Places > > for display. That code could ultimately find a home in > > gen.display.place. > > > > > > 2) Create a DisplayerFactory class which can do the > > work of figuring out the right displayer to use. Right now, > > most code accesses the global BasicUtils.name_displayer and > > DateHandler.displayer objects. This is bad programming > > practice. With the new factories, you can call: > > > gen.display.factory.get_displayer("Date") > > > and the factory will make sure that you get the right > > displayer for the current locale and user preferences. > > > Similarly, calling: > > > gen.display.factory.get_displayer("Name") > > > would return a NameDisplay object properly initialized > > to the current user settings. > > > This way, the Displayer classes themselves would not > > depend on config and we could remove code like this: > > > global WITH_GRAMP_CONFIG > > > self.name_formats = {} > > > > > self.set_name_format(self.STANDARD_FORMATS) > > > > > > if WITH_GRAMPS_CONFIG: > > > self.default_format = > > config.get('preferences.name-format') > > > if self.default_format == 0: > > > self.default_format = > > Name.LNFN > > > > > config.set('preferences.name-format', > > self.default_format) > > > else: > > > self.default_format = 1 > > > > > > I would appreciate you comments. If I can move forward > > with this scheme, I'll add it to the GEP008 wiki page. > > > > If I understand correctly, factory will depend on config, > > and call > > displayer with correct settings? > > Yes. Displayer will not have any dependency on config. > > > For me your suggestion sound ok. The idea of Doug with str > > is nice, > > but what we do is a bit more versatile than just giving a > > nice str > > reprensation of an object, so I would stick with specific > > display > > classes, with str in the object being more low level. > > Doug's idea would make gen.lib bloated because name.py and date.py would > have all the logic for displaying and they would have to depend on config > (they might already, I don't know). Date.py would have to know about the > plugin system to choose the correct localized date displayer. So it would > make those already large classes even larger. > > Brian, I understand your perspective, but let's not describe one as "bloating up the code" and the other as not. For example, in your methodology, you will need to do this in *every* place you want to display a name and a date: from someplace-that-i'll-always-have-to-lookup import some namedisplayer from someplace-that-i'll-always-have-to-lookup import some datedisplayer from some-other-place-maybe import perhaps-do-some-factory-weirdness nd = perhaps-do-some-factory-weirdness(namedisplayer) dd = perhaps-do-some-factory-weirdness(datedisplayer) name_text = nd(person.get_primary_name()) date_text = nd(person.get_birth_date()) print "%s was born on %s" % (name_text, date_text) That, in comparison to: print "%s was born on %s" % (person, person.get_birth_date()) I agree that what I suggested would put this boilerplate code in those two classes, and perhaps add a dependency, but it would be done in one place, thus reducing overall bloat. Something is going to have a dependency on config. Why are you jumping through hoops to not to put this in the most obvious places (gen.lib.Name.__str__)? $.03 :) -Doug > I'll proceed with my plan. > > ~Brian > > > ------------------------------------------------------------------------------ > This SF.Net email is sponsored by the Verizon Developer Community > Take advantage of Verizon's best-in-class app development support > A streamlined, 14 day to market process makes app distribution fast and > easy > Join now and get one step closer to millions of Verizon customers > http://p.sf.net/sfu/verizon-dev2dev > _______________________________________________ > Gramps-devel mailing list > Gramps-devel@... > https://lists.sourceforge.net/lists/listinfo/gramps-devel > |
From: Benny Malengier <benny.malengier@gm...> - 2010-01-11 15:20:28
|
2010/1/11 Doug Blank <doug.blank@...>: > On Mon, Jan 11, 2010 at 8:37 AM, Brian Matherly <brian@...> > wrote: >> >> Benny, >> >> > > As part of GEP008, I'm trying to figure out what to do >> > with the DateDisplay and NameDisplay classes. >> > > >> > > Here is my suggestion: >> > > >> > > 1) Create a new directory in gen called "display". >> > This directory will be for code that facilitates the >> > formatting of data for display (like DateDisplay and >> > NameDisplay) >> > > >> > > Initially, we will have gen.display.date and >> > gen.display.name. But I can imagine that eventually we will >> > have displayers for other objects. I already know of some >> > code in a random "utils" file somewhere that formats Places >> > for display. That code could ultimately find a home in >> > gen.display.place. >> > > >> > > 2) Create a DisplayerFactory class which can do the >> > work of figuring out the right displayer to use. Right now, >> > most code accesses the global BasicUtils.name_displayer and >> > DateHandler.displayer objects. This is bad programming >> > practice. With the new factories, you can call: >> > > gen.display.factory.get_displayer("Date") >> > > and the factory will make sure that you get the right >> > displayer for the current locale and user preferences. >> > > Similarly, calling: >> > > gen.display.factory.get_displayer("Name") >> > > would return a NameDisplay object properly initialized >> > to the current user settings. >> > > This way, the Displayer classes themselves would not >> > depend on config and we could remove code like this: >> > > global WITH_GRAMP_CONFIG >> > > self.name_formats = {} >> > > >> > self.set_name_format(self.STANDARD_FORMATS) >> > > >> > > if WITH_GRAMPS_CONFIG: >> > > self.default_format = >> > config.get('preferences.name-format') >> > > if self.default_format == 0: >> > > self.default_format = >> > Name.LNFN >> > > >> > config.set('preferences.name-format', >> > self.default_format) >> > > else: >> > > self.default_format = 1 >> > > >> > > I would appreciate you comments. If I can move forward >> > with this scheme, I'll add it to the GEP008 wiki page. >> > >> > If I understand correctly, factory will depend on config, >> > and call >> > displayer with correct settings? >> >> Yes. Displayer will not have any dependency on config. >> >> > For me your suggestion sound ok. The idea of Doug with str >> > is nice, >> > but what we do is a bit more versatile than just giving a >> > nice str >> > reprensation of an object, so I would stick with specific >> > display >> > classes, with str in the object being more low level. >> >> Doug's idea would make gen.lib bloated because name.py and date.py would >> have all the logic for displaying and they would have to depend on config >> (they might already, I don't know). Date.py would have to know about the >> plugin system to choose the correct localized date displayer. So it would >> make those already large classes even larger. >> > > Brian, > > I understand your perspective, but let's not describe one as "bloating up > the code" and the other as not. For example, in your methodology, you will > need to do this in *every* place you want to display a name and a date: > > from someplace-that-i'll-always-have-to-lookup import some namedisplayer > from someplace-that-i'll-always-have-to-lookup import some datedisplayer > from some-other-place-maybe import perhaps-do-some-factory-weirdness > nd = perhaps-do-some-factory-weirdness(namedisplayer) > dd = perhaps-do-some-factory-weirdness(datedisplayer) > name_text = nd(person.get_primary_name()) > date_text = nd(person.get_birth_date()) > print "%s was born on %s" % (name_text, date_text) > > That, in comparison to: > > print "%s was born on %s" % (person, person.get_birth_date()) > > I agree that what I suggested would put this boilerplate code in those two > classes, and perhaps add a dependency, but it would be done in one place, > thus reducing overall bloat. > > Something is going to have a dependency on config. Why are you jumping > through hoops to not to put this in the most obvious places > (gen.lib.Name.__str__)? I also don't think that our gen.lib should contain import from utils, it just makes for better coding. But ease of use is also important. One could always inject the dependency in the class, so bind a class function that is called on str. The main issue is that you need to be able to switch display between certain plugins, so this calls for not a single str, you would need an option to override the default then. After all, you would in a plugin indicate you want name display as A, while the person view still has to show B. This calls for a setup that is a bit more versatile than just str. Date is more complicated, it calls for loading localized datehandlers, which are plugins, there is no need for an str of an object to do that. Anyway, the code would look like import gen from gen.lib.date import Date _nd = gen.display.factory.get_displayer("Date") print _nd(gen.lib.date.Date(0)) If you need to override the default probably an extra argument. We could make a convenience function to make it shorter and easier to remember from gen.display import displaydate from gen.lib.date import Date print displaydate(Date(0)) Which to override the default, would also need an optional extra argument, eg the language code. Benny |
From: Doug Blank <doug.blank@gm...> - 2010-01-11 15:42:22
Attachments:
Message as HTML
|
On Mon, Jan 11, 2010 at 10:20 AM, Benny Malengier <benny.malengier@... > wrote: > 2010/1/11 Doug Blank <doug.blank@...>: > > On Mon, Jan 11, 2010 at 8:37 AM, Brian Matherly < > brian@...> > > wrote: > >> > >> Benny, > >> > >> > > As part of GEP008, I'm trying to figure out what to do > >> > with the DateDisplay and NameDisplay classes. > >> > > > >> > > Here is my suggestion: > >> > > > >> > > 1) Create a new directory in gen called "display". > >> > This directory will be for code that facilitates the > >> > formatting of data for display (like DateDisplay and > >> > NameDisplay) > >> > > > >> > > Initially, we will have gen.display.date and > >> > gen.display.name. But I can imagine that eventually we will > >> > have displayers for other objects. I already know of some > >> > code in a random "utils" file somewhere that formats Places > >> > for display. That code could ultimately find a home in > >> > gen.display.place. > >> > > > >> > > 2) Create a DisplayerFactory class which can do the > >> > work of figuring out the right displayer to use. Right now, > >> > most code accesses the global BasicUtils.name_displayer and > >> > DateHandler.displayer objects. This is bad programming > >> > practice. With the new factories, you can call: > >> > > gen.display.factory.get_displayer("Date") > >> > > and the factory will make sure that you get the right > >> > displayer for the current locale and user preferences. > >> > > Similarly, calling: > >> > > gen.display.factory.get_displayer("Name") > >> > > would return a NameDisplay object properly initialized > >> > to the current user settings. > >> > > This way, the Displayer classes themselves would not > >> > depend on config and we could remove code like this: > >> > > global WITH_GRAMP_CONFIG > >> > > self.name_formats = {} > >> > > > >> > self.set_name_format(self.STANDARD_FORMATS) > >> > > > >> > > if WITH_GRAMPS_CONFIG: > >> > > self.default_format = > >> > config.get('preferences.name-format') > >> > > if self.default_format == 0: > >> > > self.default_format = > >> > Name.LNFN > >> > > > >> > config.set('preferences.name-format', > >> > self.default_format) > >> > > else: > >> > > self.default_format = 1 > >> > > > >> > > I would appreciate you comments. If I can move forward > >> > with this scheme, I'll add it to the GEP008 wiki page. > >> > > >> > If I understand correctly, factory will depend on config, > >> > and call > >> > displayer with correct settings? > >> > >> Yes. Displayer will not have any dependency on config. > >> > >> > For me your suggestion sound ok. The idea of Doug with str > >> > is nice, > >> > but what we do is a bit more versatile than just giving a > >> > nice str > >> > reprensation of an object, so I would stick with specific > >> > display > >> > classes, with str in the object being more low level. > >> > >> Doug's idea would make gen.lib bloated because name.py and date.py would > >> have all the logic for displaying and they would have to depend on > config > >> (they might already, I don't know). Date.py would have to know about the > >> plugin system to choose the correct localized date displayer. So it > would > >> make those already large classes even larger. > >> > > > > Brian, > > > > I understand your perspective, but let's not describe one as "bloating up > > the code" and the other as not. For example, in your methodology, you > will > > need to do this in *every* place you want to display a name and a date: > > > > from someplace-that-i'll-always-have-to-lookup import some namedisplayer > > from someplace-that-i'll-always-have-to-lookup import some datedisplayer > > from some-other-place-maybe import perhaps-do-some-factory-weirdness > > nd = perhaps-do-some-factory-weirdness(namedisplayer) > > dd = perhaps-do-some-factory-weirdness(datedisplayer) > > name_text = nd(person.get_primary_name()) > > date_text = nd(person.get_birth_date()) > > print "%s was born on %s" % (name_text, date_text) > > > > That, in comparison to: > > > > print "%s was born on %s" % (person, person.get_birth_date()) > > > > I agree that what I suggested would put this boilerplate code in those > two > > classes, and perhaps add a dependency, but it would be done in one place, > > thus reducing overall bloat. > > > > Something is going to have a dependency on config. Why are you jumping > > through hoops to not to put this in the most obvious places > > (gen.lib.Name.__str__)? > > I also don't think that our gen.lib should contain import from utils, > it just makes for better coding. > But ease of use is also important. Ah, I see where you both are coming from. My philosophy is "ease of use *makes* better coding". Related to the idea that code is not to be replicated (Don't Repeat Yourself, DRY http://en.wikipedia.org/wiki/Don%27t_repeat_yourself). One could always inject the > dependency in the class, so bind a class function that is called on > str. > > The main issue is that you need to be able to switch display between > certain plugins, so this calls for not a single str, you would need an > option to override the default then. After all, you would in a plugin > indicate you want name display as A, while the person view still has > to show B. > That's a good point for that use case (which is rare, and doesn't need to be the default behavior). > This calls for a setup that is a bit more versatile than just str. > Date is more complicated, it calls for loading localized datehandlers, > which are plugins, there is no need for an str of an object to do > that. > > Ok, then I amend my suggestion to have __str__ as the default, and have a gen.lib.Name.display method that takes parameters. > Anyway, the code would look like > > import gen > from gen.lib.date import Date > _nd = gen.display.factory.get_displayer("Date") > print _nd(gen.lib.date.Date(0)) > > If you need to override the default probably an extra argument. We > could make a convenience function to make it shorter and easier to > remember > > from gen.display import displaydate > from gen.lib.date import Date > print displaydate(Date(0)) > > Which to override the default, would also need an optional extra > argument, eg the language code. > > I think this is very similar to the gen.lib issues that we have with different backends. I think a connected data Engine would be the right place to do this. -Doug > Benny > |