Gordon  Taylor

Gordon Taylor

1675948200

How to Kubernetes Migration Made Simple with Konveyor Move2Kube

Konveyor accelerates the process of replatforming to Kubernetes by analyzing source artifacts.

Konveyor Move2Kube assists developers in migrating projects from platforms such as Cloud Foundry and Docker swarm to Kubernetes and OpenShift. Move2Kube analyzes your application's source code and generates Infrastructure-as-Code (IaC) artifacts such as Kubernetes YAMLs, Helm charts, Tekton pipelines, and so on.

Move2Kube input and output options

(Mehant Kammakomati, CC BY-SA 4.0)

Powering Move2Kube is a transformer framework that enables multiple small transformers to be chained together to transform the artifacts completely.

Transformations

(Mehant Kammakomati, CC BY-SA 4.0)

Many different transformers get involved when transforming a Java or Node.js project to create all the destination artifacts. This allows for the reuse of transformers in various end-to-end flows. Each transformer is capable of performing multiple activities.

Transformers perform various activities

(Mehant Kammakomati, CC BY-SA 4.0)

Move2Kube

You can use Move2Kube as a terminal command or as a web app. Its core functionality includes planning and transformation. In the planning phase, Move2Kube analyzes artifacts to identify the services involved. In the transformation phase, it transforms those services into destination artifacts.

The terminal command is a single binary, which you can download and install. Move2Kube also provides a helper script to download and place the binary in your local filesystem:

curl \ https://raw.githubusercontent.com/konveyor/move2kube/main/scripts/install.sh \

-o move2kube_install.sh

Look through the script to ensure its install method aligns with your preference, and then run it:

$ sh ./move2kube_install.sh

To use the command, just run it on a directory containing the application source code:

$ move2kube transform -s ./src

Transform an enterprise scale application

Move2Kube can be used to replatform a real-world enterprise application. There's a demo enterprise app included in the Move2Kube git repository to demonstrate the workflow. This demo app is similar to a typical real-world application with CRUD operations and a multi-tier architecture.

To try it out, download the source code for the enterprise app:

$ curl https://move2kube.konveyor.io/scripts/download.sh \
| bash -s -- -d samples/enterprise-app/src -r move2kube-demos

The source code for the enterprise app is in the src directory.

First, use the move2kube transform command:

$ move2kube transform -s ./src

After running the command, look in the myproject folder. There are new directories, including deploy, scripts, and source. The deploy directory contains all IaC artifacts, such as Kubernetes YAML files, Tekton pipelines, Helm charts, Knative files, compose files, and OpenShift files. The scripts directory contains shell scripts to build and push container images to the registry of your choice. Finally, the source directory contains the source code and Dockerfiles.

Capabilities provided by Move2Kube

Move2Kube has a powerful QA Engine. Transformers can get input from a user using this engine. Transformers receive the input as user interaction through a terminal, a web interface, a REST API, or as a configuration file.

For instance, in the demo enterprise app, the Move2Kube QA engine might ask which port the frontend app should listen on, which container registry should be used to store images, or what ingress host should be used.

To run an app in a non-interactive mode, use the --qa-skip flag. This option causes Move2Kube to use default answers:

$ move2kube transform -s ./src --qa-skip

If you want to answer the questions from a configuration file, use the -f option:

$ move2kube transform -s ./src -f ./m2kconfig.yaml

A list of all answers used for the run is captured as a config in the m2kconfig.yaml file.

Customization capability

Move2Kube includes several transformers ready for use, and it allows users to write new transformers. Move2Kube exposes all the internal transformers' capabilities to be leveraged for writing custom transformers. These capabilities include a QA engine, extensive templating enabled by Golang templates, and isolation. Custom transformers behave exactly the same as built-in transformers. The two types can be chained together to achieve an end-to-end transformation.

Move2Kube generates artifacts you can customize to comply with organizational best practices and policies. You can direct the Move2Kube tool to customizations using the -c or --customization option.

You can create customizations using three different methods:

  1. Configure built-in transformers: Configure a built-in transformer to behave differently. For example, you can modify the parameterization transformer to parameterize different values depending on the organization's needs.
  2. Starlark-based transformers: Write a complete transformer in a Python-like language, Starlark. For example, you could use a Starlark-based transformer to add custom annotations to Kubernetes YAML files.
  3. Executable transformers: Write a complete transformer in a language of your choice and allow Move2Kube to execute it along with the other transformers. For example, generate custom Helm charts to add custom files and directories in specific locations.

Parameterization and customization capability

Move2Kube allows users to parameterize custom fields in the target platform artifacts, such as Helm charts. For instance, parameterizing the number of replicas in a Helm chart:

apiVersion: apps/v1
kind: Deployment
metadata:
    annotations:
        move2kube.konveyor.io/service.expose: "true"
    creationTimestamp: null
    labels:
        move2kube.konveyor.io/service: orders
    name: orders 
spec:
    progressDeadlineSeconds: 600
    replicas: {{ index .Values "common" "replicas" }}

Move2Kube also allows you to customize output artifacts. For instance, add a custom annotation to the Ingress YAML file:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
   annotations:
      kubernetes.io/ingress.class: haproxy
    creationTimestamp: null
    labels:
      move2kube.konveyor.io/service: myproject
    name: myproject

Move2Kube case studies

