Sending values to another function golang - function

I made a random room program with 4 rooms. I'm trying to take the attributes in each room and pass them through to other functions. In each room is a person with a name and an age attribute. I'm trying to pass on those attributes to test against if statements to put out an additional response. How do I pass these values on?
//the random maze room game
package main
//All imports can be combined into ()
import ("fmt"
//Import needed for random operation
"math/rand"
//Import requied to call upon current time
"time"
)
type Person struct {
Name string
Age int
}
func main(){
// These two lines are designed to reset the random Seed every time the program is run
// Unless the randomizer is seeded, Golang 1.6 is pseudo-random,
// always defaulting to Seed(1)
s1 := rand.NewSource(time.Now().UnixNano())
r1 := rand.New(s1)
switch r1.Intn(4){
case 0:
westRoom()
case 1:
eastRoom()
case 2:
northRoom()
case 3:
southRoom()
default:
lostRoom()
}
p := Person{}
p.Name = Avatarname
p.Age = Avatarage
avatar(&p)
appearance(&p)
}
func westRoom(){
fmt.Println("You find yourself in a room with three walls, and a door behind you.")
fmt.Println("The opposite wall is a window, overlooking the sea")
Avatarname := "Bill"
Avatarage := 25
return
}
func eastRoom(){
fmt.Println("You find yourself in a room with a door on the walls to your left, right, and behind you")
fmt.Println("on the wall across from you is a painting of a mountain scene")
Avatarname := "Mary"
Avatarage := 33
return
}
func northRoom(){
fmt.Println("You find yourself in a room with a door on the wall behind you")
fmt.Println("You see several statues of people standing around the room")
Avatarname := "Joe"
Avatarage := 58
return
}
func southRoom(){
fmt.Println("You find yourself in a room with a door on the wall in front and behind you")
Avatarname := "Abagail"
Avatarage := 67
return
}
func lostRoom(){
fmt.Println("You are unable to find a room in a maze filled only with rooms")
fmt.Println("It's almost like the programmer didn't know what he was doing")
}
func avatar(p.Name, p.Age){
if p.Name == "Bill" || "Joe" {
fmt.Println("You see a man standing in the middle of the room")
} else {
fmt.Println("You see a woman standing in the middle of the room")
}
}
func appeareance(p.Name, p.Age) {
if p.Age > 50 {
fmt.Println("They look old")
} else {
fmt.Println("They look young")
}
}

One way to do this is to change your room functions to return either a Person struct or the attributes of the Person struct.
Check out the live code here: The Go Playground
For example,
func northRoom() *Person{
fmt.Println("You find yourself in a room with a door on the wall behind you")
fmt.Println("You see several statues of people standing around the room")
return &Person{"Joe", 58}
}
Now the function calls in your switch statement can expect a Person struct being returned.
var p *Person
switch r1.Intn(4){
case 0:
p = westRoom()
case 1:
p = eastRoom()
case 2:
p = northRoom()
case 3:
p = southRoom()
default:
p = lostRoom()
}
avatar(p)
appearance(p)
Note that you will need to change the signature of your avatar() and appearance() functions to accept a *Person parameter.

Why not have your room functions return a Person? Example:
func main() {
// These two lines are designed to reset the random Seed every time the program is run
// Unless the randomizer is seeded, Golang 1.6 is pseudo-random,
// always defaulting to Seed(1)
s1 := rand.NewSource(time.Now().UnixNano())
r1 := rand.New(s1)
var p Person
switch r1.Intn(4) {
case 0:
p = westRoom()
case 1:
p = eastRoom()
case 2:
p = northRoom()
case 3:
p = southRoom()
default:
lostRoom()
}
p.printAvatar()
p.printAppeareance()
}
func westRoom() Person {
fmt.Println("You find yourself in a room with three walls, and a door behind you.")
fmt.Println("The opposite wall is a window, overlooking the sea")
return Person{
Name: "Bill",
Age: 25,
}
}
https://play.golang.org/p/9_PuPsRdXg

Related

