Kelvin Verhey

@KelvinVerhey (43) • Muskoka Tech Lab
A group of people meeting in a common space when the weather permits to hack, hammer, and do tech things.
Repl.it Desktop 😯
posted to Ask by PDanielY

Electron if you have used Discord is a brutal choice on system resources. It's stable but please don't use it. Code something native. Ughghgh... I really don't care how easy it is for you to code an application. We live in an age where ease is more important than the care it took to code something efficient. We have killed Flash, Adobe Air, and Silverlight, for a reason. Electron is in the same boat. Sorry if I'm going to upset web devs, but if I want to use a web page for an application I'll stick to a tab in my web browser.

Repl.it Desktop 😯
posted to Ask by PDanielY

@RyanRana how loose is this to be interpreted?

You agree not to access Neoreason’s content through any technology or means other than the pages of the Service itself or other explicitly authorized means that Neoreason may designate.

Right now this is an unauthorised project. With out that consent from Neoreason [Repl.IT] you are in violation of the terms of service. Regardless of the electron debate. This is a bad idea. Get permission first. Work out the details.

I can assure the reason they stopped this project, was because of the sheer amount of extra overhead this is going to take them to maintain a cross platform IDE. If they wanted to do a desktop app, it likely would have been just easy for them to talk to microsoft to get a plugin made for VSCode. Since Repl.IT uses the VSCode editor there is a reason they have chosen not to make this a reality. I fail to see how this project is going to improve on what is already provided that isn't going to make more overhead or work for the developers of this website.

I did something back in 2012 when I wrote a bot for kongregate.com. I offered to do something similar to what you all are proposing here. I wrote a client, front end, and had a vision to expand on what the website was providing to create something similar to the steam engine. The problem is this created serious issues with the intended purpose of kongregate. There are implications to Repl.IT also by choosing to go against the models that are being provided by this website and to do an unauthorised project to interface with it.

The original poster is going to attempt to employ tactics to convince them this is a good idea. There is already a project in the works which could also be contributed to, and is being ignored. So now there is going to be at least 2 electron based clients for the devs here to worry about. Poorly written code can and will put extra overhead on the servers. Who knows how well the backend is written, what caveats are implemented into the API that is exposing any of this stuff. There is way more to consider here than just simply saying... "Let's write a new desktop app in a resource hungry cross platform wrapper with zero blessings from the developers of this website."

Repl.it Desktop 😯
posted to Ask by PDanielY

@AppliDev has nothing to do with not helping. Just putting out there this is terrible idea. This is going to result in a bad user experience. HTML/CSS is a comfort zone. Break out of it. It's going to be Adobe Photoshop slow to load, and bog down your machine on startup... no good is going to come from this. Slack Electron Desktop app uses a gig of ram to just run a basic chat session. I no longer use it. This reminds me of Windows 3.11 running on DOS. It was a bad idea then... this making the web browser the new operating system is a worse idea. Making web browser apps into desktop apps is a double bad idea. It might make it easier and have some serious pros for ease of entry, and other good advantages, but the sheer garbage performance from electron apps just screams bad idea. This is like when a bunch of artists decided to write a game in unity using a visual interface similar to blueprints in unreal and resulted in a game that crawled on modern gaming systems that could get respectable frame rates in much more intensive and complicated games. There is a time and place... but when it comes to development and productivity, find the most painless way you can for the developers not for you to code the tool.

I made TETRIS
posted to Share by DynamicSquid

this has some serious bugs. when you do a tetris - 4 line clear. it only clears a single line. then causes errors with tiles and things randomly disappearing. also, it's possible to collide pieces to merge squares. no space or way to drop pieces faster. other than that. not bad. definitely have some polishing to do. keep up the good work.

Need a contact please
posted to Ask by MeredithSmith

As an individual that runs programs in schools for kids, I'm also constantly fighting with school districts to allow programs to run. It's like no one remembers that kids can and do have the ability to learn programming and work with hardware to learn real skills to get them involved in desperately needed STEM jobs across the world. Petition the parents of your students to write letters to the district.

If that door still stays shut, then there is some serious brainstorming that can still be accomplished. Also depends on what kind of computers you have access to. There are other options like buying a stack of CD's and burning LUBUNTU or something to create live CD's that don't need to be installed, and they come with GCC assuming the machines have CD-ROMs, you can also mock install python and do programming bypassing the entire school system. Bring in a home laptop you can guide the students on, you will find they are able to still make something happen.

I've been fighting since 1995 to make sure kids in schools have access to programs. The school boards are not for education of this type. Many schools are also just dumping their computer labs entirely, and moving to chrome books.

These are grade 1 and 2 students that I taught a stripped down version of Dijkstra's Shunting Yard Algorithm to. One of the students picked it up in 8 minutes. Learning how to do this long before any understanding of operator precedence, and embracing a basic understanding of stacks and queues. We had no access to a computer, and did it entirely on a whiteboard. They were able not only do the maths, but learn about Polish Notation and how stack based operations in computers work in a single 45 minute period. Think outside the box if you have to. You can still do a tremendous amount with them.

I have pictures of kids from grade 3-8 tearing down computers and rebuilding systems. Learning how to troubleshoot power supplies, install and test ram, replace batteries on motherboard and configuring BIOS settings. Starting Oct 18th. We will be going over building network cables, configuring a gateway, and setting up a server. Worst case scenario build your own program, get your own lab going. Don't give up.

Your students need you to fight for them. This is important.

Repl.it Desktop 😯
posted to Ask by PDanielY

@eankeen that would be the smart choice, to pool resources on an existing project instead of splitting everyone up on two projects of effectively the same type. This whole idea to start a second competing project seems silly. Unless they are forking/cloning the other teams electron project you were helping contribute to. This is a serious waste of resources.

Repl.it Desktop 😯
posted to Ask by PDanielY

@leon332157 I run classes in my community to help youth from grades 1 to 8. Run a tech lab out of my living. Worked in the 90's for a charity to help build schools in Africa and equip them with computers. Recycle eWaste to build computers and laptops that get sent out to low income families and teach and mentor coding classes on line for people all over the world. Donate my time to youth, and people in need and help facilitate low income families with repairs to their technology. Writing tutorials and actually being constructive in comments instead of just being... LEAVE. Seriously?

Repl.it Desktop 😯
posted to Ask by PDanielY

@leon332157 There are much better ways to increase the awareness of the website. Write more tutorials, help answer coding questions, setup more schools/classes. That is something seriously lacking on the site. Help people write better code, provide meaningful answers, and solutions. Help team building on existing projects. There is a tremendous amount of division here. Post snippets of your amazing code on social media. Draw them to the site. Do some mentoring in a school and point kids to the website. Isn't that the primary function of the site, education of the masses? I'm well aware of the infinite potential of open source driving innovation. But what are your projects really offering beyond what this site already offers other than repackaging the site as you mention into a resource hungry engine that bogs down computers? Having a meaningful conversation with a principal, teacher, or even the superintendent of a school board about getting an after school program, or maybe one on lunch hours, or a march break code camp going and using repl.it to conduct the classes. I would think that would be far more likely to raise awareness than creating applications of this nature.

https://9to5google.com/2015/01/21/whatsapp-plus-cease-and-desist/

A lot of those 3rd party apps for those websites you listed are targeted for scraping data. You are still skirting what was the main issue and is outlined in the TOS of this website, that these apps, like the websites that have those many 3rd party apps you've listed is largely a violation of their TOS.

@AppliDev just keeps shooting down existing projects as not official. That is the main point... regardless of how you package this problem. This isn't either. Your project like you say to others is not official. It's not... and at present like all the other applications is still a violation of the TOS. Could we maybe open a meaningful discussion about how to support the website, grow the community, remove the division, clean up the forums, and get more classes/schools setup? Things that might actual help the website grow? Things that might actually draw people to the community and build it's utility and core features that are already trying to focus on productivity and good reuse of much stronger open source community projects.

