what will be a better approach to StreamData when one has 2 maps? - unit-testing

The following property test is working fine, however, I think there should be a better and more efficient way of implementing this.
params in the following property will be something like this:
%{
"project_id" => "%&!XX!hLCfsS-dO_<fy?kpi4y=AEumQ$Xn:#.7Fl TnH~k>ZLB[q",
"task_id" => [
%{"asset_id" => 10, "tasks" => []},
%{"asset_id" => 10, "tasks" => []}
]
}
Property Testing:
property "bad project value" do
[user, project] = prepare()
user_gen = constant(%{id: user.id})
project_gen = constant("project_id")
|> map_of(Factory.my_terms, length: 1)
tasks = constant(%{"asset_id" => 10, "tasks" => []})
|> list_of(length: 2)
tasks_gen = constant("task_id")
|> map_of(tasks, length: 1)
check all project <- project_gen, task <- tasks_gen , user <- user_gen do
params = Map.merge(project, task)
res = ProjectTask.Save.save(params, user)
assert res == {:error, :not_found}
end
Factory.my_terms is the following:
def my_terms() do
one_of([string(:alphanumeric), string(:ascii), atom(:alphanumeric), integer(), binary()])
end
UPDATE
property "bad project value" do
[user, project] = prepare()
project_gen = constant("project_id")
|> map_of(Factory.my_terms, length: 1)
tasks = List.duplicate(%{"asset_id" => 10, "tasks" => []}, 2)
tasks = %{"tasks" => tasks}
check all project <- project_gen do
params = Map.merge(project, tasks)
res = ProjectTask.Save.save(params, %{id: user.id})
assert res == {:error, :not_found}
end
end

Related

how can I check from firestore how many items have a true or false value and show only the true in a list? - flutter

I want to make that in a Todo app, only the elements that have the true value are showing in the list. How can I do this?
You can check using where in your stream like this
Stream<List<TodoItem>> getSomeoneItems() {
return FirebaseFirestore.instance.collection('items')
.where('your field name', isEqualTo: true)
.snapshots()
.map((qSnap) =>
qSnap.docs.map((doc) => TodoItem.fromJson(doc.data())).toList());
}
we consider this is your list
List = [
Model(name:"1" , val: true)
Model(name:"2" , val: false)
Model(name:"3" , val: true)
]
and with the below code we can find items with true val
List result = [];
a.forEach((element) {
if(element.val == true){
result.add(element);
}
})

How do I transform a List[String] to a List[Map[String,String]] given that the list of string represents the keys to the map in Scala?

I have a list of references:
val references: List[String]= List("S","R")
I also have variables which is:
val variables: Map[String,List[String]]=("S"->("a","b"),"R"->("west","east"))
references is a list of keys of the variables map.
I want to construct a function which takes:
def expandReplacements(references:List[String],variables:Map[String,List[String]]):List[Map(String,String)]
and this function should basically create return the following combinations
List(Map("S"->"a"),("R"->"west"),Map("S"->"a"),("R"->"east"),Map("S"->"b"),("R"->"west"),Map("S"->"b"),("R"->"east"))
I tried doing this:
val variables: Map[String,List[String]] = Map("S" -> List("a", "b"), "R" -> List("east", "central"))
val references: List[String] = List("S","R")
def expandReplacements(references: List[String]): List[Map[String, String]] =
references match {
case ref :: refs =>
val variableValues =
variables(ref)
val x = variableValues.flatMap { variableValue =>
val remaining = expandReplacements(refs)
remaining.map(rem => rem + (ref -> variableValue))
}
x
case Nil => List.empty
}
If you have more than 2 references, you can do:
def expandReplacements(references: List[String], variables :Map[String,List[String]]): List[Map[String, String]] = {
references match {
case Nil => List(Map.empty[String, String])
case x :: xs =>
variables.get(x).fold {
expandReplacements(xs, variables)
} { variableList =>
for {
variable <- variableList.map(x -> _)
otherReplacements <- expandReplacements(xs, variables)
} yield otherReplacements + variable
}
}
}
Code run at Scastie.
So I have Figured it Out
def expandSubstitutions(references: List[String]): List[Map[String, String]] =
references match {
case r :: Nil => variables(r).map(v => Map(r -> v))
case r :: rs => variables(r).flatMap(v => expandSubstitutions(rs).map(expanded => expanded + (r -> v)))
case Nil => Nil
}
This Returns:
List(Map(R -> west, S -> a), Map(R -> east, S -> a), Map(R -> west, S -> b), Map(R -> east, S -> b))
Your references representation is suboptimal but if you want to use it...
val variables: Map[String,List[String]] = [S -> List("a", "b"), R -> List("east", "central")]
val references: List[String] = List("S","R")
def expandReplacements(references: List[String]): List[Map[String, String]] =
references match {
case List(aKey, bKey) =>
val as = variables.get(aKey).toList.flatten
val bs = variables.get(bKey).toList.flatten
as.zip(bs).map { case (a, b) =>
Map(aKey -> a, bKey -> b)
}
case _ => Nil
}

