How to make a number argument a variable? - ruby

How do I make a number argument a variable?
For example:
Snippet 1:
a=1
a_7 = a+6
alphabet = "ABCDEFGHIJKLMNOPQRSTUVQXYZ"
letter_7 = alphabet.slice[a_7..a_7]
Snippet 2:
alphabet = "ABCDEFGHIJKLMNOPQRSTUVQXYZ"
letter_7 = alphabet.slice[7..7]
I would like to make snippet 1 have the same outcome as snippet 2, with a variable as the arguments within slice action. Is there a way to do this?

So your issue come from the fact that you are using the slice method without any arguments. You can not use [] with the slice method. To make this work, you need to change [] to ()
letter_7 = alphabet.slice(7..7)
This will actually return H as the result, because arrays index start at 0, so to get the 7th letter, you will need to slice at index 6.
letter_7 = alphabet.slice(6..6) #=> 'G'
Or, you can just use the [] method on the string itself.
letter_7 = alphabet[6] #=> 'G'
Of course, you can replace the index values with variables, as long as the variables are set to integers.
a = 6
letter_7 = alphabet[a] #=> 'G'

Related

I am not getting the desired output with my python code

<code>def CheckNumber(MyList, number):
counter=0
while number!=0:
for i,element in enumerate(MyList):
if number%10==element:
del MyList[i]
else:
continue
number = number/10
if len(MyList)==0:
return 1
else:
return 2
print("Program to print all the possible combinations of a number")
MyNumber = int(input("Enter the number: "))
MyList = []
while MyNumber!=0:
MyList.append(MyNumber%10)
MyNumber=int(MyNumber/10)
MyLimit = 10**(len(MyList)-1)
for i in range(MyLimit, MyLimit*10):
answer = CheckNumber(MyList, i)
if answer == 1:
print(i)
else:
continue`</code>
I am a beginner at programming and I was trying to write a code to print all the possible combinations of a number. If user enters a 3 digit number the program will check all the three digit numbers to find possible combinations but instead it gives all the numbers as output. For example if user enters 12 then the output should be 12 21 but instead it shows every number from 10 to 99.
As far as I know everything is working fine but the results are not as I expect.
This is a pass-by-reference vs pass-by-value problem. What that means is when you pass a list to a function in python you are not passing the values in that list, you are passing the list itself, or rather its location in memory. So when you are modifying MyList in your CheckNumber function you are actually modifying the MyList variable globally. This is not true for primitive types which is why modifying number does not change i in the for loop. Quick example:
def foo(my_list):
my_list.append('world')
print(my_list)
a = []
foo(a) # this will print out 'world'
print(a) # this will print out 'world'
b = 'hello'
foo(b.copy()) # This will print out 'hello world'
print(b) # Here we have not passed b directly into foo,
# but instead passed a copy, so this will just print out 'hello' as b
# has not been modified
To summarize variable are stored in a specific location in memory. When you pass-by-reference you are passing a long that location in memory so you variable will be mutated. If you pass-by-value, you function will create a new variable and store a copy of the data so you will not mutate your outer variable. In other languages you can specify which way to pass in a variable but afaik you cannot in python.
With that out of the way this is a very easy fix. You don't want to modify your original MyList so just make a copy of it and pass that into the function. You also forgot to cast number/10 to int in the CheckNumber function. The working code should look like this:
def CheckNumber(MyList, number):
counter=0
while number!=0:
for i,element in enumerate(MyList):
if number%10==element:
del MyList[i]
else:
continue
number = int(number/10)
if len(MyList)==0:
return 1
else:
return 2
print("Program to print all the possible combinations of a number")
MyNumber = int(input("Enter the number: "))
MyList = []
while MyNumber!=0:
MyList.append(MyNumber%10)
MyNumber=int(MyNumber/10)
MyLimit = 10**(len(MyList)-1)
for i in range(MyLimit, MyLimit*10):
answer = CheckNumber(MyList.copy(), i)
if answer == 1:
print(i)
else:
continue
More info on pass-by-reference:
What's the difference between passing by reference vs. passing by value?
https://blog.penjee.com/passing-by-value-vs-by-reference-java-graphical/
https://courses.washington.edu/css342/zander/css332/passby.html

How do I sort a randomized word in python for my hangman program (without it in alphabetical order and rather in its own order)?

In my hangman program, I am experiencing some difficulties in trying to organize the user's correctly guessed inputs (when they guess a letter correctly). For example, if the word was "frog", and the user guessed in the order "r", "o", "f", "g", the program should sort it (eventually) into "frog". When I do the .sort() function, it arranges it in alphabetical order (e.g. "fgor" for "frog"). Before using the .sort() method, I had no means of arranging it.
Here is a small piece of my code (pretending the word is "frog" which it isn't in my program):
word = "frog"
guess = input("Put in a letter") # with an iteration of a while loop
def hangman():
nothing = []
points = 0
while num_of_lives >= 1:
guess = input("Put in a letter: ")
for i in word1:
if guess in i:
print(guess, "is one of the letters")
points += 1
nothing += i
nothing2 = []
for y in nothing[:]:
nothing2[0:] += y[0:]
nothing2.sort()
print(nothing2)
You can define a custom sort method using this technique:
https://www.geeksforgeeks.org/python-list-sort/
# Python program to demonstrate sorting by user's
# choice
# function to return the second element of the
# two elements passed as the parameter
def sortSecond(val):
return val[1]
# list1 to demonstrate the use of sorting
# using using second key
list1 = [(1, 2), (3, 3), (1, 1)]
# sorts the array in ascending according to
# second element
list1.sort(key = sortSecond)
print(list1)
You just need to create a function that returns the letter's position in the original word. This can be used to yield the key for comparison. For that I would look at pythons' list.index

how do i combine variables?

im making a program and i need to combine a lot of variables, most of them strings but i have some int, by doing this
name = "#{variable1}#{variable2}"
name2 = "#{variable2}#{variable1}"
it´s a simple example with just two variables but thats the idea, what im trying to make. i am doing all the possibilities one by one, even when is more than two variables but there are many combinations. Is there an easy way to do it or i have to do it one by one?Also, do i need to write the quotation marks separately or that way is fine?
Is this what you had in mind?
variable1 = "cat"
variable2 = 9
variable3 = "lives"
arr = [variable1, variable2, variable3]
#=> ["cat", 9, "lives"]
arr.join
#=> "cat9lives"
Put all or some of these variables into an array which will produce the combinations easier.
s1 = 'a'
s2 = 'b'
s3 = 'c'
n = 8
[s1, s2, s3, n].combination(3).map(&:join)
=> ["abc", "ab8", "ac8", "bc8"]
Above example assumes that you will pick any of 3 variables from the array and calculate the combinations. You may want to adjust that number to meet your needs.
The whole idea of programming is not doing all possibilities one by one. "there are many combinations": they look like permutations to me. If that is the case:
var1 = "aa"
var2 = "bb"
var3 = 2
res = [var1, var2, var3].permutation.map{|perm| perm.join}
p res #=> ["aabb2", "aa2bb", "bbaa2", "bb2aa", "2aabb", "2bbaa"]

Requesting class constant value in Ruby returns all defined values within this class

Hello I've encountered one interesting piece of code on Ruby project I've just joined. I tried to google explanation what is causing behaviour that I'm experiencing, but without any luck.
I've got class definition like this
class Values
First = 1,
Second = 2,
Third = 3
end
At other place there is call for value like this Values::First
this returns
1
2
3
If I call Values::Second or Values::Third it correctly returns just single value.
Can someone explain why it happens when lines are ended with comma character?
Thank you for your answers.
First off, these are constants not class variables.
The commas mean that this is the same as
First = 1, Second = 2, Third = 3
Which is the same as
First = 1, (Second=2), (Third=3)
This sets Second and Third but is otherwise the same as
First = 1,2,3
Which sets First to the array [1,2,3]
Your syntax defines First as an Array, while also defining Second as 2 and Third as 3 in the process. Remove the commas to have First set to 1:
class Values
First = 1
Second = 2
Third = 3
end

Using a block to find values matching criteria

To me this makes perfect sense:
triple = dice.collect {|value| if (dice.count(value) >= 3)} ---> Syntax error
OR
triple = dice.collect {|value| dice.count(value) >= 3} ----> Array of true/false
I want the value of the number, not the true or falsity of dice.count(). I know there must be a simple way of doing this.
It sounds like you want Array#select, not Array#collect (also known as Array#map).
collect/map will take each value and put the results of your block into an array. This is why you're seeing an array of true/false.
select will take each value, and return it as a member of an array if the block evaluates to true:
triple = dice.select{ |value| dice.count(value) >= 3 }
Your block needs to return whatever it is you want in the final array.
triple = dice.collect {|value|
if dice.count(value) >= 3
dice.count(value)
end
}
Note that this will return nil for elements < 3 (though you can add an else to return 0 or something). If you only want elements that match your query, you'll need to use dice.select()
As for your first code snippet,
triple = dice.collect {|value| THE_CODE_BLOCK_STARTS_HERE }
Thus, if (dice.count(value) >= 3) is an incomplete if statement. That's why you get syntax error.

Resources