Get out there, change the world for the better. There are schools in abundance in the world that don't even have computer labs. How can they reach the website when they don't even have a computer to do that? There are deeper core problems to solve here. I'm not trying to be a jerk, but this website needs help in other ways that are honestly much more productive.

I've heard Tim Chen is leaving according to the discord. A website like this has strong competition. Contributing to VSCode directly affects this website, because they use it as their core engine. Look at the open source projects they use, contribute to those. Open source struggles in general to get developers that have any real knowledge. This website could not exist without it. Think cohesiveness, bringing people together and helping them be as productive as they can be.

There are ways to just change your status in discord without having to write a custom app and repackage the entire website to do it. I'm not shooting down your learning experience, but the app you wrote is a much more convoluted method of accomplishing a goal.

https://www.youtube.com/watch?v=hNPNLBTZMak

Anything better than Java? (Not easier...)
posted to Ask by FINALBOSS

@FINALBOSS Haxe can be a real nightmare if you are not familiar with cross compilers. Since it's also a very small project, it has some issues with getting updates and patches. The android compilation is totally broken, and many of the graphics libs have problems. Dig through here to make sure none of the open issues are going to cause you problems.

https://github.com/HaxeFoundation/haxe/issues

How to make a program that, once closed, opens another window?
posted to Ask by willowblanket

@mwilki7 not a good idea to introduce fork bombs etc. servers were taken down with such silly antics.

Need a contact please
posted to Ask by MeredithSmith

@MeredithSmith Groovy. Hope the program goes well. World knows we need for people in STEM. Be well.

Need a contact please
posted to Ask by MeredithSmith

@MeredithSmith Thank you for trying to support your students like this. The world needs more teachers like you. I hope you find a solution to the classroom issue on repl.it. Keep being awesome. Can I ask what programming languages you cover?

How to return to another line of code in c++
posted to Ask by BFDMod

To tackle this problem let's focus on the core of what you need to solve, at least from what I'm able to extract from your code. Don't feel bad, this is a common problem with infinite complexity when a core piece of flow as @Geocube101 has explain with looking into using a while loop. That is good advice. Context though can be hard when the rest of the code is adding so much overflow. So we'll strip this back down.

From your cout lines we have a menu...

//main menu
std::cout <<"1. Sandwiches/Burgers\n2. Desert\n3. Meats\n4. Drinks\n";
//sandwiches
std::cout <<"1. Chicken Sandwich\n2. Fish Sandwich\n3. Double Cheese Burger\n4. Cheese Burger\n5. Ham Sandwich\n6. Pork Sandwich\n";
//dessert
std::cout <<"1. Sunday\n2. Root Beer Float\n3. Ice Cream Sandwich\n";
//meats
std::cout <<"1. Chicken Breasts\n2. Baby Back Ribs\n3. Pork Loin\n4. Pulled Pork\n";
//drinks
std::cout <<"1. Coke\n2. Pepsi\n3. Root Beer\n4. Fanta\n5. Cream Soda\n";

Lets ignore the prices for now and just how to handle the menu navigation. This can be tricky. So as mentioned a while loop would be handy, but so will an understanding of arrays, for loops, and a few other things. First let's get the string options addressed.

std::string mainMenu[] = {
  "Main",
  "Sandwiches/Burgers",
  "Desserts",
  "Meats",
  "Drinks"
};
int mainMenuLen = 4;

This has several benefits. We can loop over it, it's easier to expand, modify, and we can also use a little hack to embed the menu as the first entry in the array. Why this works...

We want the menu to be ordered starting at 1. Since arrays in C/C++ are zero based if we have to use a for loop, it would traditionally follow something like this.

for(int i = 0; i < len; ++i) { std::cout << i << ". " << menuOption[i] << std::endl; }

This will start our menu at "0. Menu Option". So we would either need to i+1 in the output. Or we need to start the index of the for loop at 1 instead of 0.

for(int i = 1; i < len; ++i) { std::cout << i << ". " << menuOption[i] << std::endl; }

However, that means we would need to pad string array with an empty entry and then add the needed entries. This creates a gap. Inside the gap, we can store the Title and this saves us having to create other janky methods of either passing the title as argument to a function that displays the menu, or create another array of the title. It's just easier to store the title in that free space and it will be addressed as array[0] and then the menu items will start a array[1] and move forward so we get the proper display of the menu with no additional maths. This is a cleaner option and reduces complexity of the code for free.

We use a 2 dimensional array to setup the rest of the menu options...

std::string menuOptions[][6] = {
  {
  "Sandwich",
  "Chicken Sandwich",
  "Fish Sandwich",
  "Double Cheese Burger",
  "Ham Sandwich",
  "Pulled Pork Sandwich"
  },{
  "Dessert",
  "Sunday",
  "Root Beer Float",
  "Ice Cream Sandwich"
  },{
  "Meat",
  "Chicken Breast",
  "Baby Back Ribs",
  "Pork Loin",
  "Pulled Pork"
  },{
  "Drink",
  "Coke",
  "Pepsi",
  "Root Beet",
  "Fanta",
  "Cream Soda"
  }
};
int menuOptionsLen[] = {5, 3, 4, 5};

So now we have a reasonable setup that should be pretty easy to modify. We just need to make sure we track the last value correctly. Then we need to hook up some sort of function that can display the menus.

std::cout with all the << and other shenanigans. So we'll make a few little old school C style macros. Despite them being a violation of C++ standard, they are handy, reduce code complexity and clean up the mess that is C++ iostreams.

These are for handling some new line parsing and other formatting to save some typing and reduce the likelihood of an error.

#define print(format) std::cout << format
#define printnl(format) print(format << std::endl)
#define nlprint(format) print(std::endl << format)
#define nlprintnl(format) printnl(std::endl << format)

Now let's tackle a menu display function.

It will need to take a couple arguments. We need the array with the menu options to display, and we'll need the last entry value. A for loop can be used to display the options and build the output. The title should be displayed and the menu options for input should also be displayed. A basic one might look something like...

void displayMenu(std::string array[], int last) {
  nlprintnl(array[0] << " Menu");

  for(int i = 1; i <= last; ++i) {
    printnl(i << ". " << array[i]);
  }

  nlprintnl("Please select an option [1-" << last << "]:");
}

Then we can call it using...

void displayMenu(std::string array[], int last) {
  nlprintnl(array[0] << " Menu");

  for(int i = 1; i <= last; ++i) {
    printnl(i << ". " << array[i]);
  }

  nlprintnl("Please select an option [1-" << last << "]:");
}

This is probably quite a bit to digest. And likely covering a huge amount of syntax you are completely unfamiliar with, so ask questions if you have them. Let's test the output, to make sure it's sort of doing close to what we need.

That doesn't look too terrible. I guess we are sort of on the right path. Okay. We still need to handle the input for the menu options. So let's address that. std::cin a real nightmare. I have posted in other sections of this forum how to parse/validate cinful input. This has way too many drawbacks. So we're going to create a custom getch to mimic the old unechoed DOS input that only reads a single character.

We need to add 2 headers.

termios.h gives us the ability to modify how the terminal acts
stdio.h allows us to use the C getchar to read a single character.

#include <termios.h>
#include <stdio.h>

And write up the replacement. We'll use this to just read a single unechoed key. This is only useful in Linux. If you need a win32 modern replacement you can look here.

https://helloacm.com/modern-getch-implementation-on-windows-cc/

