How to build a simple menu-based console application? - ruby

It's been a week since I am learning Ruby. It's an awesome language and I am enjoying it.
I am still a noob. Here's a question:
I want a Console Application in Ruby to ask users to hit Num-Keys to choose options like a program with five functions. First four functions for SUM, SUB, MUL and DIV and last one is for returning to main menu.
I tried to write code but I failed. Here is the code:
puts "Choose Option(Press the num key)\n
1. For SUM\n
2. For SUB\n
3. For MUL\n
4. For DIV\n
5. For Main Menu"
$x = 22
$y = 32
def gloabl_f(n) # <= global function start here
def sum(x,y) # <= SUM function
return x+y
end
def sub(x,y) # <= SUB function
return x-y
end
def mul(x,y) # <= MUL function
return x*y
end
def div(x,y) # <= DIV function
return x/y
end
def Main_Menu()
return puts "Choose Option(Press the num key)\n
1. For SUM\n
2. For SUB\n
3. For MUL\n
4. For DIV\n
5. For Main Menu"
end
n = gets.to_i
if n == 1
puts sum(22,32)
end
end # <= global function end here
Basically, I want the user to input two numbers first, and then to be able to choose an option of 1,2,3,4,5 by hitting the numeric keys related to above functions.

Some general points
It isn't very idiomatic to define methods inside of functions
You're never calling neither gloabl_f nor Main_Menu, you just define them.
Here's a sample solution:
def get_numbers
puts "First number:"
x = gets.chomp.to_i
puts "Second number:"
y = gets.chomp.to_i
yield(x,y)
end
def sum(x,y)
x + y
end
puts "Choose Option:
1. For SUM
2. For SUB
3. For MUL
4. For DIV
5. Exit
"
n = gets.chomp.to_i
case n
when 1
get_numbers do |x,y|
puts "Sum: #{sum(x,y)}"
end
when 2
# code
when 3
# code
when 4
# code
else
puts "Exiting"
end
I left the other options for you to implement.

puts "Choose Option(Press the num key)\n
1. For SUM\n
2. For SUB\n
3. For MUL\n
4. For DIV\n
5. For Main Menu"
x = 22
y = 32
n = gets.chomp.to_i
if n == 1
puts x + y
end

Related

Can you someone support me to use ordinal in while loop in Ruby?

I am having a difficult time figuring ordinal in the program below. I need to use the ordinal in the loop statement. When I print statement, It print out backward like 3rd, 2nd, 1st, and so on.
I tried changing my loop statment from (number -= 1) to (number += 1) but that would make infinite while loop. Can someone give me feedback on what I can do here? Thank you.
class Integer
def ordinal
case self % 10
when 1
return "#{self}st"
when 2
return "#{self}nd"
when 3
return "#{self}rd"
else
return "#{self}th"
end
end
end
puts "Let's play a numbers game."
print "How many numbers would you like to enter? >"
number = gets.chomp.to_i
while number >= 1
print "\n\nEnter the #{number.ordinal} positive integer:"
user_int = gets.chomp.to_i
number -= 1
if user_int % 3 == 0
print "#{user_int} is divisible by 3."
else
print "#{user_int} is not divisible by 3."
end
end
puts "\n\nEnd of the Game"
First I'd suggest you to patch Integer class in this way:
module MyIntegerPatch # <------ a custom module
def to_ordinal # <------ to_ordinal is better
case self % 10
when 1
return "#{self}st"
when 2
return "#{self}nd"
when 3
return "#{self}rd"
else
return "#{self}th"
end
end
end
Integer.include MyIntegerPatch # <------ "patch" the class
Then for your loop just use a Range:
(1..number).each do |n| # <---- a range here
puts "\n\nEnter the #{n.to_ordinal} positive integer:"
user_int = gets.chomp.to_i
if user_int % 3 == 0
puts "#{user_int} is divisible by 3."
else
puts "#{user_int} is not divisible by 3."
end
end
Maybe you can try below, use the ruby style times to control
class Integer
def ordinal
case self % 10
when 1
"#{self}st"
when 2
"#{self}nd"
when 3
"#{self}rd"
else
"#{self}th"
end
end
end
puts "Let's play a numbers game."
print 'How many numbers would you like to enter? >'
number = gets.chomp.to_i
number.times do |time|
print "\n\nEnter the #{(time + 1).ordinal} positive integer:"
user_int = gets.chomp.to_i
if user_int % 3 == 0
print "#{user_int} is divisible by 3."
else
print "#{user_int} is not divisible by 3."
end
end
puts "\n\nEnd of the Game"