Return value in rust function magically changing

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 hours ago.
Improve this question
I'm currently working on implementing MCTS for a game.
I have a method called
make_move
That looks like this:
(modified to be verbose for the sake of stackoverflow)
pub fn make_move(&mut self, index: usize, player: i8) -> MoveResult {
let mut result = MoveResult::Nothing;
// If the game is finished or the spot they're trying to play on is occupied set the result to be an error
// Otherwise make the move and return the result of that move (if someone won or if nothing happened)
if self.winner != 0 || self.board[index] != 0 {
self.display();
println!("Warning! Tried playing illegal move");
result = MoveResult::Error;
} else {
self.board[index] = player;
self.move_history.push(index);
result = self.check_for_win();
}
result
}
It uses this enumerator to return the result of a move
pub enum MoveResult {
// Completed meaning the move made the game over (either by win or draw)
Completed(i8),
Error,
Nothing
}
Originally, I just had a guard clause that returned an error for the first if statement, and then returned self.check_for_win() otherwise (which is always either Nothing or Completed). I've since modified it heavily in a desperate attempt to fix this bug.
The bug I'm referring to is when I use the method
let move_result = board.make_move(index, player);
move_result is always equal to either Nothing or Completed. It is never equal to Error.
In the terminal, it will even print out that there was an error, which means the if statement was true and the else shouldn't run, but it will still only return either Nothing or Completed.
I tried to check inside the method. If there was an error, the line before I return, I printed the value of result. And it printed it was equal to Error. But when I use the method and assign the return value to a variable, which I have confirmed through println's is of type Error, the variable is either Nothing or Completed!! It magically changes despite being equal to Error at every point in the process.
I have tried rewriting this method so many times in so many ways. It never works. I've been bashing my head into my keyboard all day and it simply will not cooperate. If anyone has any idea, I'd appreciate the help.
I cannot reproduce your error:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=cc3fc00a4cc4c486fd4d76b51f8f616d
#[derive(Debug, PartialEq)]
pub enum MoveResult {
// Completed meaning the move made the game over (either by win or draw)
Completed(i8),
Error,
Nothing
}
struct Game {
winner: i8,
board: Vec<i8>,
move_history: Vec<usize>
}
impl Game {
fn new(board_size: usize) -> Self {
Game{winner: 0, board: vec![0; board_size], move_history: Vec::new()}
}
fn check_for_win(&self) -> MoveResult {
MoveResult::Nothing // dummy because I don't know the win condition
}
fn display(&self) {
// pass
}
fn make_move(&mut self, index: usize, player: i8) -> MoveResult {
let mut result = MoveResult::Nothing;
// If the game is finished or the spot they're trying to play on is occupied set the result to be an error
// Otherwise make the move and return the result of that move (if someone won or if nothing happened)
if self.winner != 0 || self.board[index] != 0 {
self.display();
println!("Warning! Tried playing illegal move");
result = MoveResult::Error;
} else {
self.board[index] = player;
self.move_history.push(index);
result = self.check_for_win();
}
result
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn make_move_returns_error_when_winner_is_not_zero() {
let mut game = Game::new(10);
game.winner = 42;
let res = game.make_move(1, 2);
assert_eq!(res, MoveResult::Error);
}
#[test]
fn make_move_returns_error_when_playing_same_position_twice() {
let mut game = Game::new(10);
let res1 = game.make_move(1, 42);
assert_eq!(res1, MoveResult::Nothing);
let res2 = game.make_move(1, 55);
assert_eq!(res2, MoveResult::Error);
}
}
Of course all sorts of weird stuff might happen in your check_for_win method, but that method shouldn't even get executed if we're in the error-branch.

How to increase JSON perameter COUNT value for pagination in swift

from backend count start form 0. and 0,1,2,3...... . For each count 10 product is showing
I have taken initially count = 0 like below
var currentCount: Int = 0
and added count perameter in JSON like below in service call: but here always shows only 10 products in collectionview... even if there are more products then also not showing.. why?
fileprivate func serviceCall(){
self.currentCount+=0
let param = ["jsonrpc": "2.0",
"params": ["type" : type, "count": currentCount]] as [String : Any]
APIReqeustManager.sharedInstance.serviceCall(param: param, vc: self, url: getUrl(of: .productByFeature), header: header) {(responseData) in
if self.currentCount > 0 {
self.viewmoreDB?.result?.products! += ViewMoreBase(dictionary: responseData.dict as NSDictionary? ?? NSDictionary())?.result?.products ?? [ViewMoreProducts]()
}
else{
self.viewmoreDB = ViewMoreBase(dictionary: responseData.dict as NSDictionary? ?? NSDictionary())
}
self.productsData = self.viewmoreDB?.result?.products
self.collectionView.reloadData()
}
}
and trying to use pagination like below at the end of the collectionview activity indicator is showing but if there are more products then also not loading
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView == collectionView{
if (scrollView.contentOffset.y + scrollView.frame.size.height) == scrollView.contentSize.height {
serviceCall()
}
}
}
please do help
It could be any of may issues. One of the possible things is that you do not update currentCount when you get the data and your statement if self.currentCount > 0 always fails and the else part executes which means that data is not added but overwritten and you again have just one page of data.
If this is true you are probably missing currentCount = self.productsData.count or even better, you should simply make your currentCount as a computed property doing
var currentCount: Int { productsData?.count ?? 0 }
Since this is a guess a more appropriate answer is that you need to improve your skills when debugging. One of the widely used feature which is available in most modern IDEs is using breakpoints. In most IDEs you simply click left of the line you wish to put your breakpoint and an icon shows there. When your code executes with debugger it will stop at a breakpoint and you will be able to see all the information that is currently in the stack and you will be able to execute line by line to see what is going on. So in your case you could place a breakpoint at a first line after serviceCall and see which path the code takes you and why.
If using Xcode there is another feature that you can use WHILE stopped on breakpoint. You can use console on your bottom right of your IDE to print out values as chunks of code. So while stopped there you could enter "po self.currentCount" and you could see the count. More interesting would be to see things like "ViewMoreBase(dictionary: responseData.dict as NSDictionary? ?? NSDictionary())?.result?.products" to check if you get any products from the backend.

