Hello I am brand new to Elm and I am having some difficulty with getting the current time and converting it into a date in Elm.
I have a message type - Message and a function to add a new message to the model. I am trying to store the time the message was posted along with the text and user id.
However I keep getting this error -
The argument to function `fromTime` is causing a mismatch.
59| Date.fromTime (currentTime Time.now)
^^^^^^^^^^^^^^^^^^^^
Function `fromTime` is expecting the argument to be:
Time
But it is:
x -> Time -> Time
Hint: It looks like a function needs 2 more arguments.
Here is the code
type alias Message =
{ text : String,
date : Date,
userId : Int
}
currentTime : task -> x -> Time -> Time
currentTime _ _ time =
time
newMessage : String -> Int -> Message
newMessage message id =
{ text = message
, date = Date.fromTime (currentTime Time.now)
, userId = id
}
I really can't figure out what is going on. Any help would be much appreciated. Thanks.
Elm is a pure language, where function calls are deterministic. Requesting the current time is a little more complex, because there is no function we can call that will return us a different time depending on the time of day. Function calls with the same input will always return the same thing.
Getting the current time lies in the land of side effects. We have to ask the architecture to give us the time in a way that is pure. The way Elm deals with that is through the Task and Program functionality. You send a Task to the Elm Architecture through a Cmd in your update function. The Elm Architecture then does its own thing behind the scenes to fetch the current time, then it responds in pure code with another call to your update function.
Here is a simple example you can paste in at http://elm-lang.org/try, where you click a button to see the current time converted to a Date.
import Html exposing (..)
import Html.Events exposing (onClick)
import Time exposing (..)
import Date
import Task
main =
Html.program
{ init = { message = "Click the button to see the time" } ! []
, view = view
, update = update
, subscriptions = \_ -> Sub.none
}
type alias Model = { message: String }
view model =
div []
[ button [ onClick FetchTime ] [ text "Fetch the current time" ]
, div [] [ text model.message ]
]
type Msg
= FetchTime
| Now Time
update msg model =
case msg of
FetchTime ->
model ! [ Task.perform Now Time.now ]
Now t ->
{ model | message = "The date is now " ++ (toString (Date.fromTime t)) } ! []
If you are familiar with javascript, the purpose of the Now message could be loosely thought of as a callback function, where the argument it provides is the time sent by the Elm Architecture.
Related
I took this to the Godot Reddit first, but honestly it's not much help imo. A lot of questions go unanswered there. So here I am.
As the title says, Im making a quest system in godot 2d using nested dictionaries. Ive seen people use Nodes, Classes or otherwise for their quest systems, and a few dictionary based ones out there. I chose dictionaries as I know them the best(still isnt a whole lot, or i probably wouldnt be here asking this lol) And my quest system is set up like so:
QuestBase --> QuestHandler --> PlayerData
QuestBase is a giant dictionary of all available quests in the game.
PlayerData is a giant dictionary of all the player stats(including active, completed, or failed quests)
and QuestHandler takes a questName in a function to Copy the quest(questName) from QuestBase dict into the PlayerData.quests_active dict.(quests_active is a dictionary of quests(also dictionaries) inside of the PlayerData dictionary lol) But i cant seem to get it to work. I've done it a couple different ways now, including the way the Godot documentation states on how to add Dinctionaries into dictionaries. Please help, this is the error I get from QuestHandler:
Invalid set index 'tutorialQuest' (on base: 'Nil') with value of type 'Dictionary'
QuestBase:
var storyQuests = {
"tutorialQuest":{
"name" : "Your First Steps",#Name of the Quest
"desc" : "Get to know your environment and learn the ropes.",#Description of the Quest
"level" : 1, #Required level before player can accept quest
"questType" : 0, #0=Story Quest || 1=Side Quest || 2=Repeateable Quest
"taskType": 0, #0=Progressive(task must be completed in order) || 1=Synchronous(tasks can be completed in any order, and all at once)
"tasks":{#Dictionary of Quest's Tasks
"task1":{
"text":"Talk to Bjorn",#Text to display in Quest log
"type":0,#0=Talk,1=Slay,2=Fetch,3=Deliver,4=Collect,5=Goto
"quantity":0,#Determines the amount to complete task for Slay, Fetch, and Collect
"target":"Bjorn",#Determines Who to talk to, or who to slay, or what to collect.
"completed":false#Is this task complete?
},
"task2":{
"text":"Talk to Bjorn",
"type":"Talk",
"target":"Bjorn",
"completed":false
},
"task3":{
"text":"Talk to Bjorn",
"type":"Talk",
"target":"Bjorn",
"completed":false
}
},
"itemReward":{
"items":["Sword", "Basic Elixer"],#Names of items to give
"amount":[1, 5]#Amount of each item to give, respectively.
},
"expReward":{
"skill":["Forestry","Smithing"],#Names of skills to add Exp to
"amount": [100,100] #Amount to add to each skill, respectively.
#1st number will increase first skill in "skill", etc...
},
"Complete":false,
"Failed":false
}
}
PlayerData:
var playerData = {
... irrelevant player data...
#Quests
"quests_active": {"blank":"blank"},
"quests_completed": {},
"quests_failed": {},
and Finally, Quest Handler:
func startQuest(questName: String):
var active_quests = PlayerData.playerData.get("quests_active")
if QuestBase.storyQuests.has(questName):
var questCopy = QuestBase.storyQuests.get(questName).duplicate(true)
PlayerData.playerData.get("quests_active")[questName] = questCopy #.quests_active.append(questCopy)
#print("Story Quest Started: " + PlayerData.playerData.QuestsActive.get(questName).get("name"))
elif QuestBase.sideQuests.has(questName):
var questCopy = QuestBase.sideQuests.get(questName).duplicate(true)
active_quests.append(questCopy)
#print("Side Quest Started: " + PlayerData.playerData.QuestsActive.get(questName).get("name"))
else:
print("Quest Doesn't Exist! Check Spelling!")
So I made this very small function. it is a bonehead easy function but frankly borderline my capabilities.. Im learning. The function works as expected, but I would like to go further. I would like to make it so I can either give it an argument (a username) and just get the information for that single user, or default to reporting all users. is this possible w/o starting over from what I have so far?
I have just poked around and seen some examples but nothing that I can fit into my script. that I can understand at least.
import boto3
iam = boto3.client('iam')
def user_group():
for myusers in iam.list_users()['Users']:
Group = iam.list_groups_for_user(UserName=myusers['UserName'])
print("User: " + myusers['UserName'])
for groupName in Group['Groups']:
print("Group: " + groupName['GroupName'])
print("----------------------------")
user_group()
I would like to have the ability to run this script in two fashions.
1) add an argument(s) of 'username' so I can get the response for a particular user
2) default to getting response for all users if no argument is given.
This can be done by using an argument with a default value:
def user_group(user = None):
if user is None:
print("No user")
else:
print(user)
user_group()
user_group('some user')
prints
No user
some user
In your case you may want to write
def user_group(user = None):
users_to_list = iam.list_users()['Users'] if user is None else [user]
for myusers in user_to_list:
...
I've tried not to ask the question so i tried for 2 days to solve this :( i couldn't . here i'm
im just trying to access the list 'Signals' outside the async function to work with it later on my sync code .
this is the async function its from a discord wrapper 'discord.py'
it reads messages on a specific channel. my goal is to get some list out of every message content .
import asyncio
from syncer import sync
import discord
import os
import time
from discord.ext import commands
class A:
TOKEN = "XXXXXXXXX"
client = commands.Bot(command_prefix = ".")
#client.event
async def on_message(message):
autor = message.author
content = message.content
channel = message.channel.id
while ( channel == 'XXXXXXXXXXXXXX' ):
if #some filters
Signal =[message.content]
return Signal #'till here the code functions and i get the list'
bot =A()
tasks = asyncio.ensure_future(bot.on_message())
loop =asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(*tasks))
bot.client.run(bot.TOKEN)
this is me trying to get the Signal list :
bot =A()
tasks = asyncio.ensure_future(bot.on_message())
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(*tasks))
bot.client.run(bot.TOKEN)
loop.run_until_complete(asyncio.gather(*tasks))
AssertionError: yield from wasn't used with future
i tried to use an async_to_sync Wrapper called Syncer :
bot =A()
b = sync(bot.on_message(message))
assert Signal ==b()
b = sync(bot.on_message(message))
NameError: name 'message' is not defined
Unclosed client session
client_session:
when i define message :
message = {}
bot =A()
b = sync(bot.on_message(message))
assert Signal ==b()
b = sync(bot.on_message(message))
TypeError: on_message() takes 1 positional argument but 2 were given
Unclosed client session
client_session:
im sorry again for the dumb question i know im probably doing it all wrong
im trying my best to learn
thanks
I have written the following spec. Surprisingly it passes even though the result doesn't match
code snippet
val controller = new UserController(mockUserRepository,mockControllerComponents,mockSilhouette)
//val request = FakeRequest[AnyContentAsJson]("POST", "/ws/users/signup").withJsonBody(Json.parse("""{"bad": "field"}"""))//FakeRequest(POST,"/ws/users/signup").withJsonBody(Json.parse("""{"bad":"field"}"""));
val request = FakeRequest("POST","ws/users/signup")
println("sending request",request)
//val result = controller.someMethod()
val result = controller.signupUser(request)
Await.result(result,Duration("10 secs"))
result.map(response => {
println("response from controller:"+response)
response mustBe play.api.mvc.Results.BadRequest
})
console prints
(sending request,POST ws/users/signup)
print in controller. (received request,POST ws/users/signup)
Controller returns 200OK but I am matching it with BadRequest. Still the test passes!
response from controller:Result(200, Map())
I suspect that I am not matching the result correctly. I am doing response mustBe play.api.mvc.Results.BadRequest. I know that response is Results but BadRequest is Status. But I don'w know how else to match and also why the test doesn't fail. I also tried following and can see the the values are different but even then the test passes.
println("response from controller:"+response.header.status+" compared with "+play.api.mvc.Results.BadRequest.header.status)
response.header.status mustBe play.api.mvc.Results.BadRequest.header.status
console print - response from controller:200 compared with 400
Importing members of Helpers object like so
import play.api.test.Helpers._
gives access to various utility methods to extract results from Future[Result] in tests. For example, Helpers.status can be used to extract status code like so:
val result: Future[Result] = controller.signupUser(request)
status(result) mustBe BAD_REQUEST
Another option is to use whenReady from ScalaFutures:
val result: Future[Result] = controller.signupUser(request)
whenReady(result) { _.header.status mustBe BAD_REQUEST }
Another option is to extend AsyncWordSpec and then you can map over the Future like so:
val result: Future[Result] = controller.signupUser(request)
result.map(_.header.status mustBe BAD_REQUEST)
I'm currently implementing a SBT plugin for Gatling.
One of its features will be to open the last generated report in a new browser tab from SBT.
As each run can have a different "simulation ID" (basically a simple string), I'd like to offer tab completion on simulation ids.
An example :
Running the Gatling SBT plugin will produce several folders (named from simulationId + date of report generaation) in target/gatling, for example mysim-20140204234534, myothersim-20140203124534 and yetanothersim-20140204234534.
Let's call the task lastReport.
If someone start typing lastReport my, I'd like to filter out tab-completion to only suggest mysim and myothersim.
Getting the simulation ID is a breeze, but how can help the parser and filter out suggestions so that it only suggest an existing simulation ID ?
To sum up, I'd like to do what testOnly do, in a way : I only want to suggest things that make sense in my context.
Thanks in advance for your answers,
Pierre
Edit : As I got a bit stuck after my latest tries, here is the code of my inputTask, in it's current state :
package io.gatling.sbt
import sbt._
import sbt.complete.{ DefaultParsers, Parser }
import io.gatling.sbt.Utils._
object GatlingTasks {
val lastReport = inputKey[Unit]("Open last report in browser")
val allSimulationIds = taskKey[Set[String]]("List of simulation ids found in reports folder")
val allReports = taskKey[List[Report]]("List of all reports by simulation id and timestamp")
def findAllReports(reportsFolder: File): List[Report] = {
val allDirectories = (reportsFolder ** DirectoryFilter.&&(new PatternFilter(reportFolderRegex.pattern))).get
allDirectories.map(file => (file, reportFolderRegex.findFirstMatchIn(file.getPath).get)).map {
case (file, regexMatch) => Report(file, regexMatch.group(1), regexMatch.group(2))
}.toList
}
def findAllSimulationIds(allReports: Seq[Report]): Set[String] = allReports.map(_.simulationId).distinct.toSet
def openLastReport(allReports: List[Report], allSimulationIds: Set[String]): Unit = {
def simulationIdParser(allSimulationIds: Set[String]): Parser[Option[String]] =
DefaultParsers.ID.examples(allSimulationIds, check = true).?
def filterReportsIfSimulationIdSelected(allReports: List[Report], simulationId: Option[String]): List[Report] =
simulationId match {
case Some(id) => allReports.filter(_.simulationId == id)
case None => allReports
}
Def.inputTaskDyn {
val selectedSimulationId = simulationIdParser(allSimulationIds).parsed
val filteredReports = filterReportsIfSimulationIdSelected(allReports, selectedSimulationId)
val reportsSortedByDate = filteredReports.sorted.map(_.path)
Def.task(reportsSortedByDate.headOption.foreach(file => openInBrowser((file / "index.html").toURI)))
}
}
}
Of course, openReport is called using the results of allReports and allSimulationIds tasks.
I think I'm close to a functioning input task but I'm still missing something...
Def.inputTaskDyn returns a value of type InputTask[T] and doesn't perform any side effects. The result needs to be bound to an InputKey, like lastReport. The return type of openLastReport is Unit, which means that openLastReport will construct a value that will be discarded, effectively doing nothing useful. Instead, have:
def openLastReport(...): InputTask[...] = ...
lastReport := openLastReport(...).evaluated
(Or, the implementation of openLastReport can be inlined into the right hand side of :=)
You probably don't need inputTaskDyn, but just inputTask. You only need inputTaskDyn if you need to return a task. Otherwise, use inputTask and drop the Def.task.