NB: I use version 12 of python-telegram-bot package.
I would like to build a conversation handler: when a user chooses \charts command, the bot shows them an inline list of choices, and depending on their choice, return them a chart.
charts_handler = ConversationHandler(
entry_points=[CommandHandler('chart', chart_start)],
states={
ChartChoices.choosing_user: [CallbackQueryHandler(
individual_chart,
pass_user_data=True)
],
},
fallbacks=[done_handler],
)
But if I do not set per_message=False then it results in this error:
If 'per_message=False', 'CallbackQueryHandler' will not be tracked for every message.
If I do set per_message=True, then it results in the error:
If 'per_message=True', all entry points and state handlers
must be 'CallbackQueryHandler', since no other handlers have a message context.
So it seems that the only way to build a conversation handler with CallBackQueryHandler (or in other words to show inline keyboard during chat) is to set all handlers to CallbackQueryHandler. Is it correct?
First of all, this is not an error, it's a warning you can safely ignore: If 'per_message=False', 'CallbackQueryHandler' will not be tracked for every message.
Second, you don't need a ConversationHandler for described use case. Example user interaction:
User: /charts
Bot:
Here is the list of available charts:
Bar chart 1 /chart_1
Bar chart 2 /chart_2
Pie chart /chart_3
And this kind of flow you can implement with simple MessageHandler and Filters
Docs: MessageHandler
Docs: Filters
Namely you can use the regex filter.
ConversationHandler is useful when you need a multistep iteraction with the user (like filling out a long form step by step). If you can identify user requests by other means, like generated commands, inline buttons, message text — prefer doing it this way.
Related
This is the page I am trying to make it dynamic by enabling cross-filtering.
So the thing is they are having multiple API.
For the top first two: TOTAL CASES & DAILY CASES
They are using this API and the third one in the top is based on this API.
The bottom three AGE, GENDER, and NATIONALITY are from this API.
In all the API one thing is common that is a date but there are some API in which some data are missing for few dates like there is a gap( Not available for some of the dates).
So I thought of combining all the JSON API in terms of dates and then allow cross filter because I believe I can enable cross-filtering between them. Correct me If I am wrong.
Like If I click on gender female since it gives info about total cases where the patient was female so only confirmed cases from the Total cases will change not the recovered, deaths as data is not available. SO I guess I should combine the top 3 charts together and gender, age and nationality charts, together. Then Dc js would be able to handle nicely filtering between each segments (cases related to landmark, cases related to person info).
Line 123:
var log = console.log;
var q = queue()
.defer(d3.json, "https://api.covid19india.org/data.json")
.defer(d3.json, "https://api.rootnet.in/covid19-in/unofficial/covid19india.org/statewise/history");
q.await(function(error, data1, data2) {
log("==========>");
log("data1:", error,data1);
log("data2:", data2);
});
This is not working because I can't see console.log() output.
https://blockbuilder.org/ninjakx/8c48ab6481311aa0452046d66c4d8701
So my questions are:
1) Why d3.queue is not working?
2) Suggestion whether combining all the datas together and allowing a filltering is a good idea or not as there is limited data. Should I go for cross filtering between the same api charts. So in this case I will have 2 segments (cases related to landmark, cases related to person info)..
Using DC js I want to make it more interactive and display more info.
d3.queue is obsolete
The answer to your first question is cut-and-dried: you don't need d3.queue, and it was deprecated and removed in d3#5.
As of d3#5, D3's data loading APIs use ES6 Promises instead of asynchronous callbacks, so you can use Promise.all([...]) instead of d3.queue. Apparently no way to make the new API emit errors when called in the old way, so it just fails silently. :-/
The new way to write your code is
Promise.all([
d3.json("https://api.covid19india.org/data.json"),
d3.json("https://api.rootnet.in/covid19-in/unofficial/covid19india.org/statewise/history")
]).then(([data1,data2]) => {
log("==========>");
log("data1:", data1);
log("data2:", data2);
})
.catch(error => log('error', error))
I find this much easier to read and understand. A nice side effect is that if you neglect to do error handling (like most people), you'll automatically get a clear message in the log.
Working fork of your block.
Combining multiple data sets
Your second question is pretty open-ended, maybe it would be better to bring that to the dc.js users group?
In general, it's difficult to cross-filter more than one data set. You would have more than one chart group that redraws together, and you'd have to manually add handlers on some chart to initiate, clear filters, and redraw the other chart group.
I haven't seen too many dashboards that do this. You'd have to make it clear to users what is going on.
I have some utility method calls, that I issue console log messages inside of, whenever the methods are invoked via the template.
I'm attempting to implement a variant of an accordion component.
The screen also has a lot of ion-checkboxes, hierachically listed at various levels (root, cagetories, type within categories), and the components are part of a Reactive Form.
When the details are expanded the methods are getting called repeatedly, despite me performing no subsequent actions whatsoever.
It also seems to degrade the performance of the screen.
From this information, can anyone surmise what the cause might be?
Some sort of change detection gone wild?
There is an *ngIf that displays content when things are expanded, then a *ngFor occurs in the expanded list.
It appears to be the nested *ngFor within the *ngIf that is continuously calling out to utilitiy methods.
The getIndex() method, which appears to be the culprit is being used for two things:
<ion-checkbox [attr.id]="'type' + g + '-' + t"
[formControl]=
"jobTypes.controls[getIndex(jt, g, t)]"
(click)="toggleJobTypeCheck(getIndex(jt, g, t))"
class="col3">
</ion-checkbox>
g and t are for loop indices, jt is a Job Type, which has an interface structure like so:
export interface JobTypeMapping {
type: string,
alias?: string,
num: number,
name: string,
group: JobTypeGroup,
sel:boolean
}
We have two forms so far, and need to switch from window1 in from1 (which is login screen) to windowX in formX using button (trigger code below):
begin
show_window('windowX');
go_block('some_block_in_formX');
end;
This gives error FRM-41052: Cannot find Window: invalid ID
So question is, should I add formX into show_window parameter in certain way or is there another approach? Thank you.
Please note, that forms are in different files.
that forms are in different files.
If the forms are different files, you need to call the other form using open form/call form/newform - whatever suits your needs.
show_window/go_block sequence can be used only when you're moving to different windows/blocks of the same form - and the error message
error FRM-41052: Cannot find Window: invalid ID
is complaining that it can't go to that Window because it's in a different form.
Each form effectively has a private namespace for all its windows, blocks, items, etc - and your code always runs within the context of a single form.
To solve this, you'll need a form parameter, plus some code in the other form, e.g.:
in formX, add a parameter ACTION
in form1, pass the value 'XYZ' to ACTION
in formX, in the WHEN-NEW-FORM-INSTANCE trigger, check if :PARAMETER.ACTION = 'XYZ', and if so, do your show_window and go_block. Copy the same code to your WHEN-WINDOW-ACTIVATED trigger.
Of course, you'll need to think about the name of the parameter (e.g. ACTION) and value ('XYZ') that will make sense to people maintaining your forms in the future.
I'm working on a simple CRUD proof of concept with Rails/Backbone/JST templating. I've been able to find a lot of examples up to this point. But after much searching and reading, I've yet to find a good example of how to handle these scenarios:
info message: new item successfully added to list (shown on list screen)
info message: item successfully deleted from list
error message: problem with field(s) entry
field level error message: problem with entry
The Backbone objects are:
Collection (of "post" Models) -> Model ("post" object) -> List/Edit/New Views (and a JST template for each of these views)
So, I'm looking for a high level description of how I should organize my code and templates to achieve the level of messaging desired. I already have a handle on how to perform my validation routine on the form inputs whenever they change. But not sure what do with the error messages now that I have them.
Here is the approach I'm considering. Not sure if it's a good one:
Create a "Message" Model, which maps to a "View", which is a sub-view (if that's possible) on my existing views. This view/model can display page level messages and errors in the first three scenarios I mention above. Not sure if it's feasible to have a "sub-view" and how to handle the templating for that. But if it's possible, the parent templates could include the "message" sub-template. The message view could show/hide the sub-template based on the state of the message model. Feasible? Stupid?
For the fourth scenario, the model validation will return an error object with specific messages per each erroneous field each time a "model.set" is called by form field changes. I don't want to interrupt the "model.set" but I do want to display the error message(s) next to each field. I want to know how to factor my edit/new template and Post model/view in such a way that I don't violate the MVC pattern. I.e. I don't want to put references to DOM elements in the wrong plage.
Sorry if this is vague. If you're inclined to help, let me know what code snippets could be helpful (or other details) and I'll provide them.
You create a global eventbus. When ever an error appears trigger an event. Your view that should show the message listen to the events on this eventbus. Doing so, your error message view dont needs to know all of your collection and vice versa. The eventbus is simple:
var eventBus = _.extend({}, Backbone.Events);
Add it to your collection and trigger it when ever add was called:
var myCollection = Backbone.Collection.extend({
initialize: function([],eventbus){
this.bind('add', function(obj){eventbus.trigger('added', obj)}
}
})
Take also a look at the article: http://lostechies.com/derickbailey/2011/07/19/references-routing-and-the-event-aggregator-coordinating-views-in-backbone-js/
Suppose you have a subsystem that does some kind of work. It could be anything. Obviously, at the entry point(s) to this subsystem there will be certain restrictions on the input. Suppose this subsystem is primarily called by a GUI. The subsystem needs to check all the input it recieves to make sure it's valid. We wouldn't want to FireTheMissles() if there was invalid input. The UI is also interested in the validation though, because it needs to report what went wrong. Maybe the user forgot to specify a target or targetted the missles at the launchpad itself. Of course, you can just return a null value or throw an exception, but that doesn't tell the user SPECIFICALLY what went wrong (unless, of course, you write a separate exception class for each error, which I'm fine with if that's the best practice).
Of course, even with exceptions, you have a problem. The user might want to know if input is valid BEFORE clicking the "Fire Missles!" button. You could write a separate validation function (of course IsValid() doesn't really help much because it doesn't tell you what went wrong), but then you'll be calling it from the button click handler and again from the FireTheMissles() function (I really don't know how this changed from a vague subsystem to a missle-firing program). Certainly, this isn't the end of the world, but it seems silly to call the same validation function twice in a row without anything having changed, especially if this validation function requires, say, computing the hash of a 1gb file.
If the preconditions of the function are clear, the GUI can do its own input validation, but then we're just duplicating the input validation logic, and a change in one might not be reflected in the other. Sure, we may add a check to the GUI to make sure the missle target is not within an allied nation, but then if we forget to copy it to the FireTheMissles() routine, we'll accidentally blow up our allies when we switch to a console interface.
So, in short, how do you achieve the following:
Input validation that tells you not just that something went wrong, but what specifically went wrong.
The ability to run this input validation without calling the function which relies on it.
No double validation.
No duplicate code.
Also, and I just thought of this, but error messages should not be written in the FireTheMissles() method. The GUI is responsible for picking appropriate error messages, not the code the GUI is calling.
"The subsystem needs to check all the input it receives to make sure it's valid"
Think of the inputs not so much as a list of arguments, but as a message, it gets easier after that.
The message class has an IsValid member function, it remembers if IsValid was called and what the result was. It also remembers its state, if the state changes then it needs to be re validated. This message class also keeps a list of validation errors.
Now, the UI builds a TargetMissiles message, and the UI can validate it, or pass it directly to the MissileFiring subsystem, it checks to see if the message was validated, if not it validates it, and proceeds / fails depending.
The UI gets the message back, with the list of validations already populated.
The messages with their validation sit in a separate library. No code is duplicated.
This sound OK?
This is what Model-View-Controller is all about.
You build up a model (a launch which is composed of coordinates, missile types and number of missiles) and the model has a validate method which returns a list of errors/warnings. When you update the model (on key-up, <ENTER>, button-press) you call the validate method and show the user any warnings, errors, etc. (Eclipse has a little area just under the tools bar in a dialog that does this, you might want to look at that.)
When the model is valid, you activate the launch missiles button so that the user knows that they can launch the missiles. If you have an update event that is called particularly frequently or a part of the validation that is particularly costly, you can have a validate_light method on the model that you use for validating only the parts that are easy to do.
When you switch to a console based UI you build up the model from the command line arguments, call the same validate method (and report errors to stderr) and then launch the missiles.
Double the validation. In many case the validation is trebled (FKs and not null fields in the DB for example). Depending on your platform it may be possible to code the validation rules once. For example your front end and backend code could share C# business classes. Alternatively you could store the validation rule as metadata that both the backend and front end can access an apply.
In reality the fact that you need different responses to a validation problem (for example the Fire Missile button shouldn't even be enabled until the other inputs are valid) there will be different code associated with the same rule.
I'd suggest an input validation class, which takes the input type (an enumeration) in its' constructor, and provides a public IsValid method.
The IsValid method should return a boolean TRUE for valid and FALSE for invalid. It should also have an OUT parameter that takes a string and assigns a status message to that string. The caller will be free to ignore that message if it wants to, or report it up to the GUI if that's appropriate for the context.
So, in pseudocode (forgive the Delphi-like syntax, but it should be readable to anybody):
//different types of data we might want to validate
TValidationType = (vtMissileLaunchCodes, vtFirstName,
vtLastName, vtSSN);
TInputValidator = class
public
//call the constructor with the validation type
constructor Create(ValidationType: TValidationType);
//this should probably be ABSTRACT, implemented by descendants
//if you took that approach, then you'd have 1 descendant class
//for each validation type, instead of an enumeration
function IsValid(InputData: string; var msg: string): boolean;
And then to use it, you'd do something like this:
procedure ValidateForm;
var
validator: TInputValidator;
begin
validator := TInputValidator.Create(vtSSN);
if validator.IsValid(edtSSN.Text,labelErrorMsg.Text) then
SaveData; //it's valid, so save it!
//if it wasn't valid, then the error msg is in the GUI in "labelErrorMsg".
end;
Each piece of data has its own meta data (type, format, unit, mask, range etc.). Unfortunately this is not always specified.
The GUI controlls need to check the input with the metadata and give warnings/errors if the data is invalid.
Example: a number has a range. The range is provided by the metadata, but the range check is provided by the control.