Sorting array with starter inside the array - arrays

sorry I had issues formulating my question.
to explain it better :
I have a = ["alice", "jean", "bob"]
Now i want to let the user choose who will start the game.
If its jean, the new array should be like this
a = ["jean", "bob", "alice"]
So far, this is working :
def sort_array_players(array_player, starter)
sort_array_player = []
array_player.map do |name|
if name == starter && name == array_player[0]
sort_array_player = [array_player[0], array_player[1], array_player[2]]
elsif name == starter && name == array_player[1]
sort_array_player = [array_player[1], array_player[2], array_player[0]]
elsif name == starter && name == array_player[2]
sort_array_player = [array_player[2], array_player[0], array_player[1]]
end
end
puts sort_array_player
end
I want to refractor this code but i'm a bit new to ruby, I've spend 2 hours trying to figure out this thing. My guess is that you need to use each.with_index and then create the new array starting by the first one and the following element would be the one with the index of the starter + 1..
Thanks for helping guys

As #rubish commented, you can use Array#rotate method.
You can use positive integer as count parameter to rotate items counter clockwise or negative integers to rotate them clockwise.
a = ["alice", "jean", "bob"]
starter = "jean"
count = a.index(starter) # => 1
a.rotate(count) # => ["jean", "bob", "alice"]

Related

issue creating a list with basic python loop for a in b:

I am trying to create a list in python that is filled with the elements I have selected in Autodesk Maya. However, when I select more than one element, this element gets duplicated. I thing this is a really simple issue because I'm not looping correctly and then an key gets added to my list more than once.
If someone with more knowledge could take a look and give me some advice would be great!
Many thanks in advance,
Joan
items = []
selectedObjects = cmds.ls(sl=True)
strItems = []
for item in selectedObjects:
b = item.encode('utf-8')
strItems.append(b)
for item1 in strItems:
lenItem = len(item1)
lenItemNoGrp = lenItem - 5
lenItemNoGrp2 = lenItem - 6
grp = item1[lenItemNoGrp:lenItem]
grp2 = item1[0:lenItemNoGrp2]
grpName = grp2
if grp == 'group':
items.append({
"type": "maya_file",
"name": shotName + 'V' + versionStr + grpName,
})
else:
None
You are looping over the complete content of strItem every time you add something to it. Let's say you have selected obj1 and obj2. Then
obj1 is added to the list
the second loop takes obj1 and does something with it
the outer loop stars again and adds obj2 to the list
the inner loop again takes all contents of the list and first takes obj1 and then obj2
So iterating over the canging list is maybe not what you want to do in this case.
It looks like you indented the loop by accident. This version is still missing the variables shotName and versionString but it will not duplicate things
items = []
selectedObjects = cmds.ls(sl=True)
strItems = []
for item in selectedObjects:
b = item.encode('utf-8')
strItems.append(b)
for item1 in strItems:
lenItem = len(item1)
lenItemNoGrp = lenItem - 5
lenItemNoGrp2 = lenItem - 6
grp = item1[lenItemNoGrp:lenItem]
grp2 = item1[0:lenItemNoGrp2]
grpName = grp2
if grp == 'group':
items.append({
"type": "maya_file",
"name": shotName + 'V' + versionStr + grpName,
})
However you can simplify this in a couple of ways.
You can do the utf-8 conversion with a list comprehension
You can also find the items ending in 'group' using endswith
You can use a negative slice to get the rest of the string without 'group'
That gets you down to:
group_nodes = [item.encode('utf-8') for item in cmds.ls(sl=True) if item.endswith('group')]
entries = [{
'type':'maya_file',
'name': "{0}V{1}{2}".format(shotName, versionStr, entry[:-5])
}
for entry in group_nodes]

Why do my answers randomize in my Quiz Game?