char getch() { 
  tty working;
  char c;
  tcgetattr(0, &working);
  working.c_lflag &= ~ICANON;
  working.c_lflag &= ~ECHO;  
  tcsetattr(0, TCSANOW, &working); 
  c = getchar();
  working.c_lflag |= ECHO;
  working.c_lflag |= ICANON;
  tcsetattr(0, TCSANOW, &working);
  return c; 
}

Some references:

https://www.daemon-systems.org/man/tcgetattr.3.html
http://man7.org/linux/man-pages/man3/termios.3.html

Basically we grab the current settings on the terminal.
Shut off the buffered i/o.
Disable echo to the console.
Read the character.
Turn buffered i/o back on.
Enable echo to console.
Return the character we read in.

We also need a few other little terminal hacks that work on linux only.

#define cls() std::cout << "\033[2J\033[0;0H"
#define hideCursor() std::cout << "\033[?25l"
#define showCursor() std::cout << "\033[?25h"

So now that we have a getch() replacement. We don't need to worry about all the janky std::cin stuffs and move on to validating the input. Once the menus are displayed we need to determine what menu option has been pressed. We know the limits 1 to last entry, those are simple enough to compare against in a switch statement to test for. We'll also want to do some ascii maths so we can convert the char literals that getch() is going to pass back. '1', '2', etc are not useful, but if we look up in an ASCII table...

This shows us that char literal '0' has a decimal value of 48. So '1' would be 49. So if we take our char stored in ch and subtract 48 from it once we have validated it, we will be able to get an int value of 1,2, etc. However, the array for the alternate menu options is 0 based for the first entry, so we can actually subtract 49 instead of 48 to get the correct offset off the main menu. When we validate the sub-menu items 48 can be used since we want the actual item selected. We'll need to write a special case for this.

Let's put this mess together with the control code for the input, expansion on the menus, and main loop to control flow.

#include <iostream>
#include <termios.h>
#include <stdio.h>

typedef struct termios tty;

std::string mainMenu[] = {
  "Main",
  "Sandwiches/Burgers",
  "Desserts",
  "Meats",
  "Drinks",
};
int mainMenuLen = 4;

std::string menuOptions[][6] = {
  {
  "Sandwich",
  "Chicken Sandwich",
  "Fish Sandwich",
  "Double Cheese Burger",
  "Ham Sandwich",
  "Pulled Pork Sandwich"
  },{
  "Dessert",
  "Sunday",
  "Root Beer Float",
  "Ice Cream Sandwich"
  },{
  "Meat",
  "Chicken Breast",
  "Baby Back Ribs",
  "Pork Loin",
  "Pulled Pork"
  },{
  "Drink",
  "Coke",
  "Pepsi",
  "Root Beer",
  "Fanta",
  "Cream Soda"
  }
};
int menuOptionsLen[] = {5, 3, 4, 5};

//std::cout print replacements
#define print(format) std::cout << format
#define printnl(format) print(format << std::endl)
#define nlprint(format) print(std::endl << format)
#define nlprintnl(format) printnl(std::endl << format)

//terminal macros
#define cls() std::cout << "\033[2J\033[0;0H"
#define hideCursor() std::cout << "\033[?25l"
#define showCursor() std::cout << "\033[?25h"

char getch() { 
  tty working;
  char c;
  tcgetattr(0, &working);
  working.c_lflag &= ~ICANON;
  working.c_lflag &= ~ECHO;  
  tcsetattr(0, TCSANOW, &working); 
  c = getchar();
  working.c_lflag |= ECHO;
  working.c_lflag |= ICANON;
  tcsetattr(0, TCSANOW, &working);
  return c; 
}

#define invalidInput     -1
#define backSelected     -2
#define checkoutSelected -3
#define quitSelected     -4

int getValue(bool isMain, int last) {
  int r;

  for(char ch;;) {
    r = invalidInput;
    ch = getch();
    if(ch >= '1' && ch <= (last + 48)) {
      r = ch - ((isMain) ? 49 : 48);
    } else if(isMain) {
      if(ch == 'c' || ch == 'C')
        r = checkoutSelected;
      else if(ch == 'q' || ch == 'Q') {
        r = quitSelected;
      }
    } else if((!isMain) && (ch == 'b' || ch == 'B')) {
      r = backSelected;
    }
    if (r != invalidInput) break;
  }
  return r;
}

void displayMenu(bool isMain, std::string array[], int last) {
  std::string extras;
  
  cls();
  nlprintnl(array[0] << " Menu");
  for(int i = 1; i <= last; ++i) {
    printnl(i << ". " << array[i]);
  }
  if (!isMain) {
    printnl("B. Go Back");
    extras = "B";
  } else {
    printnl("C. Checkout");
    printnl("Q. Quit");
    extras = "CQ";
  }

  nlprintnl("Please select an option [1-" << last << " or " << extras << "]:");
}

int main() {
  cls();
  hideCursor();

  bool looping = true;
  bool checkingOut = true;
  
  for(bool isMain = true; looping;) {
    int selection;

    if(isMain) {
      displayMenu(isMain, mainMenu, mainMenuLen);
      selection = getValue(isMain, mainMenuLen);
      switch (selection) {
        case checkoutSelected: checkingOut = true;
        case quitSelected: looping = false; break;
      }
      isMain = false;
      
    } else {
      displayMenu(isMain, menuOptions[selection], menuOptionsLen[selection]);
      selection = getValue(isMain, menuOptionsLen[selection]);
      if (selection != backSelected) {
        //loop up the value
        //store in some of transaction list
        //or just update some sort of tally counter
      }
      isMain = true;
    }
  }

  cls();
  showCursor();
  nlprint("end of line");
  return 0;
}

We still have some problems to address here. We have no way to attach values to the menu items. We also have not written the total, tabulation or checkout features and we have no method create a new order/clear an existing. In order order to deal with the menu items efficiently and attach a price, a structure with members is recommended. Let's draft that up.

typedef struct {
  std::string item;
  float cost;
} TMenuItem;

Structs have members, in this case we have an item defined as a string, and a cost defined as floating point value. We have assigned it a name of TMenuItem. So we now have a custom type definition with that name. We can now think about upgrading the string array that is holding the menu options for the items.

TMenuItem mainMenu[] = {
  "Main", 0,
  "Sandwiches/Burgers", 0,
  "Desserts", 0,
  "Meats", 0,
  "Drinks", 0
};

TMenuItem menuOptions[][6] = {
  {
  "Sandwich", 0,
  "Chicken Sandwich", 2.22,
  "Fish Sandwich", 4.54,
  "Double Cheese Burger", 7.99, 
  "Ham Sandwich", 5.45,
  "Pulled Pork Sandwich", 6.34
  },{
  "Dessert", 0,
  "Sunday", 2.99,
  "Root Beer Float", 1.79,
  "Ice Cream Sandwich", 0.89,
  },{
  "Meat", 0,
  "Chicken Breast", 3.99,
  "Baby Back Ribs", 11.99,
  "Pork Loin", 9.56,
  "Pulled Pork", 8.65,
  },{
  "Drink", 0,
  "Coke", 0.99,
  "Pepsi", 0.99,
  "Root Beer", 0.99,
  "Fanta", 0.99,
  "Cream Soda", 1.29
  }
};

This prompts that we also need to update the displayMenu function and make a few other changes to display the cost on the menu items, write a janky pad function as std::string along with most of the std::namespace is nightmare. printf in C has much nicer and way easier to use string manipulation for formatting. That's a talk for another time. Let's get this updated.

