tommy

tommy

If expression in a cond - SyntaxError: unexpected token: ). The “do” at line 77 is missing terminator “end”

I created a small scripts that takes a lottery number of length x and loops until it finds a match. I created it just for learning purposes and out of curiosity of how many loops are needed to find a match.

At the moment it prints the number of loops to the terminal but I would prefer if it only printed every 5000 or so tries.

I put an if expression that checks the see if loop_num / 5000 ends in 0, in the cond for each non match but I get the following error:

"elixir elixirPlay.exs
** (SyntaxError) elixirPlay.exs:83: unexpected token: ). The “do” at line 77 is missing terminator “end”

HINT: it looks like the "do" on line 1 does not have a matching "end"

(elixir) lib/code.ex:813: Code.require_file/2

"

If I comment out the if it works again. Are if expressions allowed in conds? What’s the solution?

Any other other critiques on the code?

defmodule Play do

def random_numbered_balls num do
    (for _x <- 1..num, do: Enum.random 1..49) |> List.to_tuple
end


def loto(true), do: IO.puts "We have a match!"

def loto(num_of_balls), do: loto(random_numbered_balls(num_of_balls), num_of_balls, 0) 

def loto(static_balls_list, num_of_balls, loop_num) do
    static_balls = static_balls_list
    changing_balls = random_numbered_balls(num_of_balls)
    cond do
        (static_balls == changing_balls) ->
            IO.inspect static_balls 
            IO.inspect changing_balls
            loto(true) 
        (static_balls != changing_balls) ->
            #if (String.ends_with?(to_string(loop_num / 5000)), "0")), do: IO.puts "#{loop_num} tries"
            IO.puts "#{loop_num} tries" #(temp) would prefer to print only ever 5000 tries but can't get the above to work
            loop_num = (loop_num + 1)
            loto(static_balls, num_of_balls, loop_num)
    end
end

end #module end


Play.loto(x)

Most Liked

al2o3cr

al2o3cr

if (String.ends_with?(to_string(loop_num / 5000)), "0"))

This has too many ).

It should also be spelled if (loop_num % 5000 == 0), partly because that’s much more efficient than converting to string and checking the last character but mostly because / in Elixir does not mean integer division:

4214 / 5000
# evaluates to
0.8428

Other general notes:

static_balls = static_balls_list

What’s the intent of this line?

(static_balls != changing_balls) ->

Parentheses are not required here.

loop_num = (loop_num + 1)

And they’re DEFINITELY not required here

I highly recommend learning about and using mix format - it helps remember all the “where do the parens go” rules.

Matsa59

Matsa59

Hello,

def lotto(static_balls_list, num_of_balls, loop_num) do
    cond do
        (static_balls_list == changing_balls) ->

        (static_balls_list != changing_balls) ->
            # if your code goes the condition before is always true
    end
end

you can simply do

def lotto(static_balls_list, num_of_balls, loop_num) do
    if static_balls_list == changing_balls do
    else
    end
end

also you return loto(true you can direclty return the result {:match_found}

You have 3 functions signatures for loto

def lotto(true), do: {:match_found}
def lotto(num_of_balls), do: lotto(random_numbered_balls(num_of_balls), num_of_balls, 0) 
def lotto(static_balls_list, num_of_balls, loop_num) do

that describres 3 differents behaviour.

I rewrite your code as I probably code it (just sharing way of think not judging)

defmodule Loto do
  def shuffle(num) do
    # Use a List is better than custom Tuple length
    for _x <- 1..num, do: :rand.uniform(49)
  end

  # start loto
  def start(num_of_balls) do
    win?(
      shuffle(num_of_balls),
      shuffle(num_of_balls)
    )
  end
  
  # This line just set the default value for the 3th parameter
  # and is know as a function signature that do nothing more ;)
  def win?(list_of_balls, other_list_of_balls, loop_num \\ 1)

  # if we provide 1st et 2nd is the same value basically you win
  def win?(balls_list, balls_list, loop_num) do
    IO.puts("We have a match. It took #{loop_num} tries in total.")
    :match_found
  end

  # otherwise try again
  def win?(_, balls_list, loop_num) do
    if rem(loop_num, 100_000) == 0, do: IO.puts("#{loop_num} tries")

    balls_list
    |> Enum.count()
    |> shuffle()
    |> win?(balls_list, loop_num + 1)
  end
end


Loto.start(1)

I think win?/3 could be improve not my best piece of code.

Also start / win? will always return :match_found so not a usefull return.

Hope it help :wink:

Matsa59

Matsa59

With time you’ll start thinking different (some one already say that :thinking: )

In general term, you use tuple for a structured data that you know the size in compile time. In your case we can’t.

But why knowing the size is so important? It allows you to play easily with the data.

For example pattern matching become an elegant way to accomplish things. With list, you can use [tail | head] for matching data.

E.g:

[h|t] = [1,2,3]
# h -> 1
# y -> [2,3]

Doing this with tuple is little bit harder. The first way is : you now the size you can match data so you can do something like the code bellow

{a,b,c} = {1,2,3}

However, imagine you put 50 elements in the tuple and it become a nightmare.

Or you can use elem/2 But it’s not a pattern matching and it will not be useful in our case.

elem({1,2,3}, 1) 
2

I explain you that because the main thing about functional programming is thinking of the future. When you write a function your main goal is to provide a piece of code that could be use again and again without any modification. That’s why I had 3 little functions instead of one bigger. Each one does exactly one thing.

So here, I use a list because needs could evolve to : if there is rights numbers but in different order print « you were close » in the console. Doing this with list a pretty easy and the code will be elegant (It could be an great exercice btw).

And for charlists, you can take a look at Elixir lists interpreted as char lists - Stack Overflow

When I was young I was diagnosed with dyslexia. With time, code help me a lot. Keep in mind dyslexia is an advantage. Your brain work differently and it will give you the opportunity to think how to accomplish things differently.

Have a great day :wink:

kokolegorille

kokolegorille

You can always switch to LFE :slight_smile:

tommy

tommy

Thank you, very interesting. I’ll reread your message tomorrow, run it and reply :).

Where Next?

Popular in Questions Top

LegitStack
I’m hoping you guys can give me some general advice and perhaps code examples if you’re feeling up to it. I’m very interested in Elixir,...
New
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
gonzofish
I’m currently trying to understand how to join three tables using Ecto. All the examples I’ve seen use 2, so maybe I’m just missing somet...
New
hpopp
To simplify some tasks at work, I wrote and published this package yesterday. It’s a simple macro that enables Access behaviour on struct...
New
beno
I will often find my self writing things similar to: case some_value do nil -&gt; something() "" -&gt; something() _ -&gt; someth...
New

Other popular topics Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
977 41022 311
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
Nvim
Elixir appears to be a superior language to Python. I don’t see any advantage of Python over Elixir. Are there any?
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New

We're in Beta

About us Mission Statement