The four values of a participatory decision-making process
In the first post of the series, we talked about why have a participatory decision-making process is so important, and the value that it can bring. However, it can be quick difficult to define what that is. Fortunately, there is a set of four values that must present in each discussion or meeting or whatever the decision-making is. They are:
The four values of a participatory decision-making process are
An in-depth analysis of the four values:
First value: Full participation
Participants are comfortable in sharing uncomfortable ideas and their first draft ideas
Participants are encouraging each other to think like that
The facilitators role in achieving full participation
Protect against injunctions against thinking in public (e.g. Can we go back to the topic, we are diverging, didn’t we already discuss this)
Build a respectful and supportive atmosphere
Protect against self-censorship
Second value: Mutual understanding
The participants understand and accept the legitimacy of the others needs and goals
The participants think from each other’s point’s of view
Dialogue is more important than persuasion
The participants take time to understand everyone’s perspectives
The facilitators role in achieving mutual understanding
Prevent the “I really can’t focus on what you are saying until I feel you understand what is my points of view” mentality
Help everyone realize the value of thinking from each others point of view
Always be impartial and honor the points of view of everyone involved. This ways, every member has the feeling that someone understands them
Third value: Inclusive solutions
Solutions emerge from the integrations of everyone’s perspectives, needs and goals
Everyone has a piece of truth
The solutions are not compromises, as they work for everyone involved
They might require the discovery of a new option
Innovation and sustainability of a solution are more important than the decision being expedient
The facilitators role in achieving inclusive solutions
Help the group find innovative ideas that result from using everyone’s point of view
Help the group engage in divergent thinking
And then build a shared framework of understanding in the groan zone
To, at last, converge with sound decisions
Fourth: Shared responsibility
Everyone is an owner of the outcome
Everyone is responsible for running the meeting: settings the goals, the agenda, the priorities and arriving at conclusions
Members must be able to implement the proposals that they endorse
The problem: the group relies on authority. This makes the leaders to “get on with it” and to the work themselves
The facilitators role in achieving shared responsibility
The facilitator helps the group build assertiveness, collaboration and the ownership of the decision process and outcomes.
I have been reading “The Facilitator’s Guide to Participatory Decision-Making” by Sam Kaner. The objective of this series is to write down some notes for me, and provide content that can be found by others, to assert if the book should be bought (so for, the answer is a resounding yes!).
The importance of a participatory decision-making process
Facilitator’s Guide to Participatory Decision-Making
Well, what is this book about?
Decision making is everywhere, from small things like how to divide tasks for an afternoon project to large multi-month enterprises with several stakeholders involved and many workers. Therefore making sound decisions is super important: it will lead to better products, less time wasted. Specially, it wil lead to better morale, as everyone feels that their needs are being heard.
A participatory decision-making process means that every one that is touched by a decision is heard and participates in it. They suggest root causes, share their concerns, suggest solutions and implement the solution. Not only that, but they participate in the decision process itself: run meetings, prepare the agenda, etc.
Why is this so important? Well,
If people do not participate in the decision-making process, that decision will fail with misunderstood ideas and a half-hearted implementation
The diamond of participatory decision-making
This diagram summarizes the dynamics of group thinking. First, the group discusses a new topic as “Business as usual”. The participants stay in their comfort zone and make safe suggestions. Some times this is enough for a simple problem, and the meeting ends there. Many times it is not.
Then, the group moves into divergent thinking. It starts generating alternatives and exploring different points of view. It is important that its members feel safe to share novel ideas, without fear of judgement.
This will lead to the groan zone, where the most discomfort and heated moments exist. The group processes all the ideas created in the divergent zone to start building a shared framework of understanding. What is the shared framework of understanding? It is a “state” where the group is aware of the individual’s concerns, points of view and suggestions. Everyone shares the same level of understanding of the problem.
When this happens the group can start to converge. It summarizes key points, judges the ideas and evaluates alternatives. Hopefully, this leads to a decision without any compromise, where each affected party has its problems addressed.
Free flowing open discussion
Gathering different points of view
Understanding foreign and complex ideas
Build a shared framework of understanding
The confusion moment
Summarizing key points
Sorting ideas into categories
Last but not least, there four values adjacent to all this process. They are fundamental in ensuring that the participatory part of the decision-making process happens. They are:
There is an entire post on this series dedicated to dissecting them.
The facilitator role in participatory decision-making
Well, that explains the second part of “The Facilitator’s Guide to Participatory Decision-Making“, what about the facilitator? Who is that guy?
The facilitator is a servant leader that ensures everyone is heard and feels safe to share their opinions. Lastly, the facilitator guides the group through the diamond of participatory decision making.
There are some “smells” that prevent traditional groups from reaching perfect solutions:
Today I’ll show you how to create your custom prometheus metric for your django application. Prometheus is an awesome tool to monitor our stack, specially with its integration with grafana and its cool dashboards.
The example metric is for a recent use case. I wanted to measure my website visitors favourite pages, and where they came from.
I wanted to achieve this without tracking, cookies, paid services or having to use Google Analytics. Since I was already using a Prometheus/ Grafana suite to have visibility of my platform health, I decided to use it for this goal as well.
This was the end result, on grafana:
First step: having django-prometheus up and running!
Just follow the instructions on the project readme, they should be just:
pip install django-prometheus
Then, on settings.py
INSTALLED_APPS = [
MIDDLEWARE = [
# All your other middlewares go here, including the default
# middlewares like SessionMiddleware, CommonMiddleware,
# CsrfViewmiddleware, SecurityMiddleware, etc.
Also, if you are deploying your code using gunicorn or similar(and you should if you are deploying to a production environment!), pay attention. You need to declare multiple ports since the workers could block each other while trying to service the Prometheus scrape request. This is also very well explained in the django-Prometheus documentation.
Our custom metric will count the number of requests by view, path and referer.
The general idea is to first create a new Metrics class, that inherits from django_prometheus.Metrics. On that we will register own actual metric:
we want it to be a Counter, because it will be increasing over time.
we will unoriginally name it django_http_requests_total_by_view_path_referer,
and add a description that will be useful for documentation purposes.
lastly, our metric will have three labels: view, path and referer so that we can group and filter by them.
Last but not least, do not forget to call the parent method so that we register the remaining metrics.
from django_prometheus.conf import NAMESPACE
from django_prometheus.middleware import Metrics
from prometheus_client import Counter
self.requests_total_by_view_path_referer = self.register_metric(
"Count of requests by view, path, referer.",
["view", "path", "referer"],
Third step: creating our custom PrometheusMiddleware
Now that we have our shiny metric, we need to measure it. To do so, we will create two classes that inherit from PrometheusBeforeMiddleware and PrometheusBeforeMiddleware – they will contain our actual metric collection logic.
PrometheusAfterMiddleWare has a bunch of methods where we can add our logic. These methods are called on different moments of the request/response lifecycle, and so receive different parameters:
For example, process_exception() receives the request and exception objects,
process_response receives()request and response object,
the process_view method() receives the request and view related objects.
Take a look at the django-prometheus existing code to figure out the best place to put your metric, putting it closer to similar metrics. For this caseprocess_response()seemed like a good candidate because the view name has been resolved by then.
from django_prometheus.middleware import Metrics, PrometheusBeforeMiddleware, PrometheusAfterMiddleware
metrics_cls = CustomMetrics
metrics_cls = CustomMetrics
def _get_referer_name(self, request):
referer_name = "<unnamed referer>"
if hasattr(request, "META"):
if request.META is not None:
if request.META.get("HTTP_REFERER") is not None:
referer_name = request.META.get("HTTP_REFERER")
def process_response(self, request, response):
return super().process_response(request, response)
The actual implementation is very simple:
Label the metric with the view name, the path, and referer values:
To get the view we use the django-prometheus built-in _get_view_name function,
To get the referer we adapt the aforementioned function’s logic to get the referer field from the HTTP request header dict, and lastly,
We get the path from the django request object.
We finally increment the resulting metric
Call the parent method to get all the other metrics.
Last step: plugging everything together
This is the easiest step! We just need to replace django-prometheus middleware with our custom middleware in django settings!
Assuming your custom Middleware is in DjangoSite/MyApp/custom_metrics.py:
MIDDLEWARE = [
# .. all other middleware
If you go to your /metrics endpoint you should see it:
Then is can be exported to prometheus so we can do all the cool things with grafana:
Although it has some tricks, creating your custom Prometheus metric for your Django application is not very difficult.
For my web analytics use-case, it would be trivial to get the user-agent field to know how my visitors are reading my site, if they are registered users or not, etc.
Dokuwiki is a very simple wiki platform that you can self-host. It provides just the right balance between features and complexity. With an ecosystem of plugins, it allows you to customize your wiki to your taste. I’ve searched this ecosystem to personalize mine to the extent where I can use it without battling its rigid “wiki nature”.
Today I want to share some of the plugins that I have used on my personal wiki.
This was the first plugin that I installed— it enables the formatting of the text using markdown rather than the wiki syntax – which makes for a much more enjoying writing experience in general. Note that you can use the two interchangeably, so no dokuwiki formatting feature is lost.
The default way of creating a new page in DokuWiki is to create a new link from an already existing page — while this ensures that there are no orphans pages, this is cumbersome and not ergonomic. This plugin adds a form that enables you to quickly create a new page.
The risk of creating an orphan page is mitigated with the IndexMenu.
The third plugin on this collection creates a list of all the pages under a namespace — with many options for you to customize the filtering and display.
I use it on my main page to have a listing of all the namespaces and pages on my wiki. This makes it super easy to find what I am looking for, and ensures no page goes missing. I also list my most used namespaces (my work notes and programming snippets) there, so I can quickly jump to the info I’m looking for.
Code used to generate the previous lists:
// index everything under the tech namespace
## Site tree
* note that I have using markdown for the heading, and not wiki syntax
You should not be moving your pages manually, it is super tedious and this plugin does it automatically. To fix this, the move plugin painlessly moves and renames pages and namespaces — it then updates all the needed backlinks. A last note: I’ve had some problems with using this plugin my phone with responsive templates,it only works with the wiki in desktop mode.
The last plugin I want to share breaks the traditional hierarchy of parent and child pages. This plugin lets you assign category tags to wiki pages — which can then be listed and you can find all related pages.
A very interesting use I found was to create a “pinned” tag that I then filter by on my start page. This way I have my most used pages in one place.
That was it! Thank you for reading, I hope you enjoying this list!