Changes in widgets for consistency. Added MArkdown generator with dummy functionality
Browse files- markdownGenerator.py +68 -0
- sdc_view.py +82 -79
markdownGenerator.py
CHANGED
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
def generate_markdown(session_state):
|
2 |
+
|
3 |
+
html_str= f"""
|
4 |
+
# The Software diversity card of {session_state["master_title"]}
|
5 |
+
{session_state["master_desc"]}
|
6 |
+
## 🏢 Teams Summary
|
7 |
+
|
8 |
+
<table>
|
9 |
+
<tr>
|
10 |
+
<th>Name</th>
|
11 |
+
<th>Type</th>
|
12 |
+
<th>Age Range</th>
|
13 |
+
<th>Ethnicities</th>
|
14 |
+
<th>Genders</th>
|
15 |
+
<th>Team Size</th>
|
16 |
+
<th>Average Tenure</th>
|
17 |
+
<th>Start Date</th>
|
18 |
+
<th>Location</th>
|
19 |
+
</tr>
|
20 |
+
<tr>
|
21 |
+
<td><strong>DevelopmentTeam</strong></td>
|
22 |
+
<td>DevelopmentTeam</td>
|
23 |
+
<td>25-30</td>
|
24 |
+
<td>Colombian, Brazilian, Argentinian, French, Spanish, Pakistani, Serbian, Iranian, Moroccan, Italian</td>
|
25 |
+
<td>Male 80%, Female 20%</td>
|
26 |
+
<td>15</td>
|
27 |
+
<td>4.3</td>
|
28 |
+
<td>11-08-2022</td>
|
29 |
+
<td>Luxembourg</td>
|
30 |
+
</tr>
|
31 |
+
<tr>
|
32 |
+
<td><strong>Usability Testers</strong></td>
|
33 |
+
<td>Tester Team</td>
|
34 |
+
<td>22-24</td>
|
35 |
+
<td>French</td>
|
36 |
+
<td>Non-disclosed</td>
|
37 |
+
<td>18</td>
|
38 |
+
<td>0.5</td>
|
39 |
+
<td>17-10-2023</td>
|
40 |
+
<td>University of Luxembourg</td>
|
41 |
+
</tr>
|
42 |
+
<tr>
|
43 |
+
<td><strong>Computer Science Students</strong></td>
|
44 |
+
<td>Target Community</td>
|
45 |
+
<td>18-100</td>
|
46 |
+
<td>Non-disclosed</td>
|
47 |
+
<td>Non-disclosed</td>
|
48 |
+
<td>-</td>
|
49 |
+
<td>0</td>
|
50 |
+
<td>-</td>
|
51 |
+
<td>France & Luxembourg</td>
|
52 |
+
</tr>
|
53 |
+
<tr>
|
54 |
+
<td><strong>Climate Public Servants</strong></td>
|
55 |
+
<td>Target Community</td>
|
56 |
+
<td>20-100</td>
|
57 |
+
<td>Non-disclosed</td>
|
58 |
+
<td>Non-disclosed</td>
|
59 |
+
<td>-</td>
|
60 |
+
<td>3-5</td>
|
61 |
+
<td>-</td>
|
62 |
+
<td>Luxembourg</td>
|
63 |
+
</tr>
|
64 |
+
</table>
|
65 |
+
|
66 |
+
---
|
67 |
+
"""
|
68 |
+
return html_str
|
sdc_view.py
CHANGED
@@ -11,13 +11,14 @@ from markdownGenerator import *
|
|
11 |
|
12 |
def render_sdc():
|
13 |
|
14 |
-
|
15 |
EducationalLevelType = ['earlyChildhood','primary','lowerSecondary','upperSecondary','postSecondaryNonTertiary','shortCycleTertiary','bachelorEquivalent','masterEquivalent','doctorateEquivalent']
|
16 |
SESType = ['upperClass' ,'upperMiddleClass' ,'middleClass' , 'lowerMiddleClass' , 'lowerClass']
|
17 |
SkillLevelType = ['expert' , 'proficient' , 'advanced' , 'competent' , 'beginner']
|
18 |
ISO3166 = ['Andorra', 'UnitedArabEmirates', 'Afghanistan', 'AntiguaandBarbuda', 'Anguilla', 'Albania', 'Armenia', 'Angola', 'Antarctica', 'Argentina', 'AmericanSamoa', 'Austria', 'Australia', 'Aruba', 'ÅlandIslands', 'Azerbaijan', 'BosniaandHerzegovina', 'Barbados', 'Bangladesh', 'Belgium', 'BurkinaFaso', 'Bulgaria', 'Bahrain', 'Burundi', 'Benin', 'SaintBarthélemy', 'Bermuda', 'BruneiDarussalam', 'Bolivia,PlurinationalStateof', 'Bonaire,SintEustatiusandSaba', 'Brazil', 'Bahamas', 'Bhutan', 'BouvetIsland', 'Botswana', 'Belarus', 'Belize', 'Canada', 'Cocos(Keeling)Islands', 'Congo,DemocraticRepublicofthe', 'CentralAfricanRepublic', 'Congo', 'Switzerland', 'CôtedIvoire', 'CookIslands', 'Chile', 'Cameroon', 'China', 'Colombia', 'CostaRica', 'Cuba', 'CaboVerde', 'Curaçao', 'ChristmasIsland', 'Cyprus', 'Czechia', 'Germany', 'Djibouti', 'Denmark', 'Dominica', 'DominicanRepublic', 'Algeria', 'Ecuador', 'Estonia', 'Egypt', 'WesternSahara', 'Eritrea', 'Spain', 'Ethiopia', 'Finland', 'Fiji', 'FalklandIslands(Malvinas)', 'Micronesia,FederatedStatesof', 'FaroeIslands', 'France', 'Gabon', 'UnitedKingdomofGreatBritainandNorthernIreland', 'Grenada', 'Georgia', 'FrenchGuiana', 'Guernsey', 'Ghana', 'Gibraltar', 'Greenland', 'Gambia', 'Guinea', 'Guadeloupe', 'EquatorialGuinea', 'Greece', 'SouthGeorgiaandtheSouthSandwichIslands', 'Guatemala', 'Guam', 'Guinea-Bissau', 'Guyana', 'HongKong', 'HeardIslandandMcDonaldIslands', 'Honduras', 'Croatia', 'Haiti', 'Hungary', 'Indonesia', 'Ireland', 'Israel', 'IsleofMan', 'India', 'BritishIndianOceanTerritory', 'Iraq', 'Iran,IslamicRepublicof', 'Iceland', 'Italy', 'Jersey', 'Jamaica', 'Jordan', 'Japan', 'Kenya', 'Kyrgyzstan', 'Cambodia', 'Kiribati', 'Comoros', 'SaintKittsandNevis', 'Korea,DemocraticPeoplesRepublicof', 'Korea,Republicof', 'Kuwait', 'CaymanIslands', 'Kazakhstan', 'LaoPeoplesDemocraticRepublic', 'Lebanon', 'SaintLucia', 'Liechtenstein', 'SriLanka', 'Liberia', 'Lesotho', 'Lithuania', 'Luxembourg', 'Latvia', 'Libya', 'Morocco', 'Monaco', 'Moldova,Republicof', 'Montenegro', 'SaintMartin(Frenchpart)', 'Madagascar', 'MarshallIslands', 'NorthMacedonia', 'Mali', 'Myanmar', 'Mongolia', 'Macao', 'NorthernMarianaIslands', 'Martinique', 'Mauritania', 'Montserrat', 'Malta', 'Mauritius', 'Maldives', 'Malawi', 'Mexico', 'Malaysia', 'Mozambique', 'Namibia', 'NewCaledonia', 'Niger', 'NorfolkIsland', 'Nigeria', 'Nicaragua', 'Netherlands,Kingdomofthe', 'Norway', 'Nepal', 'Nauru', 'Niue', 'NewZealand', 'Oman', 'Panama', 'Peru', 'FrenchPolynesia', 'PapuaNewGuinea', 'Philippines', 'Pakistan', 'Poland', 'SaintPierreandMiquelon', 'Pitcairn', 'PuertoRico', 'Palestine,Stateof', 'Portugal', 'Palau', 'Paraguay', 'Qatar', 'Réunion', 'Romania', 'Serbia', 'RussianFederation', 'Rwanda', 'SaudiArabia', 'SolomonIslands', 'Seychelles', 'Sudan', 'Sweden', 'Singapore', 'SaintHelena,AscensionandTristandaCunha', 'Slovenia', 'SvalbardandJanMayen', 'Slovakia', 'SierraLeone', 'SanMarino', 'Senegal', 'Somalia', 'Suriname', 'SouthSudan', 'SaoTomeandPrincipe', 'ElSalvador', 'SintMaarten(Dutchpart)', 'SyrianArabRepublic', 'Eswatini', 'TurksandCaicosIslands', 'Chad', 'FrenchSouthernTerritories', 'Togo', 'Thailand', 'Tajikistan', 'Tokelau', 'Timor-Leste', 'Turkmenistan', 'Tunisia', 'Tonga', 'Türkiye', 'TrinidadandTobago', 'Tuvalu', 'Taiwan,ProvinceofChina', 'Tanzania,UnitedRepublicof', 'Ukraine', 'Uganda', 'UnitedStatesMinorOutlyingIslands', 'UnitedStatesofAmerica', 'Uruguay', 'Uzbekistan', 'HolySee', 'SaintVincentandtheGrenadines', 'Venezuela,BolivarianRepublicof', 'VirginIslands(British)', 'VirginIslands(U.S.)', 'VietNam', 'Vanuatu', 'WallisandFutuna', 'Samoa', 'Yemen', 'Mayotte', 'SouthAfrica', 'Zambia', 'Zimbabwe']
|
19 |
ISO639 = ['Afar' , 'Abkhazian', 'Avestan' , 'Afrikaans' , 'Akan' , 'Amharic' , 'Aragonese','Arabic','Assamese','Avaric','Aymara','Azerbaijani','Bashkir','Belarusian','Bulgarian','Bislama','Bambara','Bengali','Tibetan','Breton','Bosnian','Catalan-Valencian','Chechen','Chamorro','Corsican','Cree','Czech','ChurchSlavonic-OldSlavonic-OldChurchSlavonic','Chuvash','Welsh','Danish','German','Divehi-Dhivehi-Maldivian','Dzongkha','Ewe','GreekModern','English','Esperanto','Spanish-Castilian','Estonian','Basque','Persian','Fulah','Finnish','Fijian','Faroese','French','WesternFrisian','Irish','Gaelic-ScottishGaelic','Galician','Guarani','Gujarati','Manx','Hausa','Hebrew','Hindi','HiriMotu','Croatian','Haitian-HaitianCreole','Hungarian','Armenian','Herero','Interlingua','Indonesian','Interlingue-Occidental','Igbo','SichuanYi-Nuosu','Inupiaq','Ido','Icelandic','Italian','Inuktitut','Japanese','Javanese','Georgian','Kongo','Kikuyu-Gikuyu','Kuanyama-Kwanyama','Kazakh','Kalaallisut-Greenlandic','CentralKhmer','Kannada','Korean','Kanuri','Kashmiri','Kurdish','Komi','Cornish','Kyrgyz-Kirghiz','Latin','Luxembourgish-Letzeburgesch','Ganda','Limburgan-Limburger-Limburgish','Lingala','Lao','Lithuanian','Luba-Katanga','Latvian','Malagasy','Marshallese','Maori','Macedonian','Malayalam','Mongolian','Marathi','Malay','Maltese','Burmese','Nauru','NorwegianBokmål','NorthNdebele','Nepali','Ndonga','Dutch-Flemish','NorwegianNynorsk','Norwegian','SouthNdebele','Navajo-Navaho','Chichewa-Chewa-Nyanja','Occitan','Ojibwa','Oromo','Oriya','Ossetian-Ossetic','Punjabi-Panjabi','Pali','Polish','Pashto-Pushto','Portuguese','Quechua','Romansh','Rundi','Romanian-Moldavian-Moldovan','Russian','Kinyarwanda','Sanskrit','Sardinian','Sindhi','NorthernSami','Sango','Sinhala-Sinhalese','Slovak','Slovenian','Samoan','Shona','Somali','Albanian','Serbian','Swati','SouthernSotho','Sundanese','Swedish','Swahili','Tamil','Telugu','Tajik','Thai','Tigrinya','Turkmen','Tagalog','Tswana','Tonga','Turkish','Tsonga','Tatar','Twi','Tahitian','Uighur-Uyghur','Ukrainian','Urdu','Uzbek','Venda','Vietnamese','Volapük','Walloon','Wolof','Xhosa','Yiddish','Yoruba','Zhuang-Chuang','Chinese','Zulu']
|
20 |
|
|
|
21 |
STATE_FILE = "session_state.json"
|
22 |
|
23 |
def load_state():
|
@@ -27,6 +28,7 @@ def render_sdc():
|
|
27 |
with open(STATE_FILE, "r") as f:
|
28 |
data = json.load(f)
|
29 |
st.session_state.update(data)
|
|
|
30 |
except Exception as e:
|
31 |
st.error(f"Error loading state: {e}")
|
32 |
|
@@ -35,7 +37,7 @@ def render_sdc():
|
|
35 |
try:
|
36 |
# Convert session_state to a regular dict before dumping
|
37 |
with open(STATE_FILE, "w") as f:
|
38 |
-
json.dump(dict(st.session_state), f)
|
39 |
except Exception as e:
|
40 |
st.error(f"Error saving state: {e}")
|
41 |
|
@@ -68,11 +70,6 @@ def render_sdc():
|
|
68 |
st.cache_data.clear()
|
69 |
st.cache_data(lambda: st.session_state.form_data) # Save updated form data
|
70 |
|
71 |
-
# Function to save input into cache
|
72 |
-
def save_to_cache():
|
73 |
-
st.cache_data.clear() # Clear old cache before saving
|
74 |
-
st.cache_data(lambda: st.session_state) # Save updated state
|
75 |
-
|
76 |
# Function to create a text area with caching
|
77 |
def cached_text_area(label, key, placeholder=""):
|
78 |
if key not in st.session_state.form_data:
|
@@ -102,9 +99,9 @@ def render_sdc():
|
|
102 |
save_state()
|
103 |
# Function to create a text area with caching
|
104 |
def cached_radio_input(label, options, key, help=""):
|
105 |
-
if key not in st.session_state.form_data:
|
106 |
-
st.session_state.form_data[key] =
|
107 |
-
|
108 |
st.radio(
|
109 |
label=label,
|
110 |
options=options,
|
@@ -121,15 +118,49 @@ def render_sdc():
|
|
121 |
# Initialize session state for selected countries if needed
|
122 |
if key not in st.session_state:
|
123 |
st.session_state[key] = []
|
|
|
|
|
|
|
|
|
124 |
# Display the multiselect widget
|
125 |
st.multiselect(
|
126 |
label,
|
127 |
options=options,
|
|
|
128 |
key=key,
|
129 |
on_change=lambda: (st.session_state.form_data.update({key: st.session_state[key]}), save_to_cache())[1]
|
130 |
)
|
131 |
|
132 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
def participant(key):
|
134 |
colr, coll = st.columns([1, 1])
|
135 |
with colr:
|
@@ -142,7 +173,7 @@ def render_sdc():
|
|
142 |
st.number_input(
|
143 |
label="The age of the participant:",
|
144 |
key=agekey,
|
145 |
-
on_change=lambda: (st.session_state.form_data.update({key: st.session_state[
|
146 |
)
|
147 |
cached_text_input("Location", f"{key}_location", "The title of the card")
|
148 |
cached_radio_input("WorkplaceType", ["Presential", "Hybrid", "Remote"], f"{key}_workdplace", "The title of the card")
|
@@ -176,43 +207,14 @@ def render_sdc():
|
|
176 |
group(key)
|
177 |
|
178 |
def team(key):
|
179 |
-
|
180 |
-
#cached_text_area("Team description", f"{key}_desc", "Description of the team")
|
181 |
-
agesize = f"{key}_size"
|
182 |
-
if agesize not in st.session_state:
|
183 |
-
st.session_state[agesize] = 0 # default value
|
184 |
-
# Display a number input widget
|
185 |
-
st.slider(
|
186 |
-
label="The number of participants in the team:",
|
187 |
-
min_value=0,
|
188 |
-
max_value=120,
|
189 |
-
value=(10,20),
|
190 |
-
key=agesize,
|
191 |
-
on_change=lambda: (st.session_state.form_data.update({key: st.session_state[agesize]}), save_to_cache())[1]
|
192 |
-
)
|
193 |
-
colr, coll = st.columns([1, 1])
|
194 |
-
with colr:
|
195 |
-
st.date_input(label="Start date of the team", value=datetime.date(2019, 7, 6),key=f"{key}_startdate",on_change=lambda: (st.session_state.form_data.update({key: st.session_state[f"{key}_startdate"]}), save_to_cache())[1])
|
196 |
-
with coll:
|
197 |
-
st.date_input(label="End date of the team", value=datetime.date(2019, 7, 6),key=f"{key}_enddate",on_change=lambda: (st.session_state.form_data.update({key: st.session_state[f"{key}_enddate"]}), save_to_cache())[1])
|
198 |
-
|
199 |
group(key)
|
200 |
|
201 |
def group(key):
|
202 |
colr, coll = st.columns([1, 1])
|
203 |
with colr:
|
204 |
-
|
205 |
-
|
206 |
-
st.session_state[agekey] = 0 # default value
|
207 |
-
# Display a number input widget
|
208 |
-
st.slider(
|
209 |
-
label="The average age of the participant:",
|
210 |
-
min_value=0,
|
211 |
-
max_value=120,
|
212 |
-
value=(10,20),
|
213 |
-
key=agekey,
|
214 |
-
on_change=lambda: (st.session_state.form_data.update({key: st.session_state[agekey]}), save_to_cache())[1]
|
215 |
-
)
|
216 |
cached_text_input("Location", f"{key}_location", "Location of the organization")
|
217 |
cached_radio_input("WorkplaceType", ["Presential", "Hybrid", "Remote"], f"{key}_workplace", "The kind of organization")
|
218 |
cached_text_input("Ethnicities", f"{key}_ethnicities", "Ethinicities present in the organization, comma sepparated ")
|
@@ -224,7 +226,7 @@ def render_sdc():
|
|
224 |
cached_multiple_radio(f"{key}_edlevel",EducationalLevelType,"Educational Level")
|
225 |
cached_multiple_radio( f"{key}_sociostati", SESType,"Socioeconomic Status")
|
226 |
cached_multiple_radio( f"{key}_skills", SkillLevelType,"Skill Level")
|
227 |
-
cached_multiple_radio( f"{key}_languages",
|
228 |
# Initialize session state for the number input if it doesn't exist
|
229 |
agekey = f"{key}_tenure"
|
230 |
if agekey not in st.session_state:
|
@@ -234,7 +236,7 @@ def render_sdc():
|
|
234 |
st.number_input(
|
235 |
label="The professioanl tenure of the participant in years",
|
236 |
key=agekey,
|
237 |
-
on_change=lambda: (st.session_state.form_data.update({key: st.session_state[
|
238 |
)
|
239 |
|
240 |
def init_state(key):
|
@@ -310,7 +312,7 @@ def render_sdc():
|
|
310 |
unsafe_allow_html=True
|
311 |
)
|
312 |
st.markdown("""\
|
313 |
-
|
314 |
""")
|
315 |
|
316 |
|
@@ -322,7 +324,8 @@ def render_sdc():
|
|
322 |
cached_text_area("A description of the software project", "master_desc", "The title of the card")
|
323 |
|
324 |
|
325 |
-
with st.
|
|
|
326 |
governance, usageContext, participants = st.tabs([
|
327 |
"Governance",
|
328 |
"Usage context",
|
@@ -339,16 +342,18 @@ def render_sdc():
|
|
339 |
key = "governance_govProcesses"
|
340 |
init_state(key)
|
341 |
st.write("Define the set of governament process of your software project")
|
|
|
342 |
if st.button("Add governament processes"):
|
343 |
add_text_area(key)
|
344 |
# Loop over the array and create a text area with a remove button for each element
|
345 |
-
for idx,
|
346 |
# Create two columns: one for the text area, one for the remove button
|
347 |
col1, col2 = st.columns([6, 1])
|
348 |
with col1:
|
349 |
cached_text_area(f"Governament process {idx + 1}", f"governance_govProcesses{idx}", "Specific the governance rules of the software project. For instance, the funders, or the role and the relation between the different bodies that governs the software.")
|
350 |
with col2:
|
351 |
-
|
|
|
352 |
remove_text_area(idx,key)
|
353 |
|
354 |
# BODIES
|
@@ -370,21 +375,20 @@ def render_sdc():
|
|
370 |
|
371 |
with col2:
|
372 |
if st.button("Remove", key=f"{key}_remove_{idx}"):
|
373 |
-
remove_text_area(idx,key)
|
374 |
cached_multiple_radio(f"{key}_{idx}_type", ['funders', 'directors', 'administrators', 'other'], f"Body role type" )
|
375 |
|
376 |
-
st.
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
|
387 |
-
|
388 |
with usageContext:
|
389 |
colr, coll = st.columns([1, 1])
|
390 |
with colr:
|
@@ -392,7 +396,7 @@ def render_sdc():
|
|
392 |
cached_text_area("Social context",f"{key}_description", "Description of the usage and social context of the app")
|
393 |
with coll:
|
394 |
cached_multiple_radio(f"{key}_countries",ISO3166,"The countries where the app is intended to be deployed and used")
|
395 |
-
cached_multiple_radio( f"{key}_languages",
|
396 |
targetCommunities, adaptations = st.tabs([
|
397 |
"Targeted Communities",
|
398 |
"Adpatations",
|
@@ -406,9 +410,7 @@ def render_sdc():
|
|
406 |
with adaptations:
|
407 |
keyAdapt = key+"_adaptation"
|
408 |
cached_text_input("Name",f"{keyAdapt}_name", "Name or ID of the adaptation")
|
409 |
-
cached_text_area("Description",f"{keyAdapt}_description", "Description of the adaptation")
|
410 |
-
|
411 |
-
|
412 |
|
413 |
with participants:
|
414 |
# Participants
|
@@ -430,38 +432,39 @@ def render_sdc():
|
|
430 |
|
431 |
with col2:
|
432 |
if st.button("Remove", key=f"{key}_remove_{idx}"):
|
433 |
-
remove_text_area(idx,key)
|
434 |
cached_multiple_radio(f"{key}_{idx}_type", ['Development Team', 'NonCoding Contributor', 'Tester Team', 'Public Reporter TEam'], f"Team role type" )
|
435 |
team(f"{key}_{idx}")
|
436 |
|
437 |
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
## Showing the generated card and the generated JSON
|
442 |
st.divider()
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
# Provide a download button
|
448 |
st.download_button(
|
449 |
label="Download Markdown",
|
450 |
-
data=
|
451 |
file_name="SoftareDiveristyCard.md",
|
452 |
mime="text/markdown"
|
453 |
)
|
454 |
-
st.
|
455 |
-
|
|
|
456 |
|
457 |
# Convert the session state to a JSON string
|
458 |
session_state_json = json.dumps(serialize_session_state(), indent=4)
|
459 |
st.download_button(
|
460 |
label="Download JSON",
|
461 |
data=session_state_json,
|
462 |
-
file_name="
|
463 |
mime="application/json"
|
464 |
)
|
465 |
# Display the session state as pretty JSON
|
466 |
-
st.json(serialize_session_state())
|
|
|
|
|
467 |
|
|
|
11 |
|
12 |
def render_sdc():
|
13 |
|
14 |
+
## Constant of the Software diversity card
|
15 |
EducationalLevelType = ['earlyChildhood','primary','lowerSecondary','upperSecondary','postSecondaryNonTertiary','shortCycleTertiary','bachelorEquivalent','masterEquivalent','doctorateEquivalent']
|
16 |
SESType = ['upperClass' ,'upperMiddleClass' ,'middleClass' , 'lowerMiddleClass' , 'lowerClass']
|
17 |
SkillLevelType = ['expert' , 'proficient' , 'advanced' , 'competent' , 'beginner']
|
18 |
ISO3166 = ['Andorra', 'UnitedArabEmirates', 'Afghanistan', 'AntiguaandBarbuda', 'Anguilla', 'Albania', 'Armenia', 'Angola', 'Antarctica', 'Argentina', 'AmericanSamoa', 'Austria', 'Australia', 'Aruba', 'ÅlandIslands', 'Azerbaijan', 'BosniaandHerzegovina', 'Barbados', 'Bangladesh', 'Belgium', 'BurkinaFaso', 'Bulgaria', 'Bahrain', 'Burundi', 'Benin', 'SaintBarthélemy', 'Bermuda', 'BruneiDarussalam', 'Bolivia,PlurinationalStateof', 'Bonaire,SintEustatiusandSaba', 'Brazil', 'Bahamas', 'Bhutan', 'BouvetIsland', 'Botswana', 'Belarus', 'Belize', 'Canada', 'Cocos(Keeling)Islands', 'Congo,DemocraticRepublicofthe', 'CentralAfricanRepublic', 'Congo', 'Switzerland', 'CôtedIvoire', 'CookIslands', 'Chile', 'Cameroon', 'China', 'Colombia', 'CostaRica', 'Cuba', 'CaboVerde', 'Curaçao', 'ChristmasIsland', 'Cyprus', 'Czechia', 'Germany', 'Djibouti', 'Denmark', 'Dominica', 'DominicanRepublic', 'Algeria', 'Ecuador', 'Estonia', 'Egypt', 'WesternSahara', 'Eritrea', 'Spain', 'Ethiopia', 'Finland', 'Fiji', 'FalklandIslands(Malvinas)', 'Micronesia,FederatedStatesof', 'FaroeIslands', 'France', 'Gabon', 'UnitedKingdomofGreatBritainandNorthernIreland', 'Grenada', 'Georgia', 'FrenchGuiana', 'Guernsey', 'Ghana', 'Gibraltar', 'Greenland', 'Gambia', 'Guinea', 'Guadeloupe', 'EquatorialGuinea', 'Greece', 'SouthGeorgiaandtheSouthSandwichIslands', 'Guatemala', 'Guam', 'Guinea-Bissau', 'Guyana', 'HongKong', 'HeardIslandandMcDonaldIslands', 'Honduras', 'Croatia', 'Haiti', 'Hungary', 'Indonesia', 'Ireland', 'Israel', 'IsleofMan', 'India', 'BritishIndianOceanTerritory', 'Iraq', 'Iran,IslamicRepublicof', 'Iceland', 'Italy', 'Jersey', 'Jamaica', 'Jordan', 'Japan', 'Kenya', 'Kyrgyzstan', 'Cambodia', 'Kiribati', 'Comoros', 'SaintKittsandNevis', 'Korea,DemocraticPeoplesRepublicof', 'Korea,Republicof', 'Kuwait', 'CaymanIslands', 'Kazakhstan', 'LaoPeoplesDemocraticRepublic', 'Lebanon', 'SaintLucia', 'Liechtenstein', 'SriLanka', 'Liberia', 'Lesotho', 'Lithuania', 'Luxembourg', 'Latvia', 'Libya', 'Morocco', 'Monaco', 'Moldova,Republicof', 'Montenegro', 'SaintMartin(Frenchpart)', 'Madagascar', 'MarshallIslands', 'NorthMacedonia', 'Mali', 'Myanmar', 'Mongolia', 'Macao', 'NorthernMarianaIslands', 'Martinique', 'Mauritania', 'Montserrat', 'Malta', 'Mauritius', 'Maldives', 'Malawi', 'Mexico', 'Malaysia', 'Mozambique', 'Namibia', 'NewCaledonia', 'Niger', 'NorfolkIsland', 'Nigeria', 'Nicaragua', 'Netherlands,Kingdomofthe', 'Norway', 'Nepal', 'Nauru', 'Niue', 'NewZealand', 'Oman', 'Panama', 'Peru', 'FrenchPolynesia', 'PapuaNewGuinea', 'Philippines', 'Pakistan', 'Poland', 'SaintPierreandMiquelon', 'Pitcairn', 'PuertoRico', 'Palestine,Stateof', 'Portugal', 'Palau', 'Paraguay', 'Qatar', 'Réunion', 'Romania', 'Serbia', 'RussianFederation', 'Rwanda', 'SaudiArabia', 'SolomonIslands', 'Seychelles', 'Sudan', 'Sweden', 'Singapore', 'SaintHelena,AscensionandTristandaCunha', 'Slovenia', 'SvalbardandJanMayen', 'Slovakia', 'SierraLeone', 'SanMarino', 'Senegal', 'Somalia', 'Suriname', 'SouthSudan', 'SaoTomeandPrincipe', 'ElSalvador', 'SintMaarten(Dutchpart)', 'SyrianArabRepublic', 'Eswatini', 'TurksandCaicosIslands', 'Chad', 'FrenchSouthernTerritories', 'Togo', 'Thailand', 'Tajikistan', 'Tokelau', 'Timor-Leste', 'Turkmenistan', 'Tunisia', 'Tonga', 'Türkiye', 'TrinidadandTobago', 'Tuvalu', 'Taiwan,ProvinceofChina', 'Tanzania,UnitedRepublicof', 'Ukraine', 'Uganda', 'UnitedStatesMinorOutlyingIslands', 'UnitedStatesofAmerica', 'Uruguay', 'Uzbekistan', 'HolySee', 'SaintVincentandtheGrenadines', 'Venezuela,BolivarianRepublicof', 'VirginIslands(British)', 'VirginIslands(U.S.)', 'VietNam', 'Vanuatu', 'WallisandFutuna', 'Samoa', 'Yemen', 'Mayotte', 'SouthAfrica', 'Zambia', 'Zimbabwe']
|
19 |
ISO639 = ['Afar' , 'Abkhazian', 'Avestan' , 'Afrikaans' , 'Akan' , 'Amharic' , 'Aragonese','Arabic','Assamese','Avaric','Aymara','Azerbaijani','Bashkir','Belarusian','Bulgarian','Bislama','Bambara','Bengali','Tibetan','Breton','Bosnian','Catalan-Valencian','Chechen','Chamorro','Corsican','Cree','Czech','ChurchSlavonic-OldSlavonic-OldChurchSlavonic','Chuvash','Welsh','Danish','German','Divehi-Dhivehi-Maldivian','Dzongkha','Ewe','GreekModern','English','Esperanto','Spanish-Castilian','Estonian','Basque','Persian','Fulah','Finnish','Fijian','Faroese','French','WesternFrisian','Irish','Gaelic-ScottishGaelic','Galician','Guarani','Gujarati','Manx','Hausa','Hebrew','Hindi','HiriMotu','Croatian','Haitian-HaitianCreole','Hungarian','Armenian','Herero','Interlingua','Indonesian','Interlingue-Occidental','Igbo','SichuanYi-Nuosu','Inupiaq','Ido','Icelandic','Italian','Inuktitut','Japanese','Javanese','Georgian','Kongo','Kikuyu-Gikuyu','Kuanyama-Kwanyama','Kazakh','Kalaallisut-Greenlandic','CentralKhmer','Kannada','Korean','Kanuri','Kashmiri','Kurdish','Komi','Cornish','Kyrgyz-Kirghiz','Latin','Luxembourgish-Letzeburgesch','Ganda','Limburgan-Limburger-Limburgish','Lingala','Lao','Lithuanian','Luba-Katanga','Latvian','Malagasy','Marshallese','Maori','Macedonian','Malayalam','Mongolian','Marathi','Malay','Maltese','Burmese','Nauru','NorwegianBokmål','NorthNdebele','Nepali','Ndonga','Dutch-Flemish','NorwegianNynorsk','Norwegian','SouthNdebele','Navajo-Navaho','Chichewa-Chewa-Nyanja','Occitan','Ojibwa','Oromo','Oriya','Ossetian-Ossetic','Punjabi-Panjabi','Pali','Polish','Pashto-Pushto','Portuguese','Quechua','Romansh','Rundi','Romanian-Moldavian-Moldovan','Russian','Kinyarwanda','Sanskrit','Sardinian','Sindhi','NorthernSami','Sango','Sinhala-Sinhalese','Slovak','Slovenian','Samoan','Shona','Somali','Albanian','Serbian','Swati','SouthernSotho','Sundanese','Swedish','Swahili','Tamil','Telugu','Tajik','Thai','Tigrinya','Turkmen','Tagalog','Tswana','Tonga','Turkish','Tsonga','Tatar','Twi','Tahitian','Uighur-Uyghur','Ukrainian','Urdu','Uzbek','Venda','Vietnamese','Volapük','Walloon','Wolof','Xhosa','Yiddish','Yoruba','Zhuang-Chuang','Chinese','Zulu']
|
20 |
|
21 |
+
## The file where the state is
|
22 |
STATE_FILE = "session_state.json"
|
23 |
|
24 |
def load_state():
|
|
|
28 |
with open(STATE_FILE, "r") as f:
|
29 |
data = json.load(f)
|
30 |
st.session_state.update(data)
|
31 |
+
st.session_state['form_data'] = data
|
32 |
except Exception as e:
|
33 |
st.error(f"Error loading state: {e}")
|
34 |
|
|
|
37 |
try:
|
38 |
# Convert session_state to a regular dict before dumping
|
39 |
with open(STATE_FILE, "w") as f:
|
40 |
+
json.dump(dict(st.session_state['form_data']), f)
|
41 |
except Exception as e:
|
42 |
st.error(f"Error saving state: {e}")
|
43 |
|
|
|
70 |
st.cache_data.clear()
|
71 |
st.cache_data(lambda: st.session_state.form_data) # Save updated form data
|
72 |
|
|
|
|
|
|
|
|
|
|
|
73 |
# Function to create a text area with caching
|
74 |
def cached_text_area(label, key, placeholder=""):
|
75 |
if key not in st.session_state.form_data:
|
|
|
99 |
save_state()
|
100 |
# Function to create a text area with caching
|
101 |
def cached_radio_input(label, options, key, help=""):
|
102 |
+
if key not in st.session_state.form_data or st.session_state.form_data[key] not in options:
|
103 |
+
st.session_state.form_data[key] = options[0] # Initialize dynamically
|
104 |
+
|
105 |
st.radio(
|
106 |
label=label,
|
107 |
options=options,
|
|
|
118 |
# Initialize session state for selected countries if needed
|
119 |
if key not in st.session_state:
|
120 |
st.session_state[key] = []
|
121 |
+
default = []
|
122 |
+
else:
|
123 |
+
default = st.session_state[key]
|
124 |
+
|
125 |
# Display the multiselect widget
|
126 |
st.multiselect(
|
127 |
label,
|
128 |
options=options,
|
129 |
+
default=default,
|
130 |
key=key,
|
131 |
on_change=lambda: (st.session_state.form_data.update({key: st.session_state[key]}), save_to_cache())[1]
|
132 |
)
|
133 |
|
134 |
+
def cached_range_input(key, value, label ):
|
135 |
+
|
136 |
+
if key not in st.session_state.form_data:
|
137 |
+
st.session_state.form_data[key] = value # Initialize dynamically
|
138 |
+
else:
|
139 |
+
st.session_state[key] = st.session_state.form_data[key]
|
140 |
+
# Display a number input widget
|
141 |
+
st.slider(
|
142 |
+
label=label,
|
143 |
+
min_value=0,
|
144 |
+
max_value=120,
|
145 |
+
value=value,
|
146 |
+
key=key,
|
147 |
+
on_change=lambda: (st.session_state.form_data.update({key: st.session_state[key]}), save_to_cache())[1]
|
148 |
+
)
|
149 |
+
save_state()
|
150 |
+
|
151 |
+
def cached_date_input(label, key):
|
152 |
+
|
153 |
+
if key not in st.session_state:
|
154 |
+
st.session_state[key] = []
|
155 |
+
|
156 |
+
st.date_input(
|
157 |
+
label=label,
|
158 |
+
value=datetime.date(2019, 7, 6),
|
159 |
+
key=key,
|
160 |
+
on_change=lambda: (st.session_state.form_data.update({key: st.session_state[f"{key}_startdate"]}), save_to_cache())[1]
|
161 |
+
)
|
162 |
+
|
163 |
+
|
164 |
def participant(key):
|
165 |
colr, coll = st.columns([1, 1])
|
166 |
with colr:
|
|
|
173 |
st.number_input(
|
174 |
label="The age of the participant:",
|
175 |
key=agekey,
|
176 |
+
on_change=lambda: (st.session_state.form_data.update({key: st.session_state[agekey]}), save_to_cache())[1]
|
177 |
)
|
178 |
cached_text_input("Location", f"{key}_location", "The title of the card")
|
179 |
cached_radio_input("WorkplaceType", ["Presential", "Hybrid", "Remote"], f"{key}_workdplace", "The title of the card")
|
|
|
207 |
group(key)
|
208 |
|
209 |
def team(key):
|
210 |
+
cached_range_input(f"{key}_size", 0, "The size of the group")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
211 |
group(key)
|
212 |
|
213 |
def group(key):
|
214 |
colr, coll = st.columns([1, 1])
|
215 |
with colr:
|
216 |
+
|
217 |
+
cached_range_input(f"{key}_age",(10,20), "The age range of the participants")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
218 |
cached_text_input("Location", f"{key}_location", "Location of the organization")
|
219 |
cached_radio_input("WorkplaceType", ["Presential", "Hybrid", "Remote"], f"{key}_workplace", "The kind of organization")
|
220 |
cached_text_input("Ethnicities", f"{key}_ethnicities", "Ethinicities present in the organization, comma sepparated ")
|
|
|
226 |
cached_multiple_radio(f"{key}_edlevel",EducationalLevelType,"Educational Level")
|
227 |
cached_multiple_radio( f"{key}_sociostati", SESType,"Socioeconomic Status")
|
228 |
cached_multiple_radio( f"{key}_skills", SkillLevelType,"Skill Level")
|
229 |
+
cached_multiple_radio( f"{key}_languages", ISO639, "Select one or several langauges spoken by the participant:")
|
230 |
# Initialize session state for the number input if it doesn't exist
|
231 |
agekey = f"{key}_tenure"
|
232 |
if agekey not in st.session_state:
|
|
|
236 |
st.number_input(
|
237 |
label="The professioanl tenure of the participant in years",
|
238 |
key=agekey,
|
239 |
+
on_change=lambda: (st.session_state.form_data.update({key: st.session_state[agekey]}), save_to_cache())[1]
|
240 |
)
|
241 |
|
242 |
def init_state(key):
|
|
|
312 |
unsafe_allow_html=True
|
313 |
)
|
314 |
st.markdown("""\
|
315 |
+
Welcome to the Software Diversity Card Generator—a form-based application designed to empower you to highlight and promote diversity in software projects. Our innovative tool helps you generate comprehensive diversity cards in both JSON and Markdown formats, offering a transparent overview of the varied teams involved in development and governance, the user groups engaged in testing, and the tailored software adaptations for different social groups. By providing a structured model, an extended JSON syntax, and a toolkit backed by real-world examples, our platform aims to foster inclusive practices that can be embraced by open-source communities, academic journals, and forward-thinking businesses alike.
|
316 |
""")
|
317 |
|
318 |
|
|
|
324 |
cached_text_area("A description of the software project", "master_desc", "The title of the card")
|
325 |
|
326 |
|
327 |
+
with st.container( border=True):
|
328 |
+
st.subheader("Describe the different teams in the software project")
|
329 |
governance, usageContext, participants = st.tabs([
|
330 |
"Governance",
|
331 |
"Usage context",
|
|
|
342 |
key = "governance_govProcesses"
|
343 |
init_state(key)
|
344 |
st.write("Define the set of governament process of your software project")
|
345 |
+
|
346 |
if st.button("Add governament processes"):
|
347 |
add_text_area(key)
|
348 |
# Loop over the array and create a text area with a remove button for each element
|
349 |
+
for idx, processes in enumerate(st.session_state[key]):
|
350 |
# Create two columns: one for the text area, one for the remove button
|
351 |
col1, col2 = st.columns([6, 1])
|
352 |
with col1:
|
353 |
cached_text_area(f"Governament process {idx + 1}", f"governance_govProcesses{idx}", "Specific the governance rules of the software project. For instance, the funders, or the role and the relation between the different bodies that governs the software.")
|
354 |
with col2:
|
355 |
+
# print(st.session_state['governance_govProcesses_remove_0'])
|
356 |
+
if st.button("Remove", key=f"remove_{key}_{idx}"):
|
357 |
remove_text_area(idx,key)
|
358 |
|
359 |
# BODIES
|
|
|
375 |
|
376 |
with col2:
|
377 |
if st.button("Remove", key=f"{key}_remove_{idx}"):
|
378 |
+
remove_text_area(idx,f"{key}_remove_{idx}")
|
379 |
cached_multiple_radio(f"{key}_{idx}_type", ['funders', 'directors', 'administrators', 'other'], f"Body role type" )
|
380 |
|
381 |
+
with st.expander("If needed provide detailed information about the organizations or individuals involved in the governance", expanded=False):
|
382 |
+
# Button to add a new text area
|
383 |
+
org, individual = st.tabs([
|
384 |
+
"Organization",
|
385 |
+
"Individual",
|
386 |
+
])
|
387 |
+
with individual:
|
388 |
+
participant(f"{key}_{idx}_participant")
|
389 |
+
with org:
|
390 |
+
organization(f"{key}_{idx}_organization")
|
391 |
|
|
|
392 |
with usageContext:
|
393 |
colr, coll = st.columns([1, 1])
|
394 |
with colr:
|
|
|
396 |
cached_text_area("Social context",f"{key}_description", "Description of the usage and social context of the app")
|
397 |
with coll:
|
398 |
cached_multiple_radio(f"{key}_countries",ISO3166,"The countries where the app is intended to be deployed and used")
|
399 |
+
cached_multiple_radio( f"{key}_languages", ISO639, "The relevant languages for the app usage's context")
|
400 |
targetCommunities, adaptations = st.tabs([
|
401 |
"Targeted Communities",
|
402 |
"Adpatations",
|
|
|
410 |
with adaptations:
|
411 |
keyAdapt = key+"_adaptation"
|
412 |
cached_text_input("Name",f"{keyAdapt}_name", "Name or ID of the adaptation")
|
413 |
+
cached_text_area("Description",f"{keyAdapt}_description", "Description of the adaptation")
|
|
|
|
|
414 |
|
415 |
with participants:
|
416 |
# Participants
|
|
|
432 |
|
433 |
with col2:
|
434 |
if st.button("Remove", key=f"{key}_remove_{idx}"):
|
435 |
+
remove_text_area(idx,f"{key}_remove_{idx}")
|
436 |
cached_multiple_radio(f"{key}_{idx}_type", ['Development Team', 'NonCoding Contributor', 'Tester Team', 'Public Reporter TEam'], f"Team role type" )
|
437 |
team(f"{key}_{idx}")
|
438 |
|
439 |
|
440 |
+
|
|
|
|
|
441 |
## Showing the generated card and the generated JSON
|
442 |
st.divider()
|
443 |
+
st.subheader("The generated card")
|
444 |
+
markDownTab, jsonTab = st.tabs(["**Compiled card in markdown**", "**Generated JSON**" ])
|
445 |
+
with markDownTab:
|
446 |
+
|
447 |
# Provide a download button
|
448 |
st.download_button(
|
449 |
label="Download Markdown",
|
450 |
+
data=generate_markdown(st.session_state),
|
451 |
file_name="SoftareDiveristyCard.md",
|
452 |
mime="text/markdown"
|
453 |
)
|
454 |
+
st.text("Preview:")
|
455 |
+
st.markdown(generate_markdown(st.session_state), unsafe_allow_html=True)
|
456 |
+
with jsonTab:
|
457 |
|
458 |
# Convert the session state to a JSON string
|
459 |
session_state_json = json.dumps(serialize_session_state(), indent=4)
|
460 |
st.download_button(
|
461 |
label="Download JSON",
|
462 |
data=session_state_json,
|
463 |
+
file_name=f"{st.session_state["master_title"]}_diveristy_card.json",
|
464 |
mime="application/json"
|
465 |
)
|
466 |
# Display the session state as pretty JSON
|
467 |
+
#st.json(serialize_session_state())
|
468 |
+
st.text("Preview:")
|
469 |
+
st.json(st.session_state["form_data"])
|
470 |
|