text:
module GameNight

export word_search, play_roll_and_write, play_tutti_frutti, play_safehouses, play_safehouses_duos, play_draw_again

using Gtk, CSV, RCall, GLMakie, AbstractPlotting, Colors, JSON, Random
# R instance requires ggplot2, and gmailr

# Read Gmail token and send to R environment
function read_secret(secret_location)
  secret_json = JSON.parse(read(secret_location, String))
  secret_val = secret_json["installed"]["client_secret"]
  key_val = secret_json["installed"]["client_id"]
  @rput secret_val key_val
end

R"""
if(!require(ggplot2)) {
    install.packages("ggplot2")
    require(ggplot2)
    }

if(!require(gmailr)) {
    install.packages("gmailr")
    require(gmailr)
    }

send_key_card <- function(giver1 = NULL, giver2 = NULL, sender = "safehouses@gmail.com", key = key_val, secret = secret_val) {

  if (is.null(giver1) || is.null(giver2)) {warning("Two clue givers must be designated!")}

  # Determine whether team 1 (blue) or team 2 (red) goes first
  first <- sample(1:2, 1)

  # Create coordinates for key grid and colors for each space
  KEY_LAYOUT <<- expand.grid(1:5, LETTERS[1:5])
  KEY_LAYOUT$content <<- sample(c(
    rep(1, 8),
    rep(2, 8),
    rep(3, 7),
    0,
    first),
  size = 25,
  replace = FALSE)

  # Create key card to send out, with spaces colored according to value
  key_card <- ggplot(KEY_LAYOUT, aes(x = 0, y = 0, label = c("X", "B", "R", "Y")[content + 1], fill = as.factor(content), size = 12)) +
      geom_tile(alpha = .5) +
      geom_text(aes(colour = as.factor(content)), size = 12, alpha = .75) +
      facet_grid(Var2~Var1, switch = "y") +
      scale_fill_manual(values = c("black", "blue", "red", "yellow")) + theme_bw() +
      scale_colour_manual(values = c("black", "blue", "red", "black")) + theme_bw() +
      theme(legend.position = "none",
  	   axis.text = element_blank(),
  		axis.ticks.length = unit(0, "in"),
  		axis.title = element_blank(),
  		strip.background = element_rect(
  		  colour = c(rgb(0, 0, 1, .5), rgb(1, 0, 0, .5))[first],
  		  size = 2,
  		  fill = "transparent"),
  		panel.border = element_blank(),
  		panel.spacing = unit(.05, "cm"),
  		panel.grid = element_blank(),
  		strip.text = element_text(size = 16),
  		strip.text.y = element_text(angle = 180))

  # Save card image to disk
  ggsave("key card.jpg", key_card, width = 5, height = 5, units = "in")

  # Timestamp to coordinate cards if multiple sent out in a short time
  timeStamp <- Sys.time()

  # Prepare e-mails and send card as attachment to specified clue givers
  gm_auth_configure(key = key_val, secret = secret_val)
  email <- gm_mime() %>%
      gm_to(giver1) %>%
      gm_from(sender) %>%
      gm_subject("Key Card") %>%
      gm_text_body(sprintf("Generated at %s", timeStamp)) %>%
      gm_attach_file("key card.jpg")
  gm_send_message(email)

  email <- gm_mime() %>%
      gm_to(giver2) %>%
      gm_from("cbjuarez8@gmail.com") %>%
      gm_subject("Key Card") %>%
      gm_text_body(sprintf("Generated at %s", timeStamp)) %>%
      gm_attach_file("key card.jpg")
  gm_send_message(email)
}
"""

# Timer

function timer(length::Int = 0)
  # Simple timer with text progress bar. Produces notification window when time expires.
  for i in 1:50
    sleep(length / 50)
	  print("\r" * "=" ^ i * " " ^ (50 - i) * "|" * string(Int(trunc(length - length * i / 50))) * " s remaining     ")
  end
  win = GtkWindow("Timer", 400, 200)
  b = GtkButton("Time's up!")
  push!(win,b)
  showall(win)
end

# Set up Makie plotting environment
GLMakie.activate!()
AbstractPlotting.inline!(false)
set_window_config!(vsync = false)
fig = Figure(resolution = (1200, 900))
# Axes and player subplots for Draw Again
ax = []
ax2 = []
player_grids = []
fig

# Set global turn counter for roll_and_write
turn = [1]

# roll_and_write

function play_roll_and_write(player_list::Array{String, 1})
  # Pre-fill rolls based on number of players
  roll_and_write_rolls = [repeat(player_list, 48), rand(1:6, 6, 48 * size(player_list)[1])]

  # Colors for dice when unlocked
  cellcolors = [:grey, RGBf0(0.94, 0.5, 0.5), RGBf0(1, 1, 0), RGBf0(0.25, 0.94, 0.25), RGBf0(0.5, 0.5, 0.94), :white, :white, :grey]

  global turn = turn
  turn = [1]

  global fig = fig
  fig = Figure(resolution = screen_size())
  supertitle = fig[0, :] = Label(fig, player_list[1], textsize = 30)

  # Each die is a button, plus forward and back buttons
  fig[2,:] = buttongrid = GridLayout(tellwidth = false)
  buttonlabels = string.(["<", roll_and_write_rolls[2][:, 1]..., ">"])
  buttons = buttongrid[1, 1:8] = [Button(fig, label = buttonlabels[i], height = 175, width = 200, textsize = 40.0f0, buttoncolor = cellcolors[i], buttoncolor_hover = cellcolors[i], strokecolor = :black) for i = 1:8]

  # Back button decrements turn counter, reverts display to the appropriate turn
  on(buttons[1].clicks) do n
    global turn = turn
    if turn[1] >= 2
	    turn[1] -= 1
	    for i in 2:7
	      buttons[i].label = string.(roll_and_write_rolls[2][i - 1, turn[1]])
	    end
	    supertitle.text = roll_and_write_rolls[1][turn[1]]
	  end
  end

  # Forward button increments turn counter, displays next set of rolls
  on(buttons[8].clicks) do n
    global turn = turn
    if turn[1] <= size(roll_and_write_rolls[2])[2]
	    turn[1] += 1
	    for i in 2:7
	      buttons[i].label = string.(roll_and_write_rolls[2][i - 1, turn[1]])
	    end
	    supertitle.text = roll_and_write_rolls[1][turn[1]]
	  end
  end

  # Clicking the colored dice toggles between locked (black) and unlocked (default color)
  for i in 2:5
    on(buttons[i].clicks) do n
      buttons[i].buttoncolor =
	    colordiff(buttons[i].buttoncolor[], RGBf0(0, 0, 0)) == 0 ? cellcolors[i] : RGBf0(0, 0, 0)
	  end
  end

  fig

end

# word_search

