I get this but don't understand why ? TypeError: PetData() takes 1 positional argument but 3 were given - arguments

I keep getting an error and don't know why
import petspgm
def main():
#Get a list of pet objects.
pets = make_list()
#Display the data in the list.
print('Here is the data you entered: ')
display_list(pets)
#This function gets data from the user for 3 pets. It returns a list of pet
#objects containing the data.
def make_list():
#Create an
pet_list = []
#Add three pet objects to the list
print('Enter the data for 3 pets.')
for count in range(1, 3):
#Get the pet data
print("Pet number " + str(count) + ":")
pet_name = input("Enter your pet's name: ")
pet_type = input("Enter the type of pet: ")
pet_age = float(input("Enter the pet's age: "))
#Create a new PetData object in memory and assign it to the pet variable.
pet = petspgm.PetData(pet_name, pet_type, pet_age)
#Add the object to the list.
pet_list.append(pet)
#Return the list.
return pet_list
#This function accepts a list containing PetData objects as an argument and
#displays the data stored in each object.
def PetData(pet_list):
for item in pet_list:
print("Pet's name is: " + item.get_pet_name())
print("Pet's type is: " + item.get_pet_type())
print("Pet's age is: " + item.get_pet_age())
The error happens here I think
strong text
#Create a new PetData object in memory and assign it to the pet variable.
pet = petspgm.PetData(pet_name, pet_type, pet_age)
#Add the object to the list.
pet_list.append(pet)
#Return the list.
return pet_list
#This function accepts a list containing PetData objects as an argument and
def pet_list():
#displays the data stored in each object.
display_list(pet_list)
for item in pet_list:
print("Pet's name is: " + item.get_pet_name())
print("Pet's type is : " + item.get_pet_type())
print("Pet's age is : " + item.get_pet__age())
#Call the main function
main()

This line:
def PetData(pet_list):
tells me that PetData only takes one parameter, but the line below:
pet = petspgm.PetData(pet_name, pet_type, pet_age)
passes 3 parameters. That explains the error message.

Related

Creating a console based text game and can't get the cursor to pop up a line into the proper location (Ruby)

Edit: using the Paint gem.
So I'm re-writing the shop system in my text based game I made in ruby. I'm attempting to get multiple colors onto a single line of text. I found a method that works but for some reason the first string (which includes the item id and the item name) is getting concated at 11 characters all the time.
each item value is an array. value[0] contains the name, and so on.
Here is the code that draws each item for the shop menu:
shopbag.each { |id, value|
if id != 0
string1 = "(" + id.to_s + ")" + " " + value[0]; str1 = string1.size
string2 = "ATTACK: #{value[1]}"; str2 = string2.size
string3 = "SPEED: #{value[2]}"; str3 = string3.size
pa string1; pa "\033[1A \033[#{str1}C #{string2}", :red, :bright; pa "\033[1A \033[#{str2}C #{string3}", :green, :bright
end
}
Here is a screenshot of what it looks like:
shop bug (click for image)
Note you can see a string size before each item, as I had a print line in there to verify that the size was correct. It is not present in my code snippet here. If it was working properly, it would show the full names before the attack and speed values.

How can I access a field from a Module by using a variable?

I am using a module to hold repeated code, but I need to pass in a field as a parameter that can be changed. I have used Form1.controls(variableName & ".text") to accomplish the same thing with text boxes, but it will not work for fields as they are not controls. Here is the code I used for text boxes:
Public Sub fillTextBox(table As DataTable, column As String, value As String, txtNum As Integer)
For i As Integer = 0 To table.Rows.Count() - 1
If table.Rows(i)(column) = value Then
Form1.Controls("Text" & (txtNum).ToString()).Text = table.Rows(i)("VALUE")
End If
Next
End Sub
And this is where I would like to use a field from Form1:
Public Sub getData(table As DataTable, column As String, value As String, destination As String, bError As String)
For i As Integer = 0 To table.Rows.Count() - 1
If table.Rows(i)(column) = value Then
Form1.Controls(destination) = table.Rows(i)(column)
Form1.found = True
Exit For
End If
Next
Form1.Controls(bError) = True
End If
Form1.found = False
End Sub
"destination" and "bError" are fields that are passed into the Function, but they will be different fields depending on what table is being used and what field needs filled.

How to create a new struct when an error occurs

