1675948200
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.
(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.
(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.
(Mehant Kammakomati, CC BY-SA 4.0)
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
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.
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.
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:
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
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.
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.
Visit the Move2Kube site to learn more about replatforming using Konveyor Move2Kube.
Original article source at: https://opensource.com/
1675253940
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.
# 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
Author: Seungeunrho
Source Code: https://github.com/seungeunrho/minimalRL
License: MIT license
#machinelearning #reinforcementlearning #deeplearning #simple
1671774240
When people try to learn JavaScript, or any coding skill really, they often run into the same challenges:
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.
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:
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.
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:
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.
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.
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.
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.
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:
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:
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/
1664354160
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:
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).@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!"
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 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
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.
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
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:
The reason for splitting this away from Traits.jl are:
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
To ponder
Author: Mauro3
Source Code: https://github.com/mauro3/SimpleTraits.jl
License: MIT license
1664217000
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),
)
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
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}
.AssertionError
will be thrown if the user does not provide a value for this field.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.
Author: Pluskid
Source Code: https://github.com/pluskid/SimpleStructs.jl
License: View license
1651074840
./gormt -g=true
./gormt -g=false
go get -u -v github.com/xxjwxc/gormt@master
or: Dowloading
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: _
./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 用户名.
./gormt -H=127.0.0.1 -d=oauth_db -p=qwer -u=root --port=3306 -F=true
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
}
// 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
}
make windows
make linux
make mac
or
go generate
CHCP 65001
[@gorm default:'test']
[@gorm default:'test';->;<-:create]this is my notes
Indicates that the default value is 'test',can read/creat/write[@fk tableName.columnName]this is my notes
Represents the 'columnName' column associated with the 'tableName'Author: xxjwxc
Source Code: https://github.com/xxjwxc/gormt
License: MIT License
1627098480
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
1627092000
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
1627088400
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
1627005600
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:
Social Media:
GitHub: https://github.com/KumarArab
#ui #clean #simple #flutter #speed code #app ui
1620125743
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
1620066840
I 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 Java, Julia, and other computer languages.
#c #game #simple
1603450800
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!
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
1601408760
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.
This technique isn’t something you can implement anywhere. Use this only if your requirements match the particular scenario.
List Products : GET /products
Product Detail : GET /products/{id}
Create Product : POST /products
Update Product : PUT /products/{id}
Delete Product : DELETE /products/{id}
#nodejs #jwt-token #rest-api #simple #authorization
1598998320
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.
First of all we are going to start with our Colorpicker Component
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.
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.
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