A campanha "para abolir Stallman", que começou com a publicação no Medium, nos fornece muitos dados interessantes. Como a assinatura de cartas abertas para cancelamento e suporte para Stallman é feita no github, podemos analisar algumas características de ambas as partes usando estatísticas que estão disponíveis por meio da API.
Isso é ajudado pelo fato de que no github é difícil editar dados "retroativamente" sem perder novas assinaturas.
As seguintes suposições podem ser testadas ("X" pode ser uma proposta para cancelar Stallman ou uma expressão de seu apoio):
Os oponentes de X são mais frequentemente associados a grandes empresas do que seus apoiadores
Os proponentes do X confirmam o código com mais frequência e mais e, portanto, são mais úteis para a comunidade de código aberto.
Os oponentes do X são significativamente menos propensos a se comprometer com um repositório com licenças gratuitas.
Os oponentes do X preferem Rust (ou JS), os defensores do C (ou C ++, Python)
Os oponentes de X são mais socialmente ativos, eles têm contas sociais. redes, twitter, eles costumam escrever.
Os oponentes de X não cometem código nos fins de semana (só trabalham durante o horário comercial, não entusiastas)
A maioria dos oponentes de X foram registrados no github há menos de meio ano
Tentamos testar algumas dessas suposições e convidar qualquer pessoa interessada para testar o restante das suposições e contribuir (e testar) com outras.
Criamos um repositório no qual o trabalho ocorrerá. Ele também contém este artigo, sua cópia no Habré será atualizada à medida que as solicitações pull forem adicionadas. Junte-se à pesquisa!
Além disso, haverá detalhes.
Uma nota sobre honestidade científica
Quaisquer hipóteses e quaisquer evidências testáveis serão aceitas e adicionadas ao artigo. Não consideramos possível ocultar dados que contradigam nossa posição. Todas as interpretações serão adicionadas também. Convidamos apoiadores de ambos os cargos para trabalharem juntos (sim, é possível). Repositório de colaboração .
Campanha de cancelamento de Stallman é executada em um centro
23 Mar 2021 10:42:36 AM PDT, - 23 Mar 2021 01:23:39 PM PDT. , . , , ( ) .
$ cat get-stars.sh
#!/bin/bash
set -ue
page=1
owner_repo=$1
while true; do
curl -s -H "Authorization: token $GITHUB_OAUTH_" \\
-H "Accept: application/vnd.github.v3.star+json" \\
"<https://api.github.com/repos/$owner_repo/stargazers?per_page=100&page=$page>"| \\
jq -r .[].starred_at_ | grep . || break
((page++)) || true
done
$ echo "epoch,con" >con.stars.csv
$ ./get-stars.sh 'rms-open-letter/rms-open-letter.github.io'|while read a; do date -d $a +%s; done|sort -n|cat -n|awk '{print $2","$1}' >>con.stars.csv
$ echo "epoch,pro" >pro.stars.csv
$ ./get-stars.sh 'rms-support-letter/rms-support-letter.github.io'|while read a; do date -d $a +%s; done|sort -n|cat -n|awk '{print $2","$1}' >>pro.stars.csv
$ join -t, -e '' -o auto -a1 -a2 con.stars.csv pro.stars.csv >joined.stars.csv
, . , , / .
, -, . , - .
1345 5000+ . :
$ cat get-commits.py
#!/usr/bin/env python
import os
import requests
import json
import sys
repo = sys.argv[1]
headers = {'Authorization': 'token {}'.format(os.environ["GITHUB_OAUTH"])}
commits = []
page = 0
while page < 300:
page += 1
data = requests.get('https://api.github.com/repos/{}/commits?per_page=100&page={}'.format(repo, page), headers=headers).json()
if len(data) == 0:
break
commits += data
print(json.dumps(commits, indent=4))
$ ./get-commits.py 'rms-open-letter/rms-open-letter.github.io' >con.commits.json
$ ./get-commits.py 'rms-support-letter/rms-support-letter.github.io' >pro.commits.json
:
$ jq -r .[].commit.author.date pro.commits.json|sort -u|cat -n|awk '{print $2","$1}'|sed -e 's/T/ *' -e 's/Z/*' >pro.commits.csv
$ jq -r .[].commit.author.date con.commits.json|sort -u|cat -n|awk '{print $2","$1}'|sed -e 's/T/ *' -e 's/Z/*' >con.commits.csv
$ join -t, -e '' -o auto -a1 -a2 con.commits.csv pro.commits.csv >joined.commits.csv
, . . .
.
$ jq -r .[].commit.author.date con.commits.json |./weekday-from-date.py >con.rms_commits.csv
$ jq -r .[].commit.author.date pro.commits.json |./weekday-from-date.py >pro.rms_commits.csv
$ join -t, con.rms_commits.csv pro.rms_commits.csv >joined.rms_commits.csv
A , . , no meeting day.
.
, 100 :
$ jq -r .[].author.login con.commits.json|sort -u >con.logins
$ jq -r .[].author.login pro.commits.json|sort -u >pro.logins
$ cat get-user-events-data.sh
#!/bin/bash
set -ue
script_dir=$(dirname $(realpath $0))
get_data() {
local data_dir=$script_dir/$1 userdata events
for x in $(cat $1.logins); do
userdata=$data_dir/$x.userdata
[ -r $userdata ] && continue
curl -s -H "Authorization: token $GITHUB_OAUTH" "<https://api.github.com/users/$x>" >$userdata
sleep 1
events=$data_dir/$x.events
[ -r $events ] && continue
curl -s -H "Authorization: token $GITHUB_OAUTH" "<https://api.github.com/users/$x/events?per_page=100>" >$events
sleep 1
done
}
get_data $1
$ ./get-user-events-data.sh con
$ ./get-user-events-data.sh pro
, :
{
"login": "zyxw59",
"id": 3157093,
"node_id": "MDQ6VXNlcjMxNTcwOTM=",
"avatar_url": "https://avatars.githubusercontent.com/u/3157093?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/zyxw59",
"html_url": "https://github.com/zyxw59",
"followers_url": "https://api.github.com/users/zyxw59/followers",
"following_url": "https://api.github.com/users/zyxw59/following{/other_user}",
"gists_url": "https://api.github.com/users/zyxw59/gists{/gist_id}",
"starred_url": "https://api.github.com/users/zyxw59/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/zyxw59/subscriptions",
"organizations_url": "https://api.github.com/users/zyxw59/orgs",
"repos_url": "https://api.github.com/users/zyxw59/repos",
"events_url": "https://api.github.com/users/zyxw59/events{/privacy}",
"received_events_url": "https://api.github.com/users/zyxw59/received_events",
"type": "User",
"site_admin": false,
"name": "Emily Crandall Fleischman",
"company": "Commure",
"blog": "",
"location": null,
"email": "emilycf@mit.edu",
"hireable": null,
"bio": null,
"twitter_username": null,
"public_repos": 24,
"public_gists": 0,
"followers": 2,
"following": 12,
"created_at": "2012-12-31T05:33:30Z",
"updated_at": "2021-03-14T01:53:51Z"
}
, twitter_username, company, bio blog:
|
|
|
|
twitter_username |
31% |
8% |
company |
48% |
20% |
bio |
53% |
31% |
blog |
63% |
31% |
. ( , , .
public_repos, public_gists, followers following:
|
|
|
|
||
|
|
|
|
|
|
public_repos |
62 |
34 |
21 |
9 |
public_gists |
18 |
4 |
4 |
0 |
followers |
105 |
23 |
16 |
2 |
following |
30 |
8 |
14 |
1 |
. followers, , . followers / following 3, 1.1.
events_url, .
Agora vamos dar uma olhada nas ações dos usuários. Há muitos dados baixados e você pode analisá-los de várias maneiras. Você pode verificar a atividade do usuário por dia da semana para ver como esses dados se correlacionam com a atividade específica para os prós e contras de Stallman.
O código
cat weekday-from-date.py
#!/usr/bin/env python
import datetime
import sys
out = [0] \* 7
total = 0
for line in sys.stdin.readlines():
weekday = datetime.datetime.strptime(line.strip(), '%Y-%m-%dT%H:%M:%SZ').weekday()
out[weekday] += 1
total += 1
for day, count in enumerate(out):
print("{},{}".format(day, count / total))
$ jq -r .[].created<sub>at</sub> con/\*.events|./weekday-from-date.py >con.event<sub>day.normalized.csv</sub>
$ jq -r .[].created<sub>at</sub> pro/\*.events|./weekday-from-date.py >pro.event<sub>day.normalized.csv</sub>
$ join -t, con.event<sub>day.normalized.csv</sub> pro.event<sub>day.normalized.csv</sub>
Percebe-se que a tendência continua: a atividade dos adversários diminui drasticamente no fim de semana. Pode-se presumir que eles usam o github no trabalho e, possivelmente, trabalham em projetos de código aberto por um salário. Se essa premissa estiver correta, a opinião deles pode ser decorrente da seleção feita por empresas que contratam programadores para trabalhar em projetos de código aberto.