Issue tracking system for an hospital? [closed] - tracking

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I've a friend working in an hospital and he asked for an issue tracking system.
Currently they are using only mails. I thought to Jira or Trac, but they use
"programming terms" like "bug" or "patch".
I don't want to spend time customizing, do you know any better solution/software?

I used Trac to implement issue tracking for managing the operations of a building. It is quite configurable, so I was able to conceal the software-bug-oriented wording without a lot of effort, though the admin interface.
I applied a trivial patch to Trac so that it displays boolean values as Y and N rather than the the "computerese" 1 and 0, and also, so that the false value is displayed a blank. (This is better in a columnar report where you have boolean columns, and you just want to clearly see where the Y values are; they are harder to see in a grid of Y's and N's).
Here it is below. Everything else, I did easily through the admin interface.
Index: pyshared/trac/ticket/web_ui.py
===================================================================
--- pyshared.orig/trac/ticket/web_ui.py 2011-09-16 11:59:40.000000000 -0700
+++ pyshared/trac/ticket/web_ui.py 2011-09-16 12:11:31.000000000 -0700
## -1120,7 +1120,7 ##
elif type_ == 'checkbox':
value = ticket.values.get(name)
if value in ('1', '0'):
- field['rendered'] = value == '1' and _('yes') or _('no')
+ field['rendered'] = value == '1' and 'yes' or ''
# ensure sane defaults
field.setdefault('optional', False)
Index: pyshared/trac/ticket/query.py
===================================================================
--- pyshared.orig/trac/ticket/query.py 2011-09-16 14:36:51.000000000 -0700
+++ pyshared/trac/ticket/query.py 2011-09-16 14:37:10.000000000 -0700
## -294,9 +294,9 ##
val = datetime.fromtimestamp(int(val or 0), utc)
elif field and field['type'] == 'checkbox':
try:
- val = bool(int(val))
+ val = val == '1' and 'Y' or ''
except TypeError, ValueError:
- val = False
+ val = ''
result[name] = val
results.append(result)

I know you said that you didn't want to time customizing, but I am afraid you are just out of luck on that. I doubt that there is any issue tracking system out there that will give you exactly what you want without customizing (or without exorbitant fees). So I will still recommend JIRA.
JIRA is incredibly customizable. We use it in our organization for tracking issues of many types from software issue tracking, to Vehicle reservations, to building maintenance work order requests, purchase request, and more. We also have plans to customize it for our students (I work in a college) to be able to request assistance with registration, submit feedback, and more.
JIRA is incredibly robust and, once you get the hang of it, not terrible to configure. I won't lie. Configuring JIRA, at first, is a chore and can be difficult to get a handle on. But there is a great book from O'Reilly called Jira Administration that helped me understand it all much better. And it is quite a small book (187 pages or so), so it is not filled with a bunch of fluff. It is just great and useful information.
We use JIRA Dashboards, Issue type customizations, notification schemes, permission schemes, issue type security, custom workflows, custom screens and forms, plugins, the Web Service APIs, and more. It really is a fantastic system.

Related

How can I observe an other apps launch?

For a mental health app project, I need to intercept the startup of specific apps (like Instagram) and check if they used instagram the n-th time, possibly opening a questionair etc.
Searching for a solutions online, I came across the "android.app.usage" API. I could not get my around how to use this.
Do I need a for every running background service which does active polling with the usage api?
Or is their a way to say "run this code or start this app/service when appXY launches"?
Looking forward to any kind of input :)
Greetings Pascal
You can't listen out for an "app is being opened" intent unfortunately, Android doesn't support it. Your approach is likely the best workaround, to state it explicitly:
Have a foreground service running (so it is less likely to be killed by the OS) at all times.
Check regularly the currently running app, and see if it's the one you're trying to look for.
If this is different to last time you checked, do whatever you need to. Perhaps this will include keeping track of last time the app was opened, how many times it's been opened etc.
As a warning however, the OS won't really like this, and there's likely to be an impact on battery life. Whatever you do, make sure this check isn't happening when the screen is off, happening as infrequently as possible, and doesn't include any unnecessary computation, otherwise the user will quickly notice the negative impact.
Here's an extract from an article that looks like it'll be able to fetch the latest app even on later versions:
var foregroundAppPackageName : String? = null
val currentTime = System.currentTimeMillis()
// The `queryEvents` method takes in the `beginTime` and `endTime` to retrieve the usage events.
// In our case, beginTime = currentTime - 10 minutes ( 1000 * 60 * 10 milliseconds )
// and endTime = currentTime
val usageEvents = usageStatsManager.queryEvents( currentTime - (1000*60*10) , currentTime )
val usageEvent = UsageEvents.Event()
while ( usageEvents.hasNextEvent() ) {
usageEvents.getNextEvent( usageEvent )
Log.e( "APP" , "${usageEvent.packageName} ${usageEvent.timeStamp}" )
}

Matrox DSXLE5 mvConnectorConfig - how to check current -KeyMapping value