void displayMenu(bool isMain, TMenuItem array[], int last) {
  cls();
  nlprintnl(array[0].item << " Menu");
  for(int i = 1; i <= last; ++i) {
    print(i << ". " << array[i].item);
    if(!isMain) {
      std::string cost = toStr(array[i].cost);
      std::string pad = std::string(35 - array[i].item.length(), ' ');
      printnl(pad << "$" << cost); 
    } else {
      print(std::endl);
    }
  }

  std::string extras;
  if (!isMain) {
    printnl("B. Go Back");
    extras = "B";
  } else {
    printnl("C. Checkout");
    printnl("Q. Quit");
    extras = "CQ";
  }
  nlprintnl("Please select an option [1-" << last << " or " << extras << "]:");
}

That is so janky. As C coder, C++ totes all these benefits, and you end up with that nightmare of a function. If any of you other C++ coders know of an easier way to implement that, please post a reply. I am not a C++ coder, so took some liberties with some google fu trying to find a solution. Criticise that at will. It is seriously janky.

With that out of the way, this should give you enough code to be able to sort out the rest. I strongly urge you to look up std::vector for building your order list. And write out some of display. Add in an order reset, or extend some deeper functionality to allow replacing, removing and updating an order list. Would also be useful to show on the main menu what the current order is, and to display the tally. Hope this helps... Here's the last iteration of the code as a whole.

#include <iostream>
#include <termios.h>
#include <stdio.h>
#include <sstream>
#include <string>

template <typename Type> std::string toStr(const Type & t) {
  std::ostringstream os;
  os << t;
  return os.str ();
}

typedef struct termios tty;

typedef struct {
  std::string item;
  float cost;
} TMenuItem;

TMenuItem mainMenu[] = {
  "Main", 0,
  "Sandwiches/Burgers", 0,
  "Desserts", 0,
  "Meats", 0,
  "Drinks", 0
};
int mainMenuLen = 4;

TMenuItem menuOptions[][6] = {
  {
  "Sandwich", 0,
  "Chicken Sandwich", 2.22,
  "Fish Sandwich", 4.54,
  "Double Cheese Burger", 7.99, 
  "Ham Sandwich", 5.45,
  "Pulled Pork Sandwich", 6.34
  },{
  "Dessert", 0,
  "Sunday", 2.99,
  "Root Beer Float", 1.79,
  "Ice Cream Sandwich", 0.89,
  },{
  "Meat", 0,
  "Chicken Breast", 3.99,
  "Baby Back Ribs", 11.99,
  "Pork Loin", 9.56,
  "Pulled Pork", 8.65,
  },{
  "Drink", 0,
  "Coke", 0.99,
  "Pepsi", 0.99,
  "Root Beer", 0.99,
  "Fanta", 0.99,
  "Cream Soda", 1.29
  }
};
int menuOptionsLen[] = {5, 3, 4, 5};

//std::cout print replacements
#define print(format) std::cout << format
#define printnl(format) print(format << std::endl)
#define nlprint(format) print(std::endl << format)
#define nlprintnl(format) printnl(std::endl << format)

//terminal macros
#define cls() std::cout << "\033[2J\033[0;0H"
#define hideCursor() std::cout << "\033[?25l"
#define showCursor() std::cout << "\033[?25h"

char getch() { 
  tty working;
  char c;
  tcgetattr(0, &working);
  working.c_lflag &= ~ICANON;
  working.c_lflag &= ~ECHO;  
  tcsetattr(0, TCSANOW, &working); 
  c = getchar();
  working.c_lflag |= ECHO;
  working.c_lflag |= ICANON;
  tcsetattr(0, TCSANOW, &working);
  return c; 
}

#define invalidInput     -1
#define backSelected     -2
#define checkoutSelected -3
#define quitSelected     -4

int getValue(bool isMain, int last) {
  int r;

  for(char ch;;) {
    r = invalidInput;
    ch = getch();
    if(ch >= '1' && ch <= (last + 48)) {
      r = ch - ((isMain) ? 49 : 48);
    } else if(isMain) {
      if(ch == 'c' || ch == 'C')
        r = checkoutSelected;
      else if(ch == 'q' || ch == 'Q') {
        r = quitSelected;
      }
    } else if((!isMain) && (ch == 'b' || ch == 'B')) {
      r = backSelected;
    } 
    if (r != invalidInput) break;
  }
  return r;
}

void displayMenu(bool isMain, TMenuItem array[], int last) {
  cls();
  nlprintnl(array[0].item << " Menu");
  for(int i = 1; i <= last; ++i) {
    print(i << ". " << array[i].item);
    if(!isMain) {
      std::string cost = toStr(array[i].cost);
      std::string pad = std::string(35 - array[i].item.length(), ' ');
      printnl(pad << "$" << cost); 
    } else {
      print(std::endl);
    }
  }

  std::string extras;
  if (!isMain) {
    printnl("B. Go Back");
    extras = "B";
  } else {
    printnl("C. Checkout");
    printnl("Q. Quit");
    extras = "CQ";
  }
  nlprintnl("Please select an option [1-" << last << " or " << extras << "]:");
}

int main() {
  cls();
  hideCursor();

  bool looping = true;
  bool checkingOut = true;
  
  for(bool isMain = true; looping;) {
    int selection;

    if(isMain) {
      displayMenu(isMain, mainMenu, mainMenuLen);
      selection = getValue(isMain, mainMenuLen);
      switch (selection) {
        case checkoutSelected: checkingOut = true;
        case quitSelected: looping = false; break;
      }
      isMain = false;
      
    } else {
      displayMenu(isMain, menuOptions[selection], menuOptionsLen[selection]);
      selection = getValue(isMain, menuOptionsLen[selection]);
      if (selection != backSelected) {
        //loop up the value
        //store in some of transaction list
        //or just update some sort of tally counter
      }
      isMain = true;
    }
  }

  cls();
  showCursor();
  nlprint("end of line");
  return 0;
}

I'm sure you're going to have questions, ask... I'll be more than happy to expand on this. Keep your stick on the ice.

How to return to another line of code in c++
posted to Ask by BFDMod

@AquaMarine0421 Bad habits are hard to break. Better just to avoid them. Keep your head up. Never stop programming, and enjoy the journey. It's a worthy one that opens doors to possibility. Study lots of code, as much as you can. Over time you'll see things. I like to just practice on little snippets of code looking for better ways to tackle a problem. Sat down last night before going out for a walk and took a snippet from another piece of repl.it share on practicing with binary search trees.

Original:

void Tcase(Node** root){
    int data = 0;
    while(1){
        scanf("%d",&data);
        if(data==0)
            break;
        createBST(root,data);
    }
}

It's not terrible code, but it's a little janky. So thought about trying to get rid of that silly break creating a little bit of spaghetti in the middle of the while.

Attempt 1

void Tcase(Node** root){
  int data = 0;
  do {
    scanf("%d",&data);
    if(data != 0)
     createBST(root,data);
  } while (data != 0);
}

This doesn't really improve much. Added two conditionals, but it does get rid of the break. Not really impressed with that one.

Attempt 2

void Tcase(Node** root){
  int data = 0;
  do {
    scanf("%d",&data);
    if(data) createBST(root,data);
  } while (data != 0);
}

The janky expression for the != test in the if expression. Just flipped that, but still didn't really improve much. Thought of maybe dumping the while and possibly messing around with a for loop instead.

Attempt 3

void Tcase(Node** root){
  int data = 0;
  for(;;) {
    scanf("%d",&data);
    if(data)
      createBST(root,data);
    else
      break;
  }
}

This forced me to put some of the break spaghetti back in, and in some ways made this worse than original.

Attempt 4

void Tcase(Node** root){
  for(int data;;) {
    scanf("%d",&data);
    if(data)
      createBST(root,data);
    else
      break;
  }
}

At least we can dump the declaration of the int and embed it into the for. But this still isn't really any better than the original. Really needed to dig deep. So looked at for about 10 minutes, wrote about another 5 or 6 variations... and arrived at this.