Mov2Kube has been widely adopted in the industry and open-source communities. Here are some case studies where replatforming using Move2Kube has shown considerable improvement over manual effort.

  • InsApp
    • Language Stack: Java (springboot), Angular JS UI
    • Source Platform: Docker Swarm
    • Number of Services: 100
    • Manual Effort: 56 days
    • Move2Kube Effort: 6 days
    • In-Built Transformers Invoked: 6
    • Number of External Transformers: 0
  • AA case study
    • Language Stack: Java (springboot), Angular JS UI
    • Source Platform: Cloud-foundary
    • Number of Services: 3
    • Manual Effort: 2 days
    • Move2Kube Effort: 15 minutes
    • In-Built Transformers Invoked: 14
    • Number of External Transformers: 0
  • CP case study
    • Language Stack: Python
    • Source Platform: ECS Fargate
    • Number of Services: 7
    • Manual Effort: 12 days
    • Move2Kube Effort: 1 day
    • In-Built Transformers Invoked: 13
    • Number of External Transformers: 0
  • MFA case study
    • Language Stack: .NET Silverlight UI
    • Source Platform: Bare-metal/VM
    • Number of Services: 4
    • Manual Effort: 9 days
    • Move2Kube Effort: 5 hours
    • In-Built Transformers Invoked: 14
    • Number of External Transformers: 1 (custom dependencies)
  • TMP case study
    • Language Stack: Java (springboot)
    • Source Platform: Cloud-foundry
    • Number of Services: 24
    • Manual Effort: 25 days
    • Move2Kube Effort: 2.25 days
    • In-Built Transformers Invoked: 15
    • Number of External Transformers: 1 (custom directories)

Data source: Seshadri, Padmanabha V., Harikrishnan Balagopal, Akash Nayak, Ashok Pon Kumar, and Pablo Loyola. "Konveyor Move2Kube: A Framework For Automated Application Replatforming." In 2022 IEEE 15th International Conference on Cloud Computing (CLOUD), pp. 115-124. IEEE, 2022.

Learn more about Konveyor Move2Kube

Visit the Move2Kube site to learn more about replatforming using Konveyor Move2Kube.

Original article source at: https://opensource.com/

#kubernetes #simple 

How to Kubernetes Migration Made Simple with Konveyor Move2Kube
Royce  Reinger

Royce Reinger

1675253940

Implementations Of Basic RL Algorithms with Minimal Lines Of Codes!

minimalRL-pytorch

Implementations of basic RL algorithms with minimal lines of codes! (PyTorch based)

Each algorithm is complete within a single file.

Length of each file is up to 100~150 lines of codes.

Every algorithm can be trained within 30 seconds, even without GPU.

Envs are fixed to "CartPole-v1". You can just focus on the implementations.

Algorithms

  1. REINFORCE (67 lines)
  2. Vanilla Actor-Critic (98 lines)
  3. DQN (112 lines, including replay memory and target network)
  4. PPO (119 lines, including GAE)
  5. DDPG (145 lines, including OU noise and soft target update)
  6. A3C (129 lines)
  7. ACER (149 lines)
  8. A2C (188 lines)
  9. SAC (171 lines) added!!
  10. PPO-Continuous (161 lines) added!!
  11. Vtrace (137 lines) added!!
  12. Any suggestion ...?

Dependencies

  1. PyTorch
  2. OpenAI GYM

Usage

# Works only with Python 3.
# e.g.
python3 REINFORCE.py
python3 actor_critic.py
python3 dqn.py
python3 ppo.py
python3 ddpg.py
python3 a3c.py
python3 a2c.py
python3 acer.py
python3 sac.py

Download Details:

Author: Seungeunrho
Source Code: https://github.com/seungeunrho/minimalRL 
License: MIT license

#machinelearning #reinforcementlearning #deeplearning #simple 

Implementations Of Basic RL Algorithms with Minimal Lines Of Codes!

Six Simple Mind Tricks to Learn JavaScript Fast

When people try to learn JavaScript, or any coding skill really, they often run into the same challenges:

  • Some concepts can be confusing, especially if you’re coming from another language.
  • It’s hard to find the time (and sometimes the motivation) to learn.
  • Once you’ve understood something, it’s all too easy to forget it again.
  • The tooling landscape is so vast and constantly changing that it’s difficult to know where to begin.

Fortunately, these challenges can be recognized and ultimately conquered. In this article, I’m going to present six mind tricks that will help you learn JavaScript faster and become a happier, more productive coder.

1. Don’t Let Future Decisions Stop You from Progressing Now

For many people looking to learn quickly when diving into JavaScript, one of the first questions they ask is which framework to use (and let’s be fair, there’s a lot). But if you haven’t gotten comfortable with raw JavaScript, this is the wrong question to be asking. You’ll spend all of your time researching different frameworks and none of your time actually moving forwards.

One way to help get out of the indecision trap is to have a road map for what you need to learn. For example, to become a front-end developer, your road map might look like this:

Road map to become a front-end developer: HTML, CSS, JavaScript, jQuery, Hosting, WordPress, GitHub, Framework.

Breaking it down further, you can make a functional web page with just HTML and CSS. Seeing the individual steps laid out like this, it becomes easier to see what to focus on now so you don’t waste time worrying about things that should come later.

2. Don’t Let Confidence Trick You into Forgetting Things

Understanding a concept quickly can be one of the most damaging things to your progress in learning JavaScript. Allow me to explain.

When you read something and it makes sense, it can be tempting to move on to the next thing immediately. Maybe you’ll understand the next thing and then move on again. But soon, you’ll arrive at a point where you realize you’ve forgotten some of the previous things you’ve learned, so you need to go back. You give the previous concepts a quick glance to refresh your memory and then move on again. But now you’ve forgotten something else. You keep repeating this back-and-forth dance until you get to a point where you realize you’re completely lost. You get discouraged, take a break, and then you’ve forgotten everything when you try to come back.

Fortunately, there’s a simple two-step cure for this problem:

  1. Limit the amount of stuff you learn at one time.
  2. Practice for real — actually write code.

When you learn a new concept, make sure to try it out, play with it, get comfortable with it, and even combine it with other concepts. It’s so important to actually type out the code in any examples you are following, because that’s what helps you absorb it. Also, limiting the amount you learn at one time will help you retain the material, for the simple reason that it’s easier to remember fewer things.

This process feels like it takes longer than just reading through things and moving quickly, but it actually takes much less time because you won’t need to backtrack as much. I learned this the hard way on several occasions.

