« first day (284 days earlier)      last day (2117 days later) » 
11:00 - 22:0022:00 - 00:00

11:42 AM
look @DMA57361, I've split up the virtual measurements based on the step lengths for running and walking
not sure if its correct, but at least they look significantly different
 
hello
and the top one has an odd "backstep" :/ these dogs need to learn how to walk sensibly
 
ah, all contacts were behind the LF paw
so the pattern starts without the LF paw :P
that's lame
ah well, its just to support the numbers above it
so unless the veterinarians come up with something better, this is how its going to be for now
 
f/e
but you're still making various progresses then?
 
well I think I did this in 30 minutes
splitting up the results that is
so I'm fairly content with how fast that went
I needed to separate all results, into running and walking, so I can do some statistics on them
I'm suspecting there are some outliers, which need culling
 
btw, what's your next milestone? you have more meetings etc coming up?
 
11:51 AM
@DMA57361 the clinic is waiting for their results T minus 1.5 months ago
and I've been procrastinating from tackling the results, though I'm now finally making some progress on that area
 
oic, so you're playing a little bit of catch-up now?
 
probably going to a conference next week, where my old employer is one of the sponsors
@DMA57361 yeah, though making that .exe, cleaning up my displays, interpolating my results and such isn't wasted effort
I also fixed a slew of bugs
so that should save me time down the road
 
true, it's all progress in the right direction
 
the messing I've done with Kronos his app has helped me with my refactoring skills
every time I need to add several items now, I'll try to make classes and simply make several instances of that
normally I wouldn't do that, because so many things are different between each item
now I just pass a bunch of arguments, to tweak all those settings :)
Hopefully the next step of progress is making a generic results page, that just adapts to the input, so I can easily display multiple variations of the same thing
like currently I have a display of the average contact + the axis (which sucks) + the center of pressure (which isn't aligned) + the toe regions (which is still my old version)
the logical next step is simply to turn displaying one of these layers/addons on/off to display them
but as long as the clinic doesn't show some more interest in doing a followup, I'm not particularly in a hurry to deliver the results
 
@IvoFlipse hmmm, so if the clinic is losing interest you have other leads or market you're aiming for?
 
12:00 PM
@DMA57361 well in that case I'll have to lend money from my parents and/or make sure I can process human measurements. That way I can do a project for them, which off course they only do to support me, but allows me to continue working on it
hopefully if I split up all the results and come up with some basic stats for each dog
pass that to a spreadsheet or pdf to export, the clinic can do whatever the hell they want with the data
and then it should be enough features to start looking for some more clients
Speaking of the devil, I just got an email from the veterinarian who performed the measurements (though not in charge of things)
 
fair enough
@IvoFlipse oh?
 
well she's just asking how long I expect it will take me to get her the results
 
oic, well, she can have them Soon™
 
indeed
well I guess it would help if I installed a version of my app on one of their laptops
so that I only have to push a new update once I'm 'Done'
 
possibly
just be wary of ending up doing more support than development
 
12:07 PM
@DMA57361 oh I don't give support, it works as is
so they'll have to wait with actually using it until I'm done
but they can have a look at the data in the mean time
 
right, but to look at the data they have to use the software...? which means setting it up, getting it working, showing them how to get to the data, etc?
 
@DMA57361 That's the last thing I need to decide on, I need to pick a license to slap on my app
 
good point
 
luckily when I make it into an .exe, they can't really touch the source unless they know how to open them
 
@IvoFlipse well... don't py2exe things just hide the source in a zip?
 
12:10 PM
@DMA57361 It indeed means I have to install my app + MySQL and make sure they have all the data
@DMA57361 well the version that 'hides' everything didn't run, haven't figured out what the issue is yet
but still it packages the .pyd or pyc files, good luck with those as a non-programmer :P
 
@IvoFlipse hmmm, but still you can license it how you like
 
@DMA57361 I was thinking about one of the GPL ones, since it still allows me to sell a license as well, but prohibits anyone from profiting directly from my work
 
@IvoFlipse indeed
 
well I guess any license allows dual-licenses, but if someone wants to use my work, they'll have to come to some agreement with me
 
and there's nothing to stop you installing the pre-release version on something much more restrictive and then going GPL when you release
 
12:13 PM
@DMA57361 the phd-er in London actually has a version with no license at all, but I'm going to try and lock down some of my updates in the future
just to be save
I don't want to hinder my users either, so its a delicate balance
 
@IvoFlipse if there's no license at all you might be implicitly covered by copyright... but that's a bit dangerous, maybe :/
 
@DMA57361 well she 'promised' me she was using it safely
I just have to make sure she get's a version she can use more liberal
and if they want access to the source code (like she has), they'll simply have to do a project with me :)
 
the license for the pre-release doesn't have to impede usage, but could restrict distribution of the original or derived works.
 
@DMA57361 lol that already sounds pretty legalese ;)
 
@IvoFlipse unfortunately all licensing sounds legalese..
 
 
7 hours later…
7:19 PM
hey @IvoFlipse I'm in for the rest of the day....
 
ah nice
well I'll be around for several hours
 
ok cool... I have to remotely push an update... I made one yesterday but aparently didn't push it... so now I have to remote it and push it
 
I haven't changed anything
so you should be fine
 
@IvoFlipse I know. It was me that made the change, but didn't push
Grrr... can't connect.. .maybe I'll just redo it...
 
no, just force push
or you mean you can't remote login?
 
7:23 PM
@IvoFlipse ya I can't...
 
8:11 PM
ok back to work
 
hehe, who said I stopped working
 
I meant me... :P
 
ok so I think that I need some help... you free @IvoFlipse?
 
I can help you
 
8:16 PM
Sweet... so I've created a class in trasktrackercontroller
called weights... and it's supposed to calculate the weight of each task
 
yes, I'm seeing it
 
but I'm not exactly sure:
a) if I set it up right
b) how to implement it exactly
- as this needs to be run on EVERY button that has been activated EVERY time a button is activated
 
Ok, so how it currently worked was: you pressed a bunch of buttons, when you pressed the button in the bar, it would collect the passed times for each button
so that's wrong
 
my way is wrong or the way that it was originally done?
 
my way
though it was just to show it could be done
 
8:19 PM
whew ok...
@IvoFlipse right I figured that
 
every button needs to report how long its active at the moment a button is pressed?
 
well not exactly... so here's what we could do...
 
class Weights():
    """
    Used to calculate the weights and weighted durations of the tasks
    """

    def __init__(self, weight, numtasks, prevtime, currenttime, starttime):

        # time difference between button presses
        self.deltat = currenttime - prevtime
        # duration of time that button has been on
        self.duration = currenttime - starttime
        # sum of the weights that have been calculated.  If this is the first 'event' then weight will be orginally 0 and new weight
@KronoS tell me, I'll shut it ;)
 
have a 'global' timestamp that just updates everytime a button is pressed
but every button needs to 'update' it's weight
because it changes everytime a button is pressed
 
@KronoS help me figure out what everything means
currenttime and prevtime are?
or rather what's prevtime?
 
8:22 PM
current time is the time when a button is pressed
prev time is the time that the last button was pressed
 
right, so that's really the start time
or that's a global thing
 
start time is the time that the actual button was pressed
prev time is a global thing
deltat or delta 't' is simply the change in time from one button press to another
duration is the time that the button has been pressed thus far
weight is simply the previous weight (0 if this is the first press)
and sumweight is the sum of the previous weight, and the current weight
oh whoops there's an error in there...
just a sec
 
@KronoS what is weight(1)?
 
it's not a function, but a value... sorry for mistype
 
I know, I meant how does weight change
 
8:29 PM
ok I just sent a push with the fix...
 
so we need to split these variables for global/shared ones and those that are unique to impressed buttons
 
weight is itnitially zero
then when a button is pressed it's 1/(number of current tasks)
so first button pressed is 1/1
second is 1/2
third is 1/3
and so forth
 
well 1 + 1/2?
 
but since the buttons won't be pressed at the same time everytime we have to account for changes in time
no it'd be 0+1/2
then 1/2 + 1/3
 
so weight is global too
 
8:31 PM
(if the time intervals were exactly the same)
no... number of tasks open is a global thing
 
the next button needs to know what the weight of the previous button was
 
1/(number of tasks)
no the same button needs to know what the same button's previous weight was
 
@KronoS right, so this get's evaluated per button
what is the result of this all going to be?
 
correct
to calculate weight for that time interval we need to multiply the change in time from one button press to the other by 1/(number of buttons pressed)
to determine the ACTUAL weight of the button we need to take the previous weight and add the most recent calculated weight
to determine duration we need to take the duration the button has been pressed and multiply it by it's weight
does that all make sense @IvoFlipse ?
 
one sec
 
8:39 PM
ok
 
> weight + (deltat*(1/numtasks)) ==> so what would a hypothetical result of this be?
silly question, but shouldn't every task just have one duration?
 
