Skip to content

SaugatEDITH/Elixir

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

8 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Elixir and Phoenix:

in elixir .ex is for compiled code .exs if for interpreted code

Hello World from Elixir (.exs one)

IO.puts("Hello World from elixirel")

Mix is build tool for elexir it allows us to

  • create our project ( mix new project-name )
  • compile our project(mix compile)
  • run our project

Variable and constant:

defmodule Example do
Β  use Application
Β  @x 5 
Β  def start(_type,_args) do
Β  Β  Example.main()
Β  Β  Supervisor.start_link([],strategy: :one_for_one)
Β  end
Β  def main do
Β  Β  name="Saugat"
Β  Β  status=:gold
Β  Β  IO.puts("name: #{name} status: #{status} constant no: #{@x}")
Β  end
end

If statement:

defmodule Example do
Β  use Application
Β  def start(_type,_args) do
Β  Β  Example.main()
Β  Β  Supervisor.start_link([],strategy: :one_for_one)
Β  end
Β  def main do
Β  Β  name="Saugat"
Β  Β  status=Enum.random([:gold,:silver,:bronze])
Β  Β  if status===:gold do
Β  Β  Β  IO.puts("Welcome to Fancy lounge, #{name} ")
Β  Β  else
Β  Β  Β  IO.puts("Get lost")
Β  Β  end
Β  end
end

Case statement:

defmodule Example do

Β  use Application

Β  def start(_type,_args) do
Β  Β  Example.main()

Β  Β  Supervisor.start_link([],strategy: :one_for_one)
Β  end
Β  def main do
Β  Β  name="Saugat"
Β  Β  status=Enum.random([:gold,:silver,:bronze,:"not a member"])
Β  Β  case status do
Β  Β  Β  :gold->IO.puts("Welcome to the fancy laung, #{name} ")
Β  Β  Β  :silver->IO.puts("Come in sir")
Β  Β  Β  :bronze->IO.puts("Come in")
Β  Β  Β  :"not a member"->IO.puts("Get subscribed");
Β  Β  Β  _->IO.puts("Get lost")
Β  Β  end

Β  end

end

String interpolation and Hex in elixir: Hex is .........

defmodule Example do

Β  use Application

  

Β  def start(_type, _args) do

Β  Β  Example.main()

Β  Β  Supervisor.start_link([], strategy: :one_for_one)

Β  end

  

Β  def main do

Β  Β  IO.puts("This\nis\n\tmessage\n")

Β  Β  IO.puts("After")

Β  Β  IO.puts("String interpoluayion looks like \#{}")

Β  Β  #numeric representation of unicode

Β  Β  IO.puts(?a)

Β  end

end

Number and Number methods Integer and float in Elixir:

defmodule Example do
Β  use Application
Β  def start(_type, _args) do
Β  Β  Example.main()
Β  Β  Supervisor.start_link([], strategy: :one_for_one)
Β  end
Β  def main do
Β  Β  a=10
Β  Β  a=a+10.0
Β  Β  b=3
Β  Β  IO.puts(a/b)
Β  Β  :io.format("~20f\n",[0.1])
Β  Β  IO.puts(Float.ceil(1.6))
Β  Β  IO.puts(Float.ceil(1.1,1))
Β  Β  IO.puts(Integer.gcd(20,5))
Β  end

end

Compount types

  • Date Time

defmodule Example do

Β  use Application

Β  def start(_type, _args) do

Β  Β  Example.main()

Β  Β  Supervisor.start_link([], strategy: :one_for_one)

Β  end

Β  def main do

Β  Β  # Create a specific time (16:30:00)

Β  Β  time = Time.new!(16, 30, 0, 0)

Β  Β  # Create a specific date (January 1, 2025)

Β  Β  date = Date.new!(2025, 1, 1)

  

Β  Β  # Combine the date and time into a DateTime in the UTC timezone

Β  Β  date_time = DateTime.new!(date, time, "Etc/UTC")

  

Β  Β  # Print the date, time, and combined DateTime

Β  Β  IO.inspect(date, label: "Date")

Β  Β  IO.inspect(time, label: "Time")

Β  Β  IO.inspect(date_time, label: "DateTime")


