Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LAB 02 #4

Open
sunaynagoel opened this issue Jan 27, 2020 · 55 comments
Open

LAB 02 #4

sunaynagoel opened this issue Jan 27, 2020 · 55 comments
Labels

Comments

@sunaynagoel
Copy link

sunaynagoel commented Jan 27, 2020

After testing the simulation for LAB 01 with my codes and provided codes, I was able to set up codes for new game (LAB-02 #1). But when I got to test the game function I get error
"longer object length is not a multiple of shorter object length" and that error further creates problem in binding the table. I think it has to do with vector dimension and after trying to troubleshoot with help of google, I am here for help. The problem is with "a.pick". Here are the codes and error.

this.game <- create_game()
my.initial.pick <- select_door()
opened.doors <- open_doors( this.game, my.initial.pick )

my.final.pick.stay <- change_door( stay=T, opened.doors=opened.doors, a.pick=my.initial.pick )
my.final.pick.switch <- change_door( stay=F, opened.doors=opened.doors, a.pick=my.initial.pick )

game.outcome.stay <- determine_winner( final.pick=my.final.pick.stay, game=this.game )
game.outcome.switch <- determine_winner( final.pick=my.final.pick.switch, game=this.game )

Error
longer object length is not a multiple of shorter object length

@lecy
Copy link
Contributor

lecy commented Jan 27, 2020

@sunaynagoel Thank you for that catch. Here is the error in my code. If the first selection was a car door in the open_door() function I had:

   if( game[ a.pick ] == "car" )
   { 
     opened.car.door <- doors[ game == "car" & game != a.pick ]
     ...
     opened.doors <- c( opened.car.door, opened.goat.door )
   }

Since we have two cars, if the contestant selects a car we only have one option left to return. It has to be a car, and cannot be the current selection.

I mis-matched variable types here though:

game != a.pick    # should be doors != a.pick !!!

Make that change to your code and it should work. I'll update the solutions.

@lecy
Copy link
Contributor

lecy commented Jan 27, 2020

To be clear, update the open_door() function to:

open_doors <- function( game, a.pick )
{
   # reveal one car and one goat
   
   doors <- build_doors()
   
   if( game[ a.pick ] == "car" )
   { 
     opened.car.door <- doors[ game == "car" & doors != a.pick ]
     goat.doors <- doors[ game != "car" ] 
     opened.goat.door <- sample( goat.doors, size=1 )
     opened.doors <- c( opened.car.door, opened.goat.door )
   }
   
   if( game[ a.pick ] == "goat" )
   { 
     opened.car.door <- sample( doors[game=="car"], size=1 )
     available.goat.doors <- doors[ game != "car" & doors != a.pick ] 
     opened.goat.door <- sample( available.goat.doors, size=1 )
     opened.doors <- c( opened.car.door, opened.goat.door )
   }
   return( opened.doors ) # two numbers
}

@sunaynagoel
Copy link
Author

@lecy Thank you for the update. Even after updating the code at my end it keeps giving the same error.

@castower
Copy link

@lecy I'm curious if ImageMagick is required for our Lab 02. I noticed that it was mentioned in the lab notes, but I tried all day yesterday to get it installed and this morning and I keep running into errors. Should I abandon trying to install it and focus on the lab? Thanks! -Courtney

@sunaynagoel
Copy link
Author

@lecy After changing the way we collected data for available.door my error went away. I changed the provided code

{
   doors <- build_doors()
   
   if( stay )
   {
     final.pick <- a.pick
   }
   if( ! stay )
   {
     available.doors <- doors[ doors != opened.doors & doors != a.pick ]
     final.pick  <- sample( available.doors, size=1 ) 
   }
  
   return( final.pick )  
}

to

{
   doors <- build_doors()
   
   if( stay )
   {
     final.pick <- a.pick
   }
   if( ! stay )
   {
     keep.these.doors <- c(-opened.doors, -a.pick)
     available.doors <- doors [keep.these.doors ]
     final.pick  <- sample( available.doors, size=1 ) 
   }
  
   return( final.pick )  
}

For some reason the initial code was generating mismatched size of vectors. It was producing probability table but rbind had issues because of mismatched size.

@castower
Copy link

@lecy I'm curious if ImageMagick is required for our Lab 02. I noticed that it was mentioned in the lab notes, but I tried all day yesterday to get it installed and this morning and I keep running into errors. Should I abandon trying to install it and focus on the lab? Thanks! -Courtney

@lecy Nevermind, finally got it working!

@lecy
Copy link
Contributor

lecy commented Jan 28, 2020

@castower It is not required for LAB 02 - the solutions from the simulations will be mostly analytical:

results.df <- NULL   # collector

for( i in 1:10000 )  # iterator
{
  game.outcome <- play_game()
  # binding step
  results.df <- rbind( results.df, game.outcome )
}

table( results.df ) %>% 
  prop.table( margin=1 ) %>% 
  round( 2 ) 

##         outcome
## strategy LOSE  WIN
##   stay   0.66 0.34
##   switch 0.34 0.66

Q1: Is SWITCH still the dominant strategy? Report your chances of winning for each strategy for each scenario.

I am looking for you to report on changes to the probability of winning given each strategy as the game changes.

You are welcome to create an animation of the game, though !!!

@sunaynagoel
Copy link
Author

Does this outcome look right for the 5 doors game (3 goats and 2 cars)?
outcome
strategy LOSE WIN
stay 0.59 0.41
switch 0.60 0.40

@lecy
Copy link
Contributor

lecy commented Jan 28, 2020

With stay, you have a 2 in 5 shot of guessing correctly first time. So 40% is correct.

With switch, it would be:

prob guess car first * prob guess car second + 
prob guess goat first * prob guess car second
(0.4)(0) + (0.6)(0.5) = 30%

So that looks wrong to me.

@sunaynagoel
Copy link
Author

sunaynagoel commented Jan 28, 2020

With stay, you have a 2 in 5 shot of guessing correctly first time. So 40% is correct.

With switch, it would be:

prob guess car first * prob guess car second + 
prob guess goat first * prob guess car second
(0.4)(0) + (0.6)(0.5) = 30%

So that looks wrong to me.

@ lecy, I thought so as well that they look off. In fact probability table for all my games (with five doors and all three with ten doors) is making the same mistake. Probability for "Stay" is right but "Switch" is wrong. I have checked codes. Not sure what can I be missing. Also curious to see if anyone else encountered the same issue.

@castower
Copy link

@lecy I've run into a rather odd problem with my code where my outcome.stay does not work, but my outcome.switch runs fine. The codes for both are identical. The only think I'm noticing different is that the little eraser-like symbol next to the code for outcome.switch is pink while the one for outcome.stay is orange:

Screen Shot 2020-01-28 at 2 34 24 PM

is there a reason for this difference?

@castower
Copy link

castower commented Jan 28, 2020

@lecy I've run into a rather odd problem with my code where my outcome.stay does not work, but my outcome.switch runs fine. The codes for both are identical. The only think I'm noticing different is that the little eraser-like symbol next to the code for outcome.switch is pink while the one for outcome.stay is orange:

Screen Shot 2020-01-28 at 2 34 24 PM

is there a reason for this difference?

I found this link that indicates that orange is for context while the pink is for vectors.

It seems that my code doesn't like to have two different determine_winner that do different things, so I've made a determine_winner1 and determine_winner2 and now the code works

EDIT: Here's the link: https://support.rstudio.com/hc/en-us/articles/205273297-Code-Completion

@castower
Copy link

castower commented Jan 28, 2020

Okay, I'm a bit confused on what I'm doing wrong to produce the table. I get a long list of results, but for some reason, every time 'stay' wins and switch 'loses':

outcome
strategy LOSE WIN
  stay      0   1
  switch    1   0

I'm not sure why this is occurring? My results total is 20,000 observations of the 2 variables.

@sunaynagoel
Copy link
Author

sunaynagoel commented Jan 28, 2020

This is my data table and probability table for 5 doors ( 3 goats, 2 cars)
outcome

strategy LOSE  WIN
  stay   6046 3954
  switch 6148 3852
        outcome
strategy LOSE  WIN
  stay   0.60 0.40
  switch 0.61 0.39

Row wise total for strategies are adding upto 10,000 but column wise total are not adding up to 10,000. It is the similar problem for other three games with 10 doors.

@castower
Copy link

I've noticed when I run play_game() on its own, the results never change and I'm not sure why this is happening. It changes if I run the entire .rmd file, but not within the function. Is there a step that I'm overlooking that makes the function change on its own?

@lecy
Copy link
Contributor

lecy commented Jan 29, 2020

@sunaynagoel OK I found the issue. Dumb mistake on my part! And a nice review of logical statements.

To find one door from a set you can write: doors == 5

You cannot, however, compare two vectors: doors == c(2,5)

The correct syntax is: doors %in% c(2,5)

So the switch case was broken in change_door():

change_door <- function( stay=T, opened.doors, a.pick )
{
   doors <- build_doors()
   
   if( stay )
   {
     final.pick <- a.pick
   }
   if( ! stay )
   {
    # OLD LINE - THIS IS INCORRECT  
    # available.doors <- doors[ doors != opened.doors & doors != a.pick ]
    # THIS IS CORRECT
     available.doors <- doors[ ! ( doors %in% opened.doors | doors == a.pick ) ]
     final.pick  <- sample( available.doors, size=1 )
   }
 
   return( final.pick )  # number between 1 and 5
}

Once I changed that I got the right solutions as well.

@lecy
Copy link
Contributor

lecy commented Jan 29, 2020

This is my data table and probability table for 5 doors ( 3 goats, 2 cars)
outcome

strategy LOSE  WIN
  stay   6046 3954
  switch 6148 3852
        outcome
strategy LOSE  WIN
  stay   0.60 0.40
  switch 0.61 0.39

Row wise total for strategies are adding upto 10,000 but column wise total are not adding up to 10,000. It is the similar problem for other three games with 10 doors.

You play the game 10,000 times, but each time you record outcomes for two strategies. So there are 20,000 outcomes total in the table.

The row sums are meaningful (each game of 10,000 is split between wins and losses). The column sums are not meaningful.

@lecy
Copy link
Contributor

lecy commented Jan 29, 2020

@castower That is odd. Can you send me your RMD file by email?

@castower
Copy link

@castower That is odd. Can you send me your RMD file by email?

Yes, I just sent it. Thank you! @lecy

@sunaynagoel
Copy link
Author

sunaynagoel commented Jan 29, 2020

@sunaynagoel OK I found the issue. Dumb mistake on my part! And a nice review of logical statements.

To find one door from a set you can write: doors == 5

You cannot, however, compare two vectors: doors == c(2,5)

The correct syntax is: doors %in% c(2,5)

So the switch case was broken in change_door():

change_door <- function( stay=T, opened.doors, a.pick )
{
   doors <- build_doors()
   
   if( stay )
   {
     final.pick <- a.pick
   }
   if( ! stay )
   {
    # OLD LINE - THIS IS INCORRECT  
    # available.doors <- doors[ doors != opened.doors & doors != a.pick ]
    # THIS IS CORRECT
     available.doors <- doors[ ! ( doors %in% opened.doors | doors == a.pick ) ]
     final.pick  <- sample( available.doors, size=1 )
   }
 
   return( final.pick )  # number between 1 and 5
}

Once I changed that I got the right solutions as well.

@lecy. I get the same result even after I change the code. Is this right ?

outcome

strategy LOSE WIN
stay 6006 3994
switch 5990 4010
outcome
strategy LOSE WIN
stay 0.6 0.4
switch 0.6 0.4

my initial code was

{
   doors <- build_doors(  )
   
   if( stay )
   {
     final.pick <- a.pick
   }
   if( ! stay )
   {
    keep.these.doors<- c(-opened.doors, -a.pick)
      available.doors <- doors [keep.these.doors ]
    final.pick  <- sample( available.doors, size=1 ) 
   }
   return( final.pick ) 

@lecy
Copy link
Contributor

lecy commented Jan 29, 2020

I have seen a problem a couple of times now regarding the order of arguments and values in functions. This is subtle, but really important. When we define function, we do so as follows (using an example with one argument with default provided and another without):

f.name <- function( arg.a, arg.b = value.b )
{
   # only use arg.a and arg.b here
   # never reference as value.a or value.b 
}

# calling function:
f.name( arg.a=value.a, arg.b=value.b )

# we are assigning values to arguments
f.name( arg.a <- value.a, arg.b <- value.b )

You need to be very careful to (1) only use the argument name ("arg.a") inside of functions, never reference the value with the temp name "value.a".

door1 <- select_door()
open_goat_door( a.pick=door1, ... )

The argument a.pick here stores the value so it can be referenced inside of the function. You never want to use door1 inside the function because the next user might call it something different.

open_goat_door <- function( a.pick )
{
    doors <- 1:3
    available.doors <- doors [ - door1 ]  # not using arg name! 
    # available.doors <- doors [ - a.pick ]  # should be this
    final.pick  <- sample( available.doors, size=1 ) 
    return( final.pick )
}

# this won't work now because we don't know what door1 means
initial.pick <- select_door()
open_goat_door( a.pick=initial.pick, ... )

@lecy
Copy link
Contributor

lecy commented Jan 29, 2020

@sunaynagoel Your alternative solution looks fine for the change_door() function:

# MY SOLUTION 
   if( ! stay )
   {
     available.doors <- doors[ ! ( doors %in% opened.doors | doors == a.pick ) ]
     final.pick  <- sample( available.doors, size=1 )
   }

# YOUR SOLUTION
   if( ! stay )
   {
    keep.these.doors<- c(-opened.doors, -a.pick)
      available.doors <- doors [keep.these.doors ]
    final.pick  <- sample( available.doors, size=1 ) 
   }

# CHECKS OUT
> doors <- 1:5
> a.pick <- 2
> opened.doors <- c(1,3) 
> 
> drop.these.doors <- c( -opened.doors, -a.pick )
> drop.these.doors
[1] -1 -3 -2
> doors[ drop.these.doors ]  # available doors
[1] 4 5
> 
> drop.these.doors <- c( opened.doors, a.pick )
> drop.these.doors
[1] 1 3 2
> doors[ - drop.these.doors ]  # available doors
[1] 4 5

So it must be something else in your code. I am using the solution game steps 1-5 that I gave you for the 3 goats and 2 cars game. Here is what I get:

play_game <- function( )
{
  new.game <- create_game()
  first.pick <- select_door()
  opened.door <- open_doors( new.game, first.pick )

  final.pick.stay <- change_door( stay=T, opened.door, first.pick )
  final.pick.switch <- change_door( stay=F, opened.door, first.pick )

  outcome.stay <- determine_winner( final.pick.stay, new.game  )
  outcome.switch <- determine_winner( final.pick.switch, new.game )
  
  strategy <- c("stay","switch")
  outcome <- c(outcome.stay,outcome.switch)
  game.results <- data.frame( strategy, outcome,
                              stringsAsFactors=F )
  return( game.results )
}

play_game()



results.df <- NULL   # collector

for( i in 1:10000 )  # iterator
{
  game.outcome <- play_game()
  # binding step
  results.df <- rbind( results.df, game.outcome )
}

# library( dplyr )
> table( results.df ) %>% 
+   prop.table( margin=1 ) %>%  # row proportions
+   round( 2 )
        outcome
strategy LOSE  WIN
  stay   0.60 0.40
  switch 0.70 0.30

@sunaynagoel
Copy link
Author

@sunaynagoel Your alternative solution looks fine for the change_door() function:

# MY SOLUTION 
   if( ! stay )
   {
     available.doors <- doors[ ! ( doors %in% opened.doors | doors == a.pick ) ]
     final.pick  <- sample( available.doors, size=1 )
   }

# YOUR SOLUTION
   if( ! stay )
   {
    keep.these.doors<- c(-opened.doors, -a.pick)
      available.doors <- doors [keep.these.doors ]
    final.pick  <- sample( available.doors, size=1 ) 
   }

# CHECKS OUT
> doors <- 1:5
> a.pick <- 2
> opened.doors <- c(1,3) 
> 
> drop.these.doors <- c( -opened.doors, -a.pick )
> drop.these.doors
[1] -1 -3 -2
> doors[ drop.these.doors ]  # available doors
[1] 4 5
> 
> drop.these.doors <- c( opened.doors, a.pick )
> drop.these.doors
[1] 1 3 2
> doors[ - drop.these.doors ]  # available doors
[1] 4 5

So it must be something else in your code. I am using the solution game steps 1-5 that I gave you for the 3 goats and 2 cars game. Here is what I get:

play_game <- function( )
{
  new.game <- create_game()
  first.pick <- select_door()
  opened.door <- open_doors( new.game, first.pick )

  final.pick.stay <- change_door( stay=T, opened.door, first.pick )
  final.pick.switch <- change_door( stay=F, opened.door, first.pick )

  outcome.stay <- determine_winner( final.pick.stay, new.game  )
  outcome.switch <- determine_winner( final.pick.switch, new.game )
  
  strategy <- c("stay","switch")
  outcome <- c(outcome.stay,outcome.switch)
  game.results <- data.frame( strategy, outcome,
                              stringsAsFactors=F )
  return( game.results )
}

play_game()



results.df <- NULL   # collector

for( i in 1:10000 )  # iterator
{
  game.outcome <- play_game()
  # binding step
  results.df <- rbind( results.df, game.outcome )
}

# library( dplyr )
> table( results.df ) %>% 
+   prop.table( margin=1 ) %>%  # row proportions
+   round( 2 )
        outcome
strategy LOSE  WIN
  stay   0.60 0.40
  switch 0.70 0.30

Thank you. I figure out. At one point I was using "door" instead of "doors" so it was picking up variable from my earlier code of LAB 01. Thank you.

@castower
Copy link

I have seen a problem a couple of times now regarding the order of arguments and values in functions. This is subtle, but really important. When we define function, we do so as follows (using an example with one argument with default provided and another without):

f.name <- function( arg.a, arg.b = value.b )
{
   # only use arg.a and arg.b here
   # never reference as value.a or value.b 
}

# calling function:
f.name( arg.a=value.a, arg.b=value.b )

# we are assigning values to arguments
f.name( arg.a <- value.a, arg.b <- value.b )

You need to be very careful to (1) only use the argument name ("arg.a") inside of functions, never reference the value with the temp name "value.a".

door1 <- select_door()
open_goat_door( a.pick=door1, ... )

The argument a.pick here stores the value so it can be referenced inside of the function. You never want to use door1 inside the function because the next user might call it something different.

open_goat_door <- function( a.pick )
{
    doors <- 1:3
    available.doors <- doors [ - door1 ]  # not using arg name! 
    # available.doors <- doors [ - a.pick ]  # should be this
    final.pick  <- sample( available.doors, size=1 ) 
    return( final.pick )
}

# this won't work now because we don't know what door1 means
initial.pick <- select_door()
open_goat_door( a.pick=initial.pick, ... )

Thanks so much! This helped me understand! @castower

@jmacost5
Copy link

I am trying to solve question number 2 and I am wondering what I am doing wrong. I thought that if i used the below code that it would get me the correct proportion but I am getting an error.


results.df <- NULL   # collector

for( i in 1:10000 )  # iterator
{
  game.outcome <- play_game()
  # binding step
  results.df <- rbind( results.df, game.outcome )
}

table( results.df ) 

@lecy
Copy link
Contributor

lecy commented Jan 29, 2020

@jmacost5 That loop looks fine, so it has to be a problem with the game code.

This is the 10 doors game? What is your game set-up function?

@jmacost5
Copy link

jmacost5 commented Jan 30, 2020

@jmacost5 That loop looks fine, so it has to be a problem with the game code.

This is the 10 doors game? What is your game set-up function?
Yes, This is the ten door function game, 7 goats 3 cars, I wanted to understand what is wrong with the play_game code I am using

play_game <- function( )
{
  new.game <- create_game()
  first.pick <- select_door()
  opened.door <- open_doors( new.game, first.pick )

  final.pick.stay <- change_door( stay=T, opened.door, first.pick )
  final.pick.switch <- change_door( stay=F, opened.door, first.pick )

  outcome.stay <- determine_winner( final.pick.stay, new.game  )
  outcome.switch <- determine_winner( final.pick.switch, new.game )
  
  strategy <- c("stay","switch")
  outcome <- c(outcome.stay,outcome.switch)
  game.results <- data.frame( strategy, outcome,
                              stringsAsFactors=F )
  return( game.results )
}

play_game()



results.df <- NULL   # collector

for( i in 1:10000 )  # iterator
{
  game.outcome <- play_game()
  # binding step
  results.df <- rbind( results.df, game.outcome )
}

# library( dplyr )
table( results.df )
prop.table( margin=1 )  # row proportions
round( 2 )

This is the error I get
Error in sample(x = rep(c("goat", "car"), c(num.goats, num.cars)), size = (num.goats + : argument "num.goats" is missing, with no default

@jmacost5
Copy link

@jmacost5 That loop looks fine, so it has to be a problem with the game code.

This is the 10 doors game? What is your game set-up function?
I guess my question is am I missing the num.goat argument in the play_game or in the original code? The original code is working but the other is not.

@lecy
Copy link
Contributor

lecy commented Jan 30, 2020

@jmacost5 That sounds correct. Please check the solutions for the create_game() function specific to the 10 doors game:

build_doors <- function( n ){ return( 1:n ) }

create_game <- function( num.goats, num.cars )  # <- NEW ARGUMENTS
{
    a.game <- sample( x=rep( c("goat","car"), c(num.goats,num.cars) ), 
                      size=(num.goats+num.cars), replace=F )
    return( a.game )
}

And this is the steps of the play_game() function without being wrapped inside of a function:

num.goats <- 7
num.cars <- 3
this.game <- create_game( num.goats, num.cars )
my.initial.pick <- select_door( game=this.game )
opened.door <- open_goat_door( this.game, my.initial.pick )
# save results for both strategies for the game
my.final.pick.stay <- change_door( stay=T, game=this.game, 
                                   opened.door=opened.door, a.pick=my.initial.pick )
my.final.pick.switch <- change_door( stay=F, game=this.game,
                                     opened.door=opened.door, a.pick=my.initial.pick )

game.outcome.stay <- determine_winner( final.pick=my.final.pick.stay, game=this.game )
game.outcome.switch <- determine_winner( final.pick=my.final.pick.switch, game=this.game )

Note that create_game() requires you to specify 2 new parameters - number of goats and number of cars. There are no default values set.

Also note when creating the play_game() function you should not hard-code goat and car numbers into the function:

play_game <- function ()
{
  num.goats <- 7
  num.cars <- 3
  this.game <- create_game( num.goats, num.cars )
  ...
}

Because then you can't test the different scenarios for the assignment. You will want to convert these parameters into new arguments:

play_game <- function ( num.goats=3, num.cars=2 )  # with defaults 
{
  this.game <- create_game( num.goats, num.cars )
  ...
}

Does that make sense?

@jmacost5
Copy link

jmacost5 commented Jan 30, 2020

Does that make sense?

I am thinking you would want me to put this into the play code? as so

 play_game <- function(num.goats=7, num.cars=3)
{
  this.game <- create_game( num.goats, num.cars )
  new.game <- create_game()
  first.pick <- select_door()
  opened.door <- open_goat_door( new.game, first.pick )
  final.pick.stay <- change_door( stay=T, opened.door, first.pick )
  final.pick.switch <- change_door( stay=F, opened.door, first.pick )
  outcome.stay <- determine_winner( final.pick.stay, new.game  )
  outcome.switch <- determine_winner( final.pick.switch, new.game )
  
  # game.results <- bundle the results
  # return( <<< game.results >>> )
  
  strategy <- c("stay","switch")
  outcome <- c(outcome.stay,outcome.switch)
  game.results <- data.frame( strategy, outcome,
                              stringsAsFactors=F )
  return( game.results )
}

play_game()

@lecy
Copy link
Contributor

lecy commented Jan 30, 2020

@jmacost5 Correct. Note that when you include default arguments, you can still override them when calling functions. So in your simulation code you can use:

play_game <- function(num.goats=7, num.cars=3)
{
   ...
}

play_game()  # defaults to 7 goats 3 cars
play_game( num.goats=5, num.cars=5 )  # changing game settings

@jmacost5
Copy link

jmacost5 commented Jan 30, 2020

@jmacost5 Correct. Note that when you include default arguments, you can still override them when calling functions. So in your simulation code you can use:

play_game <- function(num.goats=7, num.cars=3)
{
   ...
}

play_game()  # defaults to 7 goats 3 cars
play_game( num.goats=5, num.cars=5 )  # changing game settings

I am still getting an error, here is the whole code



build_doors <- function( n ){ return( 1:n ) }

create_game <- function( num.goats, num.cars )  # <- NEW ARGUMENTS
{

}

select_door <- function( game )
{

}

build_doors <- function( n ){ return( 1:n ) }

create_game <- function( num.goats, num.cars )
{

}

select_door <- function( game )
{

}

open_goat_door <- function( game, a.pick )
{

}

change_door <- function( stay=T, game, opened.door, a.pick )
{

}

determine_winner <- function( final.pick, game )
{

}
 play_game <- function(num.goats=7, num.cars=3)
{
  this.game <- create_game(num.goats, num.cars )
  new.game <- create_game()
  first.pick <- select_door()
  opened.door <- open_goat_door( new.game, first.pick )
  final.pick.stay <- change_door( stay=T, opened.door, first.pick )
  final.pick.switch <- change_door( stay=F, opened.door, first.pick )
  outcome.stay <- determine_winner( final.pick.stay, new.game  )
  outcome.switch <- determine_winner( final.pick.switch, new.game )
  
  # game.results <- bundle the results
  # return( <<< game.results >>> )
  
  strategy <- c("stay","switch")
  outcome <- c(outcome.stay,outcome.switch)
  game.results <- data.frame( strategy, outcome,
                              stringsAsFactors=F )
  return( game.results )
}

play_game()

results.df <- NULL   # collector

for( i in 1:10000 )  # iterator
{
  game.outcome <- play_game()
  results.df <- rbind( results.df, game.outcome )
}

table( results.df )

Error in sample(x = rep(c("goat", "car"), c(num.goats, num.cars)), size = (num.goats + : argument "num.goats" is missing, with no default

@sunaynagoel
Copy link
Author

@lecy Link for submitting Lab 02 does not seem to be working for me.

@lecy
Copy link
Contributor

lecy commented Jan 31, 2020

@sunaynagoel Should be working now.

@lecy
Copy link
Contributor

lecy commented Jan 31, 2020

@jmacost5 Pay attention to how the functions changed between Part I and Part II.

For Part I the game size was static (always 3 goats and 2 cars), so you can hard-code that parameter into the functions.

For Part II it is no longer static, so some of the functions need explicit information about the current game to work. For example:

# PART I
create_game <- function(  )
# PART II
create_game <- function( num.goats, num.cars )

You need to make sure your play_game() function is passing all of the required variables to arguments properly:

play_game <- function(num.goats=7, num.cars=3)
{
  this.game <- create_game(num.goats, num.cars )
  new.game <- create_game()
  first.pick <- select_door()
  opened.door <- open_goat_door( new.game, first.pick )
  final.pick.stay <- change_door( stay=T, opened.door, first.pick )
  final.pick.switch <- change_door( stay=F, opened.door, first.pick )
  outcome.stay <- determine_winner( final.pick.stay, new.game  )
  outcome.switch <- determine_winner( final.pick.switch, new.game )
  
  # game.results <- bundle the results
  # return( <<< game.results >>> )
  
  strategy <- c("stay","switch")
  outcome <- c(outcome.stay,outcome.switch)
  game.results <- data.frame( strategy, outcome,
                              stringsAsFactors=F )
  return( game.results )
}

ALSO note that you have two build_doors() and two create_games().

@castower
Copy link

Hello all, I'm currently working on the final challenge question. To clarify, do we still need to create a table of the outcomes of 10,000 games too? It seems my metadata now makes multiple tables appear for each version of the game.

@lecy
Copy link
Contributor

lecy commented Jan 31, 2020

@castower That is correct. What do you mean by multiple versions?

@jmacost5
Copy link

@jmacost5 Pay attention to how the functions changed between Part I and Part II.

For Part I the game size was static (always 3 goats and 2 cars), so you can hard-code that parameter into the functions.

For Part II it is no longer static, so some of the functions need explicit information about the current game to work. For example:

# PART I
create_game <- function(  )
# PART II
create_game <- function( num.goats, num.cars )

You need to make sure your play_game() function is passing all of the required variables to arguments properly:

play_game <- function(num.goats=7, num.cars=3)
{
  this.game <- create_game(num.goats, num.cars )
  new.game <- create_game()
  first.pick <- select_door()
  opened.door <- open_goat_door( new.game, first.pick )
  final.pick.stay <- change_door( stay=T, opened.door, first.pick )
  final.pick.switch <- change_door( stay=F, opened.door, first.pick )
  outcome.stay <- determine_winner( final.pick.stay, new.game  )
  outcome.switch <- determine_winner( final.pick.switch, new.game )
  
  # game.results <- bundle the results
  # return( <<< game.results >>> )
  
  strategy <- c("stay","switch")
  outcome <- c(outcome.stay,outcome.switch)
  game.results <- data.frame( strategy, outcome,
                              stringsAsFactors=F )
  return( game.results )
}

ALSO note that you have two build_doors() and two create_games().

I guess I am missing where I defined game in the code I just cannot find out where I missed it.

Error in build_doors(n = length(game)) : argument "game" is missing, with no default

@lecy
Copy link
Contributor

lecy commented Jan 31, 2020

@jmacost5 You are repeating a bunch of functions like create_game(), which might be the problem.

Note the solutions from last week:

select_door <- function( game )
{
  ...
}
play_game <- function(num.goats=7, num.cars=3)
{
  new.game <- create_game( num.goats, num.cars )
  first.pick <- select_door( game=new.game )
 ...
}

@jmacost5
Copy link

jmacost5 commented Jan 31, 2020

@jmacost5 You are repeating a bunch of functions like create_game(), which might be the problem.

Note the solutions from last week:

select_door <- function( game )
{
  ...
}
play_game <- function(num.goats=7, num.cars=3)
{
  new.game <- create_game( num.goats, num.cars )
  first.pick <- select_door( game=new.game )
 ...
}

I tried to get rid of all the repeats. Am I not suppose to be putting the code on top that is above the "play_game <- function(num.goats=7, num.cars=3)"


@lecy
Copy link
Contributor

lecy commented Jan 31, 2020

@jmacost5 These were the repeats in play_game():

play_game <- function(num.goats=7, num.cars=3)
{
  this.game <- create_game(num.goats, num.cars )
  new.game <- create_game()

Your problem is that you are not sending any game to select_door():

first.pick <- select_door( game )  # game not defined anywhere:

It should be:

play_game <- function(num.goats=7, num.cars=3)
{
  new.game <- create_game( num.goats, num.cars )
  first.pick <- select_door( game=new.game )  # using the new game
  ... 

@jmacost5
Copy link

jmacost5 commented Jan 31, 2020

@jmacost5 These were the repeats in play_game():

play_game <- function(num.goats=7, num.cars=3)
{
  this.game <- create_game(num.goats, num.cars )
  new.game <- create_game()

Your problem is that you are not sending any game to select_door():

first.pick <- select_door( game )  # game not defined anywhere:

It should be:

play_game <- function(num.goats=7, num.cars=3)
{
  new.game <- create_game( num.goats, num.cars )
  first.pick <- select_door( game=new.game )  # using the new game
  ... 

I think I got my code to work but I am not sure if I am getting the right answer or understanding the concept that you said previously about " play_game( num.goats=5, num.cars=5 ) # changing game settings"

play_game <- function(num.goats=7, num.cars=3)
{
  this.game <- create_game(num.goats, num.cars )
  new.game <- create_game()
  my.initial.pick <- select_door( game=this.game )
opened.door <- open_goat_door( this.game, my.initial.pick )
# save results for both strategies for the game
my.final.pick.stay <- change_door( stay=T, game=this.game, 
                                   opened.door=opened.door, a.pick=my.initial.pick )
my.final.pick.switch <- change_door( stay=F, game=this.game,
                                     opened.door=opened.door, a.pick=my.initial.pick )

outcome.stay <- determine_winner( final.pick=my.final.pick.stay, game=this.game )
outcome.switch <- determine_winner( final.pick=my.final.pick.switch, game=this.game )
  
  # game.results <- bundle the results
  # return( <<< game.results >>> )
  
  strategy <- c("stay","switch")
  outcome <- c(outcome.stay,outcome.switch)
  game.results <- data.frame( strategy, outcome,
                              stringsAsFactors=F )
  return( game.results )
}
results.df <- NULL   # collector

for( i in 1:10000 )  # iterator
{
  game.outcome <- play_game()
  # binding step
  results.df <- rbind( results.df, game.outcome )
}
table( results.df )

play_game(num.goats=8, num.cars=2)
results.df <- NULL   # collector

for( i in 1:10000 )  # iterator
{
  game.outcome <- play_game()
  # binding step
  results.df <- rbind( results.df, game.outcome )
}
table( results.df )
play_game(num.goats=9, num.cars=1)
results.df <- NULL   # collector

for( i in 1:10000 )  # iterator
{
  game.outcome <- play_game()
  # binding step
  results.df <- rbind( results.df, game.outcome )
}
table( results.df )

These were the answers respectively
outcome
strategy LOSE WIN
stay 6982 3018
switch 6632 3368
outcome
strategy LOSE WIN
stay 7001 2999
switch 6601 3399
outcome
strategy LOSE WIN
stay 7069 2931
switch 6610 3390

@castower
Copy link

@lecy for just one game I get the following output (I'm going to add the other variables later, I'm just including game set up and initial contestant while I problem-solve):

strategy outcome game.set.up initial.contestant  
stay LOSE goat car goat 3  
switch WIN goat car goat 3

However, when I run it through the loop, I get this:

, , game.set.up = car goat goat, initial.contestant = 3

        outcome
strategy LOSE  WIN
  stay   0.11 0.00
  switch 0.00 0.11

, , game.set.up = goat goat car, initial.contestant = 3

        outcome
strategy LOSE  WIN
  stay   0.00 0.11
  switch 0.11 0.00
, , game.set.up = goat car goat, initial.contestant = 3

        outcome
strategy LOSE  WIN
  stay   0.11 0.00
  switch 0.00 0.11

, , game.set.up = car goat goat, initial.contestant = 1

        outcome
strategy LOSE  WIN
  stay   0.00 0.11
  switch 0.11 0.00

, , game.set.up = goat goat car, initial.contestant = 1

        outcome
strategy LOSE  WIN
  stay   0.11 0.00
  switch 0.00 0.11
, , game.set.up = goat car goat, initial.contestant = 1

        outcome
strategy LOSE  WIN
  stay   0.11 0.00
  switch 0.00 0.11

, , game.set.up = car goat goat, initial.contestant = 2

        outcome
strategy LOSE  WIN
  stay   0.12 0.00
  switch 0.00 0.12

, , game.set.up = goat goat car, initial.contestant = 2

        outcome
strategy LOSE  WIN
  stay   0.11 0.00
  switch 0.00 0.11
, , game.set.up = goat car goat, initial.contestant = 2

        outcome
strategy LOSE  WIN
  stay   0.00 0.11
  switch 0.11 0.00

This output of the loop doesn't seem to be telling me anything.

@lecy
Copy link
Contributor

lecy commented Jan 31, 2020

@jmacost5 Those answers are right for th 7,3 case. You just need to add your arguments to the play_game() function inside of the loop, otherwise for the 10,000 trials it is just using the default game set-up.

results.df <- NULL   # collector

for( i in 1:10000 )  # iterator
{
  game.outcome <- play_game()
  # binding step
  results.df <- rbind( results.df, game.outcome )
}
table( results.df )
play_game(num.goats=9, num.cars=1)

@lecy
Copy link
Contributor

lecy commented Jan 31, 2020

@castower send me your file via email?

@castower
Copy link

@lecy I sent it. Thank you!

@meliapetersen
Copy link

Hi, Jaesa and I are coming up with an issue with the data results. All of our code is running through without errors but we are getting STAY as consistently the dominant strategy. Anyone else having the same issue?

@castower
Copy link

@meliapetersen which part of the code? I did get STAY as the superior strategy for one of the outcomes, but all the rest of my results found SWITCH to be superior.

@meliapetersen
Copy link

@castower It is every single one that does it. The original simulation as well as the new simulations for part 2. -- Each time we run it there is a different result as well.

@castower
Copy link

@meliapetersen do you get results for SWITCH too and STAY is just superior? Or do you get 0s? At one point I would get 100% (1) win for SWITCH and 100% (1) lose for STAY and it turned out that the way I'd coded my variables was causing the loop to keep forcing the same value over and over. The code didn't have any errors, but the output was wrong because it was duplicating one game 10,000 times.

@lecy
Copy link
Contributor

lecy commented Jan 31, 2020

@meliapetersen I just re-sent the most up-to-date solutions for functions from Lab-01 via Canvas. I would start there and make sure you are using the current code, then try to wrap them into the play_game() function.

There is a lot of subtlety to the logic in some of the functions where you are using criteria to select doors. You usually need to review the logic of the pseudo-code to make sure your steps are correct. The next part is translating from logic to syntax, which is another way errors can creep in. For example:

x %in% c("a","b")   # correct way to do multiple comparisons at once
x == c("a","b")     # this is incorrect - will only use "a"

Or a very common one with compound statements:

# eliminate case A and case B
! ( x == "case A" | x == "case B" )

In plain English we say, we only want the cases where A and B are both true (intersection, so we use CaseA & CaseB.

We also say, I need to drop all cars AND the current selection before opening a door. But in logical statement terms this is translated to CaseA OR CaseB.

If the functions are working fine, send your play_game() code!

@JaesaR
Copy link

JaesaR commented Jan 31, 2020

@lecy Our functions are working fine, but we still keep getting inconsistent outputs for switch and stay.

Our play_games() code looks like this:


play_game <- function(num.goats=7, num.cars=3)
{
  this.game <- create_game(num.goats, num.cars )
  new.game <- create_game(num.goats, num.cars)
  first.pick <- select_door(game=this.game)
  opened.door <- open_goat_door( new.game, first.pick )
  final.pick.stay <- change_door( stay=T, opened.door=opened.door, a.pick=first.pick )
  final.pick.switch <- change_door( stay=F, opened.door=opened.door, a.pick=first.pick )
  outcome.stay <- determine_winner( final.pick.stay, new.game  )
  outcome.switch <- determine_winner( final.pick.switch, new.game )
  
  # game.results <- bundle the results
  # return( <<< game.results >>> )
  
  strategy <- c("stay","switch")
  outcome <- c(outcome.stay,outcome.switch)
  game.results <- data.frame( strategy, outcome,
                              stringsAsFactors=F )
  return( game.results )
}

play_game()

@lecy
Copy link
Contributor

lecy commented Jan 31, 2020

@JaesaR I can see one problem which I know will cause some errors. Hopefully it is your only one.

You are repeating the create_game( ) function, then using one version of the game for some steps, and another version for other steps. This could lead to conflicts (though I am not sure if yours do here).

Other that that, this step looks good. What's your simulation loop look like?

play_game <- function( num.goats=7, num.cars=3 )
{
  # this.game <- create_game(num.goats, num.cars )   
  new.game <- create_game( num.goats, num.cars )
  # first.pick <- select_door(game=this.game) # changed this.game to new.game
  first.pick <- select_door( game=new.game )
  opened.door <- open_goat_door( new.game, first.pick )
  final.pick.stay <- change_door( stay=T, opened.door=opened.door, a.pick=first.pick )
  final.pick.switch <- change_door( stay=F, opened.door=opened.door, a.pick=first.pick )
  outcome.stay <- determine_winner( final.pick.stay, new.game  )
  outcome.switch <- determine_winner( final.pick.switch, new.game )
 
  strategy <- c( "stay","switch" )
  outcome <- c( outcome.stay,outcome.switch )
  game.results <- data.frame( strategy, outcome,
                              stringsAsFactors=F )
  return( game.results )
}

play_game()

@JaesaR
Copy link

JaesaR commented Jan 31, 2020

@lecy Great, thanks! That helped.
Also, are the challenge questions a required part of the assignment or just suggested?

@lecy
Copy link
Contributor

lecy commented Jan 31, 2020

@JaesaR They are opportunities, but not required.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants