Dash app auto update with dcc.Interval not working - python-3.x

I am trying to get my dash dashboard to auto update using Dcc.Interval and Callbacks. I can't figure out what I am doing wrong here. The html.P component "children" are not updating and it doesn't seem like the Interval is bein initiated:
app.layout = html.Div([
# Previous day column
dbc.Col([html.H1(PREV_DAY,
style={'textAlign': 'center', 'height': '5%', 'margin-top': '30px', 'margin-bottom': '25px',
'font-family': 'Consolas', 'font-size': 'xxx-large'}),
dbc.Card(
[
dbc.CardBody(
[
html.H4(id='card_title_1', children=['Sales'], className='card-title'),
html.P(id='card_text_1', children=['Sample text.']),
dcc.Interval(
id='interval-component',
interval=10 * 1000, # in milliseconds
n_intervals=0
)
], style={'textAlign': 'center', 'font-family': 'Consolas'}
)
], style={'margin-top': '15px', 'margin-bottom': '15px', 'height': '30%'}
),
I am trying to update the html.P(id='card_text_1') element with each interval. Here is my callbacks:
### SECTION - Callbacks ###
#app.callback(
Output('card_text_1', 'children'),
Input('interval-component', 'n_intervals'))
def update_metrics(n):
salesYest = 'test'
return [{}.format(salesYest)]

If you look at the console where you run the app you will see this error:
AttributeError: 'dict' object has no attribute 'format'
The problem is this part in your callback
return [{}.format(salesYest)]
As the error says a dictionary doesn't have an attribute format.
Now I'm not really sure what you're trying to do exactly in the callback, but the Interval component itself is working fine. You can test this by changing your callback to something like this:
#app.callback(
Output("card_text_1", "children"), Input("interval-component", "n_intervals")
)
def update_metrics(n):
return n
Also keep in mind that you have set the interval to 10000 milliseconds. So be sure to check if 10 seconds have actually passed in case it still seems it isn't doing anything or lower the interval when debugging.
Also aside from the format issue you're currently returning the same value every time so you wouldn't notice anything either way.

Related

custom pagination of limit and page in Django Rest Framework

I wanted to create custom paginations for this get_queryset.
get_queryset = Comments.objects.filter(language_post_id=post_in_lang_id,is_post_comment=True).order_by('-created_on')[offset:offset+limit]
I want to change the offset value whenever the page_no updates. Suppose someone enters page_no=1, so offset must be 0, and when enters 2, so offset should be 10, and so on. Every time page_no updates, it should update the offset value accordingly.
like ?page_no=3:
get_queryset = Comments.objects.filter(language_post_id=post_in_lang_id,is_post_comment=True).order_by('-created_on')[offset:offset+limit] # [ 20 : 20 + 10 ]
I guess you want to do that in a ListAPIView. If that's the case, you can do this really simply using PageNumberPagination.Just define the page size and the page_query_param you want, and the default paginate_queryset() method will take care of everything for you, you don't have to override it or calculate the offset by yourself.
# pagination.py
from rest_framework.pagination import PageNumberPagination
class CustomPagination(PageNumberPagination):
# Returns 10 elements per page, and the page query param is named "page_no"
page_size = 10
page_query_param = 'page_no'
# views.py
from rest_framework.generics import ListAPIView
from my_app.pagination import CustomPagination
class MyListView(ListAPIView):
pagination_class = CustomPagination
serializer_class = CommentSerializer
def get_queryset(self):
post_in_lang_id = '1' # Retrieve your post_in_lang_id here
return Comments.objects.filter(language_post_id=post_in_lang_id,is_post_comment=True).order_by('-created_on')
You can also set it as the default paginator by defining DEFAULT_PAGINATION_CLASS in your settings file.
Here is a mock of what you would get as a result for the first page using this method :
{
"count": 20,
"previous": null,
"next": "http://localhost:8000/api/comments/?page_no=2",
"results": [ # List of first 10 elements
{
"id": 1,
[...]
},
[...]
{
"id": 10,
[...]
},
]
}

Custom opstring parsing when multiple instances of same flag is applied?

I have a command line program where I want to generate a picture given multiple arguments, where the order of the arguments should be respected, and duplicate arguments are allowed
Are there any node.js optstring parsers that would allow for this?
I would like to have something like
generate_picture --red 100 --yellow 200 --red 100 --width 500
And then it generates a "flag" with a red 100px band on top, then a 200px band of yellow, and then another 100px red band, all applied with width 500px
My program doesn't literally do that but it is similar
I think the ideal form that my program would receive these arguments would be an array of arrays like this
[
['red', 100],
['yellow', 200],
['red', 100],
['width', 500]
]
I would probably up-front scan this array-of-arrays for the things i expect to only be applied once like width
I suppose now that I write it out, it might not be too hard to manually parse the process.argv array to get it into this state but curious if there are any options available already
To help my particular circumstance I made this utility function
function parseArgv(argv) {
const map = [];
while (argv.length) {
const val = argv[0].slice(2);
argv = argv.slice(1);
const next = argv.findIndex((arg) => arg.startsWith("-"));
if (next !== -1) {
map.push([val, argv.slice(0, next)]);
argv = argv.slice(next);
} else {
map.push([val, argv]);
break;
}
}
return map;
}
Example usage
test("parse", () => {
expect(
parseArgv(
"--bam file1.bam color:red --vcf variants.vcf --bam file2.bam --defaultSession --out out.svg --fullSvg".split(
" "
)
)
).toEqual([
["bam", ["file1.bam", "color:red"]],
["vcf", ["variants.vcf"]],
["bam", ["file2.bam"]],
["defaultSession", []],
["out", ["out.svg"]],
["fullSvg", []],
]);
});
Then post processing can make a little more sense of this, but this utility function was helpful for my purposes in a way that was not achievable with yargs or other node optstring parsers

creating a start menu using sprites

I'm learning the phaser-framework to create a game, and want to make a start menu using a set of sprites I've created myself that have animations attached. Ideally, as you use 'wasd' or up and down on the keyboard, you would be able to scroll down the menu and the appropriate animation (https://imgur.com/a/TVqJRh9 for a sample)
Essentially I want to move through 5 sprites that start at one frame and are queued to animate as I scroll up and down the menu.
I've tried several things so far. My main idea was to hold all of the sprites in an array, and every time there is an appropriate key press add to an index variable so it knows which one to animate.
create() {
this.anims.create({
key: 'startanim',
frames: [
{key: 'start1'},
{key: 'start2'},
{key: 'start3'},
{key: 'start4'},
{key: 'start5'},
{key: 'start6'},
{key: 'start7'},
{key: 'start8'},
{key: 'start9'},
],
frameRate: 24,
repeat: 0,
})
this.startButton = this.add.sprite(500, 100, 'start1')
this.startButton2 = this.add.sprite(500, 200, 'start1')
this.startButton3 = this.add.sprite(500, 300, 'start1')
this.startButton4 = this.add.sprite(500, 400, 'start1')
this.startButton5 = this.add.sprite(500, 500, 'start1')
gameState.menuList = [this.startButton, this.startButton2, this.startButton3, this.startButton4, this.startButton5];
gameState.menuIndex = 0;
this.input.keyboard.on('keydown_S', () => {
gameState.menuList[gameState.menuIndex].play('startanim')
gameState.menuIndex++;
})
}
update() {
}
}
This is the closest I've gotten but if I try to add an event listener for it to go up the list it won't repeat a second time. If I put the listener in the update function it does them all at the same time . I'm honestly just looking for a push in the right direction as nothing in google seems to be helpful and I can't find anything directly related here.
I'd say you're on the right track, using array for the menu items. If I understand correctly you want to use the keyboard to go through the menu items, and each time the current selected menu item should play the animation continuously.
I think you need to make 2 changes, First make the animation repeat infinitely, and second stop the animation when selecting the next menu item. So something like this:
this.anims.create({
key: 'startanim',
frames: [
{key: 'start1'},
{key: 'start2'},
{key: 'start3'},
{key: 'start4'},
{key: 'start5'},
{key: 'start6'},
{key: 'start7'},
{key: 'start8'},
{key: 'start9'},
],
frameRate: 24,
repeat: -1 // <- once playing; infinitely repeat
})
and in the keyboard handler:
this.input.keyboard.on('keydown_S', () => {
// stop animation on current menu item (stop at first frame)
gameState.menuList[gameState.menuIndex].stopOnFrame(0);
// go to next menu item
gameState.menuIndex++;
// when past last menu item, warp to first
if (gameState.menuIndex > gameState.menuList.length-1) gameState.menuIndex = 0;
// play animation on new menu item
gameState.menuList[gameState.menuIndex].play('startanim');
})
Btw instead of .stopOnFrame(0) you could also just do .stop() and then setFrame(0) or something, to stop the animation immediately.

Make update loop in sync with music and notes in Phaser

I'm trying to make some notes appearing when the music hits a certain time in Phaser, but when I log the "hit times" in the console, it only show up sometimes.
I have an object of "notes", the key being the time I expect the note to show :
{
1377: {
jam: 1,
duration: 0.40
}
}
with 1464 notes.
But, in the update loop, if I do something like this :
update () {
if (music && music.currentTime) {
if (notes[music.currentTime]) {
console.log('notes[music.currentTime].jam', notes[music.currentTime].jam)
}
}
}
It logs only some of the notes, randomly.
Do you have any idea why ?
This is probably because music.currentTime is incrementing by ~16 ms on each update, so it can skip specific time keys from your notes object. Other than that I believe that the time can also be a floating point value, so it won't exactly match your keys in the notes variable.
An alternate way to implement what you want would be to change format of the notes variable to an array so it could be accessed later in a different manner:
var notes = [
...
{'start': 1377, 'jam': 1, 'duration': 0.40},
{'start': 2456, 'jam': 1, 'duration': 0.30},
...
];
// Index of the first note that will be played.
// Will be incremented by 1 or more with some update() calls,
// depending on the time that passed.
var nextNote = 0;
function update() {
// Process all notes that are now in the past
// compared to the current time of the playing music,
// but skip notes that have been already played before.
while (music && nextNote < notes.length && notes[nextNote].start <= music.currentTime) {
console.log(notes[nextNote]);
nextNote += 1;
}
}
For this method to work, the notes array must hold start times in an ascending order.

Ext js 3.4 window add/remove Component error

We are using extjs 3.4. The purpose is to replace a component in a Ext.Window. Even if
there is no error when we remove the old and add the new component, when trying doLayout() the error
Uncaught TypeError: Cannot read property 'offsetWidth' of undefined
occurs.
The code that creates the window is:
function createWindowConf(id, winconf, items) {
var conf = {
id: id,
title: winconf.title,
iconCls: winconf.icon,
x : winconf.xpos,
y : winconf.ypos,
width : parseInt(winconf.xsize),
height : parseInt(winconf.ysize),
layout : winconf.layout, //'border',
border : false,
resizable : winconf.resizable,
manager: windows,
shadow: false,
closable: true,
items: items
};
var win = new Ext.Window(conf);
win.render(desktopEl);
return win;
};
The items are a Ext.grid.GridPanel and a Ext.form.FormPanel.
According to user's current selection in grip (component in position 0) the old form should be removed and a new should be added (component in position 1).
The code that creates the form is:
var theConfig = {
id: config.yid,
bodyStyle: 'padding:5px 5px 0',
width: 370,
maxWidth: 370,//not resizable
minWidth: 370,
layout: 'form',
margins: '0 0 0',
region: 'east',
split: true,
colapsible : true,
trackResetOnLoad: true,
autoScroll: true,
fieldDefaults: {
msgTarget: 'side',
labelWidth: 75
},
items: [],
buttons: [scopeDetails.updateButton, scopeDetails.submitButton]
};
this.detailsForm = new Ext.form.FormPanel(theConfig);
and the items added afterwards.
The code that updates (adds/removes) components from the window is:
this.updateWin = function(moduleForRemoveId, form, idWin) {
var win = this.getWindow(idWin);
if (win != null) {
win.remove(moduleForRemoveId);
win.add(form);
win.doLayout();
}
}
and produces the error in win.doLayout().
By removing all components and add the add the new ones:
win.removeAll();
win.add(this.grid);
win.add(this.form);
win.doLayout();
we have the same error.
Any suggestion will be really helpful since more than 3 days spent for that error
I'm pretty sure the error comes from something else rather than the component remove/add.
I created a simple testcase which defines a window with a form and a grid, and a button which replaces everything with a panel. And it works.
Your code is incomplete. You should provide a full example.
Have you tried to debug it yourself? Enable "pause on uncaught exceptions" on your Chrome script debugger the reproduce the bug. You will get a stack trace of what happened, giving you hints on what is wrong. Of course include ext-all-debug.

Resources