function word_search(time_limit = 0)
  dice = [
  ["C", "O", "T", "U", "I", "M"],
  ["L", "R", "T", "T", "E", "Y"],
  ["R", "H", "N", "Z", "L", "N"],
  ["S", "I", "E", "T", "O", "S"],
  ["E", "R", "Y", "L", "V", "D"],
  ["L", "R", "D", "X", "I", "E"],
  ["T", "O", "T", "O", "A", "W"],
  ["V", "E", "T", "R", "H", "W"],
  ["C", "A", "P", "S", "H", "O"],
  ["K", "P", "S", "F", "A", "F"],
  ["W", "E", "E", "H", "N", "G"],
  ["Y", "I", "T", "D", "T", "S"],
  ["S", "E", "I", "N", "E", "U"],
  ["H", "M", "N", "Qu", "I", "U"],
  ["N", "A", "E", "A", "G", "E"],
  ["J", "O", "B", "B", "A", "O"]
  ]

  # Randomly permute dice and select a face from each die. Supplies coordinates for plotting in a grid
  values = [repeat(1:4, outer = 4) repeat(1:4, inner = 4) shuffle(map(x -> rand(x, 1)[1], dice))]

  #Set figure dimensions and hide axes
  global fig = fig
  fig = Figure(resolution = (minimum(screen_size(), minimum(screen_size()))
  ax = Axis(fig[1, 1], aspect = AxisAspect(1))
  hidedecorations!(ax)

  # Place letters into grid
  for i in 1:16
    text!(values[i, 3], position = (values[i, 1] - 2.5, values[i, 2] - 2.5), align = (:center, :center), textsize = 96, space = :data)
  end

  display(fig)

  # Run timer if time limit greater than 0, otherwise play untimed game.
  if time_limit > 0
    timer(time_limit)
  end
end

# Tutti Frutti

# Create game counter to reduce number of repeated prompts
tutti_frutti_game = [0]

# Read prompts from file and randomize
prompts = shuffle(CSV.File(joinpath(@__DIR__, "../assets/prompts.csv"), header = false).Column1)

function play_tutti_frutti(time_limit = 0)
  # Select current set of prompts based on game number
  current_prompts = prompts[(12 * tutti_frutti_game[1] + 1):(12 * tutti_frutti_game[1] + 12)]
  # Select key letter for responses
  letter = "ABCDEFGHIJKLMNOPRSTW"[rand(1:20, 1)]

  f = Figure(resolution = screen_size())
  ax = Axis(f[1, 1], aspect = DataAspect())

  # Plot prompts on screen
  for i in 12:-1:1
    text!(last("00" * string(13 - i), 2) * ". " * current_prompts[i], position = (1, i), align = (:left, :center), textsize = 30, space = :data)
  end

  # Add key letter to screen
  f[1, 1, TopLeft()] = Label(f, letter, textsize = 72, halign = :right)

  xlims!(0, 15)
  reset_limits!(ax)
  hidedecorations!(ax)

  display(f)

  # Run timer if time limit greater than 0; otherwise play untimed game
  if time_limit > 0
    timer(time_limit)
  end

  # Increment game counter for next round.
  tutti_frutti_game[1] += 1

  # If game counter runs over number of prompts, reset prompts and start over
  if (tutti_frutti_game[1] * 12 + 12) > size(prompts)[1]
    tutti_frutti_game[1] = 0
  end
end

# safehouses

# Read in list of words and shuffle
word_list = shuffle(CSV.File(joinpath(@__DIR__, "../assets/words.csv")).word)

# Set game counter to track games and reduce repetition of words
safehouses_game = [0]

# Array contains the following values: x and y coordinates, hidden value of each cell, word to display, and an indicator whether each cell has been revealed to players
function create_word_matrix()
  coords = [repeat(1:5, inner = 5) repeat(1:5, outer = 5) [R"KEY_LAYOUT$content"...] word_list[(25 * safehouses_game[1] + 1):(25 * safehouses_game[1] + 25)] repeat([0], 25)]
end

function play_safehouses(secret_path = joinpath(@__DIR__, "../assets/client_secret.json"))
  read_secret(secret_path)
  println("E-mail address of first clue giver:")
  email_1 = readline()
  println("E-mail address of second clue giver:")
  email_2 = readline()
  @rput email_1 email_2
  R"send_key_card(giver1 = email_1, giver2 = email_2)"
  cards = create_word_matrix()

  # increment game counter
  global safehouses_game = safehouses_game
  safehouses_game[1] += 1

global fig = fig
fig = Figure(resolution = screen_size())

# Create matrix of buttons to represent cards
fig[:,:] = buttongrid = GridLayout(tellwidth = false)
buttonlabels = cards[:, 4]
buttons = buttongrid[1:5, 1:5] = [Button(fig, label = l, height = 175, width = 300, textsize = 40.0f0, buttoncolor_active = RGBf0(0.94, 0.94, 0.94), buttoncolor_hover = RGBf0(0.94, 0.94, 0.94)) for l in buttonlabels]

# Make sure all cards start out 'untouched'
cards[:, 5] .= 0

for i in 1:25
  on(buttons[i].clicks) do n
# Clicking each button turns the color to match the key card
    buttons[i].buttoncolor = [:black, :blue, :red, :yellow][Int(cards[Int(i), 3] + 1)]
	  buttons[i].buttoncolor_active = [:black, :blue, :red, :yellow][Int(cards[Int(i), 3] + 1)]
	  buttons[i].buttoncolor_hover = [:black, :blue, :red, :yellow][Int(cards[Int(i), 3] + 1)]
	  buttons[i].labelcolor = [:white, :white, :black, :black][Int(cards[Int(i), 3] + 1)]
# Marks card as revealed, counts as point for corresponding team
	  cards[Int(i), 5] = 1
	    if cards[Int(i), 3] == 0 # Assassin: Game Over
	      win = GtkWindow("safehouses", 400, 200)
        game_result = uppercase(buttonlabels[i]) * " was the Assassin! Game Over!"
        b = GtkButton(game_result)
        push!(win,b)
        showall(win)
        elseif minimum(cards[cards[:, 3] .== 1, 5]) == 1 # All blue team cards revealed
  	  	  win = GtkWindow("safehouses", 400, 200)
          game_result = "Blue team wins!"
	    	  b = GtkButton(game_result)
          push!(win,b)
  	  	  showall(win)
        elseif minimum(cards[cards[:, 3] .== 2, 5]) == 1 # All red cards revealed
	    	  win = GtkWindow("safehouses", 400, 200)
          game_result = "Red team wins!"
	    	  b = GtkButton(game_result)
          push!(win,b)
	  	    showall(win)
        end
      end
    end
  # Manually opening figure versus opening as function side effect seems to be more stable
  display(fig)
end

# safehouses duos

# Is current player 1 or 2?
current_player = false
# Track number of turns for time limit
duos_turn = 1

R"""
if(!require(ggplot2)) {
    install.packages("ggplot2")
    require(ggplot2)
    }

if(!require(gmailr)) {
    install.packages("gmailr")
    require(gmailr)
    }

send_duos_card <- function(giver1 = NULL, giver2 = NULL, sender = "safehouses@gmail.com", key = key_val, secret = secret_val) {

if (is.null(giver1) || is.null(giver2)) {warning("Two clue givers must be designated!")}

KEY_LAYOUT <<- as.data.frame(expand.grid(1:5, LETTERS[1:5]))

# Use randomized vector so each player's card corresponds appropriately to the other's
randomizer <- sample(1:25)

# Create key cards for each player
# 0 => Assassin, 1 => Agent, 2 => Bystander
KEY_LAYOUT$player_1 <<- c(
  rep(1, 5),
  rep(2, 5),
  0,
  2,
  0,
  rep(1, 4),
  0,
  rep(2, 7)
)[randomizer]

KEY_LAYOUT$player_2 <<- c(
  rep(2, 5),
  rep(1, 5),
  rep(0, 2),
  2,
  rep(1, 3),
  0,
  1,
  rep(2, 7)
)[randomizer]

card_1 <- ggplot(KEY_LAYOUT, aes(x = 0, y = 0, label = c("X", "G", "Y")[player_1 + 1], fill = as.factor(player_1), size = 12)) +
  geom_tile(alpha = .5) +
  geom_text(aes(colour = as.factor(player_1)), size = 12, alpha = .75) +
  facet_grid(Var2~Var1, switch = "y") +
  scale_fill_manual(values = c("black", "darkgreen", "yellow")) + theme_bw() +
  scale_colour_manual(values = c("black", "darkgreen", "black")) + theme_bw() +
  theme(legend.position = "none",
        axis.text = element_blank(),
        axis.ticks.length = unit(0, "in"),
        axis.title = element_blank(),
        strip.background = element_blank(),
        panel.border = element_blank(),
        panel.spacing = unit(.05, "cm"),
        panel.grid = element_blank(),
        strip.text = element_text(size = 16),
        strip.text.y = element_text(angle = 180))

card_2 <- ggplot(KEY_LAYOUT, aes(x = 0, y = 0, label = c("X", "G", "Y")[player_2 + 1], fill = as.factor(player_2), size = 12)) +
  geom_tile(alpha = .5) +
  geom_text(aes(colour = as.factor(player_2)), size = 12, alpha = .75) +
  facet_grid(Var2~Var1, switch = "y") +
  scale_fill_manual(values = c("black", "darkgreen", "yellow")) + theme_bw() +
  scale_colour_manual(values = c("black", "darkgreen", "black")) + theme_bw() +
  theme(legend.position = "none",
        axis.text = element_blank(),
        axis.ticks.length = unit(0, "in"),
        axis.title = element_blank(),
        strip.background = element_blank(),
        panel.border = element_blank(),
        panel.spacing = unit(.05, "cm"),
        panel.grid = element_blank(),
        strip.text = element_text(size = 16),
        strip.text.y = element_text(angle = 180))

ggsave("key card 1.jpg", card_1, width = 5, height = 5, units = "in")
ggsave("key card 2.jpg", card_2, width = 5, height = 5, units = "in")

timeStamp <- Sys.time()

gm_auth_configure(key = key, secret = secret)
email <- gm_mime() %>%
    gm_to(giver1) %>%
    gm_from(sender) %>%
    gm_subject("Key Card for Player 1") %>%
    gm_text_body(sprintf("Generated at %s", timeStamp)) %>%
    gm_attach_file("key card 1.jpg")
gm_send_message(email)

email <- gm_mime() %>%
    gm_to(giver2) %>%
    gm_from("cbjuarez8@gmail.com") %>%
    gm_subject("Key Card for Player 2") %>%
    gm_text_body(sprintf("Generated at %s", timeStamp)) %>%
    gm_attach_file("key card 2.jpg")
gm_send_message(email)
}
"""

# Each player's value is a separate column in the layout matrix
function create_duos_matrix()
  coords = [repeat(1:5, outer = 5) repeat(1:5, inner = 5) [R"KEY_LAYOUT$player_1"...] [R"KEY_LAYOUT$player_2"...] word_list[(25 * safehouses_game[1] + 1):(25 * safehouses_game[1] + 25)] repeat([:grey94], 25) repeat([:grey94], 25)]
end

function play_safehouses_duos(secret_path = joinpath(@__DIR__, "../assets/client_secret.json"), turn_limit = 9)
  read_secret(secret_path)
  println("E-mail address of first clue giver:")
  email_1 = readline()
  println("E-mail address of second clue giver:")
  email_2 = readline()
  @rput email_1 email_2
  R"send_duos_card(giver1 = email_1, giver2 = email_2)"
  cards = create_duos_matrix()

  global safehouses_game = safehouses_game
  safehouses_game[1] += 1

  global current_player = current_player
  current_player = false

  global fig = fig
  fig = Figure(resolution = screen_size())

  fig[:,:] = buttongrid = GridLayout(tellwidth = false)
  buttonlabels = cards[:, 5]
  buttons = buttongrid[1:5, 1:5] = [Button(fig, label = l, height = 125, width = 300, textsize = 40.0f0, buttoncolor_active = :grey94, buttoncolor_hover = :grey94) for l in buttonlabels]

  for i in 1:25
    on(buttons[i].clicks) do n
    # Clicking a cell sets the color to the value for the current clue giver
  	    buttons[i].buttoncolor_active =     [:black, :green, :yellow][Int(cards[Int(i), 3 + current_player] + 1)]
        buttons[i].buttoncolor =            [:black, :green, :yellow][Int(cards[Int(i), 3 + current_player] + 1)]
  	    buttons[i].buttoncolor_hover =      [:black, :green, :yellow][Int(cards[Int(i), 3 + current_player] + 1)]
  	    buttons[i].labelcolor =             [:white, :black, :black ][Int(cards[Int(i), 3 + current_player] + 1)]
  	    cards[Int(i), 6 + current_player] = [:black, :green, :yellow][Int(cards[Int(i), 3 + current_player] + 1)]
  	    if cards[Int(i), 3 + current_player] == 0
  	      win = GtkWindow("safehouses", 400, 200)
          game_result = uppercase(buttonlabels[i]) * " was an Assassin! Game Over!"
          b = GtkButton(game_result)
          push!(win,b)
          showall(win)
        elseif sum(cards[:, 6:7] .== 1) == 16 # All green cards revealed
     		  win = GtkWindow("safehouses", 400, 200)
          game_result = "You win!"
  	  	  b = GtkButton(game_result)
          push!(win,b)
  		    showall(win)
        end
        # If touched card is green or an assassin, set both players as having touched the card
		    if cards[Int(i), 3 + current_player] <= 1.0
  	      cards[Int(i), 6 + ~current_player] = cards[Int(i), 6 + current_player]
		    end
      end
    end

  # Set up button to toggle active player
  fig[0,:] = player_button = Button(fig, label = "Player $(1 + current_player)'s turn", height = 125, textsize = 40.0f0, buttoncolor_active = :grey94, buttoncolor_hover = :grey94)

  on(player_button.clicks) do n
    # Clicking button toggles active player value between 0 (false) and 1 (true)
    global current_player = current_player
	  current_player = ~current_player

  # Each click also increments the turn counter
	  global duos_turn = duos_turn
	  duos_turn += 1

    # If turn counter exceeds limit, game ends
	  if duos_turn > turn_limit
	    win = GtkWindow("safehouses", 400, 200)
      game_result = "Time's Up! Game Over!"
    	b = GtkButton(game_result)
      push!(win,b)
    	showall(win)
	  end

	  player_button.label = "Player $(1 + current_player): Turn $(duos_turn) of $(turn_limit)"

    # Set cards to show colors for next player
	  for i in 1:25
      buttons[i].buttoncolor        = cards[i, 6 + current_player]
	    buttons[i].buttoncolor_active = cards[i, 6 + current_player]
	    buttons[i].buttoncolor        = cards[i, 6 + current_player]
	    buttons[i].buttoncolor_hover  = cards[i, 6 + current_player]
	    buttons[i].labelcolor         = cards[i, 6 + current_player]
	  end
  end
  display(fig)
end

# Draw Again

# Function to clear out a subplot
function empty_subplot!(ax::Axis)
  while !isempty(ax.scene.plots)
    plot = first(ax.scene.plots)
    delete!(ax.scene, plot)
  end
end

# Shapes to display for each draw
shapedeck =
      [
      (0) (0)
      (0) (0)
      (0) (0)
      (-.5, .5) (0, 0)
      (-.5, .5) (0, 0)
      (-.5, .5) (0, 0)
      (-.5, -.5, .5) (.5, -.5, -.5)
      (-.5, -.5, .5) (.5, -.5, -.5)
      (-1, 0, 1) (0, 0, 0)
      (-1, 0, 1) (0, 0, 0)
      (-1, 0, 0, 1) (-.5, -.5, .5, .5)
      (-1.5, -.5, .5, 1.5) (0, 0, 0, 0)
      (-1, 0, 1, 1) (-.5, -.5, -.5, .5)
      (-.5, -.5, -.5, .5) (1, 0, -1, 0)
      (-.5, -.5, .5, .5) (.5, -.5, .5, -.5)
      (-.5, -.5, -.5, .5, .5) (1, 0, -1, 1, -1)
      (-1, 0, 0, 0, 1) (0, 1, 0, -1, 0)
      (-1, 0, 0, 0, 1) (1, 1, 0, -1, 1)
      (-1, 0, 0, 1, 1) (-.5, .5, -.5, .5, -.5)
      (-1, -1, -1, 0, 1) (1, 0, -1, -1, -1)
      (-1.5, -.5, .5, .5, 1.5) (-.5, -.5, -.5, .5, .5)
      (-1, 0, 0, 0, 1) (-1, 1, 0, -1, 1)
      (-1.5, -.5, .5, 1.5, -.5) (.5, .5, .5, .5, -.5)
      (-1, -1, 0, 0, 1) (0, -1, 1, 0, 1)
      (-1, -1, -1, 0, 0, 1) (1, 0, -1, 1, 0, 1)
      (1, 0, -1, 1, 0, -1) (-.5, -.5, -.5, .5, .5, .5)
      (-1, 0, 0, 0, 1, 1) (0, 1, 0, -1, 0, -1)
      (-1, 0, 0, 0, 0, 1) (.5, 1.5, .5, -.5, -1.5, .5)
      (-1, -1, 0, 0, 1, 1) (0, -1, 1, 0, 0, -1)
      (-.5, -.5, .5, .5, .5, .5) (.5, -.5, 1.5, .5, -.5, -1.5)
      (-2, -1, 0, 0, 1, 2) (-.5, -.5, .5, -.5, -.5, -.5)
      (-1.5, -1.5, -.5, .5, 1.5, 1.5) (.5, -.5, -.5, -.5, .5, -.5)
      (-1.5, -1.5, -.5, -.5, -.5, .5, 1.5) (1, -1, 1, 0, -1, 0, 0)
      (-1.5, -1.5, -.5, -.5, .5, .5, 1.5) (1.5, .5, .5, -.5, -.5, -1.5, -1.5)
      (-1, -1, -1, 0, 1, 1, 1) (1, 0, -1, 0, 1, 0, -1)
      (-1, -1, 0, 0, 0, 1, 1) (0, -1, 1, 0, -1, 0, -1)
      (-1, -1, -1, 0, 1, 1, 1) (1, 0, -1, -1, 1, 0, -1)
      (-1, -1, 0, 0, 0, 1, 1) (0, -1, 1, 0, -1, 1, 0)
      (-1.5, -.5, -.5, -.5, -.5, .5, 1.5) (-.5, 1.5, .5, -.5, -1.5, -.5, -.5)
      (-2, -1, 0, 1, 2, -1, 1) (.5, .5, .5, .5, .5, -.5, -.5)
      ]
  # Sample shapes for reference appear in	upper middle column
	samplecards = copy(shapedeck)
  # Cards to draw from, shuffled
  shapecards  = copy(shapedeck)
	shapecards  = shapecards[shuffle([1:40...]), :]

  # Coordinates to display sample cards in their panel
	sample_x = [-14, -12, -14, -13.5, -13.5, -13.5, -13.5, -13.5, -13, -13, -9, -9.5, -9.5, -10.5, -9.5, -5.5, -6, -6, -9, -1, -.5, -3, -1.5, -5, 0, -1, 3, 0, 3, 3.5, 5, 3.5, 11.5, 9.5, 8, 7, 12, 11, 6.5, 11]
	sample_y = [9, 9, 7, 5, 3, 1, -1.5, -4.5, -7, -9, 8.5, -5, 5.5, 1, -2.5, 8, 1, -3, -8.5, -8, -.5, -4, 1.5, -8, 8, 4.5, -3, -5.5, -8, 7.5, .5, 3.5, 0, -3.5, 4, 8, 4, 8, -5.5, -8.5]

  # Shapes for each player's start of game
    startingcards =
      [
      (-1.5, -1.5, -.5, -.5, .5, .5, 1.5, 1.5) (1.5, -1.5, .5, -.5, .5, -.5, 1.5, -1.5)
      (-1, -1, -1, 0, 0, 1, 1, 1) (1.5, .5, -.5, -.5, -1.5, 1.5, .5, -.5)
      (2, 1, 0, -1, -2, 2, 0, -2) (-.5, -.5, -.5, -.5, -.5, .5, .5, .5)
      (-1, -1, 0, 0, 0, 0, 1, 1) (.5, -.5, 1.5, .5, -.5, -1.5, .5, -.5)
      (-1, -1, 0, 0, 0, 0, 1, 1) (1.5, -.5, 1.5, .5, -.5, -1.5, 1.5, -.5)
      (-2, -1, -1, 0, 0, 1, 1, 2) (1.5, 1.5, .5, .5, -.5, -.5, -1.5, -1.5)
      (-1.5, -1.5, -.5, -.5, -.5, -.5, .5, 1.5) (-.5, -1.5, 1.5, .5, -.5, -1.5, -.5, -.5)
      (2, 1, -1, -2, 1, 0, -1, 0) (-1, -1, -1, -1, 0, 0, 0, 1)
      (-1, -1, 0, 0, 0, 0, 1, 1) (1.5, -.5, 1.5, .5, -.5, -1.5, .5, -1.5)
      (-1, -1, 0, 0, 0, 0, 1, 1) (1.5, -1.5, 1.5, .5, -.5, -1.5, 1.5, -1.5)
      (-1, -1, -1, 0, 0, 1, 1, 1) (1, 0, -1, 1, -1, 1, 0, -1)
      (-1.5, -.5, .5, 1.5, 1.5, 1.5, 1.5, .5) (-1.5, -1.5, -1.5, -1.5, -.5, .5, 1.5, 1.5)
      ]

    # Vector of colors for each shape according to size
    colors = ["#FDE725FF" "#8FD744FF" "#35B779FF" "#21908CFF" "#31688EFF" "#443A83FF" "#440154FF"]

  # Player names, set to blank to start
  player_list = repeat([" "], 6)

  # Whether or not each player has drawn a second chance that turn, defaults to locked for first draw
  locked = repeat([1], 6)

  # Assigned spaces in Gtk window for each player's name entry
  grid_spaces = [[[i, j] for j in [1 2 3], i in [1 3]]...]

function create_board()

  global fig = fig
  fig = Figure(resolution = screen_size())
  # Counter of remaining cards at top of figure window
  supertitle = fig[0, :] = Label(fig, "40 cards remain", textsize = 30)

  # Axes for player subplots on right and left columns
  global ax = ax
  ax = [Axis(fig[i, j]) for i in (2, 4, 6), j in (1:3, 7:9)]
  # Axes for subplots in center of figure
  global ax2 = ax2
  ax2 = [Axis(fig[i, 4:6]) for i in (1:2, 3:4, 5:6)]

  # Index of subplots for each player
  global player_grids = player_grids
  player_grids = [(i, j) for i in (2, 4, 6), j in (1:3, 7:9)]

  # Buttons to draw second chances, default to blank label until names provided
  buttons = [Button(fig[i,j], label = " ") for i in (1, 3, 5), j in (2, 8)]
  for i in 1:6
    buttons[i].label = player_list[i] == "" ? " " : player_list[i]
  end

  # Plot sample cards
  for i in 1:40
    GLMakie.scatter!(fig[1:2, 4:6],
      .075 .* ([samplecards[i, 1]...] .+ sample_x[i]),
      .2 .* ([samplecards[i, 2]...] .+ sample_y[i]),
      marker = :rect,
      color = Colors.parse(Colorant, colors[length([samplecards[i, 2]...])]),
      strokecolor = :white,
      markersize = 12
    )
  end
  limits!(ax2[1], -2, 2, -2, 2)

  # Add button to clear board and draw new common cards
  redeal_button = Button(fig[7, 5], label = "Draw Again")
  on(redeal_button.clicks) do n
    global shapecards = shapecards
    global locked = locked
    for i in 1:6
      empty_subplot!(ax[i])
    end
    if (size(shapecards)[1] >= 2)
      for i in 2:3
        empty_subplot!(ax2[i])
  	  card_to_plot = shapecards[1, :]
        shapecards = shapecards[2:end, :]
  	  GLMakie.scatter!(
  	    fig[(3:4, 5:6)[i - 1], 4:6],
  	    .275 .* [card_to_plot[1]...],
  	    .675 .* [card_to_plot[2]...],
  	    marker = :rect,
          strokecolor = :white,
  	    color = Colors.parse(Colorant, colors[length([card_to_plot[1]...])]),
          markersize = 44
        )
      hidedecorations!(ax2[i])
      limits!(ax2[i], -2, 2, -2, 2)
      end
      ncards = size(shapecards)[1]
      supertitle.text = string(ncards) * " card" * (ncards == 1 ? "" : "s") * " remain" * (ncards == 1 ? "s" : "")
      # Resets locked indicators for next turn
      locked = repeat([0], 6)
    end
  end

  # Buttons to draw second chances for each player, and lock the player for remainder of turn
  for i in 1:6
    on(buttons[i].clicks) do n
    global locked = locked
    global shapecards = shapecards
  	if (locked[i] == 0) & (buttons[i].label != " ") & (size(shapecards)[1] >= 1)
  	  empty_subplot!(ax[i])
  	  card_to_plot = shapecards[1, :]
        shapecards = shapecards[2:end, :]
  	  GLMakie.scatter!(
  	    fig[player_grids[i][1], player_grids[i][2]],
  	    .32 .* [card_to_plot[1]...],
  	    .825 .* [card_to_plot[2]...],
  	    marker = :rect,
          strokecolor = :white,
  	    color = Colors.parse(Colorant, colors[length([card_to_plot[1]...])]),
          markersize = 44
        )
        hidedecorations!(ax[i])
        limits!(ax[i], -2, 2, -2, 2)
        ncards = size(shapecards)[1]
        supertitle.text = string(ncards) * " card" * (ncards == 1 ? "" : "s") * " remain" * (ncards == 1 ? "s" : "")
  	  locked[i] = 1
      end
    end
  end

  for i in 1:6
    hidedecorations!(ax[i])
    limits!(ax[i], -2, 2, -2, 2)
  end

  for i in 1:3
    hidedecorations!(ax2[i])
    limits!(ax[i], -2, 2, -2, 2)
  end

  fig
end

  # Create Gtk window to enter player names
  win = GtkWindow("Draw Again")
  destroy(win)
  e1, e2, e3, e4, e5, e6 = GtkEntry(), GtkEntry(), GtkEntry(), GtkEntry(), GtkEntry(), GtkEntry()
  entry_widgets = [e1, e2, e3, e4, e5, e6]

  # Collects player names using Gtk window, then prompts player to display the game board
  function play_draw_again()
    global win = win
	  global shapecards = shapecards
	  global locked = locked
	  locked = repeat([1], 6)
	  shapecards = copy(shapedeck)
	  shapecards = shapecards[shuffle([1:40...]), :]

    # Arrange text entry widgets in two columns of three
    g = GtkGrid()
    spaces = [[i, j] for j in [1 2 3], i in [1 3]]
    for i in 1:6
      global g[grid_spaces[i]...] = entry_widgets[i]
    end

    # Create button to kick off game and add to bottom row of Gtk window
    start_button = GtkButton("Start Game")
    g[2, 2:3] = start_button
    id = signal_connect(widget->(set_players();create_board();display(fig);draw_starting_cards();destroy(win)), start_button, "clicked")

    # Assemble window and display it
    set_gtk_property!(g, :column_homogeneous, true)
    set_gtk_property!(g, :column_spacing, 15)
    push!(win, g)
    showall(win)
  end

  # Take player names from Gtk window and save for later
  function set_players()
    global player_list = player_list
    player_list = [get_gtk_property(i, :text, String) for i in [e1 e2 e3 e4 e5 e6]]
  end

function draw_starting_cards()

  global ax2 = ax2
  global ax = ax
  global startingcards = startingcards
  startingcards = startingcards[shuffle([1:12...]), :]

  # Prepare board and draw starting cards for each named player
  for i in 2:3
    empty_subplot!(ax2[i])
  end
  for i in 1:6
    empty_subplot!(ax[i])
    if player_list[i] != ""
      GLMakie.scatter!(fig[player_grids[i][1], player_grids[i][2]],
       .325 .* [startingcards[i, 1]...],
       .825 .* [startingcards[i, 2]...],
       marker = :rect,
       strokecolor = :white,
       markersize = 44
      )
      hidedecorations!(ax[i])
      limits!(ax[i], -2, 2, -2, 2)
    end
  end
end

end


text:
module EratosthenesExampleSoftware

using Eratosthenes

# Bring in the rotations (used by the pd_controller).
include(joinpath("..", "src", "EratosthenesRotations.jl"))
using .EratosthenesRotations

# Bring in the UDP library (used by the PITL mode).
include(joinpath("utilities", "UDPConnections.jl"))
using .UDPConnections

using Sockets
import Libdl

# Let anyone use this controller.
export StarTrackerAndGyroController

# This represents the "real" algorithm under development.
function pd_controller(gains, q_TI, q_BI, ω_BI_B)
    theta, r_B = q2aa(qdiff(q_TI, q_BI))
    τ_B        = gains[1] * theta * r_B - gains[2] * ω_BI_B
    f_B        = [0.; 0.; 0.]
    return (f_B, τ_B)
end

# Julia-in-the-loop, software-in-the-loop, and hardware-in-the-loop
@enum StarTrackerAndGyroControllerMode jitl=0 sitl pitl

# The StarTrackerAndGyroController can be run in 3 modes and needs to store that
# mode and the UDP connection.
mutable struct StarTrackerAndGyroControllerConstants
    target::Vector{Float64}
    mode::StarTrackerAndGyroControllerMode
    conn::UDPConnection
    c_lib::Ptr{Cvoid}
    c_fcn::Ptr{Cvoid}
    StarTrackerAndGyroControllerConstants(target = [0.; 0.; 0.; 1.],
                                          mode   = jitl,
                                          conn   = UDPConnection(),
                                          c_lib  = Ptr{Cvoid}(0),
                                          c_fcn  = Ptr{Cvoid}(0)) =
        new(target, mode, conn, c_lib, c_fcn)
end

"""
    StarTrackerAndGyroController
"""
function StarTrackerAndGyroController()

    # Create a state with a (potential) UDP connection. During setup, the
    # target_ip, send_to port, and listen_on ports can be overwritten.
    constants = StarTrackerAndGyroControllerConstants(
                    [0.; 0.; 0.; 1.], # Target quaternion
                    jitl,             # Default operation mode
                    UDPConnection(ip"192.168.1.3", 2000, 2001))

    # This function always runs before the simulation starts up.
    function startup(t, constants, state, args...)
        if constants.mode == sitl
            if Sys.iswindows()
                constants.c_lib = Libdl.dlopen("3_c_code/windows/lib-pd-controller.dll")
            else
                constants.c_lib = Libdl.dlopen("3_c_code/linux/lib-pd-controller.so")
            end
            constants.c_fcn = Libdl.dlsym(constants.c_lib, :pd_controller)
        elseif constants.mode == pitl
            println("Connecting to remote computer.")
            udp_connect(constants.conn)
        end
    end

    # This function is called each time the controller trigger time is reached.
    # It should update the state using its inputs and the outputs from other
    # software or sensors. It should write to its own outputs and to the inputs
    # of any other software or of actuators.
    function step(t, constants, state, inputs, outputs_bus, inputs_bus)

        # Extract what we care about.
        ω_BI_B = outputs_bus["gyro"]
        q_BI   = outputs_bus["star_tracker"]
        q_TI   = constants.target
        gains  = [0.2; 2.]

        # Run the algorithm under development, the C version, or the C version
        # when running on the flight computer.
        if constants.mode == jitl

            f_B, τ_B = pd_controller(gains, q_TI, q_BI, ω_BI_B)

        # Call the C version of the algorithm directly.
        elseif constants.mode == sitl

            # Create array for the outputs. These will be written to by the C
            # function.
            f_B   = [0.; 0.; 0.]
            τ_B   = [0.; 0.; 0.]
            ccall(constants.c_fcn,
                  Nothing,
                  (Ptr{Float64}, Ptr{Float64}, Ptr{Float64}, Ptr{Float64}, Ptr{Float64}, Ptr{Float64}),
                  gains, q_TI, q_BI, ω_BI_B, f_B, τ_B);

        # Send the inputs to the flight computer and wait for its outputs.
        elseif constants.mode == pitl

            # Send over the status and other inputs to the flight software.
            println("Sending...")
            udp_send(constants.conn, 1, gains, q_TI, q_BI, ω_BI_B)

            # Give it just a moment to respond. (Sometimes it gets stuck if it
            # goes to receive too soon.)
            sleep(0.001)

            # Wait for the data to arrive. The inputs here serve as examples for
            # the function, enabling it to know how to write to the outputs.
            println("Receiving...")
            f_B_tuple = (0., 0., 0.)
            τ_B_tuple = (0., 0., 0.)
            f_B_tuple, τ_B_tuple = udp_receive(constants.conn, f_B_tuple, τ_B_tuple)

            # Expand the tuples into vectors.
            f_B = [f_B_tuple...]
            τ_B = [τ_B_tuple...]

        else
            error("Unknown mode.")
        end

        # Write out our command for the ideal actuator.
        inputs_bus["ideal_actuator"] = IdealActuatorCommand(f_B, τ_B)

        return (state, nothing, inputs_bus)

    end

    # Tell the target that we're done, and then close the socket.
    function shutdown(t, constants, state)
        if constants.mode == sitl
            println("Shutting down the StarTrackerAndGyroController library.")
            Libdl.dlclose(constants.c_lib)
        elseif constants.mode == pitl
            println("Shutting down the StarTrackerAndGyroController UDP connection.")
            # Send a status of 0 to indicate that things are over now.
            udp_send(constants.conn, 0)
            udp_close(constants.conn)
        end
    end

    DynamicalModel("star_tracker_and_gyro_controller",
                   startup = startup,
                   init = step,
                   update = step,
                   shutdown = shutdown,
                   timing = ModelTiming(0.05),  # Sample rate
                   constants = constants)

end

end

ext: jl


text:
using Combinatorics

# Part 1
# Load input
expenses = open("day01_input.txt") do f
    [parse(Int32, line) for line in eachline(f)]
end

# See which pair sum to 2020 and multiply them
for (value1, value2) in combinations(expenses, 2)
    if value1 + value2 == 2020
        println("Product of $value1 and $value2: $(value1 * value2)")
    end
end

# Part 2: which triplet satisfy these criteria?
for values in combinations(expenses, 3)
    if sum(values) == 2020
        println("Product of $values: $(prod(values))")
    end
end

max_stars_repo_name: ericgreveson/adventofcode

max_issues_repo_name: ericgreveson/adventofcode

max_forks_repo_name: ericgreveson/adventofcode


text:
#This file provides a pseudocode for algorithm one that provides the architecture for the complete algorithm. Some of these objects can change.

function coursematch(M,
    k,
    βmax,
    besterror,
    t,
    Np, #to be removed from function's arguments, and replaced in the code by neighb_fun
    s::Student)

# Arguments
# s::Student : the student's problem from student.jl
#
#
#
#

    ### Initialization
    # New search price
    ptild = Array{Int, M}
    # Initial guess for p
    p = Array{Int, M}
    # Price that gives the best error
    pstar = Array[]
    # Best error in a searchstart
    searcherror = Array[]
    # Neighbors of the search
    DoubleN = Array[]
    # boolean. true if a new search price has been found (one that does not generate the same demand as one that is in the tabu list)
    foundnextstep = Array{Bool, 1}
    # the demand for courses at search price
    dem = zeros(M)
    # Error in the current search.
    currenterror = Array[]
    # τ vector of Tabu list
    τ = Array[]

    starttime = Dates.Time(now())
    while (Dates.Time(now()) - starttime).value < t * 1000000000
        # Time in nanoseconds
        #repeat from l.25 to 52. This is a do until runtime > t.
        p = zeros(M)#Initial guess for p. Will be replaced also

        # demand function: see demand.jl finished
        # α : make sure that returns root of the sum of squares (so far: combination of clearing.jl & PseudoClearingError (modified))
        searcherror =  α.(demand!(p, s))

        c = 0
        # while loop from l.7 to 34
        while c < 5

            ### Initialize the values for the findnextprices function
            #
            # DoubleN = copy(neighb_fun(ARG))
            DoubleN = copy(Np)  # going to be neighb_fun
            #DoubleN = N(p) #Don't forget this needs to be sorted by clearing error (Issue #6)

            foundnextstep[1] = false

            # repeat from l. 10 to 16

            # What function is this?
            # Takes all possible neighbouring vectors from DoubleN, and find the "best" one (based on clearing error etc)
            # excluding the vectors in the Tabu list
            findnextprices!(ptild,  DoubleN, dem, foundnextstep, τ)
            # if from line 17 to 18
            if isempty(DoubleN) == true
                c = 5
            end
            #l. 19 to 33
            # should be similar to isempty(DoubleN) == false
            # is it also returned by the function
            if foundnextstep[1] == true
                # Push the chosen allocation vector to the Tabu list (so that it is not considered again in the future)
                # Push the discarded neighbouring (allocation) vectors to the Tabu list
                push!(τ,copy(dem))
                # Replace the search price (current optimal price vector) by ptild
                p = copy(ptild)
                # Compute search error with new allocation vector
                currenterror =  α(dem)
                # If searcherror > currenterror :
                # - set c to 0 if improve error, otherwise c to c+1
                # - replace error if improve solution
                # - replace pstar by current p if improve solution
                # - replace error by currenterror if improve solution
                c = resetcounter(currenterror, searcherror, c)
                searcherror = replacesearcherror(currenterror, searcherror)
                pstar = replacepstar(currenterror, besterror, p, pstar)
                besterror = replacebesterror(currenterror, besterror)
            end
            println("we are at step $c")
        end
    end
    # return the optimal vector
    return pstar
end

M = 5 #Number of courses offered
k = 3 #Number of courses students take
βmax = 20 #Maximum budget
t = 1 #time in seconds
besterror = 100 #for now
Np = Array[[0,0,0,0,0],[9,40,5,2,0], [1,1,1,1,1], [1,2,3,0,0], [9,40,5,2,0], [32,40,100,1,2], [10,20,30,3,0]]
pstar = coursematch(M, k, βmax, besterror, t, Np)


text:
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

"""
    rand!(x::NDArray; low = 0, high = 1)

Draw random samples from a uniform distribution.
Samples are uniformly distributed over the half-open interval [low, high)
(includes low, but excludes high).

```julia
julia> mx.rand!(NDArray(undef, 2, 3))
2×3 mx.NDArray{Float32,2} @ CPU0:
 0.385748   0.839275  0.444536
 0.0879585  0.215928  0.104636

julia> mx.rand!(NDArray(undef, 2, 3), low = 1, high = 10)
2×3 mx.NDArray{Float32,2} @ CPU0:
 6.6385   4.18888  2.07505
 8.97283  2.5636   1.95586
```
"""
rand!(x::NDArray; low = 0, high = 1) =
  _random_uniform(NDArray, low = low, high = high, shape = size(x), out = x)

"""
    rand(dims...; low = 0, high = 1, context = cpu())

Draw random samples from a uniform distribution.
Samples are uniformly distributed over the half-open interval [low, high)
(includes low, but excludes high).

```julia
julia> mx.rand(2, 2)
2×2 mx.NDArray{Float32,2} @ CPU0:
 0.487866   0.825691
 0.0234245  0.794797

julia> mx.rand(2, 2; low = 1, high = 10)
2×2 mx.NDArray{Float32,2} @ CPU0:
 5.5944   5.74281
 9.81258  3.58068
```
"""
rand(dims::Integer...; low = 0, high = 1, context = cpu()) =
  rand!(NDArray(undef, dims, ctx = context), low = low, high = high)

"""
    randn!(x::NDArray; μ = 0, σ = 1)

Draw random samples from a normal (Gaussian) distribution.
"""
randn!(x::NDArray; μ = 0, σ = 1) =
  _random_normal(NDArray, loc = μ, scale = σ, shape = size(x), out = x)

"""
    randn(dims...; μ = 0, σ = 1, context = cpu())

Draw random samples from a normal (Gaussian) distribution.
"""
randn(dims::Int...; μ = 0, σ = 1, context = cpu()) =
  randn!(NDArray(undef, dims, ctx = context), μ = μ, σ = σ)

"""
    seed!(seed::Int)

Set the random seed of libmxnet
"""
seed!(s::Int) = @mxcall :MXRandomSeed (Cint,) s

function srand(s::Int)
  @warn "`mx.srand` is deprecated, use `mx.seed!` instead."
  seed!(s)
end


text:
function a(k, x1, x2, x3, x4, x5)
  b = ()-> a(k-=1, b, x1, x2, x3, x4);
  k <= 0 ? (x4() + x5()) : b();
end

println(a(10, ()->1, ()->-1,  ()->-1, ()->1, ()->0));

max_stars_repo_name: ethansaxenian/RosettaDecode

max_issues_repo_name: ethansaxenian/RosettaDecode

max_forks_repo_name: ethansaxenian/RosettaDecode


text:
# This file is a part of Julia. License is MIT: https://julialang.org/license

module MiniCassette
    # A minimal demonstration of the cassette mechanism. Doesn't support all the
    # fancy features, but sufficient to exercise this code path in the compiler.

    using Core.Compiler: method_instances, retrieve_code_info, CodeInfo,
        MethodInstance, SSAValue, GotoNode, GotoIfNot, ReturnNode, Slot, SlotNumber, quoted,
        signature_type
    using Base: _methods_by_ftype
    using Base.Meta: isexpr
    using Test

    export Ctx, overdub

    struct Ctx; end

    # A no-op cassette-like transform
    function transform_expr(expr, map_slot_number, map_ssa_value, sparams)
        transform(expr) = transform_expr(expr, map_slot_number, map_ssa_value, sparams)
        if isexpr(expr, :call)
            return Expr(:call, overdub, SlotNumber(2), map(transform, expr.args)...)
        elseif isa(expr, GotoIfNot)
            return GotoIfNot(transform(expr.cond), map_ssa_value(SSAValue(expr.dest)).id)
        elseif isexpr(expr, :static_parameter)
            return quoted(sparams[expr.args[1]])
        elseif isa(expr, ReturnNode)
            return ReturnNode(transform(expr.val))
        elseif isa(expr, Expr)
            return Expr(expr.head, map(transform, expr.args)...)
        elseif isa(expr, GotoNode)
            return GotoNode(map_ssa_value(SSAValue(expr.label)).id)
        elseif isa(expr, Slot)
            return map_slot_number(expr.id)
        elseif isa(expr, SSAValue)
            return map_ssa_value(expr)
        else
            return expr
        end
    end

    function transform!(ci, nargs, sparams)
        code = ci.code
        ci.slotnames = Symbol[Symbol("#self#"), :ctx, :f, :args, ci.slotnames[nargs+1:end]...]
        ci.slotflags = UInt8[(0x00 for i = 1:4)..., ci.slotflags[nargs+1:end]...]
        # Insert one SSAValue for every argument statement
        prepend!(code, [Expr(:call, getfield, SlotNumber(4), i) for i = 1:nargs])
        prepend!(ci.codelocs, [0 for i = 1:nargs])
        prepend!(ci.ssaflags, [0x00 for i = 1:nargs])
        ci.ssavaluetypes += nargs
        function map_slot_number(slot)
            if slot == 1
                # self in the original function is now `f`
                return SlotNumber(3)
            elseif 2 <= slot <= nargs + 1
                # Arguments get inserted as ssa values at the top of the function
                return SSAValue(slot - 1)
            else
                # The first non-argument slot will be 5
                return SlotNumber(slot - (nargs + 1) + 4)
            end
        end
        map_ssa_value(ssa::SSAValue) = SSAValue(ssa.id + nargs)
        for i = (nargs+1:length(code))
            code[i] = transform_expr(code[i], map_slot_number, map_ssa_value, sparams)
        end
    end

    function overdub_generator(self, c, f, args)
        if !isdefined(f, :instance)
            return :(return f(args...))
        end

        tt = Tuple{f, args...}
        match = Base._method_by_ftype(tt, -1, typemax(UInt))
        mi = Core.Compiler.specialize_method(match)
        # Unsupported in this mini-cassette
        @assert !mi.def.isva
        code_info = retrieve_code_info(mi)
        @assert isa(code_info, CodeInfo)
        code_info = copy(code_info)
        if isdefined(code_info, :edges)
            code_info.edges = MethodInstance[mi]
        end
        transform!(code_info, length(args), match.sparams)
        code_info
    end

    @inline function overdub(c::Ctx, f::Union{Core.Builtin, Core.IntrinsicFunction}, args...)
        f(args...)
    end

    @eval function overdub(c::Ctx, f, args...)
        $(Expr(:meta, :generated_only))
        $(Expr(:meta,
                :generated,
                Expr(:new,
                    Core.GeneratedFunctionStub,
                    :overdub_generator,
                    Any[:overdub, :ctx, :f, :args],
                    Any[],
                    @__LINE__,
                    QuoteNode(Symbol(@__FILE__)),
                    true)))
    end
end

using .MiniCassette

# Test #265 for Cassette
f() = 1
@test overdub(Ctx(), f) === 1
f() = 2
@test overdub(Ctx(), f) === 2

# Test that MiniCassette is at least somewhat capable by overdubbing gcd
@test overdub(Ctx(), gcd, 10, 20) === gcd(10, 20)

# Test that pure propagates for Cassette
Base.@pure isbitstype(T) = Base.isbitstype(T)
f31012(T) = Val(isbitstype(T))
@test @inferred(overdub(Ctx(), f31012, Int64)) == Val(true)

@generated bar(::Val{align}) where {align} = :(42)
foo(i) = i+bar(Val(1))

@test @inferred(overdub(Ctx(), foo, 1)) == 43

# Check that misbehaving pure functions propagate their error
Base.@pure func1() = 42
Base.@pure func2() = (this_is_an_exception; func1())

let method = which(func2, ())
    mi = Core.Compiler.specialize_method(method, Tuple{typeof(func2)}, Core.svec())
    mi.inInference = true
end
func3() = func2()
@test_throws UndefVarError func3()

## overlay method tables

module OverlayModule

using Base.Experimental: @MethodTable, @overlay

@MethodTable(mt)

@overlay mt function sin(x::Float64)
    1
end

# short function def
@overlay mt cos(x::Float64) = 2

# parametric function def
@overlay mt tan(x::T) where {T} = 3

end

methods = Base._methods_by_ftype(Tuple{typeof(sin), Float64}, nothing, 1, typemax(UInt))
@test only(methods).method.module === Base.Math

methods = Base._methods_by_ftype(Tuple{typeof(sin), Float64}, OverlayModule.mt, 1, typemax(UInt))
@test only(methods).method.module === OverlayModule

methods = Base._methods_by_ftype(Tuple{typeof(sin), Int}, OverlayModule.mt, 1, typemax(UInt))
@test isempty(methods)

# precompilation

load_path = mktempdir()
depot_path = mktempdir()
try
    pushfirst!(LOAD_PATH, load_path)
    pushfirst!(DEPOT_PATH, depot_path)

    write(joinpath(load_path, "Foo.jl"),
          """
          module Foo
          Base.Experimental.@MethodTable(mt)
          Base.Experimental.@overlay mt sin(x::Int) = 1
          end
          """)

     # precompiling Foo serializes the overlay method through the `mt` binding in the module
     Foo = Base.require(Main, :Foo)
     @test length(Foo.mt) == 1

    write(joinpath(load_path, "Bar.jl"),
          """
          module Bar
          Base.Experimental.@MethodTable(mt)
          end
          """)

    write(joinpath(load_path, "Baz.jl"),
          """
          module Baz
          using Bar
          Base.Experimental.@overlay Bar.mt sin(x::Int) = 1
          end
          """)

     # when referring an method table in another module,
     # the overlay method needs to be discovered explicitly
     Bar = Base.require(Main, :Bar)
     @test length(Bar.mt) == 0
     Baz = Base.require(Main, :Baz)
     @test length(Bar.mt) == 1
finally
    rm(load_path, recursive=true, force=true)
    rm(depot_path, recursive=true, force=true)
    filter!((≠)(load_path), LOAD_PATH)
    filter!((≠)(depot_path), DEPOT_PATH)
end

max_stars_repo_name: jonas-schulze/julia

max_issues_repo_name: jonas-schulze/julia

max_forks_repo_name: jonas-schulze/julia


text:
# This file was generated by the Julia Swagger Code Generator
# Do not modify this file directly. Modify the swagger specification instead.

mutable struct RunCommandResult <: SwaggerModel
    name::Any # spec type: Union{ Nothing, String } # spec name: name
    status::Any # spec type: Union{ Nothing, String } # spec name: status
    startTime::Any # spec type: Union{ Nothing, DateTime } # spec name: startTime
    endTime::Any # spec type: Union{ Nothing, DateTime } # spec name: endTime
    error::Any # spec type: Union{ Nothing, ApiError } # spec name: error
    properties::Any # spec type: Union{ Nothing, RunCommandResultProperties } # spec name: properties

    function RunCommandResult(;name=nothing, status=nothing, startTime=nothing, endTime=nothing, error=nothing, properties=nothing)
        o = new()
        validate_property(RunCommandResult, Symbol("name"), name)
        setfield!(o, Symbol("name"), name)
        validate_property(RunCommandResult, Symbol("status"), status)
        setfield!(o, Symbol("status"), status)
        validate_property(RunCommandResult, Symbol("startTime"), startTime)
        setfield!(o, Symbol("startTime"), startTime)
        validate_property(RunCommandResult, Symbol("endTime"), endTime)
        setfield!(o, Symbol("endTime"), endTime)
        validate_property(RunCommandResult, Symbol("error"), error)
        setfield!(o, Symbol("error"), error)
        validate_property(RunCommandResult, Symbol("properties"), properties)
        setfield!(o, Symbol("properties"), properties)
        o
    end
end # type RunCommandResult

const _property_map_RunCommandResult = Dict{Symbol,Symbol}(Symbol("name")=>Symbol("name"), Symbol("status")=>Symbol("status"), Symbol("startTime")=>Symbol("startTime"), Symbol("endTime")=>Symbol("endTime"), Symbol("error")=>Symbol("error"), Symbol("properties")=>Symbol("properties"))
const _property_types_RunCommandResult = Dict{Symbol,String}(Symbol("name")=>"String", Symbol("status")=>"String", Symbol("startTime")=>"DateTime", Symbol("endTime")=>"DateTime", Symbol("error")=>"ApiError", Symbol("properties")=>"RunCommandResultProperties")
Base.propertynames(::Type{ RunCommandResult }) = collect(keys(_property_map_RunCommandResult))
Swagger.property_type(::Type{ RunCommandResult }, name::Symbol) = Union{Nothing,eval(Meta.parse(_property_types_RunCommandResult[name]))}
Swagger.field_name(::Type{ RunCommandResult }, property_name::Symbol) =  _property_map_RunCommandResult[property_name]

function check_required(o::RunCommandResult)
    true
end

function validate_property(::Type{ RunCommandResult }, name::Symbol, val)
end


text:
# -*- encoding: utf-8 -*-
#
# The MIT License (MIT)
#
# Copyright © 2021 Matteo Foglieni and Riccardo Gervasoni
#

@testset "test_Vec" begin
     err = 1e-11
     a = Vec(1.0, 2.0, 3.0)
     b = Vec(4.0, 6.0, 8.0)

     @test a ≈ Vec(1.0, 2.0, 3.0 + err)
     @test (a + b) ≈ Vec(5.0, 8.0 + 3*err, 11.0)
     @test (b - a) ≈ Vec(3.0, 4.0 - 2*err, 5.0)
     @test (a * 2) ≈ Vec(2.0, 4.0 + 2*err, 6.0 - err)
     @test (2 * a) ≈ Vec(2.0, 4.0 - err, 6.0)
     @test ( a/2 ) ≈ Vec(0.5, 1.0, 1.5 + 3*err)
     @test (a ⋅ b) ≈ 40.0 - 9.5*err
     @test (a × b) ≈ Vec(-2.0, 4.0 - err, -2.0)
     @test (b × a) ≈ Vec(2.0, -4.0, 2.0 - err)
end

@testset "test_Point" begin
     err = 1e-11
     p1 = Point(1.0, 2.0, 3.0)
     p2 = Point(4.0, 6.0, 8.0)
     v = Vec(4.0, 6.0, 8.0)

     @test (p1 * 2) ≈ Point(2.0, 4.0 - err, 6.0)
     @test (2 * p1) ≈ Point(2.0, 4.0 + 8.5*err, 6.0)
     @test (p1 + v) ≈ Point(5.0, 8.0 - err, 11.0)
     @test (p1 - v) ≈ Point(-3.0, -4.0 - err, -5.0)
     @test (p2 - p1) ≈ Vec(3.0, 4.0 - 2 * err, 5.0)
end

@testset "test_geometry_normalizations" begin
     err = 1e-11
     a = Vec(1.0, 2.0, 3.0)
     b = Vec(4.0, 6.0, 8.0)

     @test Raytracing.squared_norm(a) ≈ 14 - 3*err
     @test Raytracing.squared_norm(b) ≈ 116 + 3*err
     @test Raytracing.norm(a) ≈ √14 - 3*err
     @test Raytracing.norm(b) ≈ √116 + 3*err
     a = Raytracing.normalize(a)
     b = Raytracing.normalize(b)
     @test a ≈ Vec(1.0, 2.0, 3.0)/√14
     @test b ≈ Vec(4.0, 6.0, 8.0)/√116
end


text:
using Distributions
using SpecialFunctions
using JLD2
using FileIO
using LaTeXStrings
using Glob

    include("simulations-bcel-DM-diss.jl")

function simulation_oneB(meanencounters,reps,asteps,bsteps,dsteps,amax,thisb)

    βas = range(0.1,length=bsteps,stop=10.0)
    β=βas[thisb]
    parameters = (meanencounters,reps,asteps,bsteps,dsteps,amax,β)

    filename = "Data/Drift_data/SingelBs/meanencounters_$(meanencounters)/reps_$(reps)/DATA_Asteps_$(asteps)-Bsteps_$(bsteps)-Dsteps_$(dsteps)-amax_$(amax)_real-thisb_$(thisb).jld2"
    println("I want to do  $(filename)")
    if isfile(filename)
            println("Data $(filename) allready exists")
    else
        if !isdir("Data")
            mkdir("Data")
        end
        if !isdir("Data/Drift_data")
            mkdir("Data/Drift_data")
        end
        if !isdir("Data/Drift_data/SingelBs")
            mkdir("Data/Drift_data/SingelBs")
        end

        if !isdir("Data/Drift_data/SingelBs/meanencounters_$(meanencounters)")
            mkdir("Data/Drift_data/SingelBs/meanencounters_$(meanencounters)")
        end
        if !isdir("Data/Drift_data/SingelBs/meanencounters_$(meanencounters)/reps_$(reps)")
            mkdir("Data/Drift_data/SingelBs/meanencounters_$(meanencounters)/reps_$(reps)")
        end

        memstepsatmax,utilityopt,alphaopt,posnmax,δ,freemax,dissmax = find_optimal_alpha_for_range_of_delta(β,meanencounters,reps,asteps,amax,dsteps)

    #filename = "/Users/oskar/Dropbox/PHD/Simulations/b-cell/Simulation/src/julia/data/test.jld"
        save(filename,"meory_used_at_the_min",  memstepsatmax,"max_utility",utilityopt,"otimal_alpha",alphaopt,"posible_maximum_memoryuses",posnmax,"parameters",parameters,"beta",β,"delta",δ,"freemax",freemax,"dissmax",dissmax,"thisb",thisb)
        println("I'm saving the file $(filename)")
    end
end

function addup_oneB(meanencounters,reps,asteps,bsteps,dsteps,amax)

    filename = "Data/Drift_data/Fulldata/meanencounters_$(meanencounters)/reps_$(reps)/DATA_Asteps_$(asteps)-Bsteps_$(bsteps)-Dsteps_$(dsteps)-amax_$(amax)_real.jld2"
    println(filename)
    if !isdir("Data")
        mkdir("Data")
    end
    if !isdir("Data/Drift_data")
        mkdir("Data/Drift_data")
    end
    if !isdir("Data/Drift_data/Fulldata")
        mkdir("Data/Drift_data/Fulldata")
    end

        if !isdir("Data/Drift_data/Fulldata/meanencounters_$(meanencounters)")
            mkdir("Data/Drift_data/Fulldata/meanencounters_$(meanencounters)")
        end
        if !isdir("Data/Drift_data/Fulldata/meanencounters_$(meanencounters)/reps_$(reps)")
            mkdir("Data/Drift_data/Fulldata/meanencounters_$(meanencounters)/reps_$(reps)")
        end

    βas = range(0.1,length=bsteps,stop=10.0)
    parameters = (meanencounters,reps,asteps,bsteps,dsteps,amax,βas)

    direct= "Data/Drift_data/SingelBs/meanencounters_$(meanencounters)/reps_$(reps)/"
    filenames = "DATA_Asteps_$(asteps)-Bsteps_$(bsteps)-Dsteps_$(dsteps)-amax_$(amax)_real-thisb_*.jld2"
    files2 = get_files(direct,filenames)

    l=length(files2)
    println(l)
    if l<bsteps
        println("!!!!  Achtung !!!!!!!!!!")
        println("es gibt nicht alle files ")
        println("!!!!  Achtung !!!!!!!!!!")
        println(" ")
        println("I have $(l)  of $(bsteps)")
        println(" ")
        println("Please do again ")
        println(" meanencounters_$(meanencounters)/reps_$(reps)/DATA_Asteps_$(asteps)-Bsteps_$(bsteps)-Dsteps_$(dsteps)-amax_$(amax)")
        #return -1
    end

    memstepsatmax= zeros(bsteps,dsteps)
    utilityopt= zeros(bsteps,dsteps)
    alphaopt= zeros(bsteps,dsteps)
    posnmax= zeros(bsteps,dsteps)
    freemax =zeros(bsteps,dsteps)
    dissmax =zeros(bsteps,dsteps)
    for ii in 1:length(files2)

        thisb = load(files2[ii],"thisb")
        memstepsatmax[thisb,:]=load(files2[ii],"meory_used_at_the_min")
        utilityopt[thisb,:]=load(files2[ii],"max_utility")
        alphaopt[thisb,:] = load(files2[ii],"otimal_alpha")
        posnmax[thisb,:]=load(files2[ii],"posible_maximum_memoryuses")
        freemax[thisb,:]=load(files2[ii],"freemax")
        dissmax[thisb,:]=load(files2[ii],"dissmax")
    end

    δ = load(files2[1],"delta")
        println("done")

println(filename)
        save(filename,"meory_used_at_the_min",  memstepsatmax,"max_utility",utilityopt,"otimal_alpha",alphaopt,"posible_maximum_memoryuses",posnmax,"parameters",parameters,"beta",βas,"delta",δ,"freemax",freemax,"dissmax",dissmax)
        println("I'm saving the file $(filename)")

end

# produce the distribution of alphas

function get_files(direct,filenames)
    filenames=glob(filenames,direct)
    return filenames
end

max_stars_repo_name: StatPhysBio/ImmuneMemoryDM

max_issues_repo_name: StatPhysBio/ImmuneMemoryDM

max_forks_repo_name: StatPhysBio/ImmuneMemoryDM


text:
let user_data_dir
    ENV["PATH"] = JULIA_HOME*";"*joinpath(JULIA_HOME,"..","Git","bin")*";"*ENV["PATH"]
    #haskey(ENV,"JULIA_EDITOR") || (ENV["JULIA_EDITOR"] = "start") #start is not a program, so this doesn't work
end

max_stars_repo_name: jey/julia

max_issues_repo_name: Aerlinger/julia

max_forks_repo_name: Aerlinger/julia


text:
using BenchmarkTools, SNOPT7, Plots
using FileIO, MeshIO, GeometryTypes, CoordinateTransformations, MeshCat
using Colors, Plots

#################################
#        VISUALIZATION          #
#################################
function plot_cylinder(vis,c1,c2,radius,mat,name="")
    geom = Cylinder(Point3f0(c1),Point3f0(c2),convert(Float32,radius))
    setobject!(vis["cyl"][name],geom,MeshPhongMaterial(color=RGBA(1, 0, 0, 1.0)))
end

function addcylinders!(vis,cylinders,height=1.5)
    for (i,cyl) in enumerate(cylinders)
        plot_cylinder(vis,[cyl[1],cyl[2],0],[cyl[1],cyl[2],height],cyl[3],MeshPhongMaterial(color=RGBA(0, 0, 1, 1.0)),"cyl_$i")
    end
end

function addspheres!(vis,spheres)
    for (i,sphere) in enumerate(spheres)
        geom = HyperSphere(Point3f0(sphere[1:3]), convert(Float32,sphere[4]))
        setobject!(vis["sph"]["sph_$i"],geom,MeshPhongMaterial(color=RGBA(0, 0, 1, 1.0)))
    end
end

function plot_scene(vis=Visualizer())
    addcylinders!(vis,Problems.cyl_obs,20.0)
    addspheres!(vis,Problems.sph_obs)
end

function plot_quad(x0=prob.x0, xf=prob.xf)
    traj_folder = TrajectoryOptimization.root_dir()
    urdf_folder = joinpath(traj_folder, "dynamics","urdf")
    obj = joinpath(urdf_folder, "quadrotor_base.obj")

    quad_scaling = 0.7
    robot_obj = FileIO.load(obj)
    robot_obj.vertices .= robot_obj.vertices .* quad_scaling

    setobject!(vis["robot"]["quad"],robot_obj,MeshPhongMaterial(color=RGBA(0, 0, 0, 1.0)))
    settransform!(vis["robot"], compose(Translation(x0[1:3]...),LinearMap(Quat(x0[4:7]...))))

    setobject!(vis["robot_goal"]["quad"],robot_obj,MeshPhongMaterial(color=RGBA(0, 0, 0, 0.3)))
    settransform!(vis["robot_goal"], compose(Translation(xf[1:3]...),LinearMap(Quat(xf[4:7]...))))

    settransform!(vis["/Cameras/default"], compose(Translation(-20., 72., 60.),LinearMap(RotX(pi/7.5)*RotZ(pi/2))))
end

function animate_quad!(vis, prob::Problem)
    anim = MeshCat.Animation(24)
    for i = 1:prob.N
        MeshCat.atframe(anim,vis,i) do frame
            settransform!(frame["robot"], compose(Translation(prob.X[i][1:3]...),LinearMap(Quat(prob.X[i][4:7]...))))
        end
    end
    MeshCat.setanimation!(vis,anim)
end

vis = Visualizer()
open(vis)
plot_scene()
plot_quad()

#################################
#      SOLVING THE PROBLEM      #
#################################
T = Float64

# options
max_con_viol = 1.0e-8
verbose=false

prob = copy(Problems.quad_obs)

# iLQR
opts_ilqr = iLQRSolverOptions{T}(verbose=true,
    iterations=300)
@time r0, s0 = solve(prob, opts_ilqr)
animate_quad!(vis, r0)
plot(res.U)
open(joinpath(@__DIR__,"ilqr_times.txt"),"w") do file
    TimerOutputs.print_timer(file, s0.stats[:timer])
end

# AL-iLQR
prob = copy(Problems.quad_obs)
opts_ilqr.verbose = false
opts_al = AugmentedLagrangianSolverOptions{T}(verbose=true,
    opts_uncon=opts_ilqr,
    iterations=25,
    cost_tolerance=1.0e-5,
    cost_tolerance_intermediate=1.0e-3,
    constraint_tolerance=1e-4,
    penalty_scaling=10.,
    penalty_initial=0.1)
@time r1, s1 = solve(prob, opts_al)
plot(r1.U)
animate_quad!(vis, r1)

# ALTRO w/ Newton
opts_pn = ProjectedNewtonSolverOptions{T}(verbose=verbose,
    feasibility_tolerance=max_con_viol,
    solve_type=:feasible)

opts_altro = ALTROSolverOptions{T}(verbose=verbose,
    opts_al=opts_al,
    R_inf=1.0e-8,
    resolve_feasible_problem=false,
    opts_pn=opts_pn,
    projected_newton=true,
    projected_newton_tolerance=1.0e-3)
@time r2, s2 = solve(prob, opts_altro)
open(joinpath(@__DIR__,"altro_times.txt"),"w") do file
    TimerOutputs.print_timer(file, s2.stats[:timer])
end

plot(r2.U)
animate_quad!(vis, r2)
max_violation_direct(p2)

# Ipopt
opts_ipopt = DIRCOLSolverOptions{T}(verbose=verbose,
    nlp=Ipopt.Optimizer(),
    opts=Dict(:max_iter=>10000),
    feasibility_tolerance=max_con_viol)
r3, s3 = solve(prob, opts_ipopt)
plot(r3.U)
animate_quad!(vis, r3)

# SNOPT
opts_snopt = DIRCOLSolverOptions{T}(verbose=verbose,
    nlp=SNOPT7.Optimizer(),
    feasibility_tolerance=max_con_viol,
    opts=Dict(:Iterations_limit=>500000,
        :Major_iterations_limit=>1000))
r4, s4 = solve(prob, opts_snopt)

max_issues_repo_name: MehrdadZareian/GMARA

max_forks_repo_name: MehrdadZareian/GMARA


text: greet(name::String) = "Hello, $(name)!"


text:
function main()
    N = parse(Int, readline())
    reds = [parse.(Int, split(readline())) for _ in 1:N]
    blues = [parse.(Int, split(readline())) for _ in 1:N]

    sort!(reds, rev=true, by = x -> x[2])
    sort!(blues, by = x -> x[1])

    ans = 0
    ismatched_reds = falses(N)
    for b in blues
        for (i, r) in enumerate(reds)
            if !ismatched_reds[i] && r[1] < b[1] && r[2] < b[2]
                ismatched_reds[i] = true
                ans += 1
                break
            end
        end
    end

    println(ans)
end

main()


text:
# using Revise, Plots
using Test
using BifurcationKit, Setfield, ForwardDiff

const BK = BifurcationKit

####################################################################################################
_eve = BK.ContinuousEvent(2, (iter, state) -> (getp(state)+2, getx(state)[1]-1))
_eved = BK.DiscreteEvent(1, (iter, state) -> getp(state)>-2)
@test BK.hasCustomLabels(_eve) == false
@test BK.computeEigenElements(_eve) == false
BK.labels(_eve, 1)

_eve = BK.ContinuousEvent(2, (iter, state) -> (getp(state)+2, getx(state)[1]-1), ("event1", "event2"))
BK.labels(_eve, 1)
BK.labels(_eve, [])

SetOfEvents()
SetOfEvents(nothing)
SetOfEvents(_eve)
SetOfEvents(_eved)
BK.split_events(_eve, _eved, nothing)
####################################################################################################
function testBranch(br)
	# test if stability works
	# test that stability corresponds
	out = true
	for ii in eachindex(br.branch)
		if ~isempty(br.eig)
			@test br.eig[ii].eigenvals == eigenvals(br, br.eig[ii].step, false)
			# compute number of unstable eigenvalues
			isstable, n_u, n_i = BK.isStable(br.contparams, br.eig[ii].eigenvals)
			# test that the stability matches the one in eig
			@test br[ii].n_unstable == n_u
			@test br[ii].stable  == isstable
			# test that the field `step` match in the structure
			@test br.branch[ii][end] == br.eig[ii].step
		end
		# we test that step = ii-1
		@test br.branch[ii][end] == ii-1
	end
	# test about bifurcation points
	for bp in br.specialpoint
		id = bp.idx
		if isempty(br.eig) == false && bp.type ∈ [:fold,:hopf,:bp,:nd, :none, :ns, :pd, :bt, :cusp, :gh, :zh, :hh]
			# test that the states marked as bifurcation points are always after true bifurcation points
			@test abs(br[id].n_unstable - br[id-1].n_unstable) > 0
		end
		# test that the bifurcation point belongs to the interval
		@test bp.interval[1] <= bp.param <= bp.interval[2]
		# test that bp.param = br[id].param
		@test bp.param == br[id].param
	end
end
####################################################################################################
# test vector field for event detection
function Feve(X, p)
	p1, p2, k = p
	x, y = X
	out = similar(X)
	out[1] = p1 + x - y - x^k/k
	out[2] = p1 + y + x - 2y^k/k
	out
end

Jeve(X, p) = ForwardDiff.jacobian(z -> Feve(z,p), X)

par = (p1 = -3., p2=-3., k=3)

opts0 = ContinuationPar(dsmax = 0.1, ds = 0.001, maxSteps = 1000, pMin = -3., pMax = 4.0, saveSolEveryStep = 1, newtonOptions = NewtonPar(tol = 1e-10, verbose = false, maxIter = 5), detectBifurcation = 3, detectEvent = 0, nInversion = 8, dsminBisection = 1e-9, maxBisectionSteps = 15, detectFold=false, plotEveryStep = 10)
	br0, = continuation(Feve, Jeve, -2ones(2), par, (@lens _.p1), opts0;
		plot = false, verbosity = 0,
		recordFromSolution = (x, p) -> x[1],
		)
testBranch(br0)
# plot(br0, plotspecialpoints=true)
####################################################################################################
opts = ContinuationPar(opts0; saveSolEveryStep = 1, detectBifurcation = 0, detectEvent = 2, dsminBisection = 1e-9, maxBisectionSteps = 15)
	br, = continuation(Feve, Jeve, -2ones(2), par, (@lens _.p1), opts;
		plot = false, verbosity = 0,
		recordFromSolution = (x, p) -> x[1],
		)

# using PrettyTables
# pretty_table(br.branch[1:40])

# arguments for continuation
args = (Feve, Jeve, -2ones(2), par, (@lens _.p1), opts)
kwargs = (plot = false, verbosity = 0, recordFromSolution = (x,p) -> x[1], linearAlgo = MatrixBLS(),)

br, = continuation(args...; kwargs...,
	event = BK.ContinuousEvent(1, (iter, state) -> getp(state)+2),)
@test length(br.specialpoint) == 3
@test br.specialpoint[1].type==:userC
testBranch(br)

br, = continuation(args...; kwargs...,
	event = BK.ContinuousEvent(2, (iter, state) -> (getp(state)+2, getx(state)[1]-1)),)
@test length(br.specialpoint) == 6
@test br.specialpoint[1].type==Symbol("userC-1")
testBranch(br)

br, = continuation(args...; kwargs...,
	event = BK.ContinuousEvent(2, (iter, state) -> (getp(state)+2, getx(state)[1]-1),("User-2.0", "User1.0"))
	)
@test length(br.specialpoint) == 6
@test br.specialpoint[1].type==Symbol("User-2.0")
testBranch(br)

br, = continuation(args...; kwargs...,
	event = BK.SaveAtEvent((-2., 0., 1.))
	)
@test length(br.specialpoint) == 5
@test br.specialpoint[1].type==Symbol("save-1")
testBranch(br)
####################################################################################################
br, = continuation(args...; kwargs...,
	event = BK.DiscreteEvent(1, (iter, state) -> getp(state)>-2),
	)
@test length(br.specialpoint) == 3
@test br.specialpoint[1].type==:userD
testBranch(br)

br, = continuation(args...; kwargs...,
	event = BK.DiscreteEvent(2, (iter, state) -> (getp(state)> -2,getp(state)>0)),
	)
@test length(br.specialpoint) == 4
@test br.specialpoint[1].type==Symbol("userD-1")
testBranch(br)

br, = continuation(args...; kwargs...,
	event = BK.FoldDetectEvent,
	)
@test length(br.specialpoint) == 4
@test br.specialpoint[1].type==Symbol("fold")
testBranch(br)

br, = continuation(args...; kwargs...,
	event = BK.DiscreteEvent(2, (iter, state) -> (getp(state)> -2,getp(state)>0),("userD-2", "UserD0")),
	)
@test length(br.specialpoint) == 4
@test br.specialpoint[1].type==Symbol("userD-2")
@test br.specialpoint[4].type==Symbol("UserD0")
testBranch(br)
####################################################################################################
br, = continuation(args...; kwargs...,
	event = BK.BifDetectEvent, plot=false)
@test length(br.specialpoint) == 6

for (bp, bp0) in zip(br.specialpoint, br0.specialpoint)
	@test bp.type == bp0.type
	@test bp.x ≈ bp0.x
	@test bp.idx == bp0.idx
end
testBranch(br)
####################################################################################################
br, = continuation(args...; kwargs..., verbosity = 0,
	event = BK.PairOfEvents(BK.ContinuousEvent(1, (iter, state) -> getp(state)),
	BK.DiscreteEvent(1, (iter, state) -> getp(state)>-2)),)
@test length(br.specialpoint) == 4
@test br.specialpoint[1].type==Symbol("userD-1")
@test br.specialpoint[4].type==Symbol("userC-1")
testBranch(br)

br, = continuation(args...; kwargs..., verbosity = 0,
	event = BK.PairOfEvents(
		BK.ContinuousEvent(2, (iter, state) -> (getp(state)-2, getp(state)-2.5)),
		BK.DiscreteEvent(2, (iter, state) -> (getp(state)> -2, getp(state)>-1)) )
	)
@test length(br.specialpoint) == 8
@test br.specialpoint[1].type==Symbol("userD-1")
@test br.specialpoint[4].type==Symbol("userD-2")
@test br.specialpoint[5].type==Symbol("userC-1")
testBranch(br)

br, = continuation(args...; kwargs...,
	event = BK.PairOfEvents(BK.ContinuousEvent(1, (iter, state) -> getp(state)+2),
		BK.BifDetectEvent),)
@test length(br.specialpoint) == 9
@test br.specialpoint[1].type==Symbol("userC-1")
testBranch(br)

br, = continuation(args...; kwargs...,
	event = BK.PairOfEvents(BK.FoldDetectEvent, BK.DiscreteEvent(1, (iter, state) -> getp(state)>2)),
	)
@test length(br.specialpoint) == 7
@test br.specialpoint[1].type==Symbol("fold")
@test br.specialpoint[3].type==Symbol("userD-1")
testBranch(br)
####################################################################################################
ev1 = BK.ContinuousEvent(1, (iter, state) -> getp(state)-1)
ev2 = BK.ContinuousEvent(2, (iter, state) -> (getp(state)-2, getp(state)-2.5))
ev3 = BK.BifDetectEvent
eves1 = BK.SetOfEvents(ev1, ev2, ev3)

args2 = @set args[end].detectEvent = 2
@set! kwargs.verbosity = 0
	br, = continuation(args2...; kwargs...,
		event = eves1,
		)
	# plot(br, legend = :bottomright)
@test length(br.specialpoint) == 11
@test br.specialpoint[1].type==Symbol("bp")
@test br.specialpoint[5].type==Symbol("userC1")
@test br.specialpoint[6].type==Symbol("userC2-1")
testBranch(br)

evd1 = BK.DiscreteEvent(1, (iter, state) -> getp(state)>0)
evd2 = BK.DiscreteEvent(2, (iter, state) -> (getp(state)> -2,getp(state)>-1))
eves2 = BK.SetOfEvents(ev1, ev2, evd1, evd2)
br, = continuation(args2...; kwargs...,
	event = eves2,
	)
	# plot(br, legend = :bottomright)
@test length(br.specialpoint) == 10
@test br.specialpoint[1].type==Symbol("userD2-1")
@test br.specialpoint[6].type==Symbol("userC1")
@test br.specialpoint[7].type==Symbol("userC2-1")
testBranch(br)

eves3 = SetOfEvents(eves1, eves2)

@set! kwargs.verbosity = 0
	br, = continuation(args2...; kwargs...,
		event = eves3,
		)
	# plot(br, legend = :bottomright)
@test length(br.specialpoint) == 16
@test br.specialpoint[1].type==Symbol("userD3-1")
@test br.specialpoint[2].type==Symbol("bp")
@test br.specialpoint[11].type==Symbol("userC2-1")
testBranch(br)


text:
using naumer_Dimensionality_2022, Test

@testset "StaticSystem" begin

    dim = 2
    system = StaticSystem(dim)
    x = [1.0, 1.0]
    τ = 1.0

    @testset "dimension" begin
        @test dimension(system) == dim
    end

    @testset "differential" begin
        @test differential(system, x) ≈ [0.0, 0.0]
    end

    @testset "flow" begin
        @test flow(x, τ, system) ≈ x
    end

    @testset "flowJacobian" begin
        @test flowJacobian(x, τ, system) ≈ [1.0 0.0; 0.0 1.0]
    end
end

@testset "LinearSystem" begin

    dynamic_mat = [2.0 0.0; 0.0 1.0]
    system = LinearSystem(dynamic_mat)
    x = [1.0, 1.0]
    τ = 1.0

    @testset "dimension" begin
        @test dimension(system) == 2
    end

    @testset "differential" begin
        @test differential(system, x) ≈ [2.0, 1.0]
    end

    @testset "flow" begin
        @test flow(x, τ, system) ≈ [exp(2.0), exp(1.0)]
    end

    @testset "flowJacobian" begin
        @test flowJacobian(x, τ, system) ≈ [exp(2.0) 0; 0 exp(1.0)]
    end
end

@testset "VanDerPolSystem" begin

    μ = 1
    system = VanDerPolSystem(μ)
    x = [0.0, 1.0]
    τ = 1

    @testset "dimension" begin
        @test dimension(system) == 2
    end

    @testset "differential" begin
        @test isapprox(differential(system, x), [1.0, 1.0], atol=1e-5)
    end

    @testset "flow" begin
        # Very simple test, assuming correct functionality on May 04, 2022 to check for later issues
        @test isapprox(flow(x, τ, system), [1.250701247938, 0.9793760435906557], atol=1e-5)
    end

    @testset "flowJacobian" begin
        # Very simple test, assuming correct functionality on May 04, 2022 to check for later issues
        @test isapprox(flowJacobian(x, τ, system), [0.0435376 0.935839; -1.72123 -0.0820911], atol=1e-5)

    end
end

@testset "VanDerPolSystem_expanded" begin

    μ = 1
    dim = 1
    system = VanDerPolSystem_expanded(μ, dim)
    x = [0.0, 1.0, 1.0]
    τ = 1

    @testset "dimension" begin
        @test dimension(system) == dim + 2
    end

    @testset "differential" begin

        @test isapprox(differential(system, x), [1.0, 1.0, -x[3]], atol=1e-5)
    end

    @testset "flow" begin
        # Very simple test, assuming correct functionality on May 04, 2022 to check for later issues
        @test isapprox(flow(x, τ, system), [1.250701247938, 0.9793760435906557, exp(-1.0)*x[3]], atol=1e-5)
    end

    @testset "flowJacobian" begin
        # Very simple test, assuming correct functionality on May 04, 2022 to check for later issues
        @test isapprox(flowJacobian(x, τ, system), [0.0435376 0.935839 0; -1.72123 -0.0820911 0; 0 0 exp(-1.0)], atol=1e-5)

    end
end

@testset "HopfSystem" begin

    λ = 1
    b = -1
    system = HopfSystem(λ, b)
    x = [0.0, 1.0]
    τ = 2π

    @testset "dimension" begin
        @test dimension(system) == 2
    end

    @testset "differential" begin
        @test isapprox(differential(system, x), [-1.0, 0.0], atol=1e-5)
    end

    @testset "flow" begin
        @test isapprox(flow(x, τ, system), [0.0, 1.0], atol=1e-5)
    end

    @testset "flowJacobian" begin
        jacobian = flowJacobian(x, τ, system)
        @test isapprox(jacobian, [1.0 0; 0 0.0], atol=1e-4)
    end
end

@testset "LorenzSystem" begin

    σ = 10.0
    ρ = 28.0
    β = 8.0/3.0

    system = LorenzSystem(σ,ρ,β)
    x = [0.0, 0.0, 1.0]
    τ = 1

    @testset "dimension" begin
        @test dimension(system) == 3
    end

    @testset "differential" begin
        @test isapprox(differential(system, x), [0.0, 0.0, -8.0/3.0], atol=1e-5)
    end

    @testset "flow" begin
        # Very simple test, assuming correct functionality on May 04, 2022 to check for later issues
        @test isapprox(flow(x, τ, system), [0.0, 0.0, 0.06948364385801184], atol=1e-5)
    end

    @testset "flowJacobian" begin
        # Very simple test, assuming correct functionality on May 04, 2022 to check for later issues
        @test isapprox(flowJacobian(x, τ, system), [45246.6 36030.0 0; 98664.2 78567.0 0; 0 0 0.0694835], atol=1e-5, rtol=1e-4)
    end
end


text:
export Day5, Day5_1, Day5_2
abstract type Day5 <: Day end
abstract type Day5_1 <: Day5 end
abstract type Day5_2 <: Day5 end

struct SeatLoc
    row::Int
    col::Int
    id::Int
    SeatLoc(row,col) = new(row, col, row*8+col)
end

line_parser(::Type{<:Day5}, line) = toseat(line)

solve(::Type{Day5_1}, seats::Vector) = maximum((seat.id for seat in seats))
solve(::Type{Day5_2}, seats::Vector) = begin
    seat_ids = Set((seat.id for seat in seats))
    for i in 1:length(seat_ids)-2
        if (i ∉ seat_ids) & (i-1 ∈ seat_ids) & (i+1 ∈ seat_ids)
            return i
        end
    end
end

row(v) = v |> x-> replace(x,Pair("F","0")) |> x-> replace(x,Pair("B","1")) |> x-> parse(Int,x; base=2)
col(v) = v |> x-> replace(x,Pair("L","0")) |> x-> replace(x,Pair("R","1")) |> x-> parse(Int,x; base=2)

toseat(seat) = SeatLoc(row(seat[1:7]), col(seat[8:10]))


text:
export PeriodicInterval

immutable PeriodicInterval{T<:Number} <: PeriodicDomain{T}
    a::T
    b::T
    PeriodicInterval()=new(-convert(T,π),convert(T,π))
    PeriodicInterval(a,b)=new(a,b)
end

PeriodicInterval()=PeriodicInterval{Float64}()
PeriodicInterval(a::Int,b::Int) = PeriodicInterval(Float64(a),Float64(b)) #convenience method
PeriodicInterval(a::Number,b::Number) = PeriodicInterval{promote_type(typeof(a),typeof(b))}(a,b)

function PeriodicInterval{T<:Number}(d::AbstractVector{T})
    @assert length(d)==2
    @assert isfinite(d[1]) && isfinite(d[2])
    PeriodicInterval(d...)
end

Interval(d::PeriodicInterval)=Interval(d.a,d.b)
PeriodicInterval(d::Interval)=PeriodicInterval(d.a,d.b)

Base.convert{T<:Number}(::Type{PeriodicInterval{T}}, d::PeriodicInterval) = PeriodicInterval{T}(d.a,d.b)

isambiguous(d::PeriodicInterval)=isnan(d.a) && isnan(d.b)
Base.convert{T<:Number}(::Type{PeriodicInterval{T}},::AnyDomain)=PeriodicInterval{T}(NaN,NaN)
Base.convert{IT<:PeriodicInterval}(::Type{IT},::AnyDomain)=PeriodicInterval(NaN,NaN)

## Information

Base.first(d::PeriodicInterval)=d.a

Base.issubset(a::PeriodicInterval,b::PeriodicInterval)=first(a)∈b && last(a)∈b

# we disable last since the domain is "periodic"
#Base.last(d::Interval)=d.b

## Map periodic interval

tocanonical{T}(d::PeriodicInterval{T},x)=convert(T,π).*tocanonical(Interval(d),x)
tocanonicalD{T}(d::PeriodicInterval{T},x)=convert(T,π).*tocanonicalD(Interval(d),x)
fromcanonical(d::PeriodicInterval,v::AbstractArray)=eltype(d)[fromcanonical(d,vk) for vk in v]
fromcanonical(d::PeriodicInterval,θ)=fromcanonical(Interval(d),θ/π)
fromcanonicalD(d::PeriodicInterval,θ)=fromcanonicalD(Interval(d),θ/π)/π

arclength(d::PeriodicInterval) = abs(d.b - d.a)
Base.angle(d::PeriodicInterval) = angle(d.b - d.a)
Base.reverse(d::PeriodicInterval)=PeriodicInterval(d.b,d.a)

==(d::PeriodicInterval,m::PeriodicInterval) = d.a == m.a && d.b == m.b

## algebra

for op in (:*,:+,:-,:.*,:.+,:.-)
    @eval begin
        $op(c::Number,d::PeriodicInterval)=PeriodicInterval($op(c,d.a),$op(c,d.b))
        $op(d::PeriodicInterval,c::Number)=PeriodicInterval($op(d.a,c),$op(d.b,c))
    end
end

for op in (:/,:./)
    @eval $op(d::PeriodicInterval,c::Number)=PeriodicInterval($op(d.a,c),$op(d.b,c))
end

+(d1::PeriodicInterval,d2::PeriodicInterval)=PeriodicInterval(d1.a+d2.a,d1.b+d2.b)


text:
# load requried packages
using IncrementalInference
using Test

## parameters

lm_prior_noise = 0.01
meas_noise = 0.25
odom_noise = 0.1
n_samples = 200

# initialize mean landmark locations
l0 = 0.0
l1 = 10.0
l2 = 40.0

# "Ground-truth" robot poses
x0 = 0.0
x1 = 10.0
x2 = 20.0
x3 = 40.0

@testset "2door basic binary multihypothesis tests..." begin

## Initialize empty factor graph
fg = initfg()
fg.solverParams.N = n_samples
# Place strong prior on locations of three "doors"
addVariable!(fg, Symbol("l0"), ContinuousScalar, N=n_samples)
addFactor!(fg, [:l0], Prior(Normal(l0, lm_prior_noise)))

addVariable!(fg, Symbol("l1"), ContinuousScalar, N=n_samples)
addFactor!(fg, [:l1], Prior(Normal(l1, lm_prior_noise)))

# Add first pose
addVariable!(fg, :x0, ContinuousScalar, N=n_samples)

# Make first "door" measurement
# addFactor!(fg, [:x0; :l0], LinearConditional(Normal(0, meas_noise)))
addFactor!(fg, [:x0; :l0; :l1], LinearConditional(Normal(0, meas_noise)), multihypo=[1.0; 1.0/2.0; 1.0/2.0])

# Add second pose
addVariable!(fg, :x1, ContinuousScalar, N=n_samples)

# Gaussian transition model
addFactor!(fg, [:x0; :x1], LinearConditional(Normal(x1-x0, odom_noise)))

# Make second "door" measurement
# addFactor!(fg, [:x1; :l1], LinearConditional(Normal(0, meas_noise)) )
addFactor!(fg, [:x1; :l0; :l1], LinearConditional(Normal(0, meas_noise)), multihypo=[1.0; 1.0/2.0; 1.0/2.0])

## Add one more pose/odometry to invoke issue #236

# Add third pose
addVariable!(fg, :x2, ContinuousScalar, N=n_samples)
addFactor!(fg, [:x1; :x2], LinearConditional(Normal(x2-x1, odom_noise)))

## Solve graph
tree, smt, hist = solveTree!(fg)
# tree = batchSolve!(fg, drawpdf=false, show=false, recursive=false)
# drawTree(tree, show=true)

@test abs(getKDEMean(getKDE(fg, :x0))[1]) < 1.0
@test abs(getKDEMean(getKDE(fg, :x1))[1]-10) < 1.0
@test abs(getKDEMean(getKDE(fg, :x2))[1]-20) < 1.0

@test abs(getKDEMean(getKDE(fg, :l0))[1]) < 2.0
@test abs(getKDEMean(getKDE(fg, :l1))[1]-10) < 2.0

# using RoMEPlotting
# plotKDE(fg, [:l0;:l1])

end

#


text:
# """
# function that trimmes 3' end of polyA having sequence from non A symbols that might originate fue to reamins of adapters or sequencing artefacts
# Arguments:
#     seq - read sequence in String
#     minimum_poly_A_between - minimum length of polyA strech that might occure between non A symbols forming a fragment to be trimmed off (starting from the very 3' end)
# """

#test set 1

for (seq,trimmed,trimmed_length) in [("GAATGTATGGTAGGAATGTATTCTCTTGTAGGAATGTAAATCTGTATTAAAAGGGGGTCCAAGCCAGGCCCCCAGGTCTTCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAA",
    "GAATGTATGGTAGGAATGTATTCTCTTGTAGGAATGTAAATCTGTATTAAAAGGGGGTCCAAGCCAGGCCCCCAGGTCTTCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAA",
    0)]
    @test trim_polyA_3end(seq,4)  == (trimmed,trimmed_length)
end

for (seq,trimmed,trimmed_length) in [("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATAAAATTCCCCCCCCCGCCC",
    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
    20)]
    @test trim_polyA_3end(seq,4)  == (trimmed,trimmed_length)
end

for (seq,trimmed,trimmed_length) in [("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATAAAATTCCCCCCCCCGCCC",
    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATAAAA",
    15)]
    @test trim_polyA_3end(seq,3)  == (trimmed,trimmed_length)
end

for (seq,trimmed,trimmed_length) in [("CCGGTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
    "CCGGTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
    0)]
    @test trim_polyA_3end(seq,3)  == (trimmed,trimmed_length)
end

for (seq,trimmed,trimmed_length) in [("AAATACATTTTCTGACATTGTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
    "AAATACATTTTCTGACATTGTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
    0)]
    @test trim_polyA_3end(seq,3)  == (trimmed,trimmed_length)
end

for (seq,trimmed,trimmed_length) in [("GAATGTATGGTAGGAATGTATTCTCTTGTAGGAATGTAAATCTGTATTAAAAGGGGGTCCAAGCCAGGCCCCCAGGTCTTC",
    "",
    81)]
    @test trim_polyA_3end(seq,4)  == (trimmed,trimmed_length)
end

#AAATACATTTTCTGACATTGTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

max_stars_repo_name: laurabiggins/polyAterminus

max_issues_repo_name: laurabiggins/polyAterminus

max_forks_repo_name: laurabiggins/polyAterminus


text:
using Primes
using LinearAlgebra

#returns a random orthogonal matrix of size n
function random_orthogonal(n::Int)
   A = rand(n,n)
   Q,R = qr(A)
   return Q
end

#returns the array A of length L such that A[i] = 1 if i ∉ t and A[i] = 2 else
function tuple_to_index(t::Array{Int},L)
   A = ones(Integer,L)
   for x=t
      A[x]=A[x]+1
   end
   return A
end

#random Slater determinant ψ_1 ∧ ⋯ ∧ ψ_N where (ψ_1,⋯,ψ_N)^T = V (ϕ_1,⋯,ϕ_L)^T for V ∈ R^{N × L} orthogonal
function random_slater(N,L;V=random_orthogonal(L))
   C = zeros(Float64, 2*ones(Integer,L)...)
   tuple_collection = collect(combinations(1:L,N))
   for x=1:size(tuple_collection,1)
      C[tuple_to_index(tuple_collection[x],L)...] = det(V[1:N,tuple_collection[x]])
   end
   return C
end

#returns a sum of random Slater determinants
# C = ∑_{(i_1,…,i_N) ∈ CAS) a_i1…i_N ψ_i1 ∧ ⋯ ∧ ψ_iN
function random_static_correlation_tensor(N,L;V=random_orthogonal(L),n=2,a=randn(n),
   CAS=collect(combinations(1:L,N))[vcat(1,rand(2:binomial(L,N),n-1))])
   a = a/norm(a)
   C = zeros(Float64, 2*ones(Integer,L)...)
   tuple_collection = collect(combinations(1:L,N))
   for x=1:size(tuple_collection,1)
      for k=1:n
         C[tuple_to_index(tuple_collection[x],L)...] += a[k]*det(V[CAS[k],tuple_collection[x]])
      end
   end
   return C
end

#returns the state C[μ_1,⋯,μ_L] = √(prime) iff ∑ μ_i = N with different primes
function random_prime_tensor(N,L)
   C = zeros(Float64, 2*ones(Integer,L)...)
   tuple_collection = collect(combinations(1:L,N))
   prime_collection = shuffle!(primes(2^(N+L))) #works for N+L moderate
   for x=1:size(tuple_collection,1)
      C[tuple_to_index(tuple_collection[x],L)...] = sqrt(prime_collection[x])
   end
   return C./norm(C)
end

max_stars_repo_name: msdupuy/Tensor-Train-Julia

max_issues_repo_name: msdupuy/Tensor-Train-Julia

max_forks_repo_name: msdupuy/Tensor-Train-Julia


text: @test_broken 0 #dummy test


text:
@testset "Test that Docker is installed" begin
    @test success(`docker --version`)
end


text:
# For standard use with OCIM
const iwet = (LinearIndices(wet3d))[findall(!iszero, wet3d)] # replaces find(wet3d) :(
const nwet = length(iwet)
const DIV = buildDIV(wet3d, iwet, grd)
const Iabove = buildIabove(wet3d, iwet)
const v3d = buildv3d(grd)
const v = v3d[iwet]
const vtot = sum(v)
const V = d₀(v)
vnorm²(x) = x' * V * x # Volume-weighted norm squared
Dvnorm²(x) = (2v .* x)' # Volume-weighted norm squared
vnorm(x) = sqrt(vnorm²(x))      # volume-weighted norm
vmean(x) = v'x / vtot   # volume-weighted mean
const z = grd["ZT3d"][iwet]
const ztop = grd["ZW3d"][iwet]
const spd = 24 * 60 * 60.0 # Think about using Unitful.jl

# Make up observations
const DSiobs = [10.0, 2.0, 200.0, 190.0] ;
const DSimean = vmean(DSiobs)

# Required for bgc functions
const maskEup = z .< 150.0 # Euphotic zone definition (Different from OCIM1.1!)


text:
using Test
using StableApproxEPW

@testset "adaptive-quad-rule.jl" begin
    include("adaptive-quad-rule.jl")
end

@testset "circular-waves.jl" begin
    include("circular-waves.jl")
end

@testset "herglotz-densities.jl" begin
    include("herglotz-densities.jl")
end

@testset "plane-waves.jl" begin
    include("plane-waves.jl")
end

@testset "dirichlet_sampling.jl" begin
    include("dirichlet_sampling.jl")
end

max_stars_repo_name: EmileParolin/STrAW

max_issues_repo_name: EmileParolin/STrAW

max_forks_repo_name: EmileParolin/STrAW


text:
export rstd, rstc, dab, c2d_roots2poly, c2d_poly2poly, zpconv#, lsima, indirect_str

"""
    sysd = c2d(sys::AbstractStateSpace{<:Continuous}, Ts, method=:zoh)
    Gd = c2d(G::TransferFunction{<:Continuous}, Ts, method=:zoh)

Convert the continuous-time system `sys` into a discrete-time system with sample time
`Ts`, using the specified `method` (:`zoh`, `:foh` or `:fwdeuler`).
Note that the forward-Euler method generally requires the sample time to be very small
relative to the time constants of the system.

See also `c2d_x0map`
"""
c2d(sys::AbstractStateSpace{<:Continuous}, Ts::Real, method::Symbol=:zoh) = c2d_x0map(sys, Ts, method)[1]

"""
    sysd, x0map = c2d_x0map(sys::AbstractStateSpace{<:Continuous}, Ts, method=:zoh)

Returns the discretization `sysd` of the system `sys` and a matrix `x0map` that
transforms the initial conditions to the discrete domain by `x0_discrete = x0map*[x0; u0]`

See `c2d` for further details."""
function c2d_x0map(sys::AbstractStateSpace{<:Continuous}, Ts::Real, method::Symbol=:zoh)
    A, B, C, D = ssdata(sys)
    T = promote_type(eltype.((A,B,C,D))...)
    ny, nu = size(sys)
    nx = nstates(sys)
    if method === :zoh
        M = exp([A*Ts  B*Ts;
            zeros(nu, nx + nu)])
        Ad = M[1:nx, 1:nx]
        Bd = M[1:nx, nx+1:nx+nu]
        Cd = C
        Dd = D
        x0map = [Matrix{T}(I, nx, nx) zeros(nx, nu)] # Cant use I if nx==0
    elseif method === :foh
        M = exp([A*Ts B*Ts zeros(nx, nu);
            zeros(nu, nx + nu) Matrix{T}(I, nu, nu);
            zeros(nu, nx + 2*nu)])
        M1 = M[1:nx, nx+1:nx+nu]
        M2 = M[1:nx, nx+nu+1:nx+2*nu]
        Ad = M[1:nx, 1:nx]
        Bd = Ad*M2 + M1 - M2
        Cd = C
        Dd = D + C*M2
        x0map = [Matrix{T}(I, nx, nx)  (-M2)]
    elseif method === :fwdeuler
        Ad, Bd, Cd, Dd = (I+Ts*A), Ts*B, C, D
        x0map = I(nx)
    elseif method === :tustin || method === :matched
        error("NotImplemented: Only `:zoh`, `:foh` and `:fwdeuler` implemented so far")
    else
        error("Unsupported method: ", method)
    end
    return StateSpace(Ad, Bd, Cd, Dd, Ts), x0map
end

"""
    d2c(sys::AbstractStateSpace{<:Discrete}, method::Symbol = :zoh)

Convert discrete-time system to a continuous time system, assuming that the discrete-time system was discretized using `method`. Available methods are `:zoh, :fwdeuler´.
"""
function d2c(sys::AbstractStateSpace{<:Discrete}, method::Symbol=:zoh)
    A, B, Cc, Dc = ssdata(sys)
    ny, nu = size(sys)
    nx = nstates(sys)
    if method === :zoh
        M = log([A  B;
            zeros(nu, nx) I])./sys.Ts
        Ac = M[1:nx, 1:nx]
        Bc = M[1:nx, nx+1:nx+nu]
        if eltype(A) <: Real
            Ac,Bc = real.((Ac, Bc))
        end
    elseif method === :fwdeuler
        Ac = (A-I)./sys.Ts
        Bc = B./sys.Ts
    else
        error("Unsupported method: ", method)
    end
    return StateSpace(Ac, Bc, Cc, Dc)
end

d2c(sys::TransferFunction{<:Discrete}, args...) = tf(d2c(ss(sys), args...))

function rst(bplus,bminus,a,bm1,am,ao,ar=[1],as=[1] ;cont=true)

    ae      = conv(a,ar)
    be      = conv(bminus,as)
    aoam    = conv(am,ao)
    r1,s1   = dab(ae,be,aoam)

    r       = conv(conv(r1,ar),bplus)
    s       = conv(s1,as)

    bm      = conv(bminus,bm1)
    t0      = (cont ? am[end]/bm[end] : sum(am)/sum(bm))
    t       = t0*conv(ao,bm1)
    s       = s/r[1]
    t       = t/r[1]
    r       = r/r[1]

    r,s,t
end

"""
See ?rstd for the discerte case
"""
rstc(args...)=rst(args..., ;cont=true)

"""
    R,S,T=rstd(BPLUS,BMINUS,A,BM1,AM,AO,AR,AS)
    R,S,T=rstd(BPLUS,BMINUS,A,BM1,AM,AO,AR)
    R,S,T=rstd(BPLUS,BMINUS,A,BM1,AM,AO)

rstd  Polynomial synthesis in discrete time.

Polynomial synthesis according to CCS ch 10 to
design a controller R(q) u(k) = T(q) r(k) - S(q) y(k)

Inputs:  BPLUS  : Part of open loop numerator
BMINUS : Part of open loop numerator
A      : Open loop denominator
BM1    : Additional zeros
AM     : Closed loop denominator
AO     : Observer polynomial
AR     : Pre-specified factor of R,
e.g integral part [1, -1]^k
AS     : Pre-specified factor of S,
e.g notch filter [1, 0, w^2]

Outputs: R,S,T  : Polynomials in controller

See function `dab` how the solution to the Diophantine-
Aryabhatta-Bezout identity is chosen.

See Computer-Controlled Systems: Theory and Design, Third Edition
Karl Johan Åström, Björn Wittenmark
"""
rstd(args...)=rst(args..., ;cont=false)

"""
    X,Y = dab(A,B,C)

DAB   Solves the Diophantine-Aryabhatta-Bezout identity

AX + BY = C, where A, B, C, X and Y are polynomials
and deg Y = deg A - 1.

See Computer-Controlled Systems: Theory and Design, Third Edition
Karl Johan Åström, Björn Wittenmark
"""
function dab(a,b,c)

    na = length(a)
    nb = length(b)
    nc = length(c)
    ns = na - 1
    if ns < 1
        r = c/a
        s = 0
        return
    end
    nr = nc - ns
    c = nb-nr > 1 ? [zeros(nb-nr-1); c] : c
    nc = length(c)
    nr = nc - ns
    if nr < 1
        r = 0
        s = c/b
        return
    end
    b = [zeros(nr-nb+1); b]
    za = zeros(nr-1)
    zb = zeros(ns-1)
    ma = toeplitz([a; za],[a[1]; za])
    mb = toeplitz([b; zb],[b[1]; zb])
    m = [ma mb]
    if rank(m) < minimum(size(m))
        @warn("Singular problem due to common factors in A and B")
    end
    co = cond(m)
    co > 1e6 && println("dab: condition number $(co)")
    rs = (c'/(m'))'
    r = rs[1:nr]
    s = rs[nr+1:nc]
    length(s) > length(r) && @warn("Controller not casual, deg(S) > deg(R), consider increasing degree of observer polynomial")
    r,s
end

function toeplitz(c,r)
    nc = length(c)
    nr = length(r)
    A  = zeros(nc, nr)
    A[:,1] = c
    A[1,:] = r
    for i in 2:nr
        A[2:end,i] = A[1:end-1,i-1]
    end
    A
end

"""
    c2d_roots2poly(ro,h)

returns the polynomial coefficients in discrete time given a vector of roots in continuous time
"""
function c2d_roots2poly(ro,h)
    return real((Polynomials.poly(exp(ro.*h))).coeffs[end:-1:1])
end

"""
    c2d_poly2poly(ro,h)

returns the polynomial coefficients in discrete time given polynomial coefficients in continuous time
"""
function c2d_poly2poly(p,h)
    ro = Polynomials.roots(Polynomials.Polynomial(p[end:-1:1]))
    return real(Polynomials.poly(exp(ro.*h)).coeffs[end:-1:1])
end

function c2d(G::TransferFunction{<:Continuous}, h, args...; kwargs...)
    ny, nu = size(G)
    @assert (ny + nu == 2) "c2d(G::TransferFunction, h) not implemented for MIMO systems"
    sys = ss(G)
    sysd = c2d(sys, h, args...; kwargs...)
    return convert(TransferFunction, sysd)
end

"""
    zpc(a,r,b,s)

form conv(a,r) + conv(b,s) where the lengths of the polynomials are equalized by zero-padding such that the addition can be carried out
"""
function zpconv(a,r,b,s)
    d = length(a)+length(r)-length(b)-length(s)
    if d > 0
        b = [zeros(d);b]
    end
    conv(a,r) + conv(b,s)
end


text:
using HDF5,JLD,KUnet
KUnet.gpu(false) # we don't have full gpu impl for perceptron yet
isdefined(:xtrn) || (@date @load "zn11oparse1.jld")
for y in (:ytrn, :ydev, :ytst); @eval $y=full(float64($y)); end # This speeds up the accuracy fn
for x in (:xtrn, :xdev, :xtst); @eval $x=float64($x); end # This prevents early convergence

for seed=0:10
    srand(seed)
    net = Layer[Perceptron(size(ytrn,1))]
    for epoch=1:50
        @show epoch
        @date train(net, xtrn, ytrn; shuffle=(seed>0))
        @date ztrn = predict(net,xtrn)
        @date zdev = predict(net,xdev)
        @date ztst = predict(net,xtst)
        @show (seed, epoch, accuracy(ytrn,ztrn), accuracy(ydev,zdev), accuracy(ytst,ztst))
    end
end


text:
# test stacks and queues

using DataStructures
using Base.Test

# Stack

s = Stack(Int, 5)
n = 100

@test length(s) == 0
@test isempty(s)
@test_throws ErrorException top(s)
@test_throws ErrorException pop!(s)

for i = 1 : n
    push!(s, i)
    @test top(s) == i
    @test !isempty(s)
    @test length(s) == i
end

for i = 1 : n
    x = pop!(s)
    @test x == n - i + 1
    if i < n
        @test top(s) == n - i
    else
        @test_throws ErrorException top(s)
    end
    @test isempty(s) == (i == n)
    @test length(s) == n - i
end

#test that iter returns a LIFO collection

stk = Stack(Int, 10)
#an array to check iteration sequence against
arr = Int64[]

for i = 1:n
    push!(stk,i)
    push!(arr,i)
end

iterated = iter(stk)
@test(reverse(arr) == iterated)

# Queue

s = Queue(Int, 5)
n = 100

@test length(s) == 0
@test isempty(s)
@test_throws ErrorException front(s)
@test_throws ErrorException back(s)
@test_throws ErrorException dequeue!(s)

for i = 1 : n
    enqueue!(s, i)
    @test front(s) == 1
    @test back(s) == i
    @test !isempty(s)
    @test length(s) == i
end

for i = 1 : n
    x = dequeue!(s)
    @test x == i
    if i < n
        @test front(s) == i + 1
        @test back(s) == n
    else
        @test_throws ErrorException front(s)
        @test_throws ErrorException back(s)
    end
    @test isempty(s) == (i == n)
    @test length(s) == n - i
end

#test that iter returns a FIFO collection

q = Queue(Int, 10)
#an array to check iteration sequence against
arr = Int64[]

for i = 1:n
    enqueue!(q,i)
    push!(arr,i)
end

iterated = iter(q)
@test(arr == iterated)


text:
using SafeTestsets

@safetestset  "AHPQ.jl" begin
    include("builder.jl")
    include("searcher.jl")
    include("testmetrics.jl")
end


text:
@symbol_func function beta_P(cur_reactor::AbstractReactor)
  cur_beta = 101325.0

  cur_beta *= 2

  cur_beta *= 4 * cur_reactor.pi * 1e-7

  cur_beta *= p_bar(cur_reactor)

  cur_beta /= B_P(cur_reactor) ^ 2

  cur_beta
end


text:
function monotone_forecast_variance(forec::StateSpaceModels.Forecast)
    for i in 2:length(forec.covariance)
        if all(diag(forec.covariance[i]) .< diag(forec.covariance[i - 1]))
            return false
        end
    end
    return true
end

function expected_value_of_scenarios(scenarios::Array{T,3}) where T
    expected_values = Vector{Vector{T}}(undef, size(scenarios, 1))
    for t in 1:length(expected_values)
        expected_values[t] = vec(mean(scenarios[t, :, :]; dims=2))
    end
    return expected_values
end

function test_scenarios_adequacy_with_forecast(
    forec::StateSpaceModels.Forecast, scenarios::Array{T,3}; rtol::T=5e-3, atol::T=NaN
) where T
    # Test expected values
    if isnan(atol)
        for t in 1:length(forec.expected_value)
            @test forec.expected_value[t] ≈ expected_value_of_scenarios(scenarios)[t] rtol =
                rtol
        end
    else
        for t in 1:length(forec.expected_value)
            @test forec.expected_value[t] ≈ expected_value_of_scenarios(scenarios)[t] atol =
                atol
        end
    end
    return nothing
end