3. Approach Practice with the Right Mindset

Many people see practice as something boring and repetitive, so they’ll often skip it or try to take shortcuts. If you try to shortcut your JavaScript practice, you’ll actually end up taking longer to learn it. But how do you make practice more exciting so you’ll actually do it?

Try this mindset shift:

What if you learned a new JavaScript concept and you weren’t allowed to try it? How would you feel? Personally, I’d be kind of annoyed, especially after taking the time to understand it. It would be like a kid getting a new toy and not being allowed to play with it.

When you learn something new in JavaScript, try treating it like a new toy, a new car, a new pair of shoes, or whatever it is that you’d have fun trying out. Then don’t practice like you’re working, practice like you’re playing. Do something cool with your new skills. Surprise yourself. Show your friends.

With a more playful mindset, you’ll learn much faster, you’ll remember stuff longer, and you’ll have more fun.

4. Find Time to Code Using the Facebook Trick

One of the most common problems people have is that they can’t find the time to code. Often, the same people will spend hours on sites like Facebook, YouTube, Wikipedia, or Reddit. Whether or not this describes you, there are still lessons to be learned here.

I’ve definitely had times when I only meant to look at Facebook for a while, but I ended up staying on there for hours. How does that happen? It happens precisely because I didn’t intend to go on there for long. Getting started on something is the hardest part, so I find it much easier to jump in by keeping the initial commitment small. If someone had asked me if I was prepared to spend hours on Facebook, I’d say no because I don’t have that kind of time. However, I’m much more receptive to the idea of just checking one thing quickly, and that’s how I get sucked in.

The good news is that you can use this same psychology to your advantage when learning to code. Don’t try to commit to several hours of coding because then you’ll never find the time. Just tell yourself you’re going to try some code for three minutes. You’ll never struggle to find time again.

5. Think Slower and You’ll Learn Faster

This one sounds counterintuitive, so I’ll explain it with a story.

A friend of mine was once confused about a certain feature of JavaScript. I asked him to walk me through what he knew and then explain which part was confusing. As he went through the piece of code, I noticed that he was rushing.

“Hold on!” I said. “Slow down, and walk me through each step of this.”

My friend proceeded to give me an overall summary of what was happening in the code.

I stopped him again. “You’re still rushing. Try again, but this time, I want you to literally go through each line of this and tell me what exactly is happening in each line.”

This time, my friend was better able to explain what was going on in the code. The key was that he had taken the time to step through each piece of it instead of trying to understand all of it at once.

In cases like this, thinking slower actually makes you learn faster.

6. Write Complex Code in Plain Language First

If a piece of code is going to be complicated or unfamiliar, write it out in plain language first. That way, you can figure out what you want the code to do before you actually have to write it. Here are two benefits to this approach:

  1. Your code will be easier and faster to write because you won’t have to constantly stop and think about how you want it to behave.
  2. You’ll catch bugs before they happen because you’ll have a clearer idea of what the code should do.

Learning Programming Languages Faster

We’ve gone over a bunch of ways to learn JavaScript faster, but you can apply many of these tips to other skills. Here’s a recap of what we’ve covered:

  • Stop worrying about future decisions and dive in.
  • Make practice fun by treating new skills like toys.
  • Find time to code by only making tiny commitments the way you would with sites like Facebook, YouTube, or Wikipedia.
  • Slow down, take smaller steps, and you’ll learn faster.

So how do you approach learning? Do you have any tips or tricks I didn’t cover here? Or maybe you think it’s all baloney and the only way forward is to put in twelve hours a day. Either way, I’d love to hear from you in the comments.

Original article source at: https://www.sitepoint.com/

#javascript #simple #tricks 

Six Simple Mind Tricks to Learn JavaScript Fast

SimpleTraits.jl: Simple Traits for Julia

SimpleTraits

NEWS

This package provides a macro-based implementation of traits, using Tim Holy's trait trick. The main idea behind traits is to group types outside the type-hierarchy and to make dispatch work with that grouping. The difference to Union-types is that types can be added to a trait after the creation of the trait, whereas Union types are fixed after creation. The cool thing about Tim's trick is that there is no performance impact compared to using ordinary dispatch. For a bit of background and a quick introduction to traits watch my 10min JuliaCon 2015 talk.

One good example of the use of traits is the abstract array interface in Julia-Base. An abstract array either belongs to the Base.IndexLinear or Base.IndexCartesian trait, depending on how its internal indexing works. The advantage to use a trait there is that one is free to create a type hierarchy independent of this particular "trait" of the array(s).

Tim Holy endorses SimpleTraits, a bit: "I'd say that compared to manually writing out the trait-dispatch, the "win" is not enormous, but it is a little nicer." I suspect that — if you don't write Holy-traits before breakfast — your "win" should be greater ;-)

Manual

Traits are defined with @traitdef:

using SimpleTraits
@traitdef IsNice{X}
@traitdef BelongTogether{X,Y} # traits can have several parameters

All traits have one or more (type-)parameters to specify the type to which the trait is applied. For instance IsNice{Int} signifies that Int is a member of IsNice (although whether that is true needs to be checked with the istrait function). Most traits will be one-parameter traits, however, several parameters are useful when there is a "contract" between several types.

As a style convention, I suggest to use trait names which start with a verb, as above two traits. This makes distinguishing between traits and types easier as type names are usually nouns.

Add types to a trait-group with @traitimpl:

@traitimpl IsNice{Int}
@traitimpl BelongTogether{Int,String}

If there is a function which tests whether a trait is fulfilled then it can be used like so:

@traitimpl IsNice{X} <- isnice(X)
isnice(X) = false # set default

