Can Ruby call methods or procs like c calls functions? - c

I am pretty new to Ruby. I am college and just did a programming course that covered regular c. My final project for class was a slop intercept project, which was fairly easy, but i had to use functions for everything, for example:
#include <stdio.h>
#include <math.h>
int get_problem(int *choice){
do {
printf("Select the form that you would like to convert to slope-intercept form: \n");
printf("1) Two-Point form (you know two points on the line)\n");
printf("2) Point-slope form (you know the line's slope and one point)\n");
scanf("%d", &*choice);
if (*choice < 1 || *choice > 2){
printf("Incorrect choice\n");}
}while (*choice != 1 && *choice !=2);
return(*choice);
}
...
int main(void);
{
char cont;
do {
int choice;
double x1, x2, y1, y2;
double slope, intercept;
get_problem (&choice);
...
I have several more functions completing the entire program. I got a new job and i need to start learning Ruby, So for my first project I wanted to convert this program into Ruby, now I was able simply get rid of the functions and just run it without methods or procs. I wanted to know if it is possible to do the same thing, define a method, then call the method without giving an input, but getting back the variables stored in the method. Would it be possible using methods or procs. Here is a little of what i have so far using a proc.
get_problem = Proc.new {
begin
puts "Select the form that you would like to convert to slope-intercept form: "
puts "1) Two-Point form (you know two points on the line)"
puts "2) Point-slope form (you know the lines slope and one point)"
choice = gets.chomp.to_i
if (choice < 1 || choice > 2)
puts "Incorrect choice"
end
end while (choice != 1 && choice !=2)
}
....
begin
get_problem.call
case choice
when 1
get2_pt.call
display2_pt.call
slope_intcpt_from2_pt.call
when 2
get_pt_slope.call
display_pt_slope.call
intcpt_from_pt_slope.call
Now I know I probably have it all wrong, but I figured I would give it a shot. I have it as methods before where I had
def get_problem(choice)
....
end
....
get_problem(choice)
....
Is there something basic I am missing? As you can see, i used pointers in c and had to initialize the variables in the main.
Thank you for taking the time to help me out.
Robert

You can't pass a pointer to a variable in Ruby, but I don't think you need to do that to accomplish what you're trying to do. Try this:
def get_problem
puts "Select the form that you would like to convert to slope-intercept form: "
puts "1) Two-Point form (you know two points on the line)"
puts "2) Point-slope form (you know the lines slope and one point)"
loop do
choice = gets.chomp.to_i
return choice if [1, 2].include? choice
STDERR.puts "Incorrect choice: choose either 1 or 2"
end
end
choice = get_problem
puts "The user chose #{choice}"
This defines a method get_problem which loops until the user chooses either 1 or 2, and returns their chosen number, which you can store in a top-level variable choice.

Related

C: Initialize variable to random # b/w 50 & 100 so they can be used in Switch statement if user selects an option that doesn't include entering values

So i'm very much a beginner and this is an assignment for class, but i'm not looking to have someone do the assignment for me or anything. Just help on a part i'm having trouble with.
I'm not posting my code as it's an ongoing assignment and I don't want someone to happen upon it and copy it ): But the gist of it is I need to display a menu to the user and create a switch statement. Each case has a corresponding function prototype that executes the choice the user made from the menu.
1 Enter 3 grades
2 Show average (with 3 grades) and letter grade
3 Show highest grade
4 Show lowest grade
5 Exit
I've done pretty much all of the assignment, but the one requirement I can't figure out is how to initialize the 3 grade variables to random numbers between 50 and 100, so if the user chooses menu options 2 3 or 4 first then those random #'s are what is used in my prototypes. But if the user chooses menu option 1, my functions should use the 3 values input by the user from that point until exit, or if they hit 1 again to input new values.
Since I couldnt figure it out I just had each prototype prompt the user to insert 3 grades then proceed to do its assigned task using those values.
We were also instructed to not use arrays as we havent gotten to that yet.
If no one is able to figure it out without seeing the code i'll wait until after the due date and post what I was able to do. i'm honestly just wanting to learn and my professor doesn't really post any videos or lectures (online class) so we just go off our textbook and good ol google.
Thank you to whoever can help(:
If you want a variable with a random standard value, initialize it with a random value. You can generate a random integer between two numbers using the random() function in the stdlib.h header.
Your code can be structured like this.
#include<stdlib.h>
#include<time.h>
int random_range(int start, int end) {
return start + (int) ((double) random() / RAND_MAX * (end - start));
}
int main() {
srandom(time());
int grade1 = random_range(50, 100);
int grade2 = random_range(50, 100);
int grade3 = random_range(50, 100);
...
}
Now the three grade variables are always initialized and can be used. I recommend, you also read the man page for the random() function.
Not a good idea, doing processing with some randomly assigned data simply to not do the work of controlling the user's options. Imagine that one option is to write the current record into persistent storage. Do you want to risk random valued records polluting the company's database? There are stories of "test versions" that have been released "into the wild" (on the day the coder was home with a cold, but management applied pressure to ship) that... well, that would curl your toes.
Here is a sketch whereby the user has two options only: enter the data or quit the program. Presuming valid data has been accepted, the menu features more options.
Do not process junk. It'll come back to bite you.
/* Usual header files */
int main() {
char buf[ 64 ];
int hiMenuOpt = 1;
do {
printf(
"Here's menu options\n"
"0: Quit\n"
"1: Enter data\n"
);
if( hiMenuOpt > 1 )
printf(
"2: Something\n"
"3: Something else\n"
"4: Something other\n"
);
printf( "Select 0-%d : ", hiMenuOpt );
fgets( buf, sizeof buf, stdin );
int val = strtol( buf, NULL, 10 ); // Edit fix. Thanks to Lundin
if( val < 0 || hiMenuOpt < val ) {
printf( "Bad entry\n" );
continue;
}
switch( val ) {
case 0:
hiMenuOpt = 0;
break;
case 1:
puts( "Hi from one\n" );
/* yadda yadda */
hiMenuOpt = 4;
break;
/* More stuff */
}
} while( hiMenuOpt );
return 0;
}
Here's menu options
0: Quit
1: Enter data
Select 0-1 : 1
Hi from one
Here's menu options
0: Quit
1: Enter data
2: Something
3: Something else
4: Something other
Select 0-4 :
Notice that Quit is now item 0. New menu items may be added, and old ones removed. The only constant is exiting the program. It makes sense, imo, to make that the first item on the list.

Creating a grocery list via string inputs and void functions - Input string does not display

I'm fairly new to C (high school student), and my goal is to make a grocery list by inputting a set of characters. Then, the output would print out what I currently added to the list. This would go on forever until I exited the program or went to the main menu.
SCREEN1
00 - GO TO GREETINGS SCREEN
01 - ADD MORE ITEMS TO THE LIST
CODE ENTRY: ___
SCREEN2
Then I entered 01 to add items:
Input "DONE" to end program and see final list.
LIST ENTRY: ______________
SCREEN3
Then I add "apples", then it takes me to this screen:
GROCERY LIST:
POTATOES
FISH
APPLES
After that, it takes me back to SCREEN1, where I would choose whether to go to the greetings screen or add some more.
MY CURRENT CODE:
#include <stdio.h>
#include<stdlib.h>
int main()
{
int n;
char * grocery;
mainMenu:
system("cls");
n = 0;
printf("00 - Go to greetings screen\n01 - Add groceries to list\nENTRY: ");scanf("%d",&n);
if(n == 0)
{
greetings();
goto mainMenu;
}
else if(n == 1)
{
printf("GROCERY ENTRY: ");scanf("%s",grocery);
add(grocery);
goto mainMenu;
}
else
{
printf("Wrong value added. Try again.");
sleep(2);
goto mainMenu;
}
}
void greetings()
{
system("cls");
printf("hello! press any key to go back to menu");
getch();
system("cls");
}
void add(char * a)
{
system("cls");
char listData[1000] = "",slashN[4] = "\n";
strcat(listData,a);
strcat(listData,slashN);
printf("THINGS TO BUY:\n");
puts(listData);
}
NOTES
I used strcat so that it remembers the value of the original string. This'll make sure that the new input will just be put on top of the old data, right? (Hopefully, my logic is correct on that one)
Though, I have not been able to find out whether or not the string data will still be remembered by the program even if I am switching to other menus, such as the Greetings Menu (which is a placeholder for something like a calculator).
Right now, the initial functions work, except for the the grocery list one. Whenever I input a string, nothing comes out of it, even the printf("THINGS TO BUY:") part, leading me to think it's something with what I entered in void add(char * a)
After trying out your code, I received a segmentation fault where you have scanf("%s",grocery);. Try allocating space to the variable, using malloc(3) (see http://man7.org/linux/man-pages/man3/malloc.3.html). For example, char *grocery = (char *)malloc(sizeof(char) * 100); will give you 100 characters to read into your grocery variable from input.
The same objective can also be achieved by simply using char grocery[100]; as you have with other variables.
Furthermore, as many programmers would suggest, try not to use goto(). This can cause spaghetti code (see https://en.wikipedia.org/wiki/Spaghetti_code). Instead, use a while loop that stops only when the user inputs some action designed to stop entering requests.
Lastly, just so you avoid unwarranted results, \n is actually a single character. Therefore, char slashN[4] = "\n" can be char slashN = '\n';.
Happy coding! :D

Re-execute program based on user input in C

Hi i'm trying to learn programming in C on my own and have managed to make a verry, verry simple program that calculates the surface of a circle based on user input.
However the program runs only one time and then closes it.
This was initially the intention because it is only for learning but i want to expand on this program to increase my skills/knowledge and hope someone can point me in the right direction.
What i want to do now is instead of terminating the program after running it once; i would like to offer the user a choise to either stop the program or to continue it and to calculate a new circle.
I understand that it has to be done with an if else statment with the getchar function but i have some issues wrapping my mind around it on how to put it in a program flow. I hope someone can give me some directions on how to tackle this problem or can point me to some documentation that explains this properly.
Currently i have this:
int main(void){
float diameter;
double straal;
double oppervlakte;
char ch;
printf("Type de diameter van de cirkel:\t");
scanf("%g", &diameter);
printf("\n");
straal = diameter / 2;
oppervlakte = PI * (straal * straal);
printf("De straal =\t%g \n\n", straal );
printf("De oppervlakte =\t%f \n\n" , oppervlakte);
printf("Druk enter om af te sluiten.");
scanf("%c",&ch);
getchar();
return 0;
}
and im trying to accomplish something like this(below) but i can't get it to work properly (i get the warning that the label "diameter" is not defined while trying to compile it.)
#include <stdio.h>
#define PI 3.14
int main(void){
float diameter;
double straal;
double oppervlakte;
char ch;
printf("Type de diameter van de cirkel:\t");
scanf("%g", &diameter);
printf("\n");
straal = diameter / 2;
oppervlakte = PI * (straal * straal);
printf("De straal =\t%g \n\n", straal );
printf("De oppervlakte =\t%f \n\n" , oppervlakte);
printf("Druk 'd' om door te gaan of druk enter om af te sluiten.");
if(getchar() == 'd')
{
goto diameter; /* tried to use main(void) here but that also doesnt work */
}
else{
scanf("%c",&ch);
getchar();
}
return 0;
}
i do understand that goto is not the best practise to use but in this case it seemed the easyest way to solve this issue. (and the program is not that complex ofc). However if im wrong in this please let me also know.
Option 1: (likely the best choice): use a do..while loop. Place a do { above your primary code block, and add a } while (<repeat condition>); at the end. The program will run through the code once, check the repeat condition (which will be "did the user enter yes"), and if so repeat, otherwise not.
Option 2: recursively call main(). You said you "tried that", but I'm not sure if you tried it by attempting to use a goto or not. Just use the line main() to call the function again. Note that if you do this too many times you can end up with a stack overflow, because the computer keeps track of each call. It takes a lot to have it be a problem, but with enough repeats it can happen.
You can do something like:
while(true) //this is an endless loop
{
//display a menu like
1. calc area
2. [anything else if you want to add in future]
.
.
.
0. exit
//take user input (e.g 1 for calculating the area)
switch(user input)
{
case 1:
//code to calculate area
break;
case 2:
//code for anything else
break
case 0:
exit(0); //this will terminate the program
}
}
If you follow this pattern, you can add more options to your program in future. You just need to add a case in your switch statement and include that operation in your menu. You can search for menu driven c program to get more details. Try reading about while loop and switch... case statements.
I actually managed to make work in both ways.
Thanks for the tips and suggestions.

Run-Time Check Failure # 2

i was practicing my C Prog Language
and i decided to create a salon with cashier features
it looks messy,
though i'm still learning
posted here: http://pastebin.com/B2XaaCYV
it say runtime error with variable "menu", but i tried to recheck it around 5x and i don't see any error with it.
the code is really simple
like xy[0][1] = default 0 = meaning not yet purchased. its value will be 0/1 only. it will be 1 when you actually purchase it after picking the hairstyle.
then of course
xy[1][i] means price of xy[0][i]
i tried using other techniques like removing of breaks and changing variable name, but still it says runtime error with variable menu
no idea what makes the error. so i wish someone can help me with this
scanf("%1s",&menu);
No! A char isn't a string at all. You want to get a single character, so use either getchar() or scanf("%c",&menu);.
A related error is in your core_return, where you try to read 3 characters into a single character. Also, don't call your main in a sub-routine. Instead return from the sub-routine and put a loop in your main. By the way, 'yes' and 'no' aren't valid. If you want to compare strings, you have to use strcmp:
// returns 1 if the user wants to go again
int another_menu(void)
{
char tmp[20];
printf("Do you want another service?");
for(;;){
scanf("%3s",tmp);
if(strcmp("y",tmp) || strcmp("yes",tmp))
return 0;
else if(strcmp("n",tmp) || strcmp("no",tmp))
return 1;
printf("Please specify either 'no' or 'yes': ");
}
}
Use compiler warnings in order to find your errors quicker (GCC: -Wall -Wextra).

Need help with basic program in C

I have a menu when i select 2 variables and then i must choose between a man and a woman. After that i must go to man.c or woman.c with the 2 variables previously choosed but i dont know how can i do that.
my main.c (only when the man option in the menu):
printf("Insert weight: ");
scanf("%f",&a);
printf("Insert high: ");
scanf("%f",&b);
switch(opcion){
case 'm':;
--here i want to go to man.c to continue with other menu but knowing variables weight and high--
man.c and woman.c are similars the ionly difference is when calculates the body mass index
man.c :
int bmi(float weight, float high){
float bmi;
char opcion;
printf("a) Calculate body mass index");
switch(opcion){
case 'a': bmi = weight / high;
break;
}
}
now i ave only this and woman is the same. When is finished man.c and woman.c will have 4 options using weigh, high and some variables more that they asked when needed with scanf.
I'd suggest you call a function (say manMenu()) and keep it in same .c file.
1) You can't simply navigate through c files in C.
2) You can do that using includes & classes, but it's a bit hard for a beginner
3) The right way to do it is something like this:
printf("M/F");
scanf("%f",&option);
switch(option){
case M:
do_man();
break;
case F:
do_woman();
break;
}
And you should declare the functions do_man() and do_woman() before the main.
General:
It's mistake about thinking about code in means of filenames. Instead you should think about functions.
add error handling to the menu e.g. verify input and repeat in a loop until correct input or escape char.
Solution.
Add two functions void handleMan(float weight ,float height); and void handleWoman(float weight ,float height); prototypes to main.c (just copy code before menu() or main() and implement them in man.c and woman.c later on call right method upon user selection.
The easiest way would be to call a gender specific function in the switch. For example man_menu() and woman_menu().
These could also be located in different .c files but then you need to link the object files together.
Well you have to define procedures for man and woman and call procedure in switch statement and perform your individual activities in the respective methods .

Resources