no function clause matching in Ecto.Changeset.cast/4

I've been stuck with a casting error with naivedatetime. Could someone unlock me please?
This is the POST request i'm trying to do:
URL: http://localhost:4000/api/workingtimes/1
Body:
{
"start": "2019-08-21 07:27:00",
"end": "2020-09-20 07:27:00"
}
Here is my schema:
defmodule TimeManager.Workingtimes.Workingtime do
use Ecto.Schema
import Ecto.Changeset
schema "workingtimes" do
field :start, :naive_datetime
field :end, :naive_datetime
belongs_to :user, TimeManager.Users.User
timestamps()
end
#doc false
def changeset(workingtime, attrs) do
workingtime
|> cast(attrs, [:start, :end, :user_id])
|> validate_required([:start, :end, :user_id])
|> assoc_constraint(:user)
end
end
And here is my create function in the controller:
def create(conn, workingtime_params) do
with {:ok, %Workingtime{} = workingtime} <- Workingtimes.create_workingtime(workingtime_params) do
conn
|> put_status(:created)
|> put_resp_header("location", Routes.workingtime_path(conn, :show, workingtime))
|> render("workingtime.json", workingtime: workingtime)
end
end
finally here is my create_workingtime function in my workingtimes.ex
def create_workingtime(attrs \\ %{}) do
%{"start" => starttime, "end" => endtime, "user_id"=>user_id } = attrs
{:ok, naivestart} = NaiveDateTime.from_iso8601(starttime)
{:ok, naiveend} = NaiveDateTime.from_iso8601(endtime)
attrs = %{"start" => naivestart, "end"=>naiveend, "user_id"=>user_id}
Workingtime
|> Workingtime.changeset(attrs)
|> Repo.insert()
end
The error in the log is:
(exit) an exception was raised:
** (FunctionClauseError) no function clause matching in Ecto.Changeset.cast/4
(ecto 3.5.2) lib/ecto/changeset.ex:461: Ecto.Changeset.cast(TimeManager.Workingtimes.Workingtime, %{"end" => ~N[2020-10-21 19:45:24.879000], "start" => ~N[2020-10-21 19:45:24.879000], "user_id" => "1"}, [:start, :end, :user_id], [])
(time_manager 0.1.0) lib/time_manager/workingtimes/workingtime.ex:16: TimeManager.Workingtimes.Workingtime.changeset/2
(time_manager 0.1.0) lib/time_manager/workingtimes.ex:63: TimeManager.Workingtimes.create_workingtime/1
(time_manager 0.1.0) lib/time_manager_web/controllers/workingtime_controller.ex:16: TimeManagerWeb.WorkingtimeController.create/2
(time_manager 0.1.0) lib/time_manager_web/controllers/workingtime_controller.ex:1: TimeManagerWeb.WorkingtimeController.action/2
(time_manager 0.1.0) lib/time_manager_web/controllers/workingtime_controller.ex:1: TimeManagerWeb.WorkingtimeController.phoenix_controller_pipeline/2
Ecto.Changeset.cast/4 takes a schema struct as the first argument, not a schema module. In your create_workingtime/1 function, try changing to this:
%Workingtime{}
|> Workingtime.changeset(attrs)
|> Repo.insert()
Found out the issue, in the create_workingtime function it was: %Workingtime{} isntead of just Workingtime
def create_workingtime(attrs \\ %{}) do
%{"start" => starttime, "end" => endtime, "user_id"=>user_id } = attrs
{:ok, naivestart} = NaiveDateTime.from_iso8601(starttime)
{:ok, naiveend} = NaiveDateTime.from_iso8601(endtime)
attrs = %{"start" => naivestart, "end"=>naiveend, "user_id"=>user_id}
%Workingtime{}
|> Workingtime.changeset(attrs)
|> Repo.insert()
end