How can I match text that precedes an `<a>` tag then return the `<a>` node?

I have the following, where I am trying to only capture the second case, where the text matches But I want this one here. Currently, it captures both cases.
package main
import (
"bytes"
"fmt"
"io"
"strings"
"golang.org/x/net/html"
)
func getTag(doc *html.Node, tag string) []*html.Node {
var nodes []*html.Node
var crawler func(*html.Node)
crawler = func(node *html.Node) {
if node.Type == html.ElementNode && node.Data == tag {
nodes = append(nodes, node)
return
}
for child := node.FirstChild; child != nil; child = child.NextSibling {
crawler(child)
}
}
crawler(doc)
return nodes
}
func main() {
doc, _ := html.Parse(strings.NewReader(testHTML))
nodes := getTag(doc, "a")
var buf bytes.Buffer
w := io.Writer(&buf)
for i, node := range nodes {
html.Render(w, node)
if i < (len(nodes) - 1) {
w.Write([]byte("\n"))
}
}
fmt.Println(buf.String())
}
var testHTML = `<html><body>
I do not want this link here link text
But I want this one here more link text
</body></html>`
This outputs:
link text
more link text
I would like to match specific text that precedes an <a> tag and, if it matches, return the <a> node. For instance, pass in But I want this one here and it returns more link text. I've been told to not parse html with regex but now I am stuck.
You're actually pretty close, because you are already using a proper parser (html.Parse from golang.org/x/net/html).
The trick here is that the various elements of the page are bound together conveniently, so you can use your existing crawler code with a later filtering function, if you like. (You could instead combine the filtering directly into the crawler.)
Each n *html.ElementNode is preceded by something unless it's the initial element in a block (first of a document or first child node), and that something is in n.PrevSibling. If its type is html.TextNode you have a sequence of the form:
some text<a ...>thing</a>
and you can examine the "some text" in the previous node:
func wanted(re *regexp.Regexp, n *html.Node) bool {
if n.PrevSibling == nil || n.PrevSibling.Type != html.TextNode {
return false
}
return re.MatchString(n.PrevSibling.Data)
}
This won't be perfect, because you could have, e.g.:
text <font></font> broken <font></font>uplast link
and the code will try to match against the string up, when you probably should put the text together into text broken up and pass that to the matcher. See more complete example here.

Go trying to imporve insert speed with MySQL

Hi I need to upload enormous amount of small text info into the MySQL.
Unfortunately there no BulkOp with MySQL, what I am trying to use go-routines to parallelize transactions.
The problem that all this concurrency and racing stuff drives me a bit crazy.
And I am not sure if to what I come is any good.
A simplified code looks like this, the huge file is scanned line by line, and lines appends to an slice, when size of slice is 1000
sem := make(chan int, 10) //Transactions pool
sem2 := make(chan int) // auxiliary blocking semaphore
for scanner.Scan() {
line := scanner.Text()
lines = append(lines, line)
if len(lines) > 1000 {
sem <- 1 //keep max 10 transactions
go func(mylines ...lineT) {
// I use variadic, to avoid issue with pointers
// I want to path data by values.
<-sem2 // all lines of slice copied, release the lock
gopher(mylines...) //gopher does the transaction by iterating
//every each line. And here I may use slice
//I think.
<-sem //after transaction done, release the lock
}(lines...)
sem2 <- 1 //this to ensure, that slice will be reset,
//after values are copied to func, otherwise
//lines could be nil before the goroutine fired.
lines = nil //reset slice
}
}
How can I better solve thing.
I know I could have make something to bulk import via MySQL utilities, but this is not possible. I neither can make it like INSERT with many values VALUES ("1", "2), ("3", "4") because it's not properly escaping, and I just get errors.
This way looks a ta wierd, but not as my 1st approach
func gopher2(lines []lineT) {
q := "INSERT INTO main_data(text) VALUES "
var aur []string
var inter []interface{}
for _, l := range lines {
aur = append(aur, "(?)")
inter = append(inter, l)
}
q = q + strings.Join(aur, ", ")
if _, err := db.Exec(q, inter...); err != nil {
log.Println(err)
}
}

Arma 3 - addAction with dynamic variables to specific Object

Playing around with custom composition spawning in Arma 3. I am currently using "LARs Composition Spawn Script" (https://forums.bistudio.com/forums/topic/191902-eden-composition-spawning/) to spawn a custom compostion. Spawning compositions around the map works like a charm.
In the composition there is one object (AI) whith varname "quest_giver". To this specific Object I want to add an Action. My current code is:
// SPAWN RANDOM COMPOSITION ON RANDOM POSITION
_spawned_composition = [ _random_composition, _pos, [0,0,0], random 360 ] call LARS_fnc_spawnComp;
// GET OBJECTS FROM THE SPAWNED COMP BACK (ARRAY)
_objects = [_spawned_composition] call LARs_fnc_getCompObjects;
// TRYING TO ITERATE THROUGH OBJECTS TO FIND "quest_giver"
// AND ADD ACTION TO IT.
{
_type = typeName _x;
if (_type == "GROUP") then {
_units = units _x;
{
_var = missionNamespace getVariable ["name", _x];
_name = typeOf _var;
if (_name == "quest_giver") then {
player globalChat format["%1",_name];
//_speak = _x addAction ["Speak", {hint format ["Hello, it works !"]}];
};
} forEach _units;
};
} forEach _objects;
Error at If(_name == "quest_giver") where _name is an OBJECT but "quest_giver" of course a STRING. So I get Error Generic error in expression.
However, _var = missionNamespace getVariable ["name",_x]; returns "quest_giver". But it as an OBJECT, since typeOf _var returns "OBJECT" not STRING.
I just can't figure out the most simpliest thing here I guess. Any idea, if this would even work in theory ?
What I am trying to achieve
Create various custom compositions, where on Object in it is always the "quest_giver". Works so far.
Choose random comp and spawn it on random position in the world. Works so far.
Add action to the quest giver so player can speak to him. Text Pop up with simple text, content would be a random quest ala bring me 5 x Water Bottles.
I know my way around before and after the add action part but can't figure out how to add action to this specific object. ...
unless I'm mistaken, you seem to be confused about how to get the unit's name?
it might be you want to get a name var from the unit's namespace (if the thing you're using does put it there):
_name = _x getVariable ["name" /*var name*/, "" /*default value*/];
if (_name == "quest_giver") then {
//...
or more likely (if it's about the name set via editor) with the name function:
if ((name _x) == "quest_giver") then {