Attempt that was more acceptable...

void Tcase(Node** root){
  for(int data = 1; !data;) {
    scanf("%d",&data);
    if(data) createBST(root,data);
  }
}

This still requires two expression checks. We need to also set the value of data initially to 1 so the for loop doesn't bail on first loop. I'm still not happy with that. So woke up this morning and thinking maybe you can drop the conditional inside the for, and convert the other expression to a ternary.

Attempt to convert to a ternary if...

void Tcase(Node** root){
  for(int data = 0;;) {
    scanf("%d",&data);
    (data) ? createBST(root,data) : break;
  }
}

Unfortunately, you cannot put a break there in the way ternary ifs evaluate their parts... but you could do a janky space exploit and modify Attempt 4. Still dump the second evalution and get a single expression with an exit condition that happens at the tail. And you're not really adding complexity. Still the have the ability to clean up the code for simplicity.

Attempt 4 [shrunk]

void Tcase(Node** root){
  for(int data = 0;;) {
    scanf("%d",&data);
    if(data) createBST(root,data); else break;
  }
}

Could this still be improved? Is there a better way to mess around with this? I'm not a fan of compressing ifs like that. Is there limitations in the language? There are so many different ways to write code.

Conclusion

void Tcase(Node** root){
    for(int data;;) {
        scanf("%d",&data);
        if(!data) break;
        createBST(root,data);
    }
}

Write more code... lots of it. Pick it apart. I'm still not a fan of needing that break before adding a node. But it does imply the else. The while can still be dropped in place of a for with initialiser and the == 0 can be swapped for a ! check instead. This still doesn't address the validation of the scanf. Which is a real problem. But for a little coding exercise to mess around a little, it does help with understanding.

CAN SOMEONE HELP ME PLEASE.
posted to Ask by AnakNgDiyos

There are few problems you need to address.

  1. C has no way to expose length of arrays, or things that are array-like for instance strings. You must either use a function or #define a macro that can use sizeof() or statically code your length in a variable or hard code the limit inside of an expression such as a for loop.

  2. Basic understanding of stdio.h functions would be useful, but not required. You can refer here for a typical standardised include reference for it.

https://pubs.opengroup.org/onlinepubs/7908799/xsh/stdio.h.html

This will allow you to access the printf() function.

https://pubs.opengroup.org/onlinepubs/7908799/xsh/printf.html

3a. For loops. https://beginnersbook.com/2014/01/c-for-loop/
3b. While loops. https://beginnersbook.com/2014/01/c-while-loop/
3c. Do/While loop. https://beginnersbook.com/2014/01/c-dowhile-loop/

  1. If statements for basic expression logic to test conditions for if you're going need to perform a swap of numbers.

https://beginnersbook.com/2014/01/c-if-statement/

That reference is quite crude, but will equip you with at least enough to complete the assignment.

  1. Writing a swap algorithm for the array of numbers so you can trade positions of numbers while you are looping across them to determine if you need to swap them to get your descending order.

  2. Operators of greater and less than to be able to figure out your expression. Depending how you write your if expression you will need one of those to get your correct sorting order.

  3. How arrays work. https://beginnersbook.com/2014/01/c-arrays-example/


This is an example sorting ascending.

https://www.youtube.com/watch?v=nmhjrI-aW5o

You will still need to address your correct sorting order, and outputting the series of floating points numbers. It would be best to address your progress here instead of taking it offsite, so others can learn from your progress.

Repl.it Desktop 😯
posted to Ask by PDanielY

@coolguy284 I have no problems with desktop apps at all. What I have a problem with is ones that hog and bog down my entire system like ones built on Electron do. I wouldn't even attempt this in C++. C would be insanity, but I might be up for the challenge in a few years when I have time. There is the opensource VSCode git. It is Electron based. It already has REPL functionality for a lot of languages. At that point what do you even need this website for? Just use the Code Runner extension.

https://marketplace.visualstudio.com/items?itemName=formulahendry.code-runner

As far as I'm concerned there is VSCode with a much larger development community than anything we could provide backed by Microsoft using Electron and supports plugins/extensions. Alongside the Microsoft marketplace with people already solving the problem. I still fail to see what benefit this competing solution is going to provide. I refuse to use VSCode because of how slow it is. It's bad enough I have to install Visual Studio. Profiler and Debugger support for C, as it just doesn't have enough love on Linux. VSCode, nor this desktop app is going to solve that problem anytime soon. If it's for any of the things already listed in Code Runner for anything else, then it might be worth also helping contribute to that extension, or as suggested, fork it... We have an epidemic shortage of good programmers in the world.

How is making yet another tool dividing time and resources going to help that? There are other extensions to do REPL in VSCode out there. I still don't see anyone answering the question of why or what this is going to provide that isn't already out there?

Repl.it Desktop 😯
posted to Ask by PDanielY

@alphakid381 the web address is repl.it. it's really not that hard to remember. you can also create a bookmark. or a shortcut on your desktop that takes you to the website.

C# Calculator
posted to Share by mrsprinkletoes

try/catch is a dark path you are going to have a hard time getting off if you get hooked on using it. In almost every instance of its use you could employ better coding to avoid needing it altogether. Let's go over a few of those things...

So first... your original code with a few notes outlining some things.

using System;
using System.IO;
using System.Text;

class MainClass {
      public static void Main (string[] args) {
          int num1;
          int num2;
          string oper;

          //this try catch is avoidable if you actually
          //bother to validate what is being input
          //try/catch here can be avoided entirely
          //by coding properly.
          try {
                Console.Write("Number 1: ");
                //use TryParse instead to catch errors
                //and setup a loop to make sure a valid
                //number is entered
                num1 = Int32.Parse(Console.ReadLine());

                //ask this first so you can determine
                //if need to make sure for division for
                //instance needs to check for a divide
                //by zero to make sure zero cannot be
                //entered.
                Console.Write("|+|-|x|/| (choose): ");
                oper = Console.ReadLine();

                //this has some extra work to do
                //making sure you're not going to cause
                //overflow/underflow or divide by zero
                //using the try/catch is avoidable
                Console.Write("Number 2: ");
                num2 = Int32.Parse(Console.ReadLine());
                
                //convert this to a switch/case statement
                //store the evaluation 
                if (oper == "+") {
                    Console.WriteLine(num1 + num2);
                } else if (oper == "-") {
                    Console.WriteLine(num1 - num2);
                } else if (oper == "x") {
                    Console.WriteLine(num1 * num2);
                } else if (oper == "/") {
                    Console.WriteLine(num1 / num2);
                }
          } catch (Exception ex) {
              //you don't need any of this if you just
              //for proper validation checks on what
              //is being input... 
              Console.BackgroundColor = ConsoleColor.Red;
              Console.ForegroundColor = ConsoleColor.Black;
              Console.WriteLine("An error occurred, it has been logged in the errorlog.txt file.");
              if (File.Exists("errorlog.txt")) {
                  File.Delete("errorlog.txt");
              }
              using (StreamWriter sw = File.CreateText("errorlog.txt")) {
                  sw.WriteLine("Source: "+ex.Source+"\n");
                  sw.WriteLine("StackTrace: "+ex.StackTrace+"\n");
                  sw.WriteLine(ex.Message);
              }
          }
      }
}

Alright, so now we need to go over a few things on what those notes mean, and how to tackle some of those things that are addressed. try/catch is not your friend... albeit there are times when you will be forced to use it. JAVA comes to mind and several sections of the .NET libraries also leave you with no choice but to use it. Crappy and poorly implemented socket libraries... ugghgh...

Here we strip out the try/catch so our eyes no longer to bleed.