How to check existance and nil in single line for variable in ruby on rails

def import_update
require 'csv'
file = params[:file]
CSV.foreach(file.path, headers: true) do |row|
#prod = Spree::Product.find(row["id"])
#var = Spree::Variant.find_by(product_id: #prod.id)
Spree::Product.where(:id => row["id"]).update_all(:name => row["name"] if !row[name].nil?.present?, :meta_description => row["meta_description"], :shipping_category_id => row["shipping_category_id"], :description => row["description"], :meta_keywords => row["meta_keywords"], :tax_category_id => row["tax_category_id"], :available_on => row["available_on"], :deleted_at => row["deleted_at"], :promotionable => row["promotionable"], :meta_title => row["meta_title"], :featured => row["featured"], :supplier_id => row["supplier_id"])
end
end
I want check that row is present or not. if it is present then it updated when it is not null and condition is in single line because I want to apply this for all variable in updation statement.I wrote code above but showing error.
Try this:
params = ["name","meta_description","shipping_category_id","description","meta_keywords","tax_category_id","available_on","deleted_at","promotionable","meta_title","featured","supplier_id"
hash = {}
params.each do |param|
if row[param]
hash[param] = row[param]
end
end
Spree::Product.where(:id => row["id"]).update_attributes(hash)
This will let you keep your code dry.
EDIT:
What are these lines supposed to do?:
#prod = Spree::Product.find(row["id"])
#var = Spree::Variant.find_by(product_id: #prod.id)
I presume you don't have several entries with one ID. And your not using the objects that you retrieved in those two lines, so simply write the method like this:
def import_update
require 'csv'
file = params[:file]
params = ["name","meta_description","shipping_category_id","description","meta_keywords","tax_category_id","available_on","deleted_at","promotionable","meta_title","featured","supplier_id"]
CSV.foreach(file.path, headers: true) do |row|
hash = {}
params.each do |param|
if row[param]
hash[param] = row[param]
end
end
Spree::Product.find(row["id"]).update_all(hash)
end
end

javascript regex window params

need help with regex
var s = "left=123,top=345,width=123, height= 34, center=yes, help=no,resizable=yes, status=now";
need to get all params (name -> value)
tried this way /(\w+)\s?=(\S+)[\s|,]/
result:
array(3) {
[0] =>
array(3) {
[0] =>
string(28) "left=123,top=345,width=123, "
[1] =>
string(12) "center=yes, "
[2] =>
string(23) "help=no,resizable=yes, "
}
[1] =>
array(3) {
[0] =>
string(4) "left"
[1] =>
string(6) "center"
[2] =>
string(4) "help"
}
[2] =>
array(3) {
[0] =>
string(22) "123,top=345,width=123,"
[1] =>
string(4) "yes,"
[2] =>
string(17) "no,resizable=yes,"
}
}
I tried to use the split method, but don't know if it's good. Comments are welcome.
var s = "left=123,top=345,width=123, height= 34, center=yes, help=no,resizable=yes, status=now";
var params = s.replace(/\s*,\s*/g,',').replace(/\s*=\s*/g,'=').split(',');
var arg_array = {};
for(var n = 0, len=params.length; n < len; n++) {
var arg = params[n].split("=");
arg_array[arg[0]] = arg[1];
}
Result (arg_array):
({left:"123", top:"345", width:"123", height:"34", center:"yes", help:"no", resizable:"yes", status:"now"})
Try this:
/(\w+)\s*=\s*([^,\s]*)/
Try this:
([\w\d]+)\s*=\s*([\w\d]+)
I'm assuming that both parameter and value may contain only letters and digits. You may choose to be more permissive by writing this:
([^=\s,]+)\s*=\s*([^=\s,]+)