I made a Quiz Game in Swift 2 last year, now I need to use it again when I converted it to Swift 3 the answers randomize now... Here is a sample Question Structure...
Questions = [Question(Question: "What is the Biggest Hit of Bing Crosby?" , Answers: ["Swinging on a Star", "Now is the Hour", "White Christmas", "Beautiful Dreamer"], Answer: 2),]
This is where I randomize the questions and put them into the labels
func PickQuestions() {
counter += 1
score += 1
scoreLbl.text = "\(score)"
restartBtn.isEnabled = false
if Questions.count > 0 && counter <= 15 {
QNumber = Int(arc4random_uniform(UInt32(Questions.count)))
QLabel.text = Questions[QNumber].Question
AnswerNumber = Questions[QNumber].Answer
for i in 0..<Buttons.count{
Buttons[i].setTitle(Questions[QNumber].Answers[i], for: UIControlState())
}
Questions.remove(at: QNumber)
}
}
I had to change the following line manually which may have caused an issue from...
QNumber = Int(arc4random_uniform(UInt32(Questions.count)))
to
QNumber = random() % Questions.count
Thanks
Arrays are unordered collections, meaning that their order could potentially change without your knowing. Your best bet would be to create a single array containing a struct that holds both the question and answer, like so:
struct QuizItem {
var question: String!
var answer: String!
var answerOptions: [String]!
init(q: String, a: String, aOptions:[String]) {
self.question = q
self.answer = a
}
}
Change your declaration to look like the following:
let items = [QuizItem(...)]
Your code like this:
func PickQuestions() {
counter += 1
score += 1
scoreLbl.text = "\(score)"
restartBtn.isEnabled = false
if items.count > 0 && counter <= 15 {
QNumber = Int(arc4random_uniform(UInt32(Questions.count)))
let item = items[QNumber]
QLabel.text = item.question
for i in 0..<Buttons.count{
Buttons[i].setTitle(item.answerOptions[i], for: UIControlState())
}
items.remove(at: QNumber)
}
}
Also, kind of picky but worth highlighting still. Swift is a camel case language and although this rule isn't set in stone, you should try and stick to the widely recognised coding practices.

SWIFT: Copying objects from arrays then changing properties and adding them back to original array