I'm looking if there is a way to call the board (DSXLE5) and request info of the current KeyMapping value?
It is the first time I deal with DSX5 family, I've already identified that the firmware change process is different, as before, to change a DSXLE4 8 port card to be 2in + 6out we used
$mvConnectorConfig -2in6out -sn=XXXXX
and now I see that DSXLE5 needs to point the firmware (*.pin) with the load parameter.
$mvConnectorConfig load -f=xmio5_x2_00i12o.pin -sn=xxxxx
I see from the help that we can use -KeyMapping to change the boards, but how does it work and can we call the board to show which mapping is currently using?
I'm new here, so I'm sorry if it isn't 100% straight question.
Best Regards,
Rafael Girotto

Send notifications in telegram group [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 months ago.
Improve this question
How can I have my telegramBot send automatically messages in a group?
def handle_event(event):
#print(event)
global amount0In
global amount1Out
global amount1In
global amount0Out
amount0In = event['args']['amount0In']
amount1Out = event['args']['amount1Out']
amount1In = event['args']['amount1In']
amount0Out = event['args']['amount0Out']
if amount0In and amount1Out != 0:
print(f"Token Sold {amount0In /10**18}, and eth {amount1Out/10**18}")
buy()
else:
print(f"Token Bought {amount0Out /10**18}, and eth {amount1In/10**18}")
sell()
def buy(update,context):
buyMessage = f"Buy!!!!\n💴: {amount1In/10**18}\nToken Bought: {amount0Out /10**18} \n"
update.message.reply_text(buyMessage)
def sell(update, context):
sellMessage = f"Sell!!!!\n💴: {amount1In/10**18}\nToken Sold: {amount0Out /10**18} \n"
update.message.reply_text(sellMessage)
In case the IF statement is met I want to send a message to a telgram group, however I cant execute the update message this way, because I keep getting this error:
TypeError: buy() missing 2 required positional arguments: 'update' and 'context'
How can I fix this?
To send a message, all you need is an instance of telegram.Bot. Please have a look at the introduction to the API for more details.
The functions buy and sell look like callback functions for handler. Since you are apparently not using python-telegram-bots handler setup to handle the event, there is no sense in defining those functions to accept the update and context arguments.
Disclaimer: I'm currently the maintainer of python-telegram-bot.

Sometimes the Google Geocoding API returns a 500 server error [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
Sometimes the Google Maps API returns a 500 server error response according to German postal codes and i cannot understand why.
I hope it is specific enough.
Any ideas?
https://maps.googleapis.com/maps/api/geocode/json?key={api_key}&address={postal_code}&language=de&region=de&components=country:DE&sensor=false
Since you specify that the problem is not a given address but a seemingly "random" behavior, this may fall under a documented behavior of other "famous" API.
As for other cases, the recommended strategy is Exponential backoff for the Geocoding API, which basically means that you have to retry after a certain delay.
In case the above link goes down or changes, I'm quoting the article:
Exponential Backoff
In rare cases something may go wrong serving your request; you may receive a 4XX or 5XX HTTP response code, or the TCP connection may simply fail somewhere between your client and Google's server. Often it is worthwhile re-trying the request as the followup request may succeed when the original failed. However, it is important not to simply loop repeatedly making requests to Google's servers. This looping behavior can overload the network between your client and Google causing problems for many parties.
A better approach is to retry with increasing delays between attempts. Usually the delay is increased by a multiplicative factor with each attempt, an approach known as Exponential Backoff.
For example, consider an application that wishes to make this request to the Google Maps Time Zone API:
https://maps.googleapis.com/maps/api/timezone/json?location=39.6034810,-119.6822510&timestamp=1331161200&key=YOUR_API_KEY
The following Python example shows how to make the request with exponential backoff:
import json
import time
import urllib
import urllib2
def timezone(lat, lng, timestamp):
# The maps_key defined below isn't a valid Google Maps API key.
# You need to get your own API key.
# See https://developers.google.com/maps/documentation/timezone/get-api-key
maps_key = 'YOUR_KEY_HERE'
timezone_base_url = 'https://maps.googleapis.com/maps/api/timezone/json'
# This joins the parts of the URL together into one string.
url = timezone_base_url + '?' + urllib.urlencode({
'location': "%s,%s" % (lat, lng),
'timestamp': timestamp,
'key': maps_key,
})
current_delay = 0.1 # Set the initial retry delay to 100ms.
max_delay = 3600 # Set the maximum retry delay to 1 hour.
while True:
try:
# Get the API response.
response = str(urllib2.urlopen(url).read())
except IOError:
pass # Fall through to the retry loop.
else:
# If we didn't get an IOError then parse the result.
result = json.loads(response.replace('\\n', ''))
if result['status'] == 'OK':
return result['timeZoneId']
elif result['status'] != 'UNKNOWN_ERROR':
# Many API errors cannot be fixed by a retry, e.g. INVALID_REQUEST or
# ZERO_RESULTS. There is no point retrying these requests.
raise Exception(result['error_message'])
if current_delay > max_delay:
raise Exception('Too many retry attempts.')
print 'Waiting', current_delay, 'seconds before retrying.'
time.sleep(current_delay)
current_delay *= 2 # Increase the delay each time we retry.
tz = timezone(39.6034810, -119.6822510, 1331161200)
print 'Timezone:', tz
Of course this will not resolve the "false responses" you mention; I suspect that depends on data quality and does not happen randomly.

Doing an atomic update of the first instance in a QuerySet

I'm working on a system which has to handle a number of race-conditions when serving jobs to a number of worker-machines.
The clients would query the system for jobs with status='0' (ToDo), then, in an atomic way, update the 'oldest' row with status='1' (Locked) and retrieve the id for that row (for updating the job with worker information like which machine is working on it etc.).
The main issue here is that there might be any number of clients updating at the same time. A solution would be to lock around 20 of the rows with status='0', update the oldest one and release all the locks again afterwards. I've been looking into the TransactionMiddleware but I don't see how this would prevent the case of the oldest one being updated from under me after I query it.
I've looked into the QuerySet.update() thing, and it looks promising, but in the case of two clients getting a hold of the same record, the status would simply updated, and we would have two workers working on the same job.. I'm really at a loss here.
I also found ticket #2705 which seems to handle the case nicely, but I have no idea how to get the code from there because of my limited SVN experience (the last updates are simply diffs, but I don't know how to merge that with the trunk of the code).
Code: Result = Job
class Result(models.Model):
"""
Result: completed- and pending runs
'ToDo': job hasn't been acquired by a client
'Locked': job has been acquired
'Paused'
"""
# relations
run = models.ForeignKey(Run)
input = models.ForeignKey(Input)
PROOF_CHOICES = (
(1, 'Maybe'),
(2, 'No'),
(3, 'Yes'),
(4, 'Killed'),
(5, 'Error'),
(6, 'NA'),
)
proof_status = models.IntegerField(
choices=PROOF_CHOICES,
default=6,
editable=False)
STATUS_CHOICES = (
(0, 'ToDo'),
(1, 'Locked'),
(2, 'Done'),
)
result_status = models.IntegerField(choices=STATUS_CHOICES, editable=False, default=0)
# != 'None' => status = 'Done'
proof_data = models.FileField(upload_to='results/',
null=True, blank=True)
# part of the proof_data
stderr = models.TextField(editable=False,
null=True, blank=True)
realtime = models.TimeField(editable=False,
null=True, blank=True)
usertime = models.TimeField(editable=False,
null=True, blank=True)
systemtime = models.TimeField(editable=False,
null=True, blank=True)
# updated when client sets status to locked
start_time = models.DateTimeField(editable=False)
worker = models.ForeignKey('Worker', related_name='solved',
null=True, blank=True)
To merge #2705 into your django, you need to download it first:
cd <django-dir>
wget http://code.djangoproject.com/attachment/ticket/2705/for_update_11366_cdestigter.diff?format=raw
then rewind svn to the necessary django version:
svn update -r11366
then apply it:
patch -p1 for_update_11366_cdestigter.diff
It will inform you which files were patched successfully and which were not. In the unlikely case of conflicts you can fix them manually looking at http://code.djangoproject.com/attachment/ticket/2705/for_update_11366_cdestigter.diff
To unapply the patch, just write
svn revert --recursive .
If your django is running on one machine, there is a much simpler way to do it... Excuse the pseudo-code as the details of your implementation aren't clear.
from threading import Lock
workers_lock = Lock()
def get_work(request):
workers_lock.acquire()
try:
# Imagine this method exists for brevity
work_item = WorkItem.get_oldest()
work_item.result_status = 1
work_item.save()
finally:
workers_lock.release()
return work_item
You have two choices off the top of my head. One is to lock rows immediately upon retrieval and only release the lock once the appropriate one has been marked as in use. The problem here is that no other client process can even look at the jobs which don't get selected. If you're always just automatically selecting the last one then it may be a brief enough of a window to be o.k. for you.
The other option would be to bring back the rows that are open at the time of the query, but to then check again whenever the client tries to grab a job to work with. When a client attempts to update a job to work on it a check would first be done to see if it's still available. If someone else has already grabbed it then a notification would be sent back to the client. This allows all of the clients to see all of the jobs as snapshots, but if they are constantly grabbing the latest one then you might have the clients constantly receiving notifications that a job is already in use. Maybe this is the race condition to which you're referring?
One way to get around that would be to return the jobs in specific groups to the clients so that they are not always getting the same lists. For example, break them down by geographic area or even just randomly. For example, each client could have an ID of 0 to 9. Take the mod of an ID on the jobs and send back those jobs with the same ending digit to the client. Don't limit it to just those jobs though, as you don't want there to be jobs that you can't reach. So for example if you had clients of 1, 2, and 3 and a job of 104 then no one would be able to get to it. So, once there aren't enough jobs with the correct ending digit jobs would start coming back with other digits just to fill the list. You might need to play around with the exact algorithm here, but hopefully this gives you an idea.
How you lock the rows in your database in order to update them and/or send back the notifications will largely depend on your RDBMS. In MS SQL Server you could wrap all of that work nicely in a stored procedure as long as user intervention isn't needed in the middle of it.
I hope this helps.