I want to create this function:
void drawSquare(int x) {
tortuga.forward(x);
tortuga.right(90);
tortuga.forward(x);
tortuga.right(90);
tortuga.forward(x);
tortuga.right(90);
}
However, I get that the identifier "tortuga" is undefined.
I tried to modify the function like this:
void drawSquare(int x) {
ct::TurtleScreen scr;
scr.bgcolor({ "white" });
ct::Turtle tortuga(scr);
Home(tortuga);
tortuga.forward(x);
tortuga.right(90);
tortuga.forward(x);
tortuga.right(90);
tortuga.forward(x);
tortuga.right(90);
tortuga.pencolor({ "red" });
tortuga.speed(ct::TS_FASTEST);
scr.exitonclick();
}
I get that the identifier "tortuga" is defined now, which seems to work.However, 20ish windows appeared where in each window, the turtle only drew three sides of a square like the following image:
image
I expected a spiral to be drawn.
Here is all the program:
#include"CTurtle.hpp"
#include <iostream>
using namespace std;
#define Home(x) x.left(90)
namespace ct = cturtle;
int shellSize;
int initialShellSize;
void drawSquare(int x) {
ct::TurtleScreen scr;
scr.bgcolor({ "white" });
ct::Turtle tortuga(scr);
Home(tortuga);
tortuga.forward(x);
tortuga.right(90);
tortuga.forward(x);
tortuga.right(90);
tortuga.forward(x);
tortuga.right(90);
tortuga.pencolor({ "red" });
tortuga.speed(ct::TS_FASTEST);
scr.exitonclick();
}
int main(int argc, char** argv) {
std::cout << "Type the size of the outershell of the spiral: "; // Type a number and press enter
std::cin >> shellSize; // Get user input from the keyboard
initialShellSize = shellSize;
for (int i = 10; i <= initialShellSize; i = i + 10)
{
shellSize = initialShellSize - (initialShellSize/i);
drawSquare(shellSize);
}
return 0;
}
I've never used this library before, but it seems all you need to do is add a turtle parameter to your function and pass the turtle object to the function. This is not dissimilar to what you've already done with the x parameter. Parameter passing is a basic technique of the C++ language (and pretty much any programming language).
void drawSquare(ct::Turtle& tortuga, int x) {
Home(tortuga);
tortuga.forward(x);
tortuga.right(90);
tortuga.forward(x);
tortuga.right(90);
tortuga.forward(x);
tortuga.right(90);
tortuga.forward(x);
}
int main(int argc, char** argv) {
std::cout << "Type the size of the outershell of the spiral: "; // Type a number and press enter
std::cin >> shellSize; // Get user input from the keyboard
initialShellSize = shellSize;
ct::TurtleScreen scr;
scr.bgcolor({ "white" });
ct::Turtle tortuga(scr);
for (int i = 10; i <= initialShellSize; i = i + 10)
{
shellSize = initialShellSize - (initialShellSize/i);
drawSquare(tortuga, shellSize);
}
return 0;
}
I've used a reference ct::Turtle& tortuga instead of ct::Turtle tortuga. I'm guessing that is right, but as I said I've never used this library before.
And as already mentioned to get a square I'm guessing you need to call forward four times.
I've also put the call to Home inside the function, you might disagree.
Related
I am trying to pass 5th element of an array(Products[]) of class product to another function. The goal is to update the information of the element Product[5]. Everything seems to work fine except information of Product[5] variable is not updating.
Update: Problem solved by removing while(!EOF), thanks to Remy Lebeau.
The relevant part of Class:
class product
{
private:
float Wholesale_Price = 0;
float Retail_Price = 0;
string Supplier = "N/A";
string Note = "N/A";
int Stock_Amount = 0;
public:
string Name="N/A";
void UpdateRetailPrice(float New_Retail_Price)
{
Retail_Price = New_Retail_Price;
}
void UpdateProductAmount(int New_Stock_Amount)
{
Stock_Amount = New_Stock_Amount;
}
void UpdateWholesale_price(float New_Wholesale_Price)
{
Wholesale_Price = New_Wholesale_Price;
}
};
The relevant part of function:
void ReadProductFromFile(product* Products)
{
string Name, Supplier, Note, Wholesale_Price, Retail_Price, Stock_Amount;//wholesale price, stock amount,price are in string so that
//it becomes easy to use getline(). Use stoi() later for turning string to int.
ifstream ReadProductFromFile;
ReadProductFromFile.open("product.txt");
if (!ReadProductFromFile)
{
perror("Product File failed to open");
return;
}
while(!EOF)
{
/*read product info txt file------>*/
getline(ReadProductFromFile, Name);
getline(ReadProductFromFile, Wholesale_Price);
getline(ReadProductFromFile, Retail_Price);
getline(ReadProductFromFile, Stock_Amount);
/*update product info---------->*/
Products->Name = Name;
Products->UpdateWholesale_price(stoi(Wholesale_Price));
Products->UpdateProductAmount(stoi(Stock_Amount));
Products->UpdateRetailPrice(stoi(Retail_Price));
}
}
Relevant part of Main function:
int main(int argc, char const *argv[])
{
product Products[10];
ReadProductFromFile(Products+5);//is this the right way to send Products[5]? tried &(product[5]) but error
return 0;
}
Input:
Bananas
210
270
310
how to use pango markup in messagedialog text using variable
For example this code
void usb_boot::creation(){
//Gtk::MessageDialog dialogue(*this, listeDeroulante.get_active_text());
std::string message("Type de formatage : " + type), type1, chemin1;
Gtk::MessageDialog *dialogue = new Gtk::MessageDialog("Résumé", true, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO);
dialogue->set_title("Résumé");
dialogue->set_message("<span weight='bold'>message</span>",true);
dialogue->set_secondary_text("<b>listeDeroulante.get_active_text()</b>", true);
dialogue->set_default_response(Gtk::RESPONSE_YES);
int result = dialogue->run();
set_message and set_secondary_text have to print variables but just "see" word.
Is there a way to read like variables ?
While the std::stringstream solution works, I would suggest using simple string concatenation, through std::string's operator+:
#include <gtkmm.h>
int main(int argc, char **argv)
{
auto app = Gtk::Application::create(argc, argv, "so.question.q63886899");
Gtk::Window w;
w.show_all();
{
// Unformatted messages:
std::string primaryMessage = "Some message...";
std::string secondaryMessage = "Some more message details...";
Gtk::MessageDialog dialog(w, "Message dialog", true, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO);
dialog.set_title("Title");
// Add pango markup tags through string concatenation:
dialog.set_message("<span weight='bold'>" + primaryMessage + "</span>", true);
dialog.set_secondary_text("<b>" + secondaryMessage + "</b>", true);
dialog.run();
}
return app->run(w);
}
With this solution, no need to introduce an extra type.
I'm trying to call a boost::unit_test from code.
In a number of files I've got
BOOST_AUTO_TEST_SUITE(DataAccessSuite)
BOOST_AUTO_TEST_CASE(DateAppender)
{
...
}
BOOST_AUTO_TEST_SUITE_END()
For my dialog box I have a visitor to gather the IDs and names of all the test cases/suites
namespace {
unit_test::test_suite* init_unit_test_suite(int argc, char** argv) {
return 0;
}
using namespace std::string_literals;
struct test_visitor : unit_test::test_tree_visitor {
test_visitor(std::vector<std::tuple<std::string, unit_test::test_unit_id>>& tests) : m_tests(tests) {}
void visit(unit_test::test_case const& test) {
m_tests.emplace_back(std::make_tuple(suite + "/"s + static_cast<std::string>(test.p_name),test.p_id));
}
virtual bool test_suite_start(unit_test::test_suite const& ts) {
suite = ts.p_name;
return true;
}
virtual void test_suite_finish(unit_test::test_suite const&) {
suite = std::string();
}
std::string suite;
std::vector<std::tuple<std::string, unit_test::test_unit_id>>& m_tests;
};
}
TestDialogImpl::TestDialogImpl(wxWindow* parent) : TestDialog(parent)
{
// Make a list of test cases to show in my dialog box
unit_test::traverse_test_tree(unit_test::framework::master_test_suite(), test_visitor(m_tests), true);
for (auto& test : m_tests) {
m_listBox2->Append(wxString(std::get<0>(test)));
}
}
And here's my call to the test case
void TestDialogImpl::OnClick_RunButton(wxCommandEvent & event)
{
auto selection = m_listBox2->GetStringSelection();
char* argv[] = { "OptionModeller.exe","--run_test=DataAccessSuite/DateAppender" };
unit_test::framework::init(init_unit_test_suite, 2, argv);
auto finder = std::find_if(std::begin(m_tests), std::end(m_tests), [&selection](auto& v) { return std::get<0>(v) == selection; });
// This fails with setup_error(), but I don't know why?
unit_test::framework::run(std::get<1>(*finder), true);
}
Is there a way I could call the test and utilize the framework. I know I could alternatively call the free functions but that defeats the point of using BOOST_TEST
UPDATE
From #A Fagrell's idea
I changed the call of the test executor to
void TestDialogImpl::OnClick_RunButton(wxCommandEvent & event)
{
wxString selection = "--run_test=" + m_listBox2->GetStringSelection();
const char* option = static_cast<const char*>(selection);
char* argv[] = { "OptionModeller.exe" , (char*)(option)};
unit_test::unit_test_main(&init_unit_test_suite, 2, argv);
}
Seems to work ok, but does seem the wrong way of doing things. I would have expected to be able to call a test explicitly by id, rather than by fudging the command line args.
Is there a better way?
I'm on prgramming a menu for an 16x2 LCD for a small arduino project.
I'm nearly finished, but i do not understand the last small issue.
The following (simplified) code generates the problem:
int var1=0;
int var2=0;
typedef struct {
unsigned int item_value;
char item_name[17];
} Select_Item;
typedef struct {
char item_name[17];
int* variable;
Select_Item* list;
} Menu_Item;
Select_Item sel_one = { 0, "Selection 1" };
Select_Item sel_two = { 1, "Selection 2" };
Select_Item* sel_list[2] = { &sel_one, &sel_two };
Menu_Item menu_item1 = { "Item 1", &var1, NULL };
Menu_Item menu_item2 = { "Item 2", &var2, &sel_list };
Menu_Item* menu_list[2] = { &menu_item1, &menu_item2 };
It ends up with the following error:
sketch_feb08a.ino:24:53: error: cannot convert 'Select_Item* (*)[2]' to 'Select_Item*' in initialization
In the code i'm accessing the values from the variables and show it in the display and once edited i can write it back to the variable. That was not the problem as long as i had just numbers to show/edit.
Now for ease of use i wanted to add some kind of option menu, where the user can choose from the options. The item_name should be displayed, instead of the raw value, but of course the item_value should be used behind the scene.
That is why i introduced the Select_Item struct.
I don't understand the error message. What's wrong here?
I think what you're trying to do is something like this:
int var1=0;
int var2=0;
typedef struct {
unsigned int item_value;
char item_name[17];
} Select_Item;
typedef struct {
char item_name[17];
int* variable;
Select_Item* list;
} Menu_Item;
Select_Item sel_one = { 0, "Selection 1" };
Select_Item sel_two = { 1, "Selection 2" };
Select_Item sel_three = {2, "Selection 3" };
Select_Item sel_four = {3, "Selection 4" };
Select_Item* sel_list_1[] = { &sel_one, &sel_two };
Select_Item* sel_list_2[] = { &sel_three, &sel_four };
Menu_Item menu_item1 = { "Item 1", &var1, sel_list_1[0] }; // Note the syntax here
Menu_Item menu_item2 = { "Item 2", &var2, sel_list_2[0] }; // Note the syntax here
Menu_Item* menu_list[2] = { &menu_item1, &menu_item2 };
// Added for testing
int main()
{
printf("Menu item '%s'\n", menu_list[0]->item_name);
printf(" %d - %s\n", menu_list[0]->list[0].item_value, menu_list[0]->list[0].item_name);
printf(" %d - %s\n", menu_list[0]->list[1].item_value, menu_list[0]->list[1].item_name);
printf("Menu item '%s'\n", menu_list[1]->item_name);
printf(" %d - %s\n", menu_list[1]->list[0].item_value, menu_list[1]->list[0].item_name);
printf(" %d - %s\n", menu_list[1]->list[1].item_value, menu_list[1]->list[1].item_name);
return 0;
}
Note the syntax for the initialization of menu_item1 and menu_item2.
I added main() just so I could test this with a normal C compiler (since I don't have an Arduino with an LCD handy). The output from my testing looks like this:
Menu Item 'Item 1'
0 - Selection 1
1 - Selection 2
Menu Item 'Item 2'
3 - Selection 3
4 - Selection 4
And I think that's what you're trying to achieve with your data structures. You'll just need to adapt this to your Arduino code and use these data structures to manage the menu selections on your LCD.
I need to be able to have boost::program_options parse an array of doubles
that are passed on a command line. For positive doubles, this is no problem,
of course (use multitoken with std::vector<double> in add_options), but for
negative ones, I know that these are ambiguous arguments.
Here is a demonstration of what I would like to take in:
mycommand --extent -1.0 -2.0 -3.0 1.0 2.0 3.0 --some-other-argument somevalue
extent is to be backed by a Bounds class with at least one constructor
that takes in six individual T arguments (in this case -- double).
template <typename T>
class Bounds
{
public:
typedef T value_type;
typedef typename std::vector< Range<T> >::size_type size_type;
typedef typename std::vector< Range<T> > Ranges;
Bounds( T minx, T miny, T minz,
T maxx, T maxy, T maxz)
{
// fill Ranges vector
}
private:
Ranges ranges;
};
What else must I supply to support using add_options take in the Bounds class? I'd
like to do something similar to this. Possible?
namespace po = boost::program_options;
po::options_description options("options");
options.add_options()
("extent,e", po::value< Bounds< double > >(), "Extent to clip points to")
po::variables_map vm;
po::store(po::command_line_parser(argc, argv).
options(options).positional(p).run(), vm);
po::notify(vm);
if (vm.count("extent"))
{
Bounds<double> bounds = vm["extent"].as< Bounds<double> >();
// do other stuff
}
The trick is to force boost to classify all numbers as positional values (not to be confused with positional_options_description. The way you do that is define a style_parser and give it to the command_line_parser as an extra_style_parser:
#include <boost/program_options/option.hpp>
#include <boost/lexical_cast/try_lexical_convert.hpp>
#include <boost/program_options/value_semantic.hpp>
using po = boost::program_options;
std::vector<po::option> ignore_numbers(std::vector<std::string>& args)
{
std::vector<po::option> result;
int pos = 0;
while(!args.empty()) {
const auto& arg = args[0];
double num;
if(boost::conversion::try_lexical_convert(arg, num)) {
result.push_back(po::option());
po::option& opt = result.back();
opt.position_key = pos++;
opt.value.push_back(arg);
opt.original_tokens.push_back(arg);
args.erase(args.begin());
} else {
break;
}
}
return result;
}
Once you have it, this is how you use it:
po::store(po::command_line_parser(argc, argv)
.extra_style_parser(&po::ignore_numbers)
.options(commands)
.run(), vm);
You can now use negative numbers and short command line arguments at the same time.
However, there's still a problem, there's no way to restrict the number of tokens each argument takes, which can be problematic if you use positional arguments. For example, something like this won't work:
foo --coords 1 2 3 4 bar.baz
In order to fix this, we'll need to add a way to force the number of tokens an argument requires:
template<class T, class charT = char>
class bounded_typed_value : public po::typed_value<T, charT>
{
public:
bounded_typed_value(T* store_to)
: typed_value<T, charT>(store_to), m_min(-1), m_max(-1) {}
unsigned min_tokens() const {
if(m_min < 0) {
return po::typed_value<T, charT>::min_tokens();
} else {
return (unsigned)m_min;
}
}
unsigned max_tokens() const {
if(m_max < 0) {
return po::typed_value<T, charT>::max_tokens();
} else {
return (unsigned)m_max;
}
}
bounded_typed_value* min_tokens(unsigned min_tokens)
{
if(min_tokens > 1) {
po::typed_value<T, charT>::multitoken();
}
m_min = min_tokens;
return this;
}
bounded_typed_value* max_tokens(unsigned max_tokens)
{
if(max_tokens > 1) {
po::typed_value<T, charT>::multitoken();
}
m_max = max_tokens;
return this;
}
bounded_typed_value* fixed_tokens(unsigned num_tokens)
{
if(num_tokens > 1) {
po::typed_value<T, charT>::multitoken();
}
m_min = num_tokens;
m_max = num_tokens;
return this;
}
private:
int m_min;
int m_max;
};
template<class T, class charT = char>
bounded_typed_value<T, charT>*
bounded_value()
{
return new bounded_typed_value<T, charT>(0);
}
You can now put it all together like this:
po::positional_options_description p;
p.add("file-name", -1);
boost::program_options::options_description desc;
desc.add_options()
("coords,c", boost::program_options::bounded_value<std::vector<double>>()->fixed_tokens(4), "Bounding box");
po::store(po::command_line_parser(argc, argv)
.extra_style_parser(&po::ignore_numbers)
.positional(p)
.options(commands)
.run(), vm);
The approach to handling negative numbers specified here might also work for you.
I was parsing it by the simple parser
store(command_line_parser(argc, argv).options(commands).run(), vm);
, but solution was to use the extended
one:
parse_command_line
The easy way would be to wrap your parameters in quotes:
mycommand --extent '-1.0 -2.0 -3.0 1.0 2.0 3.0' --some-other-argument somevalue