using System;
using System.IO;
using System.Text;

class MainClass {
  public static void Main(string[] args) {
    int num1;
    int num2;
    string oper;

    Console.Write("Number 1: ");
    //use TryParse instead to catch errors
    //and setup a loop to make sure a valid
    //number is entered
    num1 = Int32.Parse(Console.ReadLine());

    //ask this first so you can determine
    //if need to make sure for division for
    //instance needs to check for a divide
    //by zero to make sure zero cannot be
    //entered.
    Console.Write("|+|-|x|/| (choose): ");
    oper = Console.ReadLine();

    //this has some extra work to do
    //making sure you're not going to cause
    //overflow/underflow or divide by zero
    Console.Write("Number 2: ");
    num2 = Int32.Parse(Console.ReadLine());

    //convert this to a switch/case statement
    //store the evaluation 
    if (oper == "+") {
      Console.WriteLine(num1 + num2);
    } else if (oper == "-") {
      Console.WriteLine(num1 - num2);
    } else if (oper == "x") {
      Console.WriteLine(num1 * num2);
    } else if (oper == "/") {
      Console.WriteLine(num1 / num2);
    }
  }
}

Now let's address the switch/case note at the bottom down there...

see: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/switch

using System;
using System.IO;
using System.Text;

class MainClass {
  public static void Main(string[] args) {
    int num1;
    int num2;
    string oper;

    Console.Write("Number 1: ");
    //use TryParse instead to catch errors
    //and setup a loop to make sure a valid
    //number is entered
    num1 = Int32.Parse(Console.ReadLine());

    //ask this first so you can determine
    //if need to make sure for division for
    //instance needs to check for a divide
    //by zero to make sure zero cannot be
    //entered.
    Console.Write("|+|-|x|/| (choose): ");
    oper = Console.ReadLine();

    //this has some extra work to do
    //making sure you're not going to cause
    //overflow/underflow or divide by zero
    Console.Write("Number 2: ");
    num2 = Int32.Parse(Console.ReadLine());

    //since the div will result in int
    //with a rounding, dropping the
    //floating point/decimal portion.

    int result = 0;

    switch (oper) {
      case "+": result = num1 + num2; break;
      case "-": result = num1 - num2; break;
      case "x": result = num1 * num2; break;
      //should put something that this rounds
      //and we need to make sure we have no
      //chance of a divide by zero...
      case "/": result = num1 / num2; break;
    }

    Console.WriteLine("\n" + num1 + " " + oper + " " + num2 + " = " + result);
  }
}

So let's mash down the Int32.Parse and convert those to Int32.TryParse and move the the operator question to the top of the program.

see: https://docs.microsoft.com/en-us/dotnet/api/system.int32.tryparse?view=netframework-4.8

using System;
using System.IO;
using System.Text;

class MainClass {
  public static void Main(string[] args) {
    int num1;
    int num2;
    string oper;

    //we'll need some sort of validation
    //loop here also to make sure operator
    //is acceptable.
    Console.WriteLine("What type of maths are we doing?");
    Console.Write("Choose an operator [+ - x /]: ");
    oper = Console.ReadLine();
        
    Console.Write("Number 1: ");
    //we'll need to setup a loop so it validates
    bool isValid = Int32.TryParse(Console.ReadLine(), out num1);

    //establish some sort of min/max for input
    //multiply and div are going to be troublesome

    //this has some extra work to do
    //making sure you're not going to cause
    //overflow/underflow or divide by zero
    //we will also need to setup a validation loop
    Console.Write("Number 2: ");
    isValid = Int32.TryParse(Console.ReadLine(), out num2);

    int result = 0;
    switch (oper) {
      case "+": result = num1 + num2; break;
      case "-": result = num1 - num2; break;
      case "x": result = num1 * num2; break;
      //should put something that this rounds
      //and we need to make sure we have no
      //chance of a divide by zero...
      case "/": result = num1 / num2; break;
      default: break; //we'll add some validation here later
    }

    Console.WriteLine("\n" + num1 + " " + oper + " " + num2 + " = " + result);
  }
}

Now we should tackle some basic validation loops using do/while type flow.

see: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/do

Basically in this case we want to make sure that isValid we got back from the Int32.TryParse is TRUE. This way we know we got a valid Int32 and that we can proceed. We also want to make sure that the operator is valid and we will also do a basic repeat of the validation used for the second number.

using System;
using System.IO;
using System.Text;

class MainClass {
  public static void Main(string[] args) {
    int num1;
    int num2;
    string oper;
 
    Console.WriteLine("What type of maths are we doing?");

    bool isValid = false;
    do {
      Console.Write("Choose an operator [+ - x /]: ");
      oper = Console.ReadLine();
      switch (oper) {
        case "+": //waterfalling is required
        case "-": //just like in C/C++ as nesting
        case "x": //cases is not valid...
        case "/": isValid = true; break;
        default: Console.WriteLine("Invalid choice..."); break;
      }
    } while (!isValid);

    do {
      Console.Write("Number 1: ");
      isValid = Int32.TryParse(Console.ReadLine(), out num1);
      if (!isValid)
        Console.WriteLine("Invalid choice...");
      else
        break; //exits the while;
    } while (true);

    //establish some sort of min/max for input
    //multiply and div are going to be troublesome

    //this has some extra work to do
    //making sure you're not going to cause
    //overflow/underflow or divide by zero
    do {
      Console.Write("Number 2: ");
      isValid = Int32.TryParse(Console.ReadLine(), out num2);
      if (!isValid)
        Console.WriteLine("Invalid choice...");
      else
        break; //exits the while;
    } while (true);

    int result = 0;
    switch (oper) {
      case "+": result = num1 + num2; break;
      case "-": result = num1 - num2; break;
      case "x": result = num1 * num2; break;
      case "/": {
          Console.Write("Integer maths used. ");
          Console.WriteLine("Answer subjected to rounding.");
          result = num1 / num2;
        }  break;
    }

    Console.WriteLine("\n" + num1 + " " + oper + " " + num2 + " = " + result);
  }
}

Now we are bit closer to something more user friendly. But we have some immediate code replication that we can put into a function. Since the two number validation loops only vary by the number title and the variable being input, we can put that into a function easily. We will return the validated number as int from the function, and take a single parameter which is the number we are entering.

see: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/methods

using System;
using System.IO;
using System.Text;

class MainClass {
  public static int getNumber(string name) {
    int number;
    bool isValid = false;

    do {
      Console.Write("Number " + name + ": ");
      isValid = Int32.TryParse(Console.ReadLine(), out number);
      if (!isValid)
        Console.WriteLine("Invalid choice...");
      else
        break; //exits the while;
    } while (true);

    return number;
  }

  public static void Main(string[] args) {
    int num1;
    int num2;
    string oper;

    //we'll need some sort of validation
    //loop here also to make sure operator
    //is acceptable.
    Console.WriteLine("What type of maths are we doing?");

    bool isValid = false;
    do {
      Console.Write("Choose an operator [+ - x /]: ");
      oper = Console.ReadLine();
      switch (oper) {
        case "+":
        case "-":
        case "x":
        case "/": isValid = true; break;
        default: Console.WriteLine("Invalid choice..."); break;
      }
    } while (!isValid);

    num1 = getNumber("1");

    //establish some sort of min/max for input
    //multiply and div are going to be troublesome

    //this has some extra work to do
    //making sure you're not going to cause
    //overflow/underflow or divide by zero
    num2 = getNumber("2");

    int result = 0;
    switch (oper) {
      case "+": result = num1 + num2; break;
      case "-": result = num1 - num2; break;
      case "x": result = num1 * num2; break;
      case "/": {
          Console.Write("Integer maths used. ");
          Console.WriteLine("Answer subjected to rounding.");
          result = num1 / num2;
        }  break;
    }

    Console.WriteLine("\n" + num1 + " " + oper + " " + num2 + " = " + result);
  }
}

