Naming confusion? Is having objects named FlowerGroup and FlowerGroups confusing? - c++

I'm writing a program and I seem to be creating alot of objects where one object will be the singular form and then the collection is the plural form. eg
SalesGroup
SalesGroups
Is this confusing for other programmers to read my code?

should not be confusing, in fact I find it pretty informative and clear; unless you have multiple kinds of collections (lame example: suppose you have an array but also a map of SalesGroup, then SalesGroups would not be the best choice but you'd rather pick SalesGroupArray, SalesGroupMap etc.)

I think that makes perfect sense. Not specifying the type of collection means you're at liberty to change the implementation later, and clients can't rely on a particular implementation.

While it's not confusing, I think it is very easy to miss. If I were doing this, I would use something that stands out more, perhaps SalesGroup and SalesGroupCollection.

seems OK to me. just maintain your coding style throughout all your project.

Related

Django typehinting

I created an empty migration, which now looks like this:
def forwards(apps, schema_editor):
Foo = apps.get_model('app', 'Foo')
FixedResponse.objects.create(name='Bar')
def backwards(apps, schema_editor):
Foo = apps.get_model('app', 'Foo')
Foo.objects.filter(name='Bar').delete()
class Migration(migrations.Migration):
dependencies = [
('app', '0035_fixedresponse'),
]
operations = [
migrations.RunPython(forwards, backwards)
]
Since there is no Django documentation anywhere on this topic (migrations specific) or best practice,
I want to know how do I type hint the code above?
There is no universal answer to that question, and the only reputable source you will find about it is Django's reference and documentation, which don't make any mention about annotations for migrations.
The "correct way to handle type hinting in Django" strictly depends on your company's policy. Prior to asking how, you must ask why. Once you know why, figuring out how will likely be straightforward. However, if instead of asking "why?", you (or your boss) ask "why not?", that's taking the issue upside down. You need a reason to do something, but you don't need a reason not to do something. (1)
If the reason is "to pass CI", this is no valid reason. CI is meant to work for you, not the opposite.
If the reason is "to document the code", this is no valid reason either. Type hints are documentation, the purpose of writing documentation is not "to document the code". Why is any documentation needed? Who is going to read this documentation? What information do they need that is not already clear in the code?
I see 3 valid reasons to use type hints:
Provide help for developers using the functions. In the case of migrations, forwards and backwards functions are only used internally by Django. Developers reading your code are expected to have knowledge about migrations. If they don't know what apps and schema_editor are, it seems fair to expect them to refer to migrations.RunPython documentation, rather than re-explaining it for every single backwards and forwards callbacks of every single RunPython operation of every single migration.
QA type checking. But type checking is only useful for your own code. You'll never import the functions from migrations to use them in your code, so there is nothing to check.
Provide meta information for some smart tools (internal or third party) using introspection to do magic stuff.
Unless your case fits in one of these three, or you have any other reason to use type hints, don't try to fit to "policies" blindly. Don't write annotations just because you can. Keep calm and (re)read the Zen of Python. :) (2)
TLDR: Ask your boss to tell you why he wants type hints for migrations. If the answer is a well-defined purpose, write hints to serve that purpose. If the answer is anyhow stupid, write stupid type hints. ¯\(ツ)/¯ (3)
Footnotes
(1) The double negation might be confusing. What I mean here is that if someone can't explain the purpose of doing something, you don't need to find the purpose of not doing it. Or at least, there is a very straightforward purpose: saving the time and resources required to do it and maintain it.
(2) Don't try to find any principle specific to this situation in the Zen of Python. I only meant this reference as a general reminder of Python's philosophy: keep things simple, clear explicit code is worth more than poor paraphrasing documentation, that kind of stuff.
(3) If the purpose is "to pass CI" or such, I'd personally recommend something silly like def forwards(apps: ..., schema_editor: ...) -> ... (I mean, literally annotate with the Ellipsis object). Either nobody notice and it was indeed pointless, either your boss or your colleagues throw it back at you and hopefully come with a better defined purpose.
The documentation:
code (and reverse_code if supplied) should be callable objects that accept two arguments; the first is an instance of django.apps.registry.Apps containing historical models that match the operation’s place in the project history, and the second is an instance of SchemaEditor.
https://docs.djangoproject.com/en/stable/ref/migration-operations/#django.db.migrations.operations.RunPython
So, if you want to annotate your data migrations with types, these are the appropriate annotations:
from django.apps.registry import Apps
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
def forwards(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
...

What kind of pointer should I use here?

I'm working on an old large code base with a colleague. The codebase uses a significant number of std::shared_ptr and previous developers had a fondness for long property names (m_first_username for example).
Some methods in our code access a number of those properties so our code tends to be very verbose:
if (m_first_username->isSomethingOrOther() || m_second_username->isOtherOrSomething()...
So to make the code more readable my colleague wants to use more std::shared_ptr & with local scope:
const std::shared_ptr<...> &tmp = m_first_username->returnsASharedPtr()
tmp->isSomethingOrOther();
Something I disagree with because of the shared pointer use count.
What is the best way to make this code more readable? Keeping using constant references to shared_ptr, use std::weak_ptr or live with the long lines of code?
As per #nwp's comment -the proper way to alias a variable name locally would be:
auto& v1 = m_first_user_name;
If you want to go the route of the "returnAsSharedPointer" you posted in the question, what you'd want to use in the classes of m_first_user_name and m_second user_name is the standard C++ enable_shared_from_this.
On the whole, though it's primarily opinion-based, I believe you'll find that most experienced C++ developers will find the new code less readable than the old code. There is nothing wrong with long, descriptive variable names.

framework/library for property-tree-like data structure with generic get/set-implementation?

I'm looking for a data structure which behaves similar to boost::property_tree but (optionally) leaves the get/set implementation for each value item to the developer.
You should be able to do something like this:
std::function<int(void)> f_foo = ...;
my_property_tree tree;
tree.register<int>("some.path.to.key", f_foo);
auto v1 = tree.get<int>("some.path.to.key"); // <-- calls f_foo
auto v2 = tree.get<int>("some.other.path"); // <-- some fallback or throws exception
I guess you could abuse property_tree for this but I haven't looked into the implementation yet and I would have a bad feeling about this unless I knew that this is an intended use case.
Writing a class that handles requests like val = tree.get("some.path.to.key") by calling a provided function doesn't look too hard in the first place but I can imagine a lot of special cases which would make this quite a bulky library.
Some extra features might be:
subtree-handling: not only handle terminal keys but forward certain subtrees to separate implementations. E.g.
tree.register("some.path.config", some_handler);
// calls some_handler.get<int>("network.hostname")
v = tree.get<int>("some.path.config.network.hostname");
search among values / keys
automatic type casting (like in boost::property_tree)
"path overloading", e.g. defaulting to a property_tree-implementation for paths without registered callback.
Is there a library that comes close to what I'm looking for? Has anyone made experiences with using boost::property_tree for this purpose? (E.g. by subclassing or putting special objects into the tree like described here)
After years of coding my own container classes I ended up just adopting QVariantMap. This way it pretty much behaves (and is as flexible as) python. Just one interface. Not for performance code though.
If you care to know, I really caved in for Qt as my de facto STL because:
Industry standard - used even in avionics and satellite software
It has been around for decades with little interface change (think about long term support)
It has excellent performance, awesome documentation and enormous user base.
Extensive feature set, way beyond the STL
Would an std::map do the job you are interested in?
Have you tried this approach?
I don't quite understand what you are trying to do. So please provide a domain example.
Cheers.
I have some home-cooked code that lets you register custom callbacks for each type in GitHub. It is quite basic and still missing most of the features you would like to have. I'm working on the second version, though. I'm finishing a helper structure that will do most of the job of making callbacks. Tell me if you're interested. Also, you could implement some of those features yourself, as the code to register callbacks is already done. It shouldn't be so difficult.
Using only provided data structures:
First, getters and setters are not native features to c++ you need to call the method one way or another. To make such behaviour occur you can overload assignment operator. I assume you also want to store POD data in your data structure as well.
So without knowing the type of the data you're "get"ting, the only option I can think of is to use boost::variant. But still, you have some overloading to do, and you need at least one assignment.
You can check out the documentation. It's pretty straight-forward and easy to understand.
http://www.boost.org/doc/libs/1_61_0/doc/html/variant/tutorial.html
Making your own data structures:
Alternatively, as Dani mentioned, you can come up with your own implementation and keep a register of overloaded methods and so on.
Best

Is creating an empty class purely to distinguish it from another class good practice?

I have a class CardStack. I have several classes that inherit from CardStack e.g. Cascade, Deck, Foundation etc.
Foundation doesn't need to add any functionality to CardStack, but for display purposes my app needs to know which of the CardStacks are actually Foundations.
Incidentally, I have no such function CardStack.Display() (I'm using a model-view-controller pattern where the View object simply queries the Model to find out what type of objects it's dealing with).
It seems OK to me, but is there any reason not to do this?
class Foundation : public CardStack
{
};
class Model
{
Cascade cascade[10];
Foundation foundations[10];
...
};
Nothing wrong with this.
Do it all the time.
In the future, there may be a difference in structure, behavior or implementation. For now, they happen to share a lot of common features.
I don't see any technical problem with it, so maybe you're doing this for semantic reasons. In that case, make sure you document the reason it VERY CLEARLY so maintenance programmers later on don't try and change things.
Yep, this is valid and useful. An empty class can act as placeholder for future functionality (as example). Of course, a bit of documentation is in order if the class in question is "connected" to the program in any way ;-)
In your case above, the C++ code generated won't be burdened... but readability of your code is increased.
I do it all the time for lists
public class MyObjects : List<MyObject> { }
It's good practice, since it is semantically clearer with nearly, with nearly no cost associated and allows for modifications, when the need arises for subclasses do behave differently.
Nothing wrong with it, I do this often. I like it better than empty "marker" interfaces (in Java). As others have mentioned, you should probably comment on the fact that the implementation is supposed to be empty (or perhaps "reserved for future use"), but otherwise IMHO you're fine.
The way you did it the Model class it seems to me that typedef will suffice to distinguish names (and readability!):
http://en.wikipedia.org/wiki/Typedef

Table api

Suppose you have a table widget class.
Do you do table.row(i).column(0).setText(students[i].surname())
or table[0][i] = students[i].surname()
the latter makes way less sense but the simplicity is so luring ;)
ditto for: table.row(0).column(0).setBackground(red)
vs: table[0][0].setBackground(red)
Note that Table::row returns a Table::Row, whose column function returns a Table::Cell, and Table::Cell provides either setText or op= (as well as setBackground).
Same for Table::op[] and Table::Row::op[].
Your thoughts?
As a less verbose alternative for many common cases, I would also provide something like this:
table.rowcol(i, j) = "blah"; // rowcol returns directly a cell
table.colrow(k, t).SetBackground(black);
Basically the name of the method just serves as a reminder on the order of the parameters.
Also, being a single method, you can perform better exception handling IMO.
The solution with Table::row() and Table::Row::column() methods is a bit more readable (in general) and allows you to unambiguously create a Table::column() method, Table::Column (proxy) class, and Table::Column::row() method later on, if that is ever needed. This solution also makes it easy to find all places where rows/columns are accessed, which is much harder when you use operator overloading.
As others pointed out however, the second solution is less typing and, in my opinion, not much worse in readability. (May even be more readable in certain situations.)
It's up to you to decide though, I'm just giving some implications of both solutions :-)
The second one. It carries just as much meaning as the first and is hugely easier to read and to type.(I don't really understand why you say it makes "way less sense".)
Actually you'd do neither of those. They are both buggy code and could lead to exceptions if there are no rows.
if(table.rows > 0)
{
var row = table.row[0];
if(row.columns > 0)
{
var col = row.column[0];
etc...
table.row(i).column(0)
This style is known as the Named Parameter Idiom. This makes it easy to reorder a set of calls in any way that pleases you as an alternative to positional parameters. However, this works provided each of the chained calls return the same original object. Of course, in your case you have a row object and a column object. So, there isn't much to gain here.
The ease of use of the second construct provides another compelling reason to choose the latter over the former.
There is not a way which is better than another. It depends on what you have to do with your data structure.
That said, for a simple table widget (assuming you are not coding a complex Excel-like application) I'd seek easy syntax instead of a more general interface.
So table[0][1] = "blah" would just work fine for me.