How do I update one element in an array and show new version of my array in the tictactoe grid?

This is a tictactoe game. When a player chooses a grid via a number, it is supposed to update the picked number with X or O, and then show the updated grid. Unfortunately, it continues to output the same default grid of numbers. I used map! but it does not work. If I switch #player1 : x to x: #player1, it changes the entire array to X or O.
Once I figure this out, the win method will be the next task to check. Will win work to determine the winning combinations?
#a = [1,2,3,4,5,6,7,8,9]
def game
#game_board = "#{#a[0]}|#{#a[1]}|#{#a[2]}\n" "------\n" "#{#a[3]}|#{#a[4]}|#{#a[5]}\n" "------\n" "#{#a[6]}|#{#a[7]}|#{#a[8]}\n"
#game_board
end
def secondchoice
if #player1 == "X"
#player2 = "O"
elsif #player1 == "O"
#player2 = "X"
else puts "please pick a valid number"
end
end
def start
puts " Player One, Pick Your Tic or Toe , X or O"
#player1 = gets.chomp.upcase
#player2 = secondchoice
puts "Player one is #{#player1}"
puts "Now Player Two is #{#player2}"
end
def player_turns
# player 1 gets then player 2 gets until game over == true
# nine total moves using a loop with a counter will work
moves = 1
while moves < 10
if moves.odd?
puts #game_board
puts "its player One's turn! place #{#player1} on the board by picking a number: "
cell = gets.chomp
#a.map! {|x|x == cell ? #player1 : x}
moves += 1
unless check_win == true
end
else
puts #game_board
puts "its player Two's turn! place #{#player2} on the board by picking a number: "
kell = gets.chomp
#a.map! {|x|x == kell ? #player2 : x}
moves += 1
unless check_win == true
end
end
end
end
def win
# 10 turns(count) with no combination is a draw
return [[#a[0]+ #a[1] + #a[2]],[#a[3] + #a[4] + #a[5]],[#a[6] + #a[7] + #a[8]],[#a[0]+ #a[3] + #a[6]],[#a[1] + #a[4] + #a[7]],[#a[2] + #a[5]+ #a[8]],[#a[0]+ #a[4] + #a[8]],[#a[2] + #a[4] + #a[6]]]
#game_over check if player has 3 in a row
end
# Create a loop that gives player turns. Player one then player two until a draw or three in row
def check_win
win.each do |arr|
str = arr.join
if str == "xxx"
puts "X Wins!"
return true
elsif str == "ooo"
puts "O Wins!"
return true
end
end
return false
end
while check_win != true
start
game
player_turns
end
It's not clear why map! would factor in here. A simple array manipulation is all that's required:
#a[cell.to_i - 1] = #player2
Specifying the cells as zero indexed would make this easier.
There's a lot of evidence of going against the grain here that's made for a ton more code than necessary. For example, variables like #player1 and #player2 are usually a sign of bad design. Why not #players = %w[ X O ]? That alone solves a lot of problems if you apply that array throughout your code instead of having per-player variables. Each turn: #players.unshift(#players.pop)

Ruby: Factorial Recursion

The difference between the two methods occurs at second if condition. The if condition in the first method is "if num <= 1" and the if condition in the second method is "if num = 1". I mapped out both methods on a piece of paper step by step but I don't understand why the factorial2 returns 1 instead of 6. On paper, I get 6 for both methods.
def factorial1(num)
if num < 0
return "Please use a positive number"
end
if num <= 1
1
else
num * factorial(num-1)
end
end
puts factorial1(3)
#returns 6
def factorial2(num)
if num < 0
return "Please use a positive number"
end
if num = 1
1
else
num * factorial(num-1)
end
end
puts factorial2(3)
#returns 1
if num = 1
Comparator operator is ==, not = (assignment operator).
Also don't forget to use return keyword, it is good convention to make each branch return something.
def fact(n)
return 1 if n==0
return n * fact(n-1)
end
puts "Enter number"
n=gets.to_i
a=fact(n)
puts a

How do I calculate the factorial of a number in Ruby?

Alright, so I asked an earlier question on my syntax error. I got rid of the errors, but the program doesn't do what it was intended to do. My math is wrong and doesn't find the number of trailing zeros. Here is my code:
num = " "
a = 0
sumOfFact = 1
def factorial
num = gets.to_i
a = num
(1..num).each do |a|
if a != 1
sumOfFact *= a
a -= 1
else
break
end
end
end
for c in 1..sumOfFact
if sumOfFact / c == 10
zeros += 1
end
end
factorial()
puts sumOfFact
puts zeros
Well, first, you should do the gets outside your method. Your method should accept a param. Second, why do you need the condition?
You want the multiplication from 1 to n to get the factorial. You should get started with this:
def factorial(n)
total = 1
(1..n).each do |n|
total *= n
end
total
end
puts factorial(gets.to_i)
Next is factorial with inject in case you want to learn new syntax :-)
def factorial(n)
n == 0? 1 : (1..n).inject(1) { |total, i| total*= i; total }
end
puts factorial(gets.to_i)
As #pjs commented below, here's a beautiful way of doing factorial!
def factorial(n)
n == 0? 1 : (1..n).inject(:*)
end
And, a final enhancement:
def factorial(n)
(1..n).inject(1, :*)
end
Supposing that n is a non-negative integer number, you can define a method to calculate the factorial:
def factorial(n)
tot = 1
(1..n).each do |n|
tot *= x
end
tot
end
Examples of its usage:
puts factorial(0) # 1
puts factorial(1) # 1
puts factorial(2) # 2
puts factorial(3) # 6
puts factorial(4) # 24
puts factorial(5) # 120
If you wan't to read the user input, call it like this:
puts 'Type the non-negative integer:'
n = gets.to_i
puts factorial(n)
class Factorial
attr_reader :num
def initialize(num)
#num = num
end
def find_factorial
(1..num).inject(:*) || 1
end
end
number = Factorial.new(8).find_factorial
puts number
Or you could just simply write:
(1..num).inject(:*) || 1
Try this too. Hope this helps anyone having the same problem in some way.
Method for finding the factorial of any number:
def factorial(number)
for i in 1...number do
number *= i
end
number
end
puts factorial(5)

Ruby - Prime Number calculator

I need some feedback to figure out why I cant puts or print anything from my methods on the screen. This is a simple script I wrote to solve the problem of finding the 1001st prime number. Thanks
def primes
# iterates through numbers until it has the 1001th prime number and returns it.
# I chose to create the num_primes variable instead of counting the number of
# elements in in_prime_array every iteration
# based upon a guess that it would be faster to check.
is_prime_array = []
num_primes = 0
i = 2
loop do
is_prime_array << i && num_primes += 1 if is_prime?(i) == true
i += 1
break if num_primes == 1001
end
is_prime_array[1001]
end
def is_prime? (num)
# Checks to see if the individual number given is a prime number or not.
i = 2
loop do
if i == num
return true
elsif num % i == 0
return false
else
i += 1
end
end
end
Thanks for any help!
EDIT
I took your advice and tried this pice of code:
def is_prime? (num)
# Checks to see if the individual number given is a prime number or not.
i = 2
loop do
if i == num
return true
elsif num % i == 0
return false
else
i += 1
end
end
end
i = 0
count = 0
loop do
count += 1 if is_prime?(x)
puts "#{i}" if count == 1001
break
end
It still returns nothing. Hummm
i = 0
count = 0
loop do
if is_prime(i)
count += 1
end
if count == 10001
puts "#{i}"
break
end
end
Simple method :)
It's an off-by-one error. If you have 1001 elements in an array, the last element will be at index 1000.
Where you have
is_prime_array[1001]
Change it to
is_prime_array[1000]
And you can do this:
puts primes
=> 7927
You could also have
is_prime_array.last
instead of a specific index number.
What are you trying to "puts"? The first thing I notice is that there is no call to primes in the file, so nothing will happen if you try to run this code by itself. Maybe that's why you don't see anything printed.
Here's an example of how to print a few variables inside your loop:
loop do
...
puts "At iteration #{i}, we have prime=#{is_prime?(i)}"
If you don't know, enclosing a statement with #{<statement goes here>} inside a string is the same as appending the return value of <statement goes here> to the string at that position. This is the same as "Str " + blah + " rest of str" in a language like Java.

Resources