i.e. any type X for which isnice(X)==true belongs to IsNice. Notes:

  • overhead-less (static) dispatch is only possible if isnice is pure: "[A pure method] promises that the result will always be the same constant regardless of when the method is called [for the same input arguments]." (ref).
  • Last note that in above example the @traitimpl IsNice{Int} "wins" over the @traitimpl IsNice{X} <- isnice(X), thus this can be used to define exceptions to a rule.

It can be checked whether a type belongs to a trait with istrait:

using Test
@test istrait(IsNice{Int})
@test !istrait(BelongTogether{Int,Int}) # only BelongTogether{Int,String} was added above

Functions which dispatch on traits are constructed like:

@traitfn f(x::X) where {X; IsNice{X}} = "Very nice!"
@traitfn f(x::X) where {X; !IsNice{X}} = "Not so nice!"

This means that a type X which is part of the trait IsNice will dispatch to the method returning "Very nice!", otherwise to the one returning "Not so nice!":

@test f(5)=="Very nice!"
@test f(5.)=="Not so nice!"

Note that calling a trait-function is just like calling any other function. Thus there is no extra mental gymnastics required for a "user" of a trait-based package.

Similarly for BelongTogether which has two parameters:

@traitfn f(x::X,y::Y) where {X,Y; BelongTogether{X,Y}} = "$x and $y forever!"
@test f(5, "b")=="5 and b forever!"
@test_throws MethodError f(5, 5)

@traitfn f(x::X,y::Y) where {X,Y; !BelongTogether{X,Y}} = "$x and $y cannot stand each other!"
@test f(5, 5)=="5 and 5 cannot stand each other!"

Traitor.jl-like syntax

At JuliaCon 2016 folks suggested an alternate, more compact syntax for trait-functions. However, it only works for single parameter traits. SimpleTraits now supports this. Above function f can be written as:

@traitfn ft(x::::IsNice) = "Very nice!"
@traitfn ft(x::::(!IsNice)) = "Not so nice!"

Note that the parenthesis are needed with negated traits, otherwise a parser error is thrown.

Vararg, default argument and keyword argument trait functions

Vararg, default argument and keyword argument trait functions work. However, with keyword arguments the trait function and negated trait function need both have the same keywords (however different values are allowed). Example:

@traitfn kwfn(x::::Tr1, y...; kw=1) = x+y[1]+kw
@traitfn kwfn(x::::(!Tr1), y...; kw=2) = x+y[1]+kw

For default arguments the rule is slightly different: with default arguments the trait function and negated trait function need both have the same default-argument with the same values.

@traitfn deff(x::::Tr1, y=1) = x+y
@traitfn deff(x::::(!Tr1), y=1) = x+y

Method overwritten warnings

Warnings are issued when methods are overwritten. Due to Tim's trick the @traitfn needs to create two functions the first time it is used for a particular method (see next section for an explanation). But when defining the opposite trait, then better only one method is created or else the warning appears. Some heuristics to avoid the warnings are in-place to check whether a method is defined yet or not but they fail at times (see issue #7). Long story short: define the two methods of a trait and its negation using the same argument names and no warning should be issued. Although note that the warnings are harmless.

Details of method dispatch

