mlpack
print_doc_functions_impl.hpp
Go to the documentation of this file.
1 
13 #ifndef MLPACK_BINDINGS_PYTHON_PRINT_DOC_FUNCTIONS_IMPL_HPP
14 #define MLPACK_BINDINGS_PYTHON_PRINT_DOC_FUNCTIONS_IMPL_HPP
15 
17 
18 namespace mlpack {
19 namespace bindings {
20 namespace python {
21 
25 inline std::string GetBindingName(const std::string& bindingName)
26 {
27  // No modification is needed to the name---we just use it as-is.
28  return bindingName + "()";
29 }
30 
34 inline std::string PrintImport(const std::string& bindingName)
35 {
36  return "from mlpack import " + bindingName;
37 }
38 
42 inline std::string PrintInputOptionInfo()
43 {
44  return "";
45 }
46 
50 inline std::string PrintOutputOptionInfo()
51 {
52  return "Results are returned in a Python dictionary. The keys of the "
53  "dictionary are the names of the output parameters.";
54 }
55 
59 template<typename T>
60 inline std::string PrintValue(const T& value, bool quotes)
61 {
62  std::ostringstream oss;
63  if (quotes)
64  oss << "'";
65  oss << value;
66  if (quotes)
67  oss << "'";
68  return oss.str();
69 }
70 
74 template<typename T>
75 inline std::string PrintValue(const std::vector<T>& value, bool quotes)
76 {
77  std::ostringstream oss;
78  if (quotes)
79  oss << "'";
80  oss << "[";
81  if (value.size() > 0)
82  {
83  oss << value[0];
84  for (size_t i = 1; i < value.size(); ++i)
85  oss << ", " << value[i];
86  }
87  oss << "]";
88  if (quotes)
89  oss << "'";
90  return oss.str();
91 }
92 
93 // Special overload for booleans.
94 template<>
95 inline std::string PrintValue(const bool& value, bool quotes)
96 {
97  if (quotes && value)
98  return "'True'";
99  else if (quotes && !value)
100  return "'False'";
101  else if (!quotes && value)
102  return "True";
103  else
104  return "False";
105 }
106 
110 inline std::string PrintDefault(const std::string& paramName)
111 {
112  if (IO::Parameters().count(paramName) == 0)
113  throw std::invalid_argument("unknown parameter " + paramName + "!");
114 
115  util::ParamData& d = IO::Parameters()[paramName];
116 
117  std::string defaultValue;
118  IO::GetSingleton().functionMap[d.tname]["DefaultParam"](d, NULL,
119  (void*) &defaultValue);
120 
121  return defaultValue;
122 }
123 
124 // Recursion base case.
125 std::string PrintInputOptions() { return ""; }
126 
132 template<typename T, typename... Args>
133 std::string PrintInputOptions(const std::string& paramName,
134  const T& value,
135  Args... args)
136 {
137  // See if this is part of the program.
138  std::string result = "";
139  if (IO::Parameters().count(paramName) > 0)
140  {
141  util::ParamData& d = IO::Parameters()[paramName];
142  if (d.input)
143  {
144  // Print the input option.
145  std::ostringstream oss;
146  if (paramName != "lambda") // Don't print Python keywords.
147  oss << paramName << "=";
148  else
149  oss << paramName << "_=";
150  oss << PrintValue(value, d.tname == TYPENAME(std::string));
151  result = oss.str();
152  }
153  }
154  else
155  {
156  // Unknown parameter!
157  throw std::runtime_error("Unknown parameter '" + paramName + "' " +
158  "encountered while assembling documentation! Check BINDING_LONG_DESC()"
159  + " and BINDING_EXAMPLE() declaration.");
160  }
161 
162  // Continue recursion.
163  std::string rest = PrintInputOptions(args...);
164  if (rest != "" && result != "")
165  result += ", " + rest;
166  else if (result == "")
167  result = rest;
168 
169  return result;
170 }
171 
172 // Recursion base case.
173 inline std::string PrintOutputOptions() { return ""; }
174 
175 template<typename T, typename... Args>
176 std::string PrintOutputOptions(const std::string& paramName,
177  const T& value,
178  Args... args)
179 {
180  // See if this is part of the program.
181  std::string result = "";
182  if (IO::Parameters().count(paramName) > 0)
183  {
184  util::ParamData& d = IO::Parameters()[paramName];
185  if (!d.input)
186  {
187  // Print a new line for the output option.
188  std::ostringstream oss;
189  oss << ">>> " << value << " = output['" << paramName << "']";
190  result = oss.str();
191  }
192  }
193  else
194  {
195  // Unknown parameter!
196  throw std::runtime_error("Unknown parameter '" + paramName + "' " +
197  "encountered while assembling documentation! Check BINDING_LONG_DESC()"
198  + " and BINDING_EXAMPLE() declaration.");
199  }
200 
201  // Continue recursion.
202  std::string rest = PrintOutputOptions(args...);
203  if (rest != "" && result != "")
204  result += '\n';
205  result += rest;
206 
207  return result;
208 }
209 
215 template<typename... Args>
216 std::string ProgramCall(const std::string& programName, Args... args)
217 {
218  std::ostringstream oss;
219  oss << ">>> ";
220 
221  // Find out if we have any output options first.
222  std::ostringstream ossOutput;
223  ossOutput << PrintOutputOptions(args...);
224  if (ossOutput.str() != "")
225  oss << "output = ";
226  oss << programName << "(";
227 
228  // Now process each input option.
229  oss << PrintInputOptions(args...);
230  oss << ")";
231 
232  std::string call = oss.str();
233  oss.str(""); // Reset it.
234 
235  // Now process each output option.
236  oss << PrintOutputOptions(args...);
237  if (oss.str() == "")
238  return util::HyphenateString(call, 2);
239  else
240  return util::HyphenateString(call, 2) + "\n" + oss.str();
241 }
242 
247 inline std::string ProgramCall(const std::string& programName)
248 {
249  std::ostringstream oss;
250  oss << ">>> ";
251 
252  // Determine if we have any output options.
253  std::map<std::string, util::ParamData>& parameters = IO::Parameters();
254  bool hasOutput = false;
255  for (auto it = parameters.begin(); it != parameters.end(); ++it)
256  {
257  if (!it->second.input)
258  {
259  hasOutput = true;
260  break;
261  }
262  }
263 
264  if (hasOutput)
265  oss << "d = ";
266 
267  oss << programName << "(";
268 
269  // Now iterate over every input option.
270  bool first = true;
271  for (auto it = parameters.begin(); it != parameters.end(); ++it)
272  {
273  if (!it->second.input || (it->second.persistent &&
274  it->second.name != "verbose"))
275  continue;
276 
277  if (!first)
278  oss << ", ";
279  else
280  first = false;
281 
282  // Print the input option.
283  if (it->second.name != "lambda") // Don't print Python keywords.
284  oss << it->second.name << "=";
285  else
286  oss << it->second.name << "_=";
287 
288  std::string value;
289  IO::GetSingleton().functionMap[it->second.tname]["DefaultParam"](
290  it->second, NULL, (void*) &value);
291  oss << value;
292  }
293  oss << ")";
294 
295  std::string result = util::HyphenateString(oss.str(), 8);
296 
297  oss.str("");
298  oss << result;
299 
300  // Now print output lines.
301  for (auto it = parameters.begin(); it != parameters.end(); ++it)
302  {
303  if (it->second.input)
304  continue;
305 
306  // Print a new line for the output option.
307  oss << std::endl << ">>> " << it->second.name << " = d['"
308  << it->second.name << "']";
309  }
310 
311  return oss.str();
312 }
313 
317 inline std::string PrintModel(const std::string& modelName)
318 {
319  return "'" + modelName + "'";
320 }
321 
326 inline std::string PrintDataset(const std::string& datasetName)
327 {
328  return "'" + datasetName + "'";
329 }
330 
335 inline std::string ProgramCallClose()
336 {
337  return ")";
338 }
339 
344 inline std::string ParamString(const std::string& paramName)
345 {
346  // For a Python binding we don't need to know the type.
347 
348  // Make sure that we don't print reserved keywords.
349  if (paramName == "lambda")
350  return "'" + paramName + "_'";
351  else
352  return "'" + paramName + "'";
353 }
354 
359 template<typename T>
360 inline std::string ParamString(const std::string& paramName, const T& value)
361 {
362  std::ostringstream oss;
363  if (paramName == "lambda") // Don't print reserved keywords.
364  oss << paramName << "_=" << value;
365  else
366  oss << paramName << "=" << value;
367  return oss.str();
368 }
369 
370 inline bool IgnoreCheck(const std::string& paramName)
371 {
372  return !IO::Parameters()[paramName].input;
373 }
374 
375 inline bool IgnoreCheck(const std::vector<std::string>& constraints)
376 {
377  for (size_t i = 0; i < constraints.size(); ++i)
378  {
379  if (!IO::Parameters()[constraints[i]].input)
380  return true;
381  }
382 
383  return false;
384 }
385 
386 inline bool IgnoreCheck(
387  const std::vector<std::pair<std::string, bool>>& constraints,
388  const std::string& paramName)
389 {
390  for (size_t i = 0; i < constraints.size(); ++i)
391  {
392  if (!IO::Parameters()[constraints[i].first].input)
393  return true;
394  }
395 
396  return !IO::Parameters()[paramName].input;
397 }
398 
399 } // namespace python
400 } // namespace bindings
401 } // namespace mlpack
402 
403 #endif
std::string tname
Type information of this parameter.
Definition: param_data.hpp:61
Linear algebra utility functions, generally performed on matrices or vectors.
Definition: cv.hpp:1
bool input
True if this option is an input option (otherwise, it is output).
Definition: param_data.hpp:73
static IO & GetSingleton()
Retrieve the singleton.
Definition: io.cpp:147
This structure holds all of the information about a single parameter, including its value (which is s...
Definition: param_data.hpp:52
#define TYPENAME(x)
The TYPENAME macro is used internally to convert a type into a string.
Definition: param_data.hpp:22
static std::map< std::string, util::ParamData > & Parameters()
Return a modifiable list of parameters that IO knows about.
Definition: io.cpp:154