-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathkeyword_analysis.py
More file actions
128 lines (108 loc) · 4.45 KB
/
Copy pathkeyword_analysis.py
File metadata and controls
128 lines (108 loc) · 4.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import re
import streamlit as st
import plotly.graph_objects as go
# Whole-word / phrase matching for software "modeling" — substring "model" matches inside
# unrelated words (e.g. remodel, remodeling) and is far too noisy for descriptions.
_MODELING_PHRASE = re.compile(
r'\b(?:model-driven|model-based|modeling)\b|\bunified\s+modeling\s+language\b',
re.I,
)
_MODEL_WORD = re.compile(r'\bmodels?\b', re.I)
def _matches_modeling(description: str, name: str, topics: list[str]) -> bool:
"""True if name/description/topics suggest MDE / software modeling (not substring 'model' in 'remodel')."""
text = f"{description} {name}"
if _MODELING_PHRASE.search(text):
return True
if _MODEL_WORD.search(text):
return True
for raw in topics:
t = (raw or '').lower().strip()
if not t:
continue
if t in {'model-driven', 'model-based', 'modeling', 'mda', 'mde'}:
return True
if 'model-driven' in t or 'model-based' in t or 'modeling' in t:
return True
return False
def analyze_repos_multiple_keywords(repos, keywords, category_name):
"""Analyze repositories for multiple keywords within a category"""
matching_repos = []
non_matching_repos = []
for repo in repos:
description = (repo.get('description', '') or '').lower()
name = (repo.get('name', '') or '').lower()
topics = [t.lower() for t in repo.get('topics', [])]
if category_name == 'modeling':
matches = _matches_modeling(description, name, topics)
else:
# Check if any of the keywords match
matches = any(
(keyword in description if keyword != 'ai' else (' ai ' in description or ' ai-' in description)) or
(keyword in name if keyword != 'ai' else (' ai ' in name or ' ai-' in name)) or
any(keyword == topic.strip() for topic in topics)
for keyword in keywords
)
if matches:
matching_repos.append(repo)
else:
non_matching_repos.append(repo)
return matching_repos, non_matching_repos
def display_analysis(table_repos, category):
"""Pie chart + table for *category*. *table_repos* must be the same list as the main repository table."""
# Define keyword sets for each category
keyword_sets = {
'no-code': ['nocode', 'no-code'],
'modeling': ['model', 'modeling', 'model-driven', 'model-based'],
'uml': ['uml', 'unified modeling language'],
'ai': ['ai', 'artificial intelligence']
}
# Define excluded repos for modeling category
modeling_exclusions = {'langflow', 'ludwig', 'alan-sdk-web', 'otto-m8'}
# Filter out specific repos for modeling category
repos_to_analyze = table_repos
if category == 'modeling':
repos_to_analyze = [
repo for repo in table_repos if repo["name"] not in modeling_exclusions
]
allowed_urls = frozenset(
r.get("html_url") for r in table_repos if r.get("html_url")
)
matching_repos, _non_matching_repos = analyze_repos_multiple_keywords(
repos_to_analyze,
keyword_sets[category],
category,
)
# Hard guarantee: listed rows are only repos from the table list (same slider-filtered set).
matching_repos = [r for r in matching_repos if r.get("html_url") in allowed_urls]
n_match = len(matching_repos)
n_non_match = len(repos_to_analyze) - n_match
fig = go.Figure(data=[go.Pie(
labels=[f'Mentions {category}', f'No {category} mention'],
values=[n_match, n_non_match],
hole=0.3,
marker_colors=['#2ecc71', '#e74c3c']
)])
fig.update_layout(
title=f'Distribution of {category} mentions in Low-Code Tools',
showlegend=True,
width=700,
height=500,
annotations=[{
'text': f'Total: {len(repos_to_analyze)}',
'x': 0.5,
'y': 0.5,
'font_size': 20,
'showarrow': False
}]
)
st.plotly_chart(fig)
if matching_repos:
st.write(f"### Low-Code Tools Mentioning '{category}'")
data = [{
'Name': repo['name'],
'Description': repo.get('description', 'No description'),
'Stars': repo.get('stargazers_count', 0)
} for repo in matching_repos]
st.table(data)
else:
st.write(f"No repositories found mentioning '{category}'")