Defining a trait function adds: one new method (or overwrites one) to the generic function, which contains the logic; and one helper method to do the dispatch (Tim's trick), if it has not been defined before.

When calling a generic function which has some trait-methods, dispatch will first work on the types as normal. If the selected method is a trait-method then trait dispatch will kick in too. Example:

@traitdef Tr{X}

fn(x::Integer) = 1 # a normal method
@traitfn fn(x::X) where {X<:AbstractFloat;  Tr{X}} = 2
@traitfn fn(x::X) where {X<:AbstractFloat; !Tr{X}} = 3

@traitimpl Tr{Float32}
@traitimpl Tr{Int} # this does not impact dispatch of `fn`

fn(5) # -> 1; dispatch only happens on the type
fn(Float32(5)) # -> 2; dispatch through traits
fn(Float64(5)) # -> 3; dispatch through traits

Further note that for a particular trait-method dispatch only works on one trait. Continuing above example, this does not work as one may expect:

@traitdef Tr2{X}
@traitfn fn(x::X) where {X<:AbstractFloat; Tr2{X}} = 4

@traitimpl Tr2{Float16}
fn(Float16(5)) # -> 4; dispatch through traits
fn(Float32(5)) # -> MethodError; method defined in previous example
               #    was overwritten above

This last definition of fn just overwrites the definition @traitfn f(x::X) where {X; Tr{X}} = 2 from above.

If you need to dispatch on several traits in a single trait-method, then you're out of luck. But please voice your grievance over in pull request #2.

Performance

There is no performance impact compared to normal functions thanks to Julia's clever design. Continuing the example from above and looking at the native code

julia> @code_native fn(5)
        .text
Filename: REPL[3]
        pushq   %rbp
        movq    %rsp, %rbp
Source line: 1
        movl    $1, %eax
        popq    %rbp
        retq
        nopl    (%rax,%rax)

julia> @code_native fn(Float16(5))
        .text
Filename: SimpleTraits.jl
        pushq   %rbp
        movq    %rsp, %rbp
Source line: 185
        movl    $4, %eax
        popq    %rbp
        retq
        nopl    (%rax,%rax)

shows that the normal method and the trait-method compile down to the same machine instructions.

However, if the trait-grouping function is not constant or a generated function then dispatch may be dynamic. This can be checked with @check_fast_traitdispatch, which checks whether the number of lines of LLVM code is the same for a trait function than a normal one:

checkfn(x) = rand()>0.5 ? true : false # a bit crazy!
@traitdef TestTr{X}
@traitimpl TestTr{X} <- checkfn(X)
# this tests a trait-function with TestTr{Int}:
@check_fast_traitdispatch TestTr
# this tests a trait-function with TestTr{String} and will
# also prints number of LLCM-IR lines of trait vs normal function:
@check_fast_traitdispatch TestTr String true

# Now this is fast:
@traitimpl TestTr{String}
@check_fast_traitdispatch TestTr String true

Advanced features

The macros of the previous section are the official API of the package and should be reasonably stable. What follows in this section is "under the hood" and may well be updated (but still signalled with minor version changes).

Instead of using @traitimpl to add types to traits, it can be programmed. Running @traitimpl IsNice{Int} essentially expands to

SimpleTraits.trait(::Type{IsNice{X1}}) where {X1 <: Int} = IsNice{X1}

I.e. trait is the identity function for a fulfilled trait and returns Not{TraitInQuestion{...}} otherwise (this is the fall-back for <:Any). So instead of using @traitimpl this can be coded directly. Note that anything but a constant function will probably not be inlined away by the JIT and will lead to slower dynamic dispatch (see @check_fast_traitdispatch for a helper to check).

Example leading to static dispatch:

@traitdef IsBits{X}
SimpleTraits.trait(::Type{IsBits{X1}}) where {X1} = isbits(X1) ? IsBits{X1} : Not{IsBits{X1}}
istrait(IsBits{Int}) # true
istrait(IsBits{Array{Int,1}}) # false
struct A
    a::Int
end
istrait(IsBits{A}) # true

Dynamic dispatch can be avoided using a generated function or pure functions (sometimes they need to be annotated with Base.@pure):

@traitdef IsBits{X}
@generated function SimpleTraits.trait(::Type{IsBits{X1}}) where X1
    isbits(X1) ? :(IsBits{X1}) : :(Not{IsBits{X1}})
end

What is allowed in generated functions is heavily restricted, see Julia manual. In particular, no methods which are defined after the generated function are allowed to be called inside the generated function, otherwise this issue is encountered. Generally, try non-generated functions first and only in a pinch generated functions. See also issue 40.

Note that these programmed-traits can be combined with @traitimpl IsBits{XYZ}, i.e. program the general case and add exceptions with @traitimpl IsBits{XYZ}.

Trait-inheritance can also be hand-coded with above trick. For instance, the trait given by (in pseudo syntax) BeautyAndBeast{X,Y} <: IsNice{X}, !IsNice{Y}, BelongTogether{X,Y}:

@traitdef BeautyAndBeast{X,Y}
function SimpleTraits.trait(::Type{BeautyAndBeast{X,Y}}) where {X,Y}
    if istrait(IsNice{X}) && !istrait(IsNice{Y}) && BelongTogether{X,Y}
        BeautyAndBeast{X,Y}
    else
        Not{BeautyAndBeast{X,Y}}
    end
end

Note that this will lead to slower, dynamic dispatch, as the function is not pure (it depends on the global state of which types belong to the traits IsNice and BelongTogether).

Note also that trait functions can be generated functions:

@traitfn @generated fg(x::X) where {X; IsNice{X}} = (println(x); :x)

Innards

The function macroexpand shows the syntax transformations a macro does. Here the edited output of running it for the macros of this package:

julia> macroexpand(:(@traitdef Tr{X}))

struct Tr{X} <: SimpleTraits.Trait
end

julia> macroexpand(:(@traitimpl Tr{Int}))

# this function does the grouping of types into traits:
SimpleTraits.trait(::Type{Tr{X1}}) where X1 <: Int = Tr{X1}
SimpleTraits.istrait(::Type{Tr{X1}}) where X1 <: Int = true # for convenience, really

julia> macroexpand(:(@traitfn g(x::X) where {X; Tr{X}}= x+1))

@inline g(x::X) where {X} = g(trait(Tr{X}), x) # this is Tim's trick, using above grouping-function
g(::Type{Tr{X}},x::X) where {X} = x + 1 # this is the logic

julia> macroexpand(:(@traitfn g(x::X) where {X; !Tr{X}}= x+1000))

# the trait dispatch helper function needn't be defined twice,
# only the logic:
g(::Type{ Not{Tr{X}} }, x::X) where {X} = x + 1000

For a detailed explanation of how Tim's trick works, see Traits.jl: Dispatch on traits. The difference here is I make the methods containing the logic part of the same generic function (there it's in _f).

Base Traits

I started putting some Julia-Base traits together which can be loaded with using SimpleTraits.BaseTraits, see the source for all definitions.

Example, dispatch on whether an argument is immutable or not:

@traitfn f(x::X) where {X; IsImmutable{X}} = X(x.fld+1) # make a new instance
@traitfn f(x::X) where {X; !IsImmutable{X}} = (x.fld += 1; x) # update in-place

# use
mutable struct A; fld end
struct B; fld end
a=A(1)
f(a) # in-place
@assert a.fld == A(2).fld

b=B(1) # out of place
b2 = f(b)
@assert b==B(1)
@assert b2==B(2)

Background

