I've got a function which looks like this:
bool generate_script (bool net, bool tv, bool phone,
std::string clientsID,
std::string password,
int index, std::string number,
std::string Iport, std::string sernoID,
std::string VoiP_number, std::string VoiP_pass,
std::string target, int slot, int port,
int onu, int extra, std::string IP, std::string MAC);
In my opinion it looks ugly. What is the proper way of handling this problem? Should I create few vectors with different data types (int, string and bool) and pass them as arguments to this function?
If all these parameters are meaningfully related, pack them in a structure.
Put them in a struct
Create a structure
struct GenerateScriptParams { /* ... */ };
and put all the parameters in there. You can actually provide default values for the initialization of the struct as well by implementing a default constructor or, in C++11, by providing default initialization of individual members. You can then change the values that are not supposed to be defaulted. This selective picking of non-default parameters is not possible for a function call with lots of parameters in C++.
Making the interface nice for the caller
Yet, the usage is a little ugly, since you have to create a temporary name object, then change the values that should not be default and then pass the object to the function:
GenerateScriptParams gsp;
gsp.net = true;
gsp.phone = false;
gps.extra = 10;
generate_script( gsp );
If you call that function in several different places, it makes sense to avoid this uglyness by providing mutating member functions that can be chained:
GenerateScriptParams & GenerateScriptParams::setNet ( bool val );
GenerateScriptParams & GenerateScriptParams::setTV ( bool val );
GenerateScriptParams & GenerateScriptParams::setPhone( bool val );
// ... //
Then calling code can write
generate_script( GenerateScriptParams()
.setNet(true),
.setPhone(false),
.setExtra(10) );
without the above uglyness. This avoids the named object that is only used once.
I personally do not believe that moving all the arguments in one struct will make the code much better. You just move dirt under the carpet. When you are going to deal with the creation of the struct you have the same problem.
The question is how much reusable this struct will be? If you end up with a 18 parameters for one function call something it is not quite right in your design. After further analysis you may discover that those parameters can be group in several different classes and those classes could be aggregated to one single object that will be the input of your function. You may want also prefer classes to struct in order to protect your data.
EDIT
I will give you a small example to describe why several classes are better than one monolithic struct. Let's start counting the tests that you need to write to cover the function above. There are 18 parameters as input (3 boolean). So we are going to need at least 15 tests only to validate the input (assuming the values are not interconnected).
The overall number of tests is impossible to be calculated without the implementation, but we can have an idea of the magnitude. Let take the lower bound all the input can be treat as boolean the number of possible combination are 2^18 so around 262000 tests.
Now, what happen if we split the input in several objects?
First of all, the code to validate the input is moved away from the function to the body of every single object (and it can be reused).
But more importantly the number of tests will collapse, let say in group of four (4,4,4 and 4 params per object) the total number of tests is only:
2^4 + 2^4 + 2^4 + 2^4 + 2^4 = 80
The fifth attributes is due to the permutation of the objects with themselves.
So, what is more cost demanding? Write thousand of tests or few more classes?
Obviously, this is a crude simplification, however, it will underlying the core of the problem. A clutter interface is not just matter of style or an inconvenient for the developer it is a true impediment to produce quality code.
This is the most important lesson I ever learnt in my career as a professional developer: "Big classes and fat interfaces are evil". That's just my heuristic version of the single responsibility principle (I have notice that the SRP can be tricky to get it right, what it seems reasonable to be single responsibility it can be not quite the same after a hour coding, so I used some heuristic rule to help me to revaulate my initial choices).
Or you could use a fluent interface. It would look like this:
script my_script(mandatory, parameters);
my_script.net(true).tv(false).phone(true);
This is applicable if you have default values for your specified parameters or it is allowed to have a partially constructed script.
Ignoring the possibility or desirability of changing the function or program in some way as to reduce the number of parameters...
I have seen coding standards that specify how long parameter lists should be formatted, for cases where refactoring is not possible. One such example is using double indentations and one parameter per line (Not for all functions - only for those that have multiple-lines of parameters).
E.g.
bool generate_script (
bool net,
bool tv,
bool phone,
std::string clientsID,
std::string password,
int index,
std::string number,
std::string Iport,
std::string sernoID,
std::string VoiP_number,
std::string VoiP_pass,
std::string target,
int slot,
int port,
int onu,
int extra,
std::string IP,
std::string MAC);
The point here is to create a consistent layout and look for all functions with a large number of parameters.
A bit late here, but since nobody has done it yet, I'd like to point out an obvious aspect of the issue: to me, a function which takes so many arguments is likely to do a lot of computation, so consider the possibility of decomposing it in smaller functions as a first step.
This should help you structuring your data.
Related
There are a number of functions for creating XlaOps from native C++ values. I'm trying to figure out how to use each to construct a graph. I've gone through xla_builder.h and picked out some candidates, omitting overloads and convenience wrappers. The two most likely candidates seem to be
// Enqueues a "retrieve parameter value" instruction for a parameter that was
// passed to the computation.
XlaOp Parameter(XlaBuilder* builder, int64 parameter_number, const Shape& shape,
const string& name);
// Enqueues a constant with the value of the given literal onto the
// computation.
XlaOp ConstantLiteral(XlaBuilder* builder, const LiteralSlice& literal);
Am I right in thinking Parameter is for "symbols", while ConstantLiteral is for constant values? For example, in f(x) = x + 1, we'd encode 1 as a ConstantLiteral, and then for x we could either
write f(x) as a C++ function, and at application site use another ConstantLiteral for our value of x, or
encode x using Parameter and build an XlaComputation from the corresponding XlaBuilder. That said, I'm not clear on how to actually call the XlaComputation with a Literal, other than with LocalClient which doesn't work with to multiple XlaComputations afaict.
What's the difference between these two approaches? Is one better than the other? I notice the former doesn't appear possible for higher-order functions: those which accept XlaComputations.
Next there's
Infeed, which I'd guess is a streaming version of Parameter.
Recv which looks like a way to pass data between computations, but doesn't actually create a completely new XlaOp itself.
ReplicaId, Iota, and XlaOp CreateToken(XlaBuilder* builder); appear largely irrelevant for this discussion.
Have I got this right? Are there any other important functions I've missed?
Let's say I'm building a simple class that prints some text on the screen, and it has the possibility to change the colors of the text.
myclass a("this is the text");
a.setColor("green");
I'm still learning C++ and I recently got introduced to enum and thought I'd give it a try. I was wondering if it is a good practice to use enum types in interface functions like the above setColor?
What are the advantages or disadvantages of using enum classes in interface functions? Are there cases where they are more applicable than and are there case where they are bad to use?
What if I want to combine properties? E.g.
a.setAttribute("bold reverse");
I don't know if interface is the correct term for what I want to describe: the functions that a user of my class would end up using.
In your case, there are (at least) two advantages:
No need to parse the string at run-time, leading to higher efficiency. You can use an enum variable directly in a switch statement.
An enum is (to some extent) self-documenting, the user of your code has to work hard to provide an invalid value.
One potential "disadvantage" is in the case where the colour string has come from e.g. run-time userinput (they've typed into a textbox or something). You will need to parse this string and convert it into an enum. But it's not really a disadvantage, because you'll need to do this anyway. Best practice is for the user-interface logic to validate the string and convert to the enum at the earliest opportunity.
What if I want to combine properties?
I can think of at least three options:
Use multiple calls to setAttribute.
Pass an array of attributes.
Define each enum value to be a power-of-two, and then you can combine enums with |.
Yes, using an enum in this case seems better than an actual string.
One clear advantage - strong typing.
If setColor accepts a char*, like in your case, you could do:
a.setColor("horse");
which you can only detect as an error at runtime.
If setColor takes an eColors as parameter:
a.setColor(eGreen);
a.setColor(eRed);
would compile, but
a.setColor(eHorse);
would not.
Enums are definitely more explicit than strings for this case. As for the concatenation of values, you can use some bit fiddling to make this work. Set the values of your enum to increasing powers of two, then you can OR them together.
enum TextAttributes {
Bold = 1,
Italic = 2,
Reverse = 4,
StrikeThrough = 8,
Underline = 16
};
TextAttributes attr = Bold | Reverse;
what is the best way to call a function with the following declaration
string Extract(const char* pattern,const char* input);
i use
string str=Extract("something","input text");
is there a problem with this usage
should i use the following
char pattern[]="something";
char input[]="input";
//or use pointers with new operator and copy then free?
the both works but i like the first one but i want to know the best practice.
A literal string (e.g. "something") works just fine as a const char* argument to a function call.
The first method, i.e. passing them literally in, is usually preferable.
There are occasions though where you don't want your strings hard-coded into the text. In some ways you can say that, a bit like magic numbers, they are magic words / phrases. So you prefer to use constant identifier to store the values and pass those in instead.
This would happen often when:
1. a word has a special meaning, and is passed in many times in the code to have that meaning.
or
2. the word may be cryptic in some way and a constant identifier may be more descriptive
Unless you plain to have duplicates of the same strings, or alter those strings, I'm a fan of the first way (passing the literals directly), it means less dotting about code to find what the parameters actually are, it also means less work in passing parameters.
Seeing as this is tagged for C++, passing the literals directly allows you to easily switch the function parameters to std::string with little effort.
I'm wondering if there is a library like Boost Format, but which supports named parameters rather than positional ones. This is a common idiom in e.g. Python, where you have a context to format strings with that may or may not use all available arguments, e.g.
mouse_state = {}
mouse_state['button'] = 0
mouse_state['x'] = 50
mouse_state['y'] = 30
#...
"You clicked %(button)s at %(x)d,%(y)d." % mouse_state
"Targeting %(x)d, %(y)d." % mouse_state
Are there any libraries that offer the functionality of those last two lines? I would expect it to offer a API something like:
PrintFMap(string format, map<string, string> args);
In Googling I have found many libraries offering variations of positional parameters, but none that support named ones. Ideally the library has few dependencies so I can drop it easily into my code. C++ won't be quite as idiomatic for collecting named arguments, but probably someone out there has thought more about it than me.
Performance is important, in particular I'd like to keep memory allocations down (always tricky in C++), since this may be run on devices without virtual memory. But having even a slow one to start from will probably be faster than writing it from scratch myself.
The fmt library supports named arguments:
print("You clicked {button} at {x},{y}.",
arg("button", "b1"), arg("x", 50), arg("y", 30));
And as a syntactic sugar you can even (ab)use user-defined literals to pass arguments:
print("You clicked {button} at {x},{y}.",
"button"_a="b1", "x"_a=50, "y"_a=30);
For brevity the namespace fmt is omitted in the above examples.
Disclaimer: I'm the author of this library.
I've always been critic with C++ I/O (especially formatting) because in my opinion is a step backward in respect to C. Formats needs to be dynamic, and makes perfect sense for example to load them from an external resource as a file or a parameter.
I've never tried before however to actually implement an alternative and your question made me making an attempt investing some weekend hours on this idea.
Sure the problem was more complex than I thought (for example just the integer formatting routine is 200+ lines), but I think that this approach (dynamic format strings) is more usable.
You can download my experiment from this link (it's just a .h file) and a test program from this link (test is probably not the correct term, I used it just to see if I was able to compile).
The following is an example
#include "format.h"
#include <iostream>
using format::FormatString;
using format::FormatDict;
int main()
{
std::cout << FormatString("The answer is %{x}") % FormatDict()("x", 42);
return 0;
}
It is different from boost.format approach because uses named parameters and because
the format string and format dictionary are meant to be built separately (and for
example passed around). Also I think that formatting options should be part of the
string (like printf) and not in the code.
FormatDict uses a trick for keeping the syntax reasonable:
FormatDict fd;
fd("x", 12)
("y", 3.141592654)
("z", "A string");
FormatString is instead just parsed from a const std::string& (I decided to preparse format strings but a slower but probably acceptable approach would be just passing the string and reparsing it each time).
The formatting can be extended for user defined types by specializing a conversion function template; for example
struct P2d
{
int x, y;
P2d(int x, int y)
: x(x), y(y)
{
}
};
namespace format {
template<>
std::string toString<P2d>(const P2d& p, const std::string& parms)
{
return FormatString("P2d(%{x}; %{y})") % FormatDict()
("x", p.x)
("y", p.y);
}
}
after that a P2d instance can be simply placed in a formatting dictionary.
Also it's possible to pass parameters to a formatting function by placing them between % and {.
For now I only implemented an integer formatting specialization that supports
Fixed size with left/right/center alignment
Custom filling char
Generic base (2-36), lower or uppercase
Digit separator (with both custom char and count)
Overflow char
Sign display
I've also added some shortcuts for common cases, for example
"%08x{hexdata}"
is an hex number with 8 digits padded with '0's.
"%026/2,8:{bindata}"
is a 24-bit binary number (as required by "/2") with digit separator ":" every 8 bits (as required by ",8:").
Note that the code is just an idea, and for example for now I just prevented copies when probably it's reasonable to allow storing both format strings and dictionaries (for dictionaries it's however important to give the ability to avoid copying an object just because it needs to be added to a FormatDict, and while IMO this is possible it's also something that raises non-trivial problems about lifetimes).
UPDATE
I've made a few changes to the initial approach:
Format strings can now be copied
Formatting for custom types is done using template classes instead of functions (this allows partial specialization)
I've added a formatter for sequences (two iterators). Syntax is still crude.
I've created a github project for it, with boost licensing.
The answer appears to be, no, there is not a C++ library that does this, and C++ programmers apparently do not even see the need for one, based on the comments I have received. I will have to write my own yet again.
Well I'll add my own answer as well, not that I know (or have coded) such a library, but to answer to the "keep the memory allocation down" bit.
As always I can envision some kind of speed / memory trade-off.
On the one hand, you can parse "Just In Time":
class Formater:
def __init__(self, format): self._string = format
def compute(self):
for k,v in context:
while self.__contains(k):
left, variable, right = self.__extract(k)
self._string = left + self.__replace(variable, v) + right
This way you don't keep a "parsed" structure at hand, and hopefully most of the time you'll just insert the new data in place (unlike Python, C++ strings are not immutable).
However it's far from being efficient...
On the other hand, you can build a fully constructed tree representing the parsed format. You will have several classes like: Constant, String, Integer, Real, etc... and probably some subclasses / decorators as well for the formatting itself.
I think however than the most efficient approach would be to have some kind of a mix of the two.
explode the format string into a list of Constant, Variable
index the variables in another structure (a hash table with open-addressing would do nicely, or something akin to Loki::AssocVector).
There you are: you're done with only 2 dynamically allocated arrays (basically). If you want to allow a same key to be repeated multiple times, simply use a std::vector<size_t> as a value of the index: good implementations should not allocate any memory dynamically for small sized vectors (VC++ 2010 doesn't for less than 16 bytes worth of data).
When evaluating the context itself, look up the instances. You then parse the formatter "just in time", check it agaisnt the current type of the value with which to replace it, and process the format.
Pros and cons:
- Just In Time: you scan the string again and again
- One Parse: requires a lot of dedicated classes, possibly many allocations, but the format is validated on input. Like Boost it may be reused.
- Mix: more efficient, especially if you don't replace some values (allow some kind of "null" value), but delaying the parsing of the format delays the reporting of errors.
Personally I would go for the One Parse scheme, trying to keep the allocations down using boost::variant and the Strategy Pattern as much I could.
Given that Python it's self is written in C and that formatting is such a commonly used feature, you might be able (ignoring copy write issues) to rip the relevant code from the python interpreter and port it to use STL maps rather than Pythons native dicts.
I've writen a library for this puporse, check it out on GitHub.
Contributions are wellcome.
I am considering the problem of validating real numbers of various formats, because this is very similar to a problem I am facing in design.
Real numbers may come in different combinations of formats, for example:
1. with/without sign at the front
2. with/without a decimal point (if no decimal point, then perhaps number of decimals can be agreed beforehand)
3. base 10 or base 16
We need to allow for each combination, so there are 2x2x2=8 combinations. You can see that the complexity increases exponentially with each new condition imposed.
In OO design, you would normally allocate a class for each number format (e.g. in this case, we have 8 classes), and each class would have a separate validation function. However, with each new condition, you have to double the number of classes required and it soon becomes a nightmare.
In procedural programming, you use 3 flags (i.e. has_sign, has_decimal_point and number_base) to identify the property of the real number you are validating. You have a single function for validation. In there, you would use the flags to control its behaviour.
// This is part of the validation function
if (has_sign)
check_sign();
for (int i = 0; i < len; i++)
{
if (has_decimal_point)
// Check if number[i] is '.' and do something if it is. If not, continue
if (number_base = BASE10)
// number[i] must be between 0-9
else if (number_base = BASE16)
// number[i] must be between 0-9, A-F
}
Again, the complexity soon gets out of hand as the function becomes cluttered with if statements and flags.
I am sure that you have come across design problems of this nature before - a number of independent differences which result in difference in behaviour. I would be very interested to hear how have you been able to implement a solution without making the code completely unmaintainable.
Would something like the bridge pattern have helped?
In OO design, you would normally
allocate a class for each number
format (e.g. in this case, we have 8
classes), and each class would have a
separate validation function.
No no no no no. At most, you'd have a type for representing Numeric Input (in case String doesn't make it); another one for Real Number (in most languages you'd pick a built-in type, but anyway); and a Parser class, which has the knowledge to take a Numeric Input and transform it into a Real Number.
To be more general, one difference of behaviour in and by itself doesn't automatically map to one class. It can just be a property inside a class. Most importantly, behaviours should be treated orthogonally.
If (imagining that you write your own parser) you may have a sign or not, a decimal point or not, and hex or not, you have three independent sources of complexity and it would be ok to find three pieces of code, somewhere, that treat one of these issues each; but it would not be ok to find, anywhere, 2^3 = 8 different pieces of code that treat the different combinations in an explicit way.
Imagine that add a new choice: suddenly, you remember that numbers might have an "e" (such as 2.34e10) and want to be able to support that. With the orthogonal strategy, you'll have one more independent source of complexity, the fourth one. With your strategy, the 8 cases would suddenly become 16! Clearly a no-no.
I don't know why you think that the OO solution would involve a class for each number pattern. My OO solution would be to use a regular expression class. And if I was being procedural, I would probably use the standard library strtod() function.
You're asking for a parser, use one:
http://www.pcre.org/
http://www.complang.org/ragel/
sscanf
boost::lexical_cast
and plenty of other alternatives...
Also: http://en.wikipedia.org/wiki/Parser_generator
Now how do I handle complexity for this kind of problems ? Well if I can, I reformulate.
In your case, using a parser generator (or regular expression) is using a DSL (Domain Specific Language), that is a language more suited to the problem you're dealing with.
Design pattern and OOP are useful, but definitely not the best solution to each and every problem.
Sorry but since i use vb, what i do is a base function then i combine a evaluator function
so ill fake code it out the way i have done it
function getrealnumber(number as int){ return getrealnumber(number.tostring) }
function getrealnumber(number as float){ return getrealnumber(number.tostring) }
function getrealnumber(number as double){ return getrealnumber(number.tostring) }
function getrealnumber(number as string){
if ishex(){ return evaluation()}
if issigned(){ return evaluation()}
if isdecimal(){ return evaluation()}
}
and so forth up to you to figure out how to do binary and octal
You don't kill a fly with a hammer.
I realy feel like using a Object-Oriented solution for your problem is an EXTREME overkill. Just because you can design Object-Oriented solution , doesn't mean you have to force such one to every problem you have.
From my experience , almost every time there is a difficulty in finding an OOD solution to a problem , It probably mean that OOD is not appropiate. OOD is just a tool , its not god itself. It should be used to solve large scale problems , and not problems such one you presented.
So to give you an actual answer (as someone mentioned above) : use regular expression , Every solution beyond that is just an overkill.
If you insist using an OOD solution.... Well , since all formats you presented are orthogonal to each other , I dont see any need to create a class for every possible combination. I would create a class for each format and pass my input through each , in that case the complexity will grow linearly.