Β  Β  # Create a future DateTime (January 1, 2082, 00:00:00 UTC)

Β  Β  future_time = DateTime.new!(Date.new!(2082, 1, 1), Time.new!(0, 0, 0, 0), "Etc/UTC")

Β  Β  # Calculate the difference in seconds between now and the future time

Β  Β  time_till = DateTime.diff(DateTime.utc_now(), future_time)

Β  Β  # Print the total seconds until the future time

Β  Β  IO.puts("Total seconds until future time: #{time_till}")

Β  Β  # Calculate the number of days from the total seconds

Β  Β  days = div(time_till, 86_400) # 86,400 seconds in a day

Β  Β  # Print the remaining seconds after dividing by days

Β  Β  IO.puts("Remaining seconds after days: #{rem(time_till, 86_400)}")

Β  Β  # Calculate the number of hours from the remaining seconds

Β  Β  hours = div(rem(time_till, 86_400), 60 * 60) # 60 * 60 seconds in an hour

Β  Β  # Calculate the number of minutes from the remaining seconds after hours

Β  Β  mins = div(rem(time_till, 60 * 60), 60) # 60 seconds in a minute

Β  Β  IO.puts(

Β  Β  Β  "Time until 2082: #{days} days, #{hours} hours, #{mins} minutes"

Β  Β  )

Β  end

end

Touple:

defmodule Example do

Β  use Application

  

Β  def start(_type, _args) do

Β  Β  Example.main()

Β  Β  Supervisor.start_link([], strategy: :one_for_one)

Β  end

  

Β  def main do

Β  Β  membership={:bronz,:silver}

Β  Β  membership=Tuple.append(membership,":gold")

Β  Β  IO.inspect(membership)

Β  Β  prices={5,10,15}

Β  Β  avg=Tuple.sum(prices)/tuple_size(prices)

Β  Β  IO.puts(avg)

Β  Β  IO.puts("Average price from #{elem(membership,0)} #{elem(membership,1)} #{elem(membership,2)} avg is #{avg}")

Β  Β  user1={"Saugat",:gold}

Β  Β  user2={"Hari",:silver}

Β  Β  user3={"Sits",:bronz}

Β  Β  {name,membership}=user1

Β  Β  IO.puts("#{name} has a #{membership} membership")

Β  Β  {name,membership}=user2

Β  Β  IO.puts("#{name} has a #{membership} membership")

Β  Β  {name,membership}=user3

Β  Β  IO.puts("#{name} has a #{membership} membership")

Β  end

end

List and Loop:

defmodule Example do

Β  use Application

  

Β  def start(_type, _args) do

Β  Β  Example.main()

Β  Β  Supervisor.start_link([], strategy: :one_for_one)

Β  end

  
Β  def main do

Β  Β  users=[

Β  Β  Β  {"Saugat",:gold},

Β  Β  Β  {"Hari",:silver},

Β  Β  Β  {"Sits",:bronz},

Β  Β  Β  {"John",:bronz},

Β  Β  ]
Β  Enum.each(users,fn {name,membership}->IO.puts("#{name} has a #{membership} membership")

Β  end

Β  )
  

Β  end

end

Mapping :

defmodule Example do

Β  use Application

  

Β  def start(_type, _args) do

Β  Β  Example.main()

Β  Β  Supervisor.start_link([], strategy: :one_for_one)

Β  end

  

Β  def main do

Β  Β  # :apple type str is called adem

Β  Β  prices=%{

Β  Β  Β  gold: 25,

Β  Β  Β  silver: 20,

Β  Β  Β  bronze: 25,

Β  Β  Β  none: 0,

  

Β  Β  }

Β  Β  memberships=%{

Β  Β  Β  gold: :gold ,

Β  Β  Β  silver: :silver,

Β  Β  Β  bronze: :bronze,

Β  Β  Β  none: :none

Β  Β  }

  

Β  Β  users=[

Β  Β  Β  {"Saugat",memberships.gold},

Β  Β  Β  {"Hari",memberships.silver},

Β  Β  Β  {"Sits",memberships.bronze},

Β  Β  Β  {"John",memberships.bronze},

Β  Β  ]