I'm working on a SRS-based Flashcard program in swift. My problem (other than being new at programming, haha) is... once I alter the values of due date, score, etc; how do I add them back to the wordBank array keeping the new property values?
I started out creating a class for other flashcards to inherit properties like word, translation, sentence 1 & 2, audio URL, score (1-100 for scheduling purposes), etc; etc;
class Flashcard {
var id: Int = 0
var score: Int = 0
var word: String = ""
var sentence1: String = ""
// etc; etc;
From here, I created a new file and class called words, inheriting the Flashcard properties.
class Words: Flashcard {
// Example word 1
let you = Flashcard()
you.id = 0
you.score = 2
you.word = "khun"
you.sentence1 = "khun blah blah"
// Example word 2
let me = Flashcard()
you.id = 1
you.score = 1
you.word = "pohm"
you.translation = "Me or I"
// Create an array of all the words that will be in the program
var wordBank: [Flashcard] = [you, me, him, her, them, it] // etc;
Now, from here I can sort
// Sort array by lowest
wordBank.sort({ $1.score > $0.score })
// Create a new array for testing Session
var SessionArray: [Flashcard] = []
// Add the lowest scores to the SessionArray for testing
SessionArray += WordArray[0...6]
For the sake of remembering, My problem is once I alter the values of due date, score, etc; how do I add them back to the wordBank array keeping the new property values? I won't bother asking about how to persist this data right now, lol. I'm still reading about core data.
Thanks for any help you can give me!

How can I stop an array from repeating in Visual Basic 2010?

I have randomized an array, so questions are shown in a different order every time that the quiz is played, but would prefer it if the questions weren't able to repeat.
Here is how my array is set up:
Function loadQuestions()
Questions(0).Question = "Which of these words are an adjective?"
Questions(0).option1 = "Dog"
Questions(0).option2 = "Beautiful"
Questions(0).option3 = "Steven"
Questions(0).option4 = "Bird"
Questions(0).Answer = "B"
Questions(1).Question = "What's the adjective in this sentence:" & vbCrLf & "'Kelly handled the breakable glasses very carefully'"
Questions(1).option1 = "Kelly"
Questions(1).option2 = "Handled"
Questions(1).option3 = "Carefully"
Questions(1).option4 = "Breakable"
Questions(1).Answer = "D"
...
This is the function that calls the questions when the quiz begins.
Function GetQuestion(ByVal intQuestion As Integer)
tmrOne.Start()
If questionNumber < 11 Then
lblQuestionNumber.Text = "Question" & " " & questionNumber
Dim questionChosen As Integer
questionChosen = random.Next(25)
lblQuestion.Text = Questions(questionChosen).Question
btnAnswerA.Text = Questions(questionChosen).option1
btnAnswerB.Text = Questions(questionChosen).option2
btnAnswerC.Text = Questions(questionChosen).option3
btnAnswerD.Text = Questions(questionChosen).option4
strAnswer = Questions(questionChosen).Answer
questionNumber = questionNumber + 1
btnAnswerA.BackColor = Color.White
btnAnswerB.BackColor = Color.White
btnAnswerC.BackColor = Color.White
btnAnswerD.BackColor = Color.White
btnAnswerA.Enabled = True
btnAnswerB.Enabled = True
btnAnswerC.Enabled = True
btnAnswerD.Enabled = True
Return intQuestion
Else
MsgBox("You have finished")
End
End If
End Function
I have tried to find something on the internet to help with this, but haven't been successful or understood it as I am new to this. I have found ArrayList.RemoveAt but not sure that is the correct syntax to use with my array?
So, how do I stop my array from repeating a question once it has already been asked? Do I put them into another array?
Any help is greatly appreciated!
As I understand from your question, you are using an ArrayList. In that case, yes, the RemoveAt option sounds as the best alternative. Bear in mind that pure arrays (e.g., Dim Questions() As String) are the most efficient type of Collection; the main advantage of Lists/ArrayLists is precisely how easy is adding/removing elements, so if you use an ArrayList, better maximising one of its defining features.
The additional advantage in your specific case is that every time you remove an item, its position is filled (and the total number of items decreased). Thus, you have just to update the maximum value of your random number generator to the current number of indices (not elements, because the first index is zero).
In summary, the following changes in your code will deliver what you want:
If(Questions.Count > 0) Then
questionChosen = random.Next(0, Questions.Count - 1)
End If
And once you are done with it:
If(questionChosen >= 0 And questionChosen <= Questions.Count - 1) Then
Questions.RemoveAt(questionChosen)
End If

Adding items to a multidimensional array without overwriting the old ones?

this may be a simple question, yet I haven't been able to find an answer to it:
How do I add a value to an array without overwriting (all) old values, or having to rewrite them? Is there such a thing as array_push in LUA? And if so, does it work for multidimensional arrays as well?
Example:
Array={"Forest","Beach","Home"} --places
Array["Forest"] = {"Trees","Flowers"} --things you find there
Array["Forest"]["Trees"] = "A tree is a perennial woody plant" --description
If I'd like to add a description of a new thing in a new place, I can't do it using
Array["Restaurant"]["Spoon"] = "A type of cutlery."
because I'd have to declare all these things, as well as the old ones so I don't overwrite them. So I'm looking for something like:
array_push(Array, "Restaurant")
array_push(Array["Restaurant"],"Spoon")
Array["Restaurant"]["Spoon"] = "A type of cutlery."
Thanks!
The following index metamethod implementation should do the trick.
local mt = {}
mt.__index = function(t, k)
local v = {}
setmetatable(v, mt)
rawset(t, k, v)
return v
end
Array={"Forest","Beach","Home"} --places
setmetatable(Array, mt)
Array["Forest"] = {"Trees","Flowers"} --things you find there
Array["Forest"]["Trees"] = "A tree is a perennial woody plant" --description
Array["Restaurant"]["Spoon"] = "A type of cutlery."
Note that you are mixing array indexed values with with string indexed values, and I don't think you intended to do so. For example, your first line stores "Forest" under the key "1", while the second line creates a new table key "Forest" with a table value that holds sequential string values. The following code prints out the generated structure to demonstrate my meaning.
local function printtree(node, depth)
local depth = depth or 0
if "table" == type(node) then
for k, v in pairs(node) do
print(string.rep('\t', depth)..k)
printtree(v, depth + 1)
end
else
print(string.rep('\t', depth)..node)
end
end
printtree(Array)
Next is the resulting output of the two code snippets listed above.
1
Forest
2
Beach
3
Home
Restaurant
Spoon
A type of cutlery.
Forest
1
Trees
2
Flowers
Trees
A tree is a perennial woody plant
With this understanding, you could then solve your problem without such trickery as follows.
Array = {
Forest = {},
Beach = {},
Home = {}
}
Array["Forest"] = {
Trees = "",
Flowers = "",
}
Array["Forest"]["Trees"] = "A tree is a perennial woody plant"
Array["Restaurant"] = {
Spoon = "A type of cutlery."
}
printtree(Array)
The output is then what you probably expected.
Restaurant
Spoon
A type of cutlery.
Beach
Home
Forest
Flowers
Trees
A tree is a perennial woody plant
With all of that in mind, the following accomplishes the same thing, but is much clearer in my humble opinion.
Array.Forest = {}
Array.Beach = {}
Array.Home = {}
Array.Forest.Trees = ""
Array.Forest.Flowers = ""
Array.Forest.Trees = "A tree is a perennial woody plant"
Array.Restaurant = {}
Array.Restaurant.Spoon = "A type of cutlery."
printtree(Array)
First, what you're making is not an array at all, but a dictionary. Try:
T = { Forest = { } , Beach = { } , Home = { } }
T.Forest.Spoon = "A type of cutlery"
Otherwise table.insert may be what you want in array_push
This is almost identically there in standard Lua like this:
Array.Restaurant={}
Array.Restaurant.Spoon={}
Array.Restaurant.Spoon[1]="A type of cutlery."
the table.key notation is equivalent of the table["key"] notation.
Now every item has it's description in the value corresponding to a number-key, and sub items as values corresponding to string keys.
If you really want to have exactly the same syntax as your example, you'll have to use metatables (__index and __newindex methods).

Resources