This package grew out of an attempt to reduce the complexity of Traits.jl, but at the same time staying compatible (but which it isn't). Compared to Traits.jl, it drops support for:

  • Trait definition in terms of methods and constraints. Instead the user needs to assign types to traits manually. This removes the most complex part of Traits.jl: the checking whether a type satisfies a trait definition.
  • trait functions which dispatch on more than one trait. This allows to remove the need for generated functions, as well as removing the rules for trait-dispatch.

The reason for splitting this away from Traits.jl are:

  • creating a more reliable and easier to maintain package than Traits.jl
  • exploring inclusion in Base (see #13222).

My JuliaCon 2015 talk gives a 10 minute introduction to Traits.jl and SimpleTraits.jl.

The Future

The future of traits in Julia-Base: According to Stefan Karpinski's JuliaCon 2016 talk, Julia 1.0, traits are scheduled to land after Julia 1.0. My crystal ball tells me that all or most of the functionality of this package will be supported in the future trait system (multiparameter-traits may not be). Thus I expect the transition will be mostly a matter of a syntax update and less of a semantic update. Also, an advantage to using this package versus hand-coding Holy-traits will be that all occurrences of trait usage are clearly marked and thus easier to update.

The future of this package: I see it as light-weight package focusing on letting functions use dispatch based on traits. This dispatch is currently fairly limited, see section "Gotcha" above, but may be expanded in the future: either through something like in PR m3/multitraits.

In the unlikely event that I find myself with too much time on my hands, I may try to develop a companion package to allow the specification of a trait in terms of interfaces. The combination of the two packages would then have similar functionality to my experimental package Traits.jl. If anyone fancies a go at writing this companion package, I would be very happy to help and contribute. After the type-system overhaul lands, this should be much less hackish than what's in Traits.jl.

References

  • Traits.jl and its references. In particular here is an in-depth discussion on limitations of Holy-Traits, which this package implements.

To ponder

  • There is a big update sitting in the branch m3/multitraits; but I never quite finished it. It would also address the next point:
  • Could type inheritance be used for sub-traits (Jutho's idea)? In particular could it be used in such a way that it is compatible with the multiple inheritance used in Traits.jl?

Download Details:

Author: Mauro3
Source Code: https://github.com/mauro3/SimpleTraits.jl 
License: MIT license

#julia #simple 

SimpleTraits.jl: Simple Traits for Julia

SimpleStructs.jl: Easy to Use Struct Definition with Defaults

SimpleStructs    

This is a simple utility of defining structs by specifying types, default values and value constraints for fields, with an automatically defined user-friendly constructor. This code is extracted from Mocha.jl and MXNet.jl.

This utility is useful to define structs holding specifications or hyperparameters. The following is an example of specifications of a stochastic gradient descent optimizer used in MXNet.jl:

@defstruct SGDOptions <: AbstractOptimizerOptions (
  (lr                :: Real = 0.01, lr > 0),
  (momentum          :: Real = 0.0, momentum >= 0),
  (grad_clip         :: Real = 0, grad_clip >= 0),
  (weight_decay      :: Real = 0.0001, weight_decay >= 0),
  lr_scheduler       :: Any  = nothing,
  momentum_scheduler :: Any  = nothing
)

And this is an example of the definition of a Dropout layer in Mocha.jl:

@defstruct DropoutLayer <: Layer (
  name       :: AbstractString = "dropout",
  auto_scale :: Bool = true,
  (ratio     :: AbstractFloat = 0.5, 0 < ratio < 1),
  (bottoms   :: Vector{Symbol} = Symbol[], length(bottoms) == 1),
)

API

The main utilities provided by this package are two macros: @defstruct and @defimmutable. They are almost the same, except that the latter defines a type that is immutable. The macros can be called in the following way

@defstruct StructName (
  field_name :: field_type,
  (fname2    :: ftype2 = default_val2, fname2 > 0 && fname2 < 5),
  (fname3    :: ftype3 = default_val3, fname3 <= fname2),
)

The StructName can be StructName <: SuperTypeName if the struct needs to be a subtype of SuperTypeName. Each field should have

  • field name: the name of the field.
  • field type: the type used to store the field value. Note the constructor accept any value type, and calls convert explicitly on the user supplied values. So there is no frustration about Julia types being not covariant. For example, for a field of type Vector{AbstractString}, it is OK if user call with ["foo", "bar"], which will be of type Vector{ASCIIString}.
  • field default value: this is optional. When a default value is not presented, it means the field is required. An AssertionError will be thrown if the user does not provide a value for this field.
  • field value constraints: this is optional. Value constraints can be used to ensure the user supplied values are reasonable. Note the constraints are asserted in the order as the fields are defined. So in the example above, the constraint for fname3 can use the value for fname2 and safely assume the constraints for fname2 is already satisfied.

A constructor will be automatically defined, where each argument should be provided as keyword arguments:

struct = StructName(field_name=7, fname3=8)

Please see the unit tests for more examples.

Download Details:

Author: Pluskid
Source Code: https://github.com/pluskid/SimpleStructs.jl 
License: View license

#julia #simple #util 

SimpleStructs.jl: Easy to Use Struct Definition with Defaults
Waylon  Bruen

Waylon Bruen

1651074840

Gormt: Database to Golang Struct

mysql database to golang struct conversion tools base on gorm(v1/v2),You can automatically generate golang sturct from mysql database. big Camel-Case Name Rule, JSON tag.

gui support

show

./gormt -g=true

cmd support

show

./gormt -g=false

install

go get -u -v github.com/xxjwxc/gormt@master

or: Dowloading


1. Configure default configuration items through the current directory config.yml file

note: for latest version of config format, please check /data/config/MyIni.go

out_dir : "./model"  # out dir
url_tag : json # web url tag(json,db(https://github.com/google/go-querystring))
language :  # language(English,中 文)
db_tag : gorm # DB tag(gorm,db)
simple : false #simple output
is_out_sql : false # Whether to output sql
is_out_func : true # Whether to output function
is_foreign_key : true # Whether to mark foreign key or not
is_gui : false # Whether to operate on gui
is_table_name : false # Whether to out GetTableName/column function
is_null_to_point : false # database is 'DEFAULT NULL' then set element type as point
is_web_tag: false
is_web_tag_pk_hidden: false
table_prefix: "" #table prefix
table_names: "" # Specified table generation, multiple tables with , separated
is_column_name: true # Whether to generate column names
is_out_file_by_table_name: false # Whether to generate multiple models based on table names
db_info :
    host : "127.0.0.1"
    port : 3306
    username : "root"
    password : "qwer"
    database : "oauth_db"
    type: 0 # database type (0:mysql , 1:sqlite , 2:mssql)
self_type_define: # Custom data type mapping
    datetime: time.Time
    date: time.Time
out_file_name: "" # Custom build file name
web_tag_type: 0 # json tag 0: Small Camel-Case 1: _

2. get help

./gormt --help
or
./gormt -h

-------------------------------------------------------
base on gorm tools for mysql database to golang struct

Usage:
  main [flags]

Flags:
  -d, --database string   数据库名
  -f, --foreign           是否导出外键关联
  -F, --fun               是否导出函数
  -g, --gui               是否ui显示模式
  -h, --help              help for main
  -H, --host string       数据库地址.(注意-H为大写)
  -o, --outdir string     输出目录
  -p, --password string   密码.
      --port int          端口号 (default 3306)
  -s, --singular          是否禁用表名复数
  -b, --table_names string 表名称  
  -l, --url string        url标签(json,url)
  -u, --user string       用户名.
  

3. Can be updated configuration items using command line tools

./gormt -H=127.0.0.1 -d=oauth_db -p=qwer -u=root --port=3306 -F=true

4. Support for gorm attributes

  • Database tables, column field annotation support
  • json tag json tag output
  • gorm.Model Support export gorm.model>>>
  • PRIMARY_KEY Specifies column as primary key
  • UNIQUE Specifies column as unique
  • NOT NULL Specifies column as NOT NULL
  • INDEX Create index with or without name, same name creates composite indexes
  • UNIQUE_INDEX Like INDEX, create unique index
  • Support foreign key related properties Support export gorm.model>>>
  • Support function export (foreign key, association, index , unique and more)Support export function >>>
  • model.Condition{} sql link

You can enrich data types in def

5. Demonstration

  • sql:
CREATE TABLE `user_account_tbl` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`account` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`password` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`account_type` int(11) NOT NULL DEFAULT '0' COMMENT '帐号类型:0手机号,1邮件',
`app_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT 'authbucket_oauth2_client表的id',
`user_info_tbl_id` int(11) NOT NULL,
`reg_time` datetime DEFAULT NULL,
`reg_ip` varchar(15) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`bundle_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`describ` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `account` (`account`) USING BTREE,
KEY `user_info_id` (`user_info_tbl_id`) USING BTREE,
CONSTRAINT `user_account_tbl_ibfk_1` FOREIGN KEY (`user_info_tbl_id`) REFERENCES `user_info_tbl` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='用户账号'

--->Derived results

// UserAccountTbl 用户账号
type UserAccountTbl struct {
    ID            int    `gorm:"primary_key"`
    Account       string `gorm:"unique"`
    Password      string
    AccountType   int         // 帐号类型:0手机号,1邮件
    AppKey        string      // authbucket_oauth2_client表的id
    UserInfoTblID int         `gorm:"index"`
    UserInfoTbl   UserInfoTbl `gorm:"association_foreignkey:user_info_tbl_id;foreignkey:id"` // 用户信息
    RegTime       time.Time
    RegIP         string
    BundleID      string
    Describ       string
}

more>>>

6. support func export

The exported function is only the auxiliary class function of Gorm, and calls Gorm completely

// FetchByPrimaryKey primary or index 获取唯一内容
func (obj *_UserAccountTblMgr) FetchByPrimaryKey(ID int) (result UserAccountTbl, err error) {
    err = obj.DB.Table(obj.GetTableName()).Where("id = ?", ID).Find(&result).Error
    if err == nil && obj.isRelated {
        {
            var info UserInfoTbl // 用户信息
            err = obj.DB.Table("user_info_tbl").Where("id = ?", result.UserInfoTblID).Find(&info).Error
            if err != nil {
                return
            }
            result.UserInfoTbl = info
        }
    }

    return
}

more>>>

how to use call style>>>

7. page

Use of paging query in gormt

8. build

make windows
make linux
make mac

or

go generate

note : in windows not support utf-8 style . ASCALL model

  • Switch encoding mode
CHCP 65001 

column notes default

  • Add a comment to the column starting with [@gorm default:'test']
  • example [@gorm default:'test';->;<-:create]this is my notes Indicates that the default value is 'test',can read/creat/write
  • Use of foreign key notes[@fk tableName.columnName]this is my notes Represents the 'columnName' column associated with the 'tableName'

9. one windows gui tools

1

2

3

4

Download

link

Stargazers over time

Stargazers over time

中文文档

Author: xxjwxc
Source Code: https://github.com/xxjwxc/gormt 
License: MIT License

#go #golang #orm #mysql 

Gormt: Database to Golang Struct
Vicky  Graham

Vicky Graham

1627098480

Coffee Shop App UI-Speed Code-FLUTTER -Simple | Clean | UI

Regards to all coders out there.

Here comes the sixth video of this channel and
today we are going to code a Coffee Shop App UI in Flutter which looks pretty simple
but modern and covers minute details of designing. and that’s what exactly our aim is to give you.

#ui #simple #flutter #speed code #app ui #coffee shop

Coffee Shop App UI-Speed Code-FLUTTER -Simple | Clean | UI
Vicky  Graham

Vicky Graham

1627092000

Audio Books App UI-PART-1-Speed Code-FLUTTER-Simple | Clean | UI

Regards to all coders out there.

Here comes the Seventh video of this channel
today we are going to code a AudioBooks App UI in Flutter which is again pretty simple
but consist new widgets and covers minute details of designing. and that’s what exactly our aim is to give you.

#ui #simple #flutter #speed code #app ui #audio

Audio Books App UI-PART-1-Speed Code-FLUTTER-Simple | Clean | UI
Vicky  Graham

Vicky Graham

1627088400

Audio Books App UI-PART-2-Speed Code-FLUTTER-Simple | Clean | UI

Regards to all coders out there.

Here comes the Eighth video of this channel which is also the second part of
AudioBooks App UI Series in Flutter which is again pretty simple
but consist new widgets and covers minute details of designing. and that’s what exactly our aim is to give you.

#ui #flutter #simple #speed code #app ui

Audio Books App UI-PART-2-Speed Code-FLUTTER-Simple | Clean | UI
Vicky  Graham

Vicky Graham

1627005600

E- Commerce App UI - Speed Code - FLUTTER | Simple | Clean | UI

Sup coders!!

Today we’ll be converting another dribbble inspiration into a real coded app. Our today’s
inspiration is a e-Commerce Mobile App Design by Oyasim Ahmed Naeem for Dude Shape. Thank you so much for creating such an awesome #UI.
This UI contains 3 screens:

  1. Sign in
  2. Cart
  3. Payments
    UI is smooth and simple but what we’ll be focusing on is the use of a consistent Theme all over the app and see how it is easy to maintain.
    Check out the video to see how easy it is to create a consistent theme for our app and use it all over the app without repetition.

Social Media:
GitHub: https://github.com/KumarArab

#ui #clean #simple #flutter #speed code #app ui

E- Commerce App UI - Speed Code - FLUTTER | Simple | Clean | UI
Delbert  Ferry

Delbert Ferry

1620125743

In Database Machine Learning — Made Simple

One of the biggest problems with creating ML models is that the models are built in environments that are useless for deployment.

The fundamental issue is that Machine Learning deployment is a young and immature field, and it hasn’t yet developed the toolkits that database or software development have. Databases, for example, are widely available, stable, (sometimes) scalable and extremely fast. Because of this, we’re going to piggyback on the work that database engineers have done, and use their tools to our advantage. Here, we’ll focus on using scale-out RDBMS for model deployment.

#database #machine-learing #simple #data

In Database Machine Learning — Made Simple
Abdullah  Kozey

Abdullah Kozey

1620066840

Learn C by writing a simple game

taught myself about programming back in elementary school. My first programs were on the Apple II, but eventually, I learned C by reading books and practicing. And the best way to practice programming is to write sample programs that help exercise your new knowledge.

One program I like to write in a new language is a simple “guess the number” game. The computer picks a random number from 1 to 100, and you have to figure it out by making guesses. In another article, I showed how to write this “Guess the number” game in Bash, and my fellow Opensource.com authors have written articles about how to write it in JavaJulia, and other computer languages.

#c #game #simple

Learn C by writing a simple game
Arne  Denesik

Arne Denesik

1603450800

Cohort Analysis : Simplified, Actionable

I’ve read a lot of articles and blogs on cohort analysis, churn and customer retention, most of them are very technical & hard to understand. So, I decided to choose a different path and try to make it simple as well as actionable.

If you want to know more about cohort analysis, and how to apply it to improve your business, this blog is perfectly made for you.

Let’s jump right into it!

WHAT IS COHORT ANALYSIS?

A Cohort is a group of people who share a common characteristic over a certain period of time, such as first purchase date, signup date, the location they belong to, etc.,

Example: Class — 2020 is a cohort, and all the students who graduated in that year are parts of that same cohort.

In cohort analysis, we track these group of people over a certain period of time, and try to draw insights to get a better understanding of your product/service / Marketing campaigns, etc…,

Cohort analysis is a widely used method to reduce the churn rate and improve customer retention. Before we dive into the cohort analysis, first try to understand what is churn rate and customer retention.

CHURN RATE:

Percentage of customers who stop using or buying from your website/store/e-commerce site etc, within a given period of time. Churn rate is sometimes also called a ‘Rate of Attrition’.

#cohort-analysis #customer-retention #simple #actionable #data-analysis

Cohort Analysis : Simplified, Actionable
Flo  D'Amore

Flo D'Amore

1601408760

Dead Simple Authorization Technique Based on HTTP Verbs

Authorization is a basic feature of modern web applications. It’s a mechanism of specifying access rights or privileges to resources according to user roles. In case of CMS like applications, it needs to be equipped with advanced libraries and authorization techniques. But for minimal applications a full fledged library can be an overhead.

I will discuss a dead simple authorization technique based on HTTP verbs, for this particular purpose.

Things to consider beforehand

This technique isn’t something you can implement anywhere. Use this only if your requirements match the particular scenario.

  • It works only for REST APIs. Everything happens on middleware layer. If you have a simple MVC based REST APIs, this is for you.
  • It heavily relies on the HTTP verbs and the URL naming convention. So API endpoints should be super clear and structured. Similar to some structure like this one.
List Products  : GET    /products
Product Detail : GET    /products/{id}
Create Product : POST   /products
Update Product : PUT    /products/{id}
Delete Product : DELETE /products/{id}
  • A URL can perform many stuffs; but all cannot be expressed just in its naming and HTTP verb. If you require complex authorization, you can’t just rely on this technique.

#nodejs #jwt-token #rest-api #simple #authorization

Dead Simple Authorization Technique Based on HTTP Verbs
Annalise  Hyatt

Annalise Hyatt

1598998320

Change Your Site’s Color Scheme with an Awesome Colorpicker in Vue.js 🎨

This article is about creating a global colorpicker for your Vue.js application quickly and easily. In the colorpicker you can select certain colors, which then determine the look of the application. You can then store these colors either locally as a cookie or to an API to store them in a database. For this article I decided to use cookies, but the code is actually the same for APIs.

Requirements

Vue.js

Vue-Cookies

Colorpicker Component

First of all we are going to start with our Colorpicker Component

Image for post

Template Tag

The Main Cointainer places our Colorpicker centered on the page. TopBar is this small menu bar and the AccentBar shows the currently selected color. Now it gets more exciting in the ColorContainer.

Image for post

Color Picker

In the second div we see a v-for loop which gives us the colors. A clickevent which changes the gloabel color and a dynamic :style tag which sets the current color as background color.

Now to our script tag.

Image for post

Script Tag

currentColor is the selected color with a default value. Colors are our available colors, they can be fetched from an API or defined locally like here. ChangeColor(color) is our clickevent in which the clicked color is passed. Here we simply set the selected color as currenColor and save it in the cookie “Theme”. Optionally an API post/put can be sent here.

Mounted() gets the currently selected color from the cookie when rendering the page and sets it as currentColor.

#color-picker #web-development #simple #vuejs #javascript

Change Your Site’s Color Scheme with an Awesome Colorpicker in Vue.js 🎨