Β  Enum.each(users,fn {name,membership}->IO.puts("#{name} has a #{membership} membership which price is #{prices[membership]}")

Β  end

Β  )

  

Β  end

end

Structs :

defmodule Membership do

Β  defstruct [:type, :price]

end

  

defmodule User do

Β  defstruct [:name, :membership]

end

  

defmodule Example do

Β  use Application

  

Β  def start(_type, _args) do

Β  Β  Example.main()

Β  Β  Supervisor.start_link([], strategy: :one_for_one)

Β  end

  

Β  def main do

Β  Β  # :apple type str is called adem

  

Β  Β  gold_membership = %Membership{type: :gold, price: 25}

Β  Β  silver_membership = %Membership{type: :silver, price: 20}

Β  Β  bronze_membership = %Membership{type: :bronze, price: 15}

Β  Β  none_membership = %Membership{type: :none, price: 0}

  

Β  Β  users = [

Β  Β  Β  %User{name: "Saugat", membership: gold_membership},

Β  Β  Β  %User{name: "Hari", membership: silver_membership},

Β  Β  Β  %User{name: "Sits", membership: bronze_membership},

Β  Β  Β  %User{name: "John", membership: none_membership}

Β  Β  ]

  

Β  Β  Enum.each(users, fn %User{name: name,membership: membership} ->

Β  Β  Β  IO.puts("#{name} has a #{membership.type} membership which price is #{membership.price}")

Β  Β  end)

Β  end

end

Number guessing game:

defmodule Example do

Β  use Application

  

Β  def start(_type, _args) do

Β  Β  Example.main()

Β  Β  Supervisor.start_link([], strategy: :one_for_one)

Β  end

  

Β  def main do

Β  Β  correct=:rand.uniform(11)-1

Β  Β  guess=IO.gets("Guess a number between 0 & 10: ") |> String.trim() ##method chaining

Β  Β  if String.to_integer(guess)==correct do

Β  Β  Β  IO.puts("You won")

Β  Β  else

Β  Β  Β  IO.puts("You lost")

Β  Β  end

Β  Β  IO.puts("You guess #{guess} , correct was #{correct}")

Β  end

end

Cases and pattern Matching

defmodule Example do

Β  use Application

  

Β  def start(_type, _args) do

Β  Β  Example.main()

Β  Β  Supervisor.start_link([], strategy: :one_for_one)

Β  end

  

Β  def main do

Β  Β  correct=:rand.uniform(11)-1

Β  Β  guess=IO.gets("Guess a number between 0 & 10: ") |> String.trim() |> Integer.parse() ##method chaining

Β  Β  IO.inspect(guess)

Β  Β case guess do

Β  Β  Β {result, ""}->IO.puts("parse sucessful #{result}")

Β  Β  Β {result,other}->IO.puts("parse partially sucessful #{result} and #{other}")

Β  Β  :error->IO.puts("Something went wrong !")

Β  Β end

Β  end

end

Game of above using case and pattern matching:

defmodule Example do

Β  use Application

Β  def start(_type, _args) do

Β  Β  Example.main()

Β  Β  Supervisor.start_link([], strategy: :one_for_one)

Β  end

Β  def main do

Β  Β  correct=:rand.uniform(11)-1

Β  Β  guess=IO.gets("Guess a number between 0 & 10: ") |> String.trim() |> Integer.parse() ##method chaining

Β  Β  IO.inspect(guess)

Β  Β case guess do

Β  Β  Β {result, _}->

Β  Β  Β  IO.puts("parse sucessful #{result}")

Β  Β  Β  if result===correct do

Β  Β  Β  Β  IO.puts("You won")

Β  Β  Β  else

Β  Β  Β  Β  IO.puts("You lose the correct ans is : #{correct}")

Β  Β  Β  end

Β  Β  :error->IO.puts("The correct !")

Β  Β end

Β  end

end

Lists and List comprehension:

defmodule Example do

Β  require Integer

Β  use Application

  

Β  def start(_type, _args) do

Β  Β  Example.main()

Β  Β  Supervisor.start_link([], strategy: :one_for_one)

Β  end

  

Β  def main do

Β  Β  grades=[25,50,75,100]

Β  Β  for n <- grades do

Β  Β  Β  Β IO.puts(n)