Things are getting a little more organised now. We still need to work out what numbers we can input for validation so we cannot cause overflows/underflows and divide by zero. Let's think about this. The first number we enter shouldn't make a difference, so it can be between Int32.MinValue and Int32.MaxValue. The seconds number though has some special cases we need to address.

Addition can use...

if (num1 < 0) {
  numMin = Int32.MinValue - num1;
elseif (nume 1 > 0) {
  numMax = Int32.MaxValue - num1;
}

Subtraction can use a variation of the Addition minimum check by reversing the position of the Int32.MinValue and Int32.MaxValue.

if (num1 < 0) {
  numMin = Int32.MaxValue - num1;
elseif (nume 1 > 0) {
  numMin = Int32.MinValue - num1;
}

Division is easy enough, since we are never dealing with fractions, we'll always get back a smaller number. We just need to make sure the second number is never 0.

Multiplication can take the absolute value of the Int32.MaxValue divided by num1 and then use -1 * the result for the numMin and the absolute value as the numMax.

Let's code those in...

using System;
using System.IO;
using System.Text;

class MainClass {
  //need to take a few more args for validation
  public static int getNumber(string name) {
    int number;
    bool isValid = false;

    do {
      Console.Write("Number " + name + ": ");
      
      //show the min max range for valid input

      isValid = Int32.TryParse(Console.ReadLine(), out number);
      
      //need to test for min and max value validation

      if (!isValid)
        Console.WriteLine("Invalid choice...");
      else
        break; //exits the while;
    } while (true);

    return number;
  }

  public static void Main(string[] args) {
    int num1;
    int num2;
    string oper;

    //we'll need some sort of validation
    //loop here also to make sure operator
    //is acceptable.
    Console.WriteLine("What type of maths are we doing?");

    bool isValid = false;
    do {
      Console.Write("Choose an operator [+ - x /]: ");
      oper = Console.ReadLine();
      switch (oper) {
        case "+":
        case "-":
        case "x":
        case "/": isValid = true; break;
        default: Console.WriteLine("Invalid choice..."); break;
      }
    } while (!isValid);

    int numMin = Int32.MinValue;
    int numMax = Int32.MaxValue;
    bool isZeroValid = true;

    //need to pass the min and max values and isZeroValid
    num1 = getNumber("1");
        
    switch (oper) {
      case "+": {
          if (num1 < 0)
            numMin = Int32.MinValue - num1;
          else if (num1 > 0)
            numMax = Int32.MaxValue - num1;
        } break;
      case "-": {
          if (num1 < 0)
            numMin = Int32.MaxValue - num1;
          else if (num1 > 0)
            numMax = Int32.MinValue - num1;
        } break;
      case "x": {
          int t = Math.Abs(Int32.MaxValue / num1);
          numMin = -t;
          numMax = t;
        } break;
      case "/": isZeroValid = false; break;
    }

    //need to pass the min and max values and isZeroValid
    num2 = getNumber("2");

    int result = 0;
    switch (oper) {
      case "+": result = num1 + num2; break;
      case "-": result = num1 - num2; break;
      case "x": result = num1 * num2; break;
      case "/": {
          Console.Write("Integer maths used. ");
          Console.WriteLine("Answer subjected to rounding.");
          result = num1 / num2;
        }
        break;      
    }

    Console.WriteLine("\n" + num1 + " " + oper + " " + num2 + " = " + result);
  }
}

We are almost there and free of having nightmares of relying on try/catch.
Just a few last things to address. This could still use some cleanup and other things, but at least this does validation, provides useful information to the user and does not just subject them to crashing with exceptions, and other silly nonsense.

using System;
using System.IO;
using System.Text;

class MainClass {  
  public static int getNumber(
    string name,
    int min, int max,
    bool isZeroValid
    ) {

    int number;
    bool isValid = false;

    do {
      Console.WriteLine("Enter number " + name);
      Console.Write("[" + min + " to ");

      if (!isZeroValid) Console.Write(" -1 and 1 to ");
      Console.WriteLine(max + "]");      

      isValid = Int32.TryParse(Console.ReadLine(), out number);
      
      if (isValid && (number >= min && number <= max)) {
        if (!isZeroValid) {
          if (number != 0) break; //exits the while;
        }
      } else
        break; //exits the while;

      Console.WriteLine("Invalid choice...");
    } while (true);

    return number;
  }

  public static void Main(string[] args) {
    int num1;
    int num2;
    string oper;

    //we'll need some sort of validation
    //loop here also to make sure operator
    //is acceptable.
    Console.WriteLine("What type of maths are we doing?");

    bool isValid = false;
    do {
      Console.Write("Choose an operator [+ - x /]: ");
      oper = Console.ReadLine();
      switch (oper) {
        case "+":
        case "-":
        case "x":
        case "/": isValid = true; break;
        default: Console.WriteLine("Invalid choice..."); break;
      }
    } while (!isValid);

    int numMin = Int32.MinValue;
    int numMax = Int32.MaxValue;
    bool isZeroValid = true;
    
    num1 = getNumber("1", numMin, numMax, isZeroValid);
        
    switch (oper) {
      case "+": {          
          if (num1 < 0)
            numMin = Int32.MinValue - num1;
          else if (num1 > 0)
            numMax = Int32.MaxValue - num1;
        } break;
      case "-": {
          if (num1 < 0)
            numMin = Int32.MaxValue - num1;
          else if (num1 > 0)
            numMax = Int32.MinValue - num1;
        } break;
      case "x": {
          int t = Math.Abs(Int32.MaxValue / num1);
          numMin = -t;
          numMax = t;
        } break;
      case "/": isZeroValid = false; break;
    }
    
    num2 = getNumber("2", numMin, numMax, isZeroValid);

    int result = 0;
    switch (oper) {
      case "+": result = num1 + num2; break;
      case "-": result = num1 - num2; break;
      case "x": result = num1 * num2; break;
      case "/": {
          Console.Write("Integer maths used. ");
          Console.WriteLine("Answer subjected to rounding.");
          result = num1 / num2;
        }
        break;      
    }

    Console.WriteLine("\n" + num1 + " " + oper + " " + num2 + " = " + result);
  }
}

There might be bugs, I didn't check everything. I'll leave the rest of the cleanup of the output and things to you. But this is a much better way to deal with this type of code than to just bail and puke with a try/catch and leave validation to random chance. Keep your head up... if you have any questions please ask.

My first four-function calculator on C++
posted to Share by ZControls_Games

this is not an end all solution. cin is plagued with problems. a non-blocking key input and custom input functions should replace it for instant validation. this is just a basic example of using the cinful methods to sort of validate input. does a few checks for things like divide by zero and tries to prevent other overflows.

#include <iostream>
#include <cmath>
#include <cstdio>
#include <bits/stdc++.h>

using namespace std;

#define put(string) cout << string
#define nlput(string) cout << endl << string
#define putnl(string) put(string) << endl
#define nlputnl(string) nlput(string) << endl
#define nlputdnl(string) nlputnl(string) << endl

#define setMinMax(a, b)   \
  if (num1 < 0) {         \
    numMin = a - num1;    \
  } else if (num1 > 0) {  \
    numMax = b - num1;    \
  } break

#define cinReset() cin.clear(); cin.ignore(10000, '\n')

int readNumber(string num, int min, int max, int zeroValid) {
  int r = 0;
  int isValid = false;

  do {
    cinReset();
    
    nlput("Enter your " << num << " number");
    
    nlput("[" << min << " to ");
    if (!zeroValid) put(" -1 and 1 to ");
    putnl(max << "]:");

    cin >> r;

    if (!cin.fail() && (r >= min && r <= max)) {
      if (zeroValid == false) {
        if (r != 0) isValid = true;
      } else
        isValid = true;
    }

    if (!isValid) putnl("Not a valid number.");
  } while (!isValid);

  return r;
}

int main() {
  string name;
  nlputnl("Please enter your name:"); cin >> name;
  nlputnl("Hello " << name);

  const char *operations[] = {
    "Add", "Subtract", "Divide", "Multiply"
  };

  int option;
  while (true) {
    nlputdnl("Would you like to:");
    for (int i = 0; i < 4; ++i) {
      putnl((i + 1) << " - " << operations[i]);
    }
    put(endl);

    int isValid = false;
    do {
      cinReset();
      putnl("Select an operation [1-4]:"); cin >> option;
    
      if (!cin.fail())
        if (option > 0 && option < 5)
          isValid = true;
     
      if (!isValid) nlputnl("Invalid option. ");
    } while (!isValid);

    nlputnl(operations[option-1] << " has been confirmed.");

    int numMin = INT_MIN;
    int numMax = INT_MAX;
    int isZeroValid = true;

    int num1 = readNumber("first", numMin, numMax, isZeroValid);
    switch (option) {
      case 1: setMinMax(INT_MIN, INT_MAX);
      case 2: setMinMax(INT_MAX, INT_MIN);
      case 3: isZeroValid = false; break;
      case 4: {
        int t = INT_MAX / num1;
        t = abs(t);

        numMin = -t;
        numMax = t;
      } break;
    }

    int num2 = readNumber("second", numMin, numMax, isZeroValid);

    switch (option) {
      case 1: num1 += num2; break;
      case 2: num1 -= num2; break;
      case 3: {
        putnl("Integer maths is used. Rounding happens.");
        num1 /= num2;
      } break;
      case 4: num1 *= num2; break;
    }

    nlputnl("Your answer is " << num1);

    putnl("Calculate again? [Y]es or any other quits");
    cinReset();
    int playAgain; cin >> playAgain;
    if (playAgain != 'Y' && playAgain != 'y') break;
  }

  nlputnl("END OF LINE");
  return 0;
}
My first four-function calculator on C++
posted to Share by ZControls_Games

@CowNationz this method would be very hard for a novice to parse. especially for a divide by zero check. also multiplication overflow of ints. this is not a good method unless you can promote from a smaller bit width type to a larger one. cin also cannot be validated for input using this method for bad data put into either position. this is not recommended unless you are suggesting writing a full blown expression parser based on something like a shunting yard. there are deeper problems to address. lack of knowledge of flow control such as loops, functions, and cin validation.

variables
posted to Share by AhmadIg

A better method... also char literal constants are converted to int by the compiler and can be stored in an int type.

#include <stdio.h>
#include <string.h>

void display(const char *base, char *format, int x) {
  puts("\n----------------------------------------");  
  puts("");
  char buff[100];
  strcpy(buff, "Convert[\'%s\']  x = '");
  strcat(buff, format);
  strcat(buff, "'\n");
  printf(buff,base, x);
  puts("");
}

void process(int x) {
  display("Decimal", "%d", x);    //https://en.wikipedia.org/wiki/Decimal
  display("Hexadecimal", "%x", x); //https://en.wikipedia.org/wiki/Hexadecimal  
  display("Octal", "%o", x);      //https://en.wikipedia.org/wiki/Octal
  display("ASCII", "%c", x);      //https://he.wikipedia.org/wiki/ASCII
  puts("\n----------------------------------------");  
  puts("----------------------------------------\n");
}

void displayCharInt(int x) {  
  printf("\n int x = '%c'\n",x);
  process(x);
}

int main(void) { 
  int x = 65; 
  printf("\n int x = '%d'\n", x);
  process(x);
    
  displayCharInt('a');
  displayCharInt('z');
  displayCharInt('A');
  displayCharInt('Z');
  
  return 0;
}
Error
posted to Ask by saianurag

@mwilki7 @saianurag this is a correct.

Make sure you delete main1.c from the project and it will compile. That is a direct copy of main.c and as mentioned puts two main() functions in the project. The compiler can only sort out one entry for a program.

Coding help
posted to Ask by SkyyCivil
  //This is the header ↓
  #include <stdio.h> //HEADER for all C codes
    //points out that you have integers ↓
    int main(void) 
    {  //this is the opening bracket this is where the code starts ↓
  printf("Hello World\n");
  return 0;
}

Please, before you get into spitting out code as tutorials, at least get your spacing sorted out. That is the basic C start code from repl.it and you still managed somehow to get it mixed up.

//This is the header ↓
#include <stdio.h> //HEADER for all C codes

Not true... this is just to declare output. Not all programs need this.

//points out that you have integers ↓
int main(void) {

Also not true. This is the main entry to the program and it's function prototype.
int at the beginning is the return type.
main is the name
(void) is the argument list

  //this is the opening bracket this is where the code starts ↓

Not even sure what this is trying to explain? the { opening
scope for the code block for the function?

  printf("Hello World\n");

  return 0;
}

Ughghg...

⌨️ Hacker Typer 💥
posted to Share by mat1

Nice work.

Missing Self-Learner assignments from my Classroom
posted to Ask by pmorrow

@pmorrow Awesome work. Thanks for doing this for the students you work with. Amazing. Embedded System module, using nanos, arduinos, pis? Something custom? This is really cool. And in C. Bless you!

Missing Self-Learner assignments from my Classroom
posted to Ask by pmorrow

Not related to your problem, but curious in general about the program you are running. The C classroom is it on repl.it? Can I ask what grades you work with? Also do you have an active computer science/technology program running at your school? Keep up the good fight.

C++ Classes vs Structs
posted to Ask by TheDrone7

@SPQR Structs and Classes are effectively equal in C++ short of which members are Private and Public by default. That is not true either about structs being left in for that reason. Classes internally in C++ are built from structs.

How to return to another line of code in c++
posted to Ask by BFDMod

@AquaMarine0421 do not advise a new programmer to use GOTO statements. you do not want to touch that spaghet. There is only one case where it can be required in C, when you need to escape multiple nests of a for loop. Outside that, there is almost guaranteed to be a better way to write code.

How To
posted to Ask by etian
#include <iostream>
#include <unistd.h>

using namespace std;

int main() {
  int tries = 3;
  int success = 0;

  do {
    int password = 0;

    cout << "You have " << tries << " tries reamaining.\n";
    cout << "(must be 8 digits)\nPassword:";
  
    //would be good to validate
    cin >> password;
 
    //what happens if they get the password right
    if (password==14724179) {
      cout << "Files:\n";
      cout << "twisted pulley\n";
      cout << "simple pulley\n";
      cout << "Whiteney's pulley\n";
      cout << "starfleet voyager\n";
      cout << "flying car\n";
      success = 1;
    }
  } while (!success && --tries > 0);

  if (!success) {     
    for (int i = 5; i >= 0; --i) {
      cout << i << "\n"; 
      usleep(300000);
    }
    cout << "just kidding";
  }
}

This vastly reduces your code replication. Loops are handy. Some code cleanup is still possible, and validation of the input is highly recommended. You can crash the program by entering alpha characters.

Repl.it Desktop 😯
posted to Ask by PDanielY

@leon332157 this website is not a problem. it's an excellent service. never said this site is useless. just the app that detracts people from using it. creating things to detract from here and splitting the community. and that people should spend more time supporting the website that drawing them away to use apps that are detracting from the usefulness of this service and being able to build better parts of the community. not sure were you got that from. keep your head up.