so let's say that no buttons have been pressed
I press button 'one'
it's weight was zero
currently there are 1 task(s) running
therefore 1/1
so weight would be 1 + deltat*1/1
let's say that deltat = 1
so weight would be 1
not let's say that 1 time unit passes and I press button 'two'
weight of button two was zero
I then add 1/2 or 1 / (num of tasks)
I multiply delta t by 1/2 = 1/2
button 'one' prev weight was 1
I take deltat and multiply it by 1/2
--> 1/2
I take prev weight of 1 and add 1/2
--> 1.5
 
what is deltat at this moment?
 
I'm assuming deltat is 1
everytime, in this scenario
 
that means you press a new button every second right?
 
8:47 PM
yes in this case, but it's not that pretty everytime...
 
btw its self.deltat not deltat
I might be dumb, but shouldn't the total time of a button be
 
right sorry... didn't want to type 'self' a bunch of times
 
time1 * weight1 + time2 * weight2 + time3 * weight3
my point being, every time a button is pressed, EVERY button calculates time * weight
where time is 0 if it was inactive
 
Hmmmm... yes that's right....
 
so every button keeps track of its own time, where new time get's added until you're done (assuming the button get's activated at some point)
all we need to share is how many buttons are active at one point in time
assuming the whole round runs within 1 second (within your margin of error)
what we should do is let every button sent a message to the controller
 
8:53 PM
@IvoFlipse wait what?
 
where we keep a dictionary with keys for every task and 'log' whether the button is true or false
 
what if it's less than one second? are you saying it'll screw up?
 
@KronoS A: that's stupid, you would be doing 2 tasks at the same time
but my point is concurrency, you first need to have a weight, before you can continue calculating
so every button needs to report if they're active or not before you can continue
oh wait no, that's not needed
my point is
we have this one dictionary that keeps track of all tasks being active
we could just use an int or a list, but with a dictionary you can track what button was active and such
 
well a dictionary would be better
 
ok, what we should do is add a function + attribute to tasktrackercontroller
 
8:57 PM
but I don't know a thing about dictionaries, other than what I just looked up
 
we call it: def updateweight(self, message):
 
under which class?
my weights class?
 
then the message should be -1 or 1, for when you a button is turned off (weight - 1) or on (weight + 1)
no the main class: TaskTrackerController
 
ok that's what i thought and just did
 
ok
so our button class (in tasktrackerpanel) should sent 2 messages
pub.sendMessage("ButtonClass.toggledbutton", -1/1)
to explain how pubsub works
when importing wx.lib.pubsub, we import Publisher as pub
this has 2 methods we use: sendMessage and subscribe (there may be more but I don't need them yet)
like I shared the link, we will have to update this at some point, but not now
you send a message by giving a string " "
 
9:03 PM
but what is the message then?
where it goes?
 
you decide what this will be, it can be anything as long as they are unique or they will override similar messages (perhaps not allowed)
pub.sendMessage("ButtonClass.toggledbutton", -1/1)
then you pass along your actual 'message', being the object you want to move elsewhere
 
so I could very well do this: pub.sendMessage("HolyCrapItsIVO",-1/1)
if I wanted to?... like the message has nothing to do with other sections of the code
 
the other method we use is pub.**subscribe**("message you're subscribed to", object your sending)
yup
I started using the standard of MainClass.function, because it allows me to backtrack where they came from
 
you just use that syntax to keep track of what you're doing?
brb
 
yeah and its predictable, because I know what the format SHOULD be
 
9:07 PM
ok that makes sense then... but what if you have multiple message to the same function?
 
the function can subscribe to as many messages as it wants to
and several functions can send the same message too
its like delivering mail
it makes 1 round, delivers to all subscribers and then quits
so all buttons sent one message: "ButtonClass.toggledbutton"
 
so I can have two functions that send the same HolyCrapItsIVO message
 
yup
 
ok
 
what's nice is that you don't necessarily have to tweak your message
thats also what the new style API with keywords is for, you can deliver different data with the same message by adding a keyword
 
9:09 PM
ya thats really nice
 
but we're not using that
also, I believe you NEED to use the same keyword everywhere, because pubsub compares all the subscribers + sendmessage pairs
hence I just use 'message' in each function
its useful to use the same thing everywhere, because it makes your code predictable/readable
 
message being the "Class.function" ?
 
no
def functioname(self, message): <-- this message
 
oh got it.. ok
that makes sense as well
 
@KronoS then message is an object, to get the object out of it you have to use message.data
 
9:14 PM
ok so when I 'subscribe' to something i have to use message.data
 
@KronoS yes, the subscribed function needs the message keyword in the def statement and message.data to use it
btw you can also sent empty messages, basically its a way to trigger functions elsewhere
we use that between the ribbon + mainframe + other functions
 
oh wow... ok...
i think I get that
 
ok
then this updateweight function will sent a message with the weight out to every instance of the Weight Class you made
 
ok so I have a updateweight function that sends messages to the Weight class
The weight class calculates a new weight for the button and then....
what?
 
well you need to create an instance of that Weight class for every button
OR
 
9:26 PM
which I would do with the creation of each button... right?
 
have a dictionary with all the variables it needs to keep track off
@KronoS well its in the controller, so whatever the panel does is the panel's business
a dictionary is a data structure where objects are stored based on a key:value basis
 
but what if I want to create/edit new or old tasks...
which would be easier to implement in that case?
 
a = { 'a' : 1, 'b' : 2, 3 : [1, 2, 3]}
@KronoS then we need to create that dictionary in a generic way and/or have keys added to the dictionary based on buttons created
 
where 'a' and 'b' are labels and 1,2,3 are values?
 
a b 3 are keys
 
9:29 PM
ok so a dictionary is the way to go
 
a 2 [1, 2, 3] are values
what we would do is store the tasks based on the name we use in the panel
{'Data Gathering':[ ],'Collaboration':[ ],,'Outputs':[ ],,'Documentation':[ ],}
either we let the ButtonClass.__init__ sent a message to add a key
 
Oh... I see then...
 
or we let the ButtonClass.toggledbutton sent along the name of the button
the latter is a 'lazy' approach, which only tries to calculate the times for buttons that have actually been pressed, so that's probably preferable
so that sends a message: [self.name, -1/1] or {'name':self.name, 'state':-1}
then in tasktrackercontroller we need to tweak your class
the first time a button is pressed, we want to calculate its 'adjusted time' (timediff * weight)
so when we get a message we check against the dictionary whether it has any keys with the given value
if not, create one, if so get the values from it
 
ok so let me see if I got this... what we're going to do is create a dictionary that we'll parse info of task name and status and current weight to?
 
yeah
but when the state == 1 (button is turned on)
it should fill starttime with time.time() (or whatever)
then when another button comes in and has that state
it should go to this button's values
compare if starttime <= time.time() (its older)
then calculate the weightduration and store that
and update starttime with time.time() (or currenttime)
when the button state is -1 or another button comes along, we simply rinse and repeat
 
9:40 PM
so state 1 is active and state -1 is inactive?
lol
 
because the -1 state is also used to adjust the weight
you can have it be 0 too, but then you need to write a loop to check against its value
now its just weight + state
 
oh and -1 would make it 'negate' itself... literally
 
indeed
 
hey is this a dictionary?
self.timediff[message.data['name']] = {'userid':userid,
'tasktrackerid':tasktrackerid,
'taskname':message.data['name'],
'timediff':round(message.data['stop'] - message.data['start'])}
 
though, it should only be applied AFTER calculating the time
yes
to create a new key with the {} you do: dictionary[keyname] = value
 
9:46 PM
ok so first the dictionary needs to be created it sounds like...
 
and dictionaries can contain anything
you just need to create an initial dictionary
self.timediff = {}
you just do that in the init of tasktrackercontroller
 
ok so I'll create a dictionary 'self.buttonstatus'
in the init of tasktrackercontroller
ok done...
 
@KronoS well that can just be an int
or wait, buttonstatus is going to contain what?
 
the dictionary that we need to use...
so like current weight, start time, current time, etc,.... everything that we've been talking about...
 
right, but why call it buttonstatus?
well I guess the times are attributes of a button
nvm :)
 
9:51 PM
esp since we're going to be putting this in the ButtonClass.toggledbutton
ok so in the ButtonClass.toggeledbutton what do I do then?
 
sent a message
{'name':self.name, 'state':-1}
 
so something like this:
pub.sendMessage("TaskTrackerController.updateweights",{'name':self.name, 'state':-1})
for when the button is turned off
and then this for when it's on:
pub.sendMessage("TaskTrackerController.updateweights",{'name':self.name, 'state':1})
 
yes
are you sending that from TaskTrackerController.updateweights?
 
no that's from TaskTrackerPanel.toggeledbutton
if value == true state = 1
if value == false state = -1
 
I always call my messages after who sends them, so I know from whom it comes
 
9:58 PM
oh and not to where it goes?
ok that makes sense
so something like this then:
pub.sendMessage("ButtonClass.toggeledbutton",{'name':self.name, 'state':1})
 
yes, now when you're following a trail of messages, you always know where to go and look
 
11:00 - 22:0022:00 - 00:00

« first day (284 days earlier)      last day (2117 days later) »