Β  Β  end

  

Β  Β  grades=[25,50,75,100]

Β  Β  new= for n <- grades,do: n+5

Β  Β  new=new ++ [125]

Β  Β  new=new ++ [150,175]

Β  Β  IO.inspect(new)

Β  Β  final=[5|new]

Β  Β  IO.inspect(final)

Β  Β  even=for n <- final,rem(n,2)==0, do: n

Β  Β  # even=for n <- final,Integer.is_even(n)==0, do: n

Β  Β  IO.inspect(even)

  

Β  end

  

end

functional programming and Defining Custom function

defmodule Example do

Β  require Integer

Β  use Application

  

Β  def start(_type, _args) do

Β  Β  Example.main()

Β  Β  Supervisor.start_link([], strategy: :one_for_one)

Β  end

Β  # function that takes numbers then return sum and average

Β  def sum_and_average(numbers) do

Β  Β  sum=Enum.sum(numbers)

Β  Β  average=sum/Enum.count(numbers)

Β  Β  {sum,average}

Β  end

Β  @spec print_numbers(any()) :: none()

Β  def print_numbers(numbers) do

Β  Β  numbers |> Enum.join(" ") |> IO.puts()

Β  end

Β  def get_numbers_from_user do

Β  Β  IO.puts("Enter number seperated by spaces:> ")

Β  Β  user_input=IO.gets("") |>String.trim()

Β  Β  String.split(user_input," ")|>Enum.map(&String.to_integer/1)

Β  end

Β  def main do

Β  user_given_numbers=get_numbers_from_user()

Β IO.inspect(sum_and_average(user_given_numbers))

Β {sum,average}=sum_and_average(user_given_numbers)

Β IO.puts("The sum is #{sum} and the average is #{average}")

Β  Β numbers =[1,2,3,4,5,6]

Β  Β #ananomus function

Β  Β Enum.each(numbers,fn num->IO.puts(num) end)

Β  Β numbers =["1","2","3","4","5","6"]

Β  # Β passing function as argument with &

Β  Β result=Enum.map(numbers,&String.to_integer/1)

Β  Β  IO.inspect(sum_and_average(result))

  

Β  end

  

end

Phoenix Start:

βœ… Phoenix App Setup Summary

Phoenix is a web framework built on Elixir, designed for high performance, scalability, and maintainability. It is particularly well-suited for real-time applications and APIs. If you're coming from frameworks like Django, Express, or Rails, this guide will help you get started with Phoenix.


1. Install Hex (Elixir package manager)

Hex is the package manager for the Elixir ecosystem, similar to npm for Node.js or pip for Python. It is used to manage dependencies in your Phoenix project.

mix local.hex
  • What it does: Installs or updates Hex locally.
  • Where it stores Hex: ~/.mix/archives/

2. Install Phoenix Project Generator

The Phoenix project generator (phx_new) scaffolds a new Phoenix project with all the necessary files and dependencies.

mix archive.install hex phx_new
  • What it does: Installs the phx_new archive, which is used to generate new Phoenix projects.
  • Versioning: The latest version (e.g., 1.7.21) is stored as an .ez archive.

3. Generate a New Phoenix App

This command creates a new Phoenix project with a specified name and database backend.

mix phx.new forum --database sqlite3
  • What it does:

    • Creates a new app named forum.
    • Sets up the project structure.
    • Installs dependencies.
    • Configures SQLite3 as the database backend (you can also use PostgreSQL or MySQL).
  • Key Flags:

    • --database sqlite3: Specifies the database adapter. Replace sqlite3 with postgres or mysql if needed.

4. Navigate into the App Folder

cd forum
  • Why?: Phoenix commands like mix phx.server and mix ecto.create must be run from within the project folder to access the mix.exs file and configuration files.

5. Create the Database

mix ecto.create
  • What it does:

    • Compiles the project (if not already compiled).
    • Creates the database using Ecto, Phoenix's database wrapper and query generator.
  • Ecto: Think of Ecto as the ORM (like Django ORM or Sequelize). It handles database migrations, queries, and schema definitions.


6. Run the Phoenix Server