I am trying to make a text based game using ruby to learn the language, I want to throw an error if a player enters a string incorrectly, it should ask them to start the character making process over again.
My issue is that when I re-call the function to make the character, it creates a new struct and keeps the old one. So at the end I have something that is printing the new corrected struct as well as the old wrong struct. I obviously only want to keep the correct one so how do I go about getting rid of the old one?
Character = Struct.new(:name,:race,:alignment,:str,:dex,:int,:const,:char,:wis)
def makeChar()
newChar = Character.new()
until i == 6 do
case skillArray[i]
when "str"
newChar.str = rolledStats[i]
when "int"
newChar.int = rolledStats[i]
when "dex"
newChar.dex = rolledStats[i]
when "wis"
newChar.wis = rolledStats[i]
when "const"
newChar.const = rolledStats[i]
when "char"
newChar.char = rolledStats[i]
else
puts("It appears you have entered an invalid value for a skill")
puts("Please try again but enter only the following: str, dex, int, char, wis, const")
makeChar()
end
i += 1
end
puts("Our brave adventurer's name is #{name} the #{race}")
puts("#{name}'s stats are as follows:\n Str: #{newChar.str} \n Dex: #{newChar.dex}
Const: #{newChar.const} \n Int: #{newChar.int} \n Wis: #{newChar.wis} \n Char: #{newChar.char}")
print("#{name} prepare for your quest!")
There are cases when you need to 'get rid of' variables but this doesn't sound like one.
Just see this example:
word = "test"
def guess_word
guess = gets.chomp
exit if word == guess
end
loop do
puts "guess word"
guess_word
end
This program runs on a loop. Each iteration, it prompts the user for a word. If the word is correct, it exits. You can see in guess_word that the guess variable is assigned each time the method is called.
If you have a method which defines a variable, that variable's scope is just in that method unless there is a variable with the same name in a higher scope.

Read a file into an associative array

I want to be able to read the file into an associative array where I can access the elements by the column head name.
My file is formatted as follows:
KeyName Val1Name Val2Name ... ValMName
Key1 Val1-1 Val2-1 ... ValM-1
Key2 Val1-2 Val2-2 ... ValM-2
Key3 Val1-3 Val2-3 ... ValM-3
.. .. .. .. ..
KeyN Val1-N Val2-N ... ValM-N
The only problem is I don't have a clue how to do it. So far I have:
scores = File.read("scores.txt")
lines = scores.split("\n")
lines.each { |x|
y = x.to_s.split(' ')
}
Which gets close to what I want, but still am unable to get it into the format that is usable for me.
f = File.open("scores.txt") #get an instance of the file
first_line = f.gets.chomp #get the first line in the file (header)
first_line_array = first_line.split(/\s+/) #split the first line in the file via whitespace(s)
array_of_hash_maps = f.readlines.map do |line|
Hash[first_line_array.zip(line.split(/\s+/))]
end
#read the remaining lines of the file via `IO#readlines` into an array, split each read line by whitespace(s) into an array, and zip the first line with them, then convert it into a `Hash` object, and return a collection of the `Hash` objects
f.close #close the file
puts array_of_hash_maps #print the collection of the Hash objects to stdout
Can be done in 3 lines (This is why I love Ruby)
scores = File.readlines('/scripts/test.txt').map{|l| l.split(/\s+/)}
headers = scores.shift
scores.map!{|score|Hash[headers.zip(score)]}
now scores contains your hash array
Here is a verbose explanation
#open the file and read
#then split on new line
#then create an array of each line by splitting on space and stripping additional whitespace
scores = File.open('scores.txt', &:read).split("\n").map{|l| l.split(" ").map(&:strip)}
#shift the array to capture the header row
headers = scores.shift
#initialize an Array to hold the score hashs
scores_hash_array = []
#loop through each line
scores.each do |score|
#map the header value based on index with the line value
scores_hash_array << Hash[score.map.with_index{|l,i| [headers[i],l]}]
end
#=>[{"KeyName"=>"Key1", "Val1Name"=>"Val1-1", "Val2Name"=>"Val2-1", "..."=>"...", "ValMName"=>"ValM-1"},
{"KeyName"=>"Key2", "Val1Name"=>"Val1-2", "Val2Name"=>"Val2-2", "..."=>"...", "ValMName"=>"ValM-2"},
{"KeyName"=>"Key3", "Val1Name"=>"Val1-3", "Val2Name"=>"Val2-3", "..."=>"...", "ValMName"=>"ValM-3"},
{"KeyName"=>"..", "Val1Name"=>"..", "Val2Name"=>"..", "..."=>"..", "ValMName"=>".."},
{"KeyName"=>"KeyN", "Val1Name"=>"Val1-N", "Val2Name"=>"Val2-N", "..."=>"...", "ValMName"=>"ValM-N"}]
scores_hash_array now has a hash for each row in the sheet.
You can try something like this:-
enter code here
fh = File.open("scores.txt","r")
rh={} #result Hash
fh.readlines.each{|line|
kv=line.split(/\s+/)
puts kv.length
rh[kv[0]] = kv[1..kv.length-1].join(",") #***store the values joined by ","
}
puts rh.inspect
fh.close
If you want to get an array of values,replace the last line in loop by
rh[kv[0]] = kv[1..kv.length-1]

How would I dynamically reassign a variable based on the user's text input?

I have
board_a1 = " [ ] "
board_a2 = " [ ] "
board_a3 = " [ ] "
etc. I prompt the user, and get input:
puts "Choose your square"
user_input = gets.chomp.downcase
If the user types in "a2", I need to reassign board_a2:
board_a2 = " [X] "
How would I match the user input to reassign the proper board square? I thought I could concatenate the pieces like so:
board_assignment = "board_#{user_input}"
Then use
board_assignment = " [X] "
But board_assignment != board_a2. It's a new variable. I need to reassign the proper variable based on the user input right after the user types it in. Is there some special syntax to concatenate strings that can then represent the existing variable? What do you call this situation, and how would I go about getting my dynamic variable set?
You should use a single variable, which contains a hash, mapping the space's name to its current state:
board = {
"a1" => " [ ] ",
"a2" => " [ ] ",
"a3" => " [ ] "
}
The rest becomes pretty self-explanatory. When the user enters "a2", modify the value at board["a2"].

Resources