mix phx.server
  • What it does:

    • Starts the Phoenix web server (default: http://localhost:4000).
    • Watches for code changes and recompiles automatically.
  • Default Web Server: Phoenix uses the Cowboy web server, which is highly performant and lightweight.


7. (Optional) Run Phoenix with IEx

iex -S mix phx.server
  • What it does:
    • Starts the Phoenix server with the interactive Elixir shell (IEx).
    • Useful for debugging, testing database queries, and exploring the application state.

⚠️ Note: Symlink Warning on Windows

If you see a warning like:

β€œPhoenix is unable to create symlinks...”

Fix:

  1. Run your terminal as Administrator at least once.
  2. Phoenix will then be able to create symlinks for faster reloads.

πŸ“ Phoenix Directory Structure vs Django vs Express

Phoenix organizes its files in a way that promotes separation of concerns. Here's how it compares to Django and Express:

βœ… Root-Level Overview

Path Phoenix Purpose Django Equivalent Express Equivalent
mix.exs Project config (like package.json) settings.py, pyproject.toml package.json
config/ App and database configs settings.py, env.py .env, config files
lib/ Main application code Django project/ folder src/ or main app folder
test/ Unit tests (ExUnit) tests/ test/, __tests__/
.formatter.exs Elixir code formatting pyproject.toml (Black) .prettierrc, .eslintrc
assets/ JavaScript/CSS (frontend assets) static/, templates/ public/, views/

πŸ”Ή Inside lib/ (Main App Code)

Path Phoenix Purpose Django Equivalent Express Equivalent
forum.ex Main app entrypoint __init__.py index.js, app.js
forum/application.ex Supervision tree / app lifecycle Not applicable App setup in app.js
forum_web/ Web layer: routes, controllers, templates Views, URLs, templates Routes & views

πŸ”Ή Inside lib/forum_web/ (Phoenix Web Layer)

Path Phoenix Purpose Django Equivalent Express Equivalent
controllers/ Request logic handlers views.py Route handler functions
views/ Rendering logic (separate from controllers) Context processors Templating logic (optional)
templates/ EEx templates (HTML) templates/ EJS/Pug templates
router.ex Route definitions urls.py app.get(), app.post()
endpoint.ex Entry point for HTTP requests (Bandit/Cowboy) WSGI application Express app (app)

πŸ”Ή Database, Migrations & ORM

Path Phoenix Purpose Django Equivalent Express Equivalent
priv/repo/migrations/ Ecto migration files migrations/ Sequelize/Mongoose files
lib/forum/repo.ex Ecto Repo for DB operations Django ORM Mongoose/Sequelize
schema files (*.ex) Define database schema + changesets models.py Models in Mongoose/ORM

πŸ”Ή Frontend

Path Phoenix Purpose Django Equivalent Express Equivalent
assets/js/ JavaScript (esbuild or webpack) Static JS in static/ public/ or views/
assets/css/ CSS stylesheets Static CSS in static/ Same
assets/ Overall frontend pipeline Django static/ + templates/ public/ or static files

πŸ”Ή Common Tasks

Task Phoenix Django Express
Generate project mix phx.new app_name django-admin startproject express-generator (optional)
Run dev server mix phx.server python manage.py runserver node app.js or nodemon
Migrate DB mix ecto.migrate python manage.py migrate ORM-dependent
Create migration mix ecto.gen.migration python manage.py makemigrations ORM-dependent
Create model/schema mix phx.gen.schema Django models ORM-dependent

🧠 TL;DR: Concept Mapping

Concept Phoenix Django Express
Project Config mix.exs settings.py package.json
Routing router.ex urls.py app.get() etc.
Controllers controllers/ views.py Route handlers
Templates templates/ templates/ EJS/Pug views
ORM/Models schema + changeset Django Models Mongoose/Sequelize
DB Migrations ecto.migrations Django migrations ORM-based tools
Frontend assets/ static/ public/

πŸ“¦ Phoenix JSON API Generator: mix phx.gen.json

Phoenix provides a powerful generator for creating JSON APIs. This is particularly useful for API-first applications or when building a backend for a frontend framework like React or Vue.


βœ… Command

mix phx.gen.json Posts Post posts body:string title:string

🧠 Breakdown

Part Description
mix phx.gen.json Generates a JSON-only resource (no HTML views/templates).
Posts (Context) A module grouping logic (e.g., Forum.Posts).
Post (Schema) The database model (e.g., Posts.Post).
posts (DB Table) Table name used in the DB (plural of schema).
body:string Adds :body field (type :string).
title:string Adds :title field (type :string).

πŸ“ Files Generated

πŸ”Ή Context & Schema

File Purpose
lib/forum/posts/post.ex Defines the Post Ecto schema.
lib/forum/posts.ex CRUD functions (context): list_posts/0, create_post/1, etc.

πŸ”Ή Migration

File Purpose
priv/repo/migrations/*_create_posts.exs Migration to create the posts table.

πŸ”Ή Controller & View

File Purpose
lib/forum_web/controllers/post_controller.ex Handles API endpoints.
lib/forum_web/views/post_json.ex Formats JSON responses.

πŸ”Ή Router Update

Adds:

scope "/api", ForumWeb do
  pipe_through :api
  resources "/posts", PostController, except: [:new, :edit]
end

πŸ› οΈ After the Generator

1. Run the Migration

mix ecto.migrate

2. Start the Server

mix phx.server

3. API Endpoints (Default)

Method Route Action
GET /api/posts List posts
GET /api/posts/:id Show post
POST /api/posts Create post
PUT /api/posts/:id Update post
DELETE /api/posts/:id Delete post

βœ… Summary

Phoenix is a powerful framework for building scalable, maintainable web applications. It provides a clean separation of concerns with contexts, schemas, and controllers. The mix tool simplifies common tasks like generating code, running migrations, and starting the server. Phoenix is ideal for API-first applications or real-time features using WebSockets.


mix phx.gen.json Accounts User users name:string email:string:unique

🧠 Breakdown

Part Description
mix phx.gen.json Generates a JSON-only resource (no HTML views/templates).
Accounts (Context) The context module that groups related logic (e.g., Forum.Accounts).
User (Schema) The schema module for User (e.g., Accounts.User).
users (DB Table) The name of the table in the database (e.g., users).
name:string Adds a name field (type string).
email:string:unique Adds an email field (type string) with a unique constraint to ensure no duplicate emails.

πŸ“ Files Generated

πŸ”Ή Context and Schema (in lib/forum/)

File Purpose
lib/forum/accounts/user.ex Defines the User schema with name and email fields.
lib/forum/accounts.ex Context module for Accounts, containing functions for CRUD operations on users.

πŸ”Ή Migration (in priv/repo/migrations/)

File Purpose
*_create_users.exs Migration to create the users table with name and email fields, and ensure the email field is unique.

πŸ”Ή Controller and View (in lib/forum_web/)

File Purpose
lib/forum_web/controllers/user_controller.ex Handles API requests for users.
lib/forum_web/views/user_json.ex Renders JSON responses for users.

πŸ”Ή Router Update (in router.ex)

Adds the following route to handle user-related API requests:

scope "/api", ForumWeb do
  pipe_through :api
  resources "/users", UserController, except: [:new, :edit]
end

πŸ› οΈ Next Steps

1. Run the Migration

Ensure your database is updated to reflect the changes:

mix ecto.migrate

2. Start the Phoenix Server

Run your server to start receiving requests:

mix phx.server

3. API Endpoints (for /api/users)

Method Route Action
GET /api/users List users
GET /api/users/:id Show user
POST /api/users Create user
PUT /api/users/:id Update user
DELETE /api/users/:id Delete user

πŸ” Concept Mapping

Phoenix JSON Generator Django Equivalent Express Equivalent
mix phx.gen.json Django REST Framework (DRF) ViewSet Express + Mongoose/Sequelize
Context Django accounts/ app Folder/module for accounts
Schema Django models.py for User Mongoose schema for User
Controller DRF ViewSet for User Express route/controller
Migration Django makemigrations + migrate Sequelize migration

βœ… Summary

  • The mix phx.gen.json command simplifies the creation of JSON APIs in Phoenix.
  • It generates a clean separation of concerns with context, schema, controller, and view files.
  • The generated API is ready to handle CRUD operations for the User resource.
  • Phoenix's mix tool ensures a streamlined development process, from migrations to server setup.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published