From 740a07cdfa6e824a9b19188505921753efbbfbd7 Mon Sep 17 00:00:00 2001 From: kazisean Date: Mon, 3 Nov 2025 14:17:31 -0500 Subject: [PATCH 01/40] added sample hello world --- pytermai/main.py | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 pytermai/main.py diff --git a/pytermai/main.py b/pytermai/main.py new file mode 100644 index 0000000..972ad06 --- /dev/null +++ b/pytermai/main.py @@ -0,0 +1,9 @@ +from openai import OpenAI +client = OpenAI(api_key="...") +stream = client.chat.completions.create( + model="gpt-4", + messages=[{"role": "user", "content": "hello world"}], + stream=True, +) +for part in stream: + print(part.choices[0].delta.content or "") \ No newline at end of file From 61aefd3450b009ec81bef2ba9924a804cf0d8f03 Mon Sep 17 00:00:00 2001 From: kazisean Date: Mon, 3 Nov 2025 14:57:45 -0500 Subject: [PATCH 02/40] added bloomberg as ascii --- bloomsays/bloomberg/black.txt | 76 +++++++++++++++++++++++++++++++++ bloomsays/bloomberg/color.txt | 80 +++++++++++++++++++++++++++++++++++ bloomsays/main.py | 0 pytermai/main.py | 9 ---- 4 files changed, 156 insertions(+), 9 deletions(-) create mode 100644 bloomsays/bloomberg/black.txt create mode 100644 bloomsays/bloomberg/color.txt create mode 100644 bloomsays/main.py delete mode 100644 pytermai/main.py diff --git a/bloomsays/bloomberg/black.txt b/bloomsays/bloomberg/black.txt new file mode 100644 index 0000000..ed1b18c --- /dev/null +++ b/bloomsays/bloomberg/black.txt @@ -0,0 +1,76 @@ + . .,. . . + .,,,,,,,,*****///**,/,,. + .,,,,,**,**//*/*,*,,,,**/**/*//****,,,, + ,,,,,,,****,,,,,,,,,,****,*//*,,*/(///*****,*, + ..,,,,,,,,*,.,,,,,.,,,,,,......,,*,,,,,,**,,,,/(****,*,,. .. . + ,,,,,,,..,,,....,,,...,.,,,,,,,,***,,,,,,,,,,**,,..,,***,,,,,,,,,..... + ,,,,**,,..,,...,,,,,,,,*******,,,,,******/*/*/***,,,.,......,,,.,,,,,...... + .,,,,,.,...,,,,,,*******/*/*//*************////*////(((///*,,,...........,,.,... + ,,,,,........,,**//////(/////(//////////(((/((((((((((((((((((//*,...........,,,,.... + ,,,...... ...,,***////(((((((((((((((((((((((((#########((((((((((((//**,.. .....,,,. + ,.......... ..,,*////(((((((((((((##############################((((((((((///*.. ............ + .*....... .....,***///(((((((((((#####################################(#(((((((////,. ........ + ......... ...,,**//((((((((###############################################((((((((//*,. ....... + ......... ..,**//(((((((((###################################%%%#############((((((///,.. .. ... + ... .. ....*///(((((((((#################%####%%%%#######%%#%###%%%###########((((((((/*. .... + ,.... ......,*//((((((((#################%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%########(((((((((/,.. . .... + ..... .... ..,*//((((((((((####################%%%%%%%%%%%%%#%%%%%%%%%%%%##%#######((((((((//,.... ...... + ........ ....,*//(((((((((###############%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%#########((((((((/,........... + ...........,*///((((((((((#########%%%%%%%%%%%#%%%%%%%%%%%%##%#%%%%%%%%%%%%%##########((((((/*...... .... + ...........,,*/(/((((((((((###########%%%%%%%%#%%%%%%%%%%%%%%%%%%%%%###################((((((/*,..... .... + ..........,,*/(((((((((((((#########%%%##%%%%%%%%%%%%%%%%%%%%%%%%%%###%%##%##############((((//,........... + ............,,*//(((((((((((############%##%##%%%%%%%%%%%%%%%%%%%%%%%######################(((((/,...... ..... + ............,,*//(((((((((##################%####%%%%%%%%%%%%%%%%%%%##%%###################(((((/,,........... + ..... ........,*/(((((((((################%##########%%%%%%%%%%%%%%%%%%%%#%%%###############(((((/*,,.... ... . + ... ........,,*//((((((((((###############%%%#####%%%%%%%%%%%%%%%%%%%%%%%%%%%%#############(((((//,.,......... + ... . ......,*///((((((((##############%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%##############((((((/*,.. ....... + .. . ......,*////((((((##################%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%###############((((((*,.. ...... + ... . .......,*//(((((((########################%%%%%%%%%%%%%%%%%%%############((((///((###((((((/,. .. ...., + ... . ...*///(((((((#((((/////////(((((((########%%%%%%%%#########(////****////***//(((((((((/,. ....... + ,... ...,*///(((((((/******,,,,,.,,,,,**///((###############(((//**,,,,,....,,*,,****/(/((/(((*.. ...... + ... ....,/(//////***********,,,,,,,,,..,,**//((((########(((///**,,*,,***////***////*,,*////((*.. . ...*.. + ,. .. ....*/(((((*,,**/*****,*,***,,,,,,*******///((#######(((///////**,..... ....,,*******///((/... ..*(((((. + .*///*,. .....*/((((//////***.. ....,*.//,//*******///((##%%%###(((///***,//,(*./*,*((,....*///(((((/,....,*/((//(/ + .///(((/*,.....,//(((((/////,,..,,///******/%%#/**(/////((####%%###((////**(##(******(#(/**,,**/(((((((,....,,*(//*//. + (/*,,*////,....*/(((((((///******//(((#((###((((((((((//((####%####(((((///(((((###(#((/////(//((((((((/ ...,*/(((/((, + (/***//((/,....*/(((((((((//((((((((/(/(/////(((((#(((((((###%%####(((((#((((///(((((/(((((((####(##(((/..,//(##((/((, + ((/**/((((*....///((((((#(#((((((((((((((((((((((((((((((((########((((##((((#######((##############((//*,*(####(((((, + ((/*/((#(((,..,*/((((((###########################(#((((((#########((((######(((####################(((/*,*/(###(((#(, + .((//((((((*...*//((((((##########################(#(((((####%%%%###(((####################%#######((((/*,,*/((#(((#/ + .((//(((/**,,.,*//((((((########(#################(((((((#####%%%####(((###########%%#%%%%%%%######((((/**////(##(#(, + ,((/((/**,,*,.*////(((((########################(((((((((###%%%%%#%##(((##########################((((/*,,((/((#((( + *((((/***//,..*//(((((((######################((((((((###%%%%%%%%###(((((######################((((((/,..((/((#(* + .((((/**/*..,,//((((((((###################((((((((((##%%#%%%%%%###(((((####################(((((((//,..*/(##((. + .(/((/*//,..,*//((((((((#################(((((((((((((#########(((((#((##################(##((((((/*,../((((((. + ,((////(*...,*/(((((((((((#############(((((/(//***/((###((((((/..*///###################(((((((//,..,/(##((, + *((((((*...,**//((((((((((#############(((//*,,,,***,/(/////**//*,**(###############((((((((((/*,,...(((((* + //(((*.....*****/////(((((((####((((((////**,,.,*,****,***,/**,,///((((((######(((((((/*****,*,...,((((/ + .//(//,...,,*,,**,***////((#((///***///**,*,*,,/*/**/***//*,*,,,/***//////(((((((((///*///***,,....*((. + *//*. ....,.,,*,**///((((*****,**/****,,,,,,,*******,****,,,*,*/,,****/**/*/////(/**//***,,,....,/. + *,, ......,,,**/*///(/*,.,,,,,,,,,*,,,,,**,*,****,,,*****,,.,,..,*,,,,,*,,,,**///****,,........ + ........,.,*,****/*,,..,,.,...,,,,,,*,****,**,*,,,,***,,,*,*,,,,,,,.,,**,.,,,/**,.,*.,...... + .,........,,,*,***.,.,,......,,,*,******,***/**/////****//**,,,,,,.,,,*,,,,,,.*,,,,,......... + .........,.,.,,,**,.,....,.. ..,,,,,,,,,,,,*****,********,****,....,..,.,,*,.,,,,.......... + ...... .......,,,....,,..,,*////////((((((((((((((((((((///////,...,......,*,........... + ,,...........,..,.**,..**/(((((((/((((((((#((###(((((((((((((((/*,,,,.,..,.,,..... .... + ,*,............,,..,.,**/(/(((((((((((((((((((((((((((((//(((((//,,,,.,.,.,.. .. ... + .//*.... ...........,,,*///////////*******,,******//////(/((/*//,,........... .... + /(#(//*..... ...........,,,**///******,,,.,,,,,,.,,,***////////***,,,........ . ... + *%%(/*,/(/*,.. ..............,***,*//***,,,,,.,,.,,,,***///**//***,,.,..... . . .... + .&%**,,./((((/,..................,,.,,,***,,,*******,,**//****,/**,.,........ .. .... + &&&%,.../((((/**,.. .............., ....,,,*,,****,*,*********,.,,.......... ..,. + %&&&&#*../((((((/,..,....................*,,,,,,,,,,*,,,,*/*,,.,....... .. ... .,/* + *%%&&&&&%*.*(((((((*,,..........................,,,*,*,,,,,,,,,,....... . . ...,((## + .&%&%&%&&&%*,/((((((/**,,,....... .. ......,...,.,,.,,,..,,,,..... . .. . . ...,/(((%&&, + /&%&%&&&%&%&&#/(((((((((*,,,..........................,,,,,........,............,/((((#%&&@, + &&&&&%&%&&%&#&%//((((((((//*,,,,........ .... ..........,,,........ . .......*((((((#%%&&&& + ,%&&&&&&&&&&&&&&&&%(/(((((((///*/***,................. ...,... . .. .........,*/(((((((#%%&&&&&##( + .%&&&&&&&&&@&&&&&&&&&%/(((/((//////////***,......... ........... ...........**/(((((((/(#%%&&&&&@&&&&%* + .&&&%%&&&&&@&&&&&&&&&&&@&&&%//(((((/(////////////***,... .. .. ... . .....,**/(((((((((/./#(&%&@&&%&&&@@&&&&&, + &&&&%&&&&&&%&&&&@&@@&&@#&&#@&%&&#%////(//////((//////////***,,,.... ............,*///(((((((((((/..(#%%&&&&&&&&&&&&&&&@&&&@. + /&&&&&&&&&%&&&&&%&%&&%@%&@%@&&&@&&&&&&&&#//((((((((((//(///(///////***,*,**********((((((((((####(((/. .(#%&&&&@&&&&&&&&&&&&&&&&&&&@. + ,%&&&&&&&@&&&&&&&&&&&@&&@&@@&&@@@@@@&&&&&&&&%#/((((((((((((((((///(////////////////(((((((((((((####(((/,..,(%&&&&%&@&&&&&&&&&&&&@&@&@@@&&*, + *&&&&&@&&@&@@@&@@@@&&@@@@@@@@@@@@@@@@&&@%&@&&&%&&#%(/(((((((((((((((((((((/////////((((((((((((((######(((/*..,/#%&&&@&&&&&&&&&&&&&&&&&&&&&&@@@&&&/, + (&&&@&@@%@@&@@@@@&&@@&&&&@@@@@@@@@&@@&@&%@&&@&%@%&@%@@&%(/((((((((((((((((((((((((((/(((((((((((((########((((*.,*/(#%&&%&@@@&&&&&&&&&&&&&&&&&&&&&&&&&&&&%(. + #&&&@@@@&@@&&@@@@@@@&@@&@@%@&&&@@&@@%@@#@@&@@@@@@@@@@&@&@@@&&#((((##########(((((((((((((((((((((#############(((*,/((((#%&@@@&@@@&&&&&&&&@@&&&&&&&&&&&&&&&&&&&&&&## + .%&&&&@@@@@@@@@@%@@&@@@@@&&@@&@@@&@@#@@&@@@@@@@@@@@@@@@&@&@@@&&@&@&%#((#################(#(((((((##################((//#####%&@@&@&@@@&&&&&&&&@&&@&&&&&&&&&@&&&&&&&&&&&&&&%% diff --git a/bloomsays/bloomberg/color.txt b/bloomsays/bloomberg/color.txt new file mode 100644 index 0000000..9e3c048 --- /dev/null +++ b/bloomsays/bloomberg/color.txt @@ -0,0 +1,80 @@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&@&%&@&@&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&%%%%%%%%#####(((##%(%%&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&%%%%%##%%#((#(#%#%%%%##(##(#((####%%%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%%%%%%####%%%%%%%%%%#%##%#((#%%#(/(((#####%#%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&%%%%%%%%#%&%%%%%&%%%%%%&&&&&&%%#%%%%%%#%%%%%(/####%#%%%@&&@@&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%%%%%%&&%&%&&&&%%%&&&%&%%%%%%%%###%%%%%%%%%%##%%&&%%###%%%%%%%%%&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%%%##%%&&%%&&&%%%&%%%%#######%%%%%###%##(#(#(###%%%&%&&&&&&%%%&%%%%%&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&%%%%%&%&&&%%%%%%#######(#(#((##############(((#((((///(((#%%&&&&&&&&&&&&%%&%%&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&%%%%&&&&&&&&&%%##(((((((((((((((((((((((///(//////////////////((#%&&&&&&&&&&&%%%%&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%%&&&&&@@&&&&%###((((//////////(/////////////**********////////////((#%%&&@@@&&&&&%%%&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%&&&&&&&&&&@&&%%#((((/////////////******************************//////////(((#&&@@&&&&&&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&#&&&&&&&@&&&&&%%##(((///////////*************************************/////////((((%&@@@&&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&@&@@&&&%%##((/////////**********************************************////////((#%&@@@&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&&&&@&&%##((//////////**********************************,,*************///////(((%&&@@@@@&@&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&@&&@&&&&#(((//////////*********************,,,,*******,,*,***,,,***********////////(#&@@@@@@&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%&&&&@&&&&&&%#((////////******************,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,********/////////(%&&@@@@@@&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&@&&&&@&&%#(((//////////*******************,,,,,,,,,,,,,,,,,,,,,,,,,,**,*******////////((%&&&&@&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&&&@&&&&%#((//////////**************,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*********///////((%&&&&&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&@&&&&%#(((//////////*********,,,,,,,,,,,*,,,,,,,,,,,,*,,,,,,,,,,,,,,,,*********///////(#&&&&&&@@&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&&&&&&%%#(((///////////**********,,,,,,,,*,,,,,,,,,,,,,,,,,,,,,*******************//////(#%&&&&&@@&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&&&&&%%#((////////////*********,,,**,,,,,,,,,,,,,,,,,,,,,,,,,,***,,**,**************////((%&&&&&&@&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&&&&&&&%%#((////////////*****************,,,,,,,,,,,,,,,,,,,,,,,,*********************/////(%%&&&&&@&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&&&&&&&%%#((//////////*****************,****,,,,,,,,,,,,,,,,,,,,*,,*******************/////(%%&&&&&&@&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&@&&&&&&&&%#(///////////*//**********************,,,,,,,,,,,,,,,,,,,,*,,,***************/////(#%%&&&&@&&&@&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&@@&&&&&&&&%%#((///////////**************,,,*****,,,,,,,,,,,,,,,,,,,,,,,,,,,,*************/////((%%%&&&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&@&@@&&&&&&%#(((/////////*/************,*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*************///////(#%&&@&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&@&@@@&&&&&&%#((((///////****************,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,***************//////#%&&@@&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&@@@@&&&&&&&%#((/(/////************************,,,,,,,,,,,,,,,,,,,,,**,*******////(((/****//////(%&@&@@&&&&%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&%&@@@@@@@@&&#(((((/////*////(((((((((//////*********,,,,,,,,*********/((((####((((###((/////////(%&@&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%&&&@@@@@&&&%#((((((////(######%%%%%%%%%%%##(((//***************///((##%%%%%&%%&%%##%####(/(//(//(%&&@&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&@@@&&&&%((((((((###########%%%%%%%%%&%%%##((////********///(((##%%#%####((((###(((/#%%#((((//#&&@&@&&&#&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%&@&&@@&&&&#(/////#%%##(#######%###%%%%%%#######(((//*******///(((((((##%&&&&&&&&&&%%#######(((//(&&&@@&&(/////&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&((((#%&@@&&&&&#(/(//((((((###&&@&&&&#(&((%((#######(((//***,,***///(((####((%/#&/#%(//%&&&&#(((/////(%&&&&%#(//((/(@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&(/(///(#%&&&&&%((/////(((((%%&&%%((/######(,,*/##/(((((//****,,***///(((##/**/#####(/*/((#%%##(///////%&&&&%%#/((#((&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@/(#%%#((((%&&&&#((//////(((######((///******//////////((//***,,,,**///*///(/////*****//(((((/(/////////(@&&%%#(///(//%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@//###((//(%&&@&#((////////((////////(/(/((((//////*///////***,,*,**////**////(((/////(////**/****/**///(&&%(//**/////%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@//(#((////#&&&&(((//////*/*///////////////////**//////////***,,,***////****/********/***************//((#%#*****////*#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@//(#(//*///%&&%#(//////*****************************//////***,,*,,*////******///********************///(#%#(******/**%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&//((//////#&&&#((//////**************************/*/////****,,,,,***//********************,*******////(#%%#(//**/**(@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&//((///(##%%&%#((((/////*******/*****************///////*****,,,****///***********,,*,,,,,,,******////(##((((/**/*/%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%//(//(##%%#%&#(((((/////***********************////////****,,,,,*,**//***************************////(#%%//(//**//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#////(###((%&&#(((//////**********************////////***,,,,,,,,***/////**********************//////(%&&//(//**#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&////(##(#&&%%((////////*******************//////////**,,,,,,,,,***//*//********************///////((%&&(//**//&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&////((((%&%%#((////////*****************////////////***,**,****////*//******************/****////(#%&&(////*/&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%//((((/#&&&%#(///////////*************/////(/((###(//****/***/(&&#((/********************//////((%&&%(/***/#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#//////#&&&%##(((/////////*************///((#%%%%###%(/(((((#(((#%#(/****************/////////(#%%&&&/***/#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@(////#&&&&&#####(((((///////****//////((((##%%&%#%####%###%(####(((/**//*******///////(#####%#%&&&%////(@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&((/((%&&&%%#%%%#%###((((//*//(((###(((##%#%#%%(#(##((##((#%#%%%(###((((((/////////(((#(((###%%&&&%(//&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@(((#&@&&&&%&%%%%##(((////#####%##(####%%%%%%%#######%##(#%%%#%#(%%####(##(#(((((/(##((###%%%&&&&%(&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#%%@&&&&&&%%%##(#(((((#%&%%%%%%%%%#%%%%%##%#%####%%%#####%%&%%&&%#%%%%%#%%%%##(((####%%&&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&&&%&%#%####(#%%&&%%&%&&&%%%%%%%%####%#(##%%%%###%%%#%#%%%%%%%&%%##%&%%%(##%&%#&%&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&%&&&&&&&&&%%#%###&%&%%&&&&&&%%%#%##########(##(((((###(((##%%%%%%&%%%%%%%%%%&#%%%%%&&&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&&&&%&%&%%%%#%&%&&&&%&&@@&&%%%%%%%%%%%%##############%####%&&&&%&&%&%%#%%%%%%&&&&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&@&&&&&&&%%%&&&&%%&&%%#((((((((//////////////////////(((((%&&&%&&&&&&%#%&&&&&&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%&&@&&&&&&&&%&&%&##%&&##(//////////////********//*///*////////(#%%%%%%&&%%%%&&&&&@&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%#%&&&&&&&&&&&&%%&&%&%##(/(//////////////////////*//////((/////((%%%%&%%%%%&&@@&&@&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%((#&&&&@@&&&&&&&&&&&%%%#(((((((((((########%######((((((((//(#((%%&&&&&&&&&&&@@&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@(**/((#&&&&&@&&&&&&&&&&&%%%##(((######%%%%%%%%%%&%%%###((((((((###%%%&&&&&&&&@@@&@&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#,,/(#%(((#%&@@@&&&&&&&&&&&&&&%##%%#((###%%%%%&%%&%%%%###(((##((###%%%%&&&&&&&@&@@@&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%.,#%%%&(///((%&&&&&&&&&&&&&&&&&&%%&%%%###%%%#######%%##((####%(##%&%&&&&&&&&@&&@@&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@...,%&&&(////(##%&&@&&&&&&&&&&&&&&%@&&&&%%%#%%####%#%#########%&%%&&&&&&&&&&@@@@&&%&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@,....*#&&(/////((%&&%&&&&&&&&&&&&&&&&&&&&#%%%%%%%%%%#%%%%#(#%%&%&&&&&&&@&&@&&&@@&%((@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#,,.....,#&#///////#%%&&&&&&&&&&@&&&&&&&&&&&&&%&%%%#%#%%%%%%%%%%&&&&&&&@@&@&@@&&&%//**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%.,.,.,...,#%(//////((#%%%&&&&&&&@&&@&&&&&&%&&&%&%%&%%%&&%%%%&&&&&@&@&&@@&@&@&&&%(///,..%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@(...,...,.,..*(////////(#%%%&&&&&&&&&&&&&&&&&&&&&&&&&&%%%%%&&&&&&&&%&&&&&&&&&&&&%/////*,.. %@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.....,.,..,.*.,((////////((#%%%%&&&&&&&&@&&&&@&&&&&&&&&&%%%&&&&&&&&@@&@&&&&&&&&#//////*,,....@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%,................,/(///////(((#(###%&&@&&&&&&&&&&&&&&@&&&%&&&@&@@&&@@&&&&&&&&&%#(///////,,,. ...,*/@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&,......... .........,(///(//((((((((((###%&&&&&&&&&@&&&&&&&&&&&@@@@&&&&&&&&&&&##(///////(**,,..... ....,#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%...,,.... ...... .. . ...,((/////(/((((((((((((###%&&&@@@&&@&&@@@&&&@@&@&&&&&%##(/////////(&(*/.,. . .. ....%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&...........,.... . .. *..* ., .*,((((/((((((//((((((((((###%%%&&&&@&&&&&&&&&&&&%#(((////**/////(&&/*,,.. ............ ... &@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@(..... ...,.....,., ., , , .. ........*((//////////((/(((/(((((((###%#%##########//////////*****//(&@&/,,.... .................. &@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%,..... . ..... ... . .. . .. . ...,*(////////////////((((((((((((((((((((/////////////****///(%&&%/,....,. ............ . . ..#%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@#..... .. . . . .. .. ,..*,/(/////////////////////(((((((((//////////////******///(%&&%(*,... .......... .......... ..(%@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@/... . . . .. . . .. .. .. ,. . .,/(//////////////////////////(/////////////********////#&%#(/*,. , ............... ...... .....,/&@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@*... . .. . , .. . , * . . ..*///************////////////////////*************///#%(///**,. . ..... .. ..... ... ......... ..**@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@&,.... , .. . . , . . . .,*//*******************///////******************//((*****, . ...... .. ........ ... . .... ...,,@@@@@@@@@@@ diff --git a/bloomsays/main.py b/bloomsays/main.py new file mode 100644 index 0000000..e69de29 diff --git a/pytermai/main.py b/pytermai/main.py deleted file mode 100644 index 972ad06..0000000 --- a/pytermai/main.py +++ /dev/null @@ -1,9 +0,0 @@ -from openai import OpenAI -client = OpenAI(api_key="...") -stream = client.chat.completions.create( - model="gpt-4", - messages=[{"role": "user", "content": "hello world"}], - stream=True, -) -for part in stream: - print(part.choices[0].delta.content or "") \ No newline at end of file From 38e54b90cc1b18c66634e073c579938af2f425c0 Mon Sep 17 00:00:00 2001 From: kazisean Date: Mon, 3 Nov 2025 15:02:45 -0500 Subject: [PATCH 03/40] improved quality ascii --- bloomsays/bloomberg/black.txt | 108 ++++++++++----------------------- bloomsays/bloomberg/color.txt | 110 ++++++++++------------------------ 2 files changed, 62 insertions(+), 156 deletions(-) diff --git a/bloomsays/bloomberg/black.txt b/bloomsays/bloomberg/black.txt index ed1b18c..5267c42 100644 --- a/bloomsays/bloomberg/black.txt +++ b/bloomsays/bloomberg/black.txt @@ -1,76 +1,32 @@ - . .,. . . - .,,,,,,,,*****///**,/,,. - .,,,,,**,**//*/*,*,,,,**/**/*//****,,,, - ,,,,,,,****,,,,,,,,,,****,*//*,,*/(///*****,*, - ..,,,,,,,,*,.,,,,,.,,,,,,......,,*,,,,,,**,,,,/(****,*,,. .. . - ,,,,,,,..,,,....,,,...,.,,,,,,,,***,,,,,,,,,,**,,..,,***,,,,,,,,,..... - ,,,,**,,..,,...,,,,,,,,*******,,,,,******/*/*/***,,,.,......,,,.,,,,,...... - .,,,,,.,...,,,,,,*******/*/*//*************////*////(((///*,,,...........,,.,... - ,,,,,........,,**//////(/////(//////////(((/((((((((((((((((((//*,...........,,,,.... - ,,,...... ...,,***////(((((((((((((((((((((((((#########((((((((((((//**,.. .....,,,. - ,.......... ..,,*////(((((((((((((##############################((((((((((///*.. ............ - .*....... .....,***///(((((((((((#####################################(#(((((((////,. ........ - ......... ...,,**//((((((((###############################################((((((((//*,. ....... - ......... ..,**//(((((((((###################################%%%#############((((((///,.. .. ... - ... .. ....*///(((((((((#################%####%%%%#######%%#%###%%%###########((((((((/*. .... - ,.... ......,*//((((((((#################%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%########(((((((((/,.. . .... - ..... .... ..,*//((((((((((####################%%%%%%%%%%%%%#%%%%%%%%%%%%##%#######((((((((//,.... ...... - ........ ....,*//(((((((((###############%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%#########((((((((/,........... - ...........,*///((((((((((#########%%%%%%%%%%%#%%%%%%%%%%%%##%#%%%%%%%%%%%%%##########((((((/*...... .... - ...........,,*/(/((((((((((###########%%%%%%%%#%%%%%%%%%%%%%%%%%%%%%###################((((((/*,..... .... - ..........,,*/(((((((((((((#########%%%##%%%%%%%%%%%%%%%%%%%%%%%%%%###%%##%##############((((//,........... - ............,,*//(((((((((((############%##%##%%%%%%%%%%%%%%%%%%%%%%%######################(((((/,...... ..... - ............,,*//(((((((((##################%####%%%%%%%%%%%%%%%%%%%##%%###################(((((/,,........... - ..... ........,*/(((((((((################%##########%%%%%%%%%%%%%%%%%%%%#%%%###############(((((/*,,.... ... . - ... ........,,*//((((((((((###############%%%#####%%%%%%%%%%%%%%%%%%%%%%%%%%%%#############(((((//,.,......... - ... . ......,*///((((((((##############%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%##############((((((/*,.. ....... - .. . ......,*////((((((##################%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%###############((((((*,.. ...... - ... . .......,*//(((((((########################%%%%%%%%%%%%%%%%%%%############((((///((###((((((/,. .. ...., - ... . ...*///(((((((#((((/////////(((((((########%%%%%%%%#########(////****////***//(((((((((/,. ....... - ,... ...,*///(((((((/******,,,,,.,,,,,**///((###############(((//**,,,,,....,,*,,****/(/((/(((*.. ...... - ... ....,/(//////***********,,,,,,,,,..,,**//((((########(((///**,,*,,***////***////*,,*////((*.. . ...*.. - ,. .. ....*/(((((*,,**/*****,*,***,,,,,,*******///((#######(((///////**,..... ....,,*******///((/... ..*(((((. - .*///*,. .....*/((((//////***.. ....,*.//,//*******///((##%%%###(((///***,//,(*./*,*((,....*///(((((/,....,*/((//(/ - .///(((/*,.....,//(((((/////,,..,,///******/%%#/**(/////((####%%###((////**(##(******(#(/**,,**/(((((((,....,,*(//*//. - (/*,,*////,....*/(((((((///******//(((#((###((((((((((//((####%####(((((///(((((###(#((/////(//((((((((/ ...,*/(((/((, - (/***//((/,....*/(((((((((//((((((((/(/(/////(((((#(((((((###%%####(((((#((((///(((((/(((((((####(##(((/..,//(##((/((, - ((/**/((((*....///((((((#(#((((((((((((((((((((((((((((((((########((((##((((#######((##############((//*,*(####(((((, - ((/*/((#(((,..,*/((((((###########################(#((((((#########((((######(((####################(((/*,*/(###(((#(, - .((//((((((*...*//((((((##########################(#(((((####%%%%###(((####################%#######((((/*,,*/((#(((#/ - .((//(((/**,,.,*//((((((########(#################(((((((#####%%%####(((###########%%#%%%%%%%######((((/**////(##(#(, - ,((/((/**,,*,.*////(((((########################(((((((((###%%%%%#%##(((##########################((((/*,,((/((#((( - *((((/***//,..*//(((((((######################((((((((###%%%%%%%%###(((((######################((((((/,..((/((#(* - .((((/**/*..,,//((((((((###################((((((((((##%%#%%%%%%###(((((####################(((((((//,..*/(##((. - .(/((/*//,..,*//((((((((#################(((((((((((((#########(((((#((##################(##((((((/*,../((((((. - ,((////(*...,*/(((((((((((#############(((((/(//***/((###((((((/..*///###################(((((((//,..,/(##((, - *((((((*...,**//((((((((((#############(((//*,,,,***,/(/////**//*,**(###############((((((((((/*,,...(((((* - //(((*.....*****/////(((((((####((((((////**,,.,*,****,***,/**,,///((((((######(((((((/*****,*,...,((((/ - .//(//,...,,*,,**,***////((#((///***///**,*,*,,/*/**/***//*,*,,,/***//////(((((((((///*///***,,....*((. - *//*. ....,.,,*,**///((((*****,**/****,,,,,,,*******,****,,,*,*/,,****/**/*/////(/**//***,,,....,/. - *,, ......,,,**/*///(/*,.,,,,,,,,,*,,,,,**,*,****,,,*****,,.,,..,*,,,,,*,,,,**///****,,........ - ........,.,*,****/*,,..,,.,...,,,,,,*,****,**,*,,,,***,,,*,*,,,,,,,.,,**,.,,,/**,.,*.,...... - .,........,,,*,***.,.,,......,,,*,******,***/**/////****//**,,,,,,.,,,*,,,,,,.*,,,,,......... - .........,.,.,,,**,.,....,.. ..,,,,,,,,,,,,*****,********,****,....,..,.,,*,.,,,,.......... - ...... .......,,,....,,..,,*////////((((((((((((((((((((///////,...,......,*,........... - ,,...........,..,.**,..**/(((((((/((((((((#((###(((((((((((((((/*,,,,.,..,.,,..... .... - ,*,............,,..,.,**/(/(((((((((((((((((((((((((((((//(((((//,,,,.,.,.,.. .. ... - .//*.... ...........,,,*///////////*******,,******//////(/((/*//,,........... .... - /(#(//*..... ...........,,,**///******,,,.,,,,,,.,,,***////////***,,,........ . ... - *%%(/*,/(/*,.. ..............,***,*//***,,,,,.,,.,,,,***///**//***,,.,..... . . .... - .&%**,,./((((/,..................,,.,,,***,,,*******,,**//****,/**,.,........ .. .... - &&&%,.../((((/**,.. .............., ....,,,*,,****,*,*********,.,,.......... ..,. - %&&&&#*../((((((/,..,....................*,,,,,,,,,,*,,,,*/*,,.,....... .. ... .,/* - *%%&&&&&%*.*(((((((*,,..........................,,,*,*,,,,,,,,,,....... . . ...,((## - .&%&%&%&&&%*,/((((((/**,,,....... .. ......,...,.,,.,,,..,,,,..... . .. . . ...,/(((%&&, - /&%&%&&&%&%&&#/(((((((((*,,,..........................,,,,,........,............,/((((#%&&@, - &&&&&%&%&&%&#&%//((((((((//*,,,,........ .... ..........,,,........ . .......*((((((#%%&&&& - ,%&&&&&&&&&&&&&&&&%(/(((((((///*/***,................. ...,... . .. .........,*/(((((((#%%&&&&&##( - .%&&&&&&&&&@&&&&&&&&&%/(((/((//////////***,......... ........... ...........**/(((((((/(#%%&&&&&@&&&&%* - .&&&%%&&&&&@&&&&&&&&&&&@&&&%//(((((/(////////////***,... .. .. ... . .....,**/(((((((((/./#(&%&@&&%&&&@@&&&&&, - &&&&%&&&&&&%&&&&@&@@&&@#&&#@&%&&#%////(//////((//////////***,,,.... ............,*///(((((((((((/..(#%%&&&&&&&&&&&&&&&@&&&@. - /&&&&&&&&&%&&&&&%&%&&%@%&@%@&&&@&&&&&&&&#//((((((((((//(///(///////***,*,**********((((((((((####(((/. .(#%&&&&@&&&&&&&&&&&&&&&&&&&@. - ,%&&&&&&&@&&&&&&&&&&&@&&@&@@&&@@@@@@&&&&&&&&%#/((((((((((((((((///(////////////////(((((((((((((####(((/,..,(%&&&&%&@&&&&&&&&&&&&@&@&@@@&&*, - *&&&&&@&&@&@@@&@@@@&&@@@@@@@@@@@@@@@@&&@%&@&&&%&&#%(/(((((((((((((((((((((/////////((((((((((((((######(((/*..,/#%&&&@&&&&&&&&&&&&&&&&&&&&&&@@@&&&/, - (&&&@&@@%@@&@@@@@&&@@&&&&@@@@@@@@@&@@&@&%@&&@&%@%&@%@@&%(/((((((((((((((((((((((((((/(((((((((((((########((((*.,*/(#%&&%&@@@&&&&&&&&&&&&&&&&&&&&&&&&&&&&%(. - #&&&@@@@&@@&&@@@@@@@&@@&@@%@&&&@@&@@%@@#@@&@@@@@@@@@@&@&@@@&&#((((##########(((((((((((((((((((((#############(((*,/((((#%&@@@&@@@&&&&&&&&@@&&&&&&&&&&&&&&&&&&&&&&## - .%&&&&@@@@@@@@@@%@@&@@@@@&&@@&@@@&@@#@@&@@@@@@@@@@@@@@@&@&@@@&&@&@&%#((#################(#(((((((##################((//#####%&@@&@&@@@&&&&&&&&@&&@&&&&&&&&&@&&&&&&&&&&&&&&%% +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&%%%##(##&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%%#%%%%%%%%%#######%@&@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@%%#%%&%%%###%%####(#%&&&%%%%&&@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@%&&&&&#((///((((////**////(#&&&&&&%@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@&&&&&&%#(////***************////(#@@&&&@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@&&&@&#(///***************,*****///(&@&&&@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@&&&&&#(///********,,,,,,,,,,,****///(&&&&&@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@&&&&%(////*****,*,*,,,,,,,,,,,,****//#&&@&@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@&&&&&%(////*******,,,,,,,,,,********//(&&&&&@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@&@&&&%////**********,,,,,,,,,,******//(%&&&&@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@&@@&&%(///*******,,,,,,,,,,,,,,******//#&@&&@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@&&@@&%(///(#(####(/****,**//(%%%%##(///(&&&@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@&&&&(//%###%##%%###(/***/(((%&&&&%###((&@&//@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@(((#&&(//(#%#(*##,/(/(/***///(**#*/(((///&%#((/@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@/(//&&(//***//*////////****/*****/******/#(**/*@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@/(/(%&(//***/*******//**,,*/*******,,**//##(*/@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@/(#(&(///*********///*,,,,*//*********//%%(*#@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@///&%(//********/////****///*******///(&%//&@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@(/&&##((///**//((#&##%####(//***//(###&#/&@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@(&&&&%#(/(%%###%%%##%##%%%((##(((##%&&&@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@&&&&%##%&%&&%###%##((###%%%%#%%%%%&&&@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@&&&&&&%&%%#//(////////////%&&&#&&&&@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@(%&@&&&&%#((((###%##((((((%&&&&@&%@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@,#%/#&&&&&&&&%##%%#%%%##(#%&&%&&@&@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@..(&//(&&&&&&&&&%%%%#%%(%%&&@&&@%(@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@....,///(%&&&&@&&&&%%%%%&&&&@@@&(/..@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@.......////((#%&&&&&&@&&&@&@&&@%(//*,../@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@............//(((((((##&&@@@@@&&#/////#,,......(@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@%.......... ...*///////(((((((//////*//&(.......... *@@@@@@@@@@@@ +@@@@@@@@@%. ..,..//**///////////****//%/*. ............ .&@@@@@@ \ No newline at end of file diff --git a/bloomsays/bloomberg/color.txt b/bloomsays/bloomberg/color.txt index 9e3c048..a3e6ab3 100644 --- a/bloomsays/bloomberg/color.txt +++ b/bloomsays/bloomberg/color.txt @@ -1,80 +1,30 @@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&@&%&@&@&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&%%%%%%%%#####(((##%(%%&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&%%%%%##%%#((#(#%#%%%%##(##(#((####%%%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%%%%%%####%%%%%%%%%%#%##%#((#%%#(/(((#####%#%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&%%%%%%%%#%&%%%%%&%%%%%%&&&&&&%%#%%%%%%#%%%%%(/####%#%%%@&&@@&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%%%%%%&&%&%&&&&%%%&&&%&%%%%%%%%###%%%%%%%%%%##%%&&%%###%%%%%%%%%&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%%%##%%&&%%&&&%%%&%%%%#######%%%%%###%##(#(#(###%%%&%&&&&&&%%%&%%%%%&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&%%%%%&%&&&%%%%%%#######(#(#((##############(((#((((///(((#%%&&&&&&&&&&&&%%&%%&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&%%%%&&&&&&&&&%%##(((((((((((((((((((((((///(//////////////////((#%&&&&&&&&&&&%%%%&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%%&&&&&@@&&&&%###((((//////////(/////////////**********////////////((#%%&&@@@&&&&&%%%&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%&&&&&&&&&&@&&%%#((((/////////////******************************//////////(((#&&@@&&&&&&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&#&&&&&&&@&&&&&%%##(((///////////*************************************/////////((((%&@@@&&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&@&@@&&&%%##((/////////**********************************************////////((#%&@@@&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&&&&@&&%##((//////////**********************************,,*************///////(((%&&@@@@@&@&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&@&&@&&&&#(((//////////*********************,,,,*******,,*,***,,,***********////////(#&@@@@@@&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%&&&&@&&&&&&%#((////////******************,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,********/////////(%&&@@@@@@&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&@&&&&@&&%#(((//////////*******************,,,,,,,,,,,,,,,,,,,,,,,,,,**,*******////////((%&&&&@&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&&&@&&&&%#((//////////**************,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*********///////((%&&&&&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&@&&&&%#(((//////////*********,,,,,,,,,,,*,,,,,,,,,,,,*,,,,,,,,,,,,,,,,*********///////(#&&&&&&@@&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&&&&&&%%#(((///////////**********,,,,,,,,*,,,,,,,,,,,,,,,,,,,,,*******************//////(#%&&&&&@@&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&&&&&%%#((////////////*********,,,**,,,,,,,,,,,,,,,,,,,,,,,,,,***,,**,**************////((%&&&&&&@&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&&&&&&&%%#((////////////*****************,,,,,,,,,,,,,,,,,,,,,,,,*********************/////(%%&&&&&@&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&&&&&&&%%#((//////////*****************,****,,,,,,,,,,,,,,,,,,,,*,,*******************/////(%%&&&&&&@&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&@&&&&&&&&%#(///////////*//**********************,,,,,,,,,,,,,,,,,,,,*,,,***************/////(#%%&&&&@&&&@&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&@@&&&&&&&&%%#((///////////**************,,,*****,,,,,,,,,,,,,,,,,,,,,,,,,,,,*************/////((%%%&&&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&@&@@&&&&&&%#(((/////////*/************,*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*************///////(#%&&@&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&@&@@@&&&&&&%#((((///////****************,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,***************//////#%&&@@&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&@@@@&&&&&&&%#((/(/////************************,,,,,,,,,,,,,,,,,,,,,**,*******////(((/****//////(%&@&@@&&&&%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&%&@@@@@@@@&&#(((((/////*////(((((((((//////*********,,,,,,,,*********/((((####((((###((/////////(%&@&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%&&&@@@@@&&&%#((((((////(######%%%%%%%%%%%##(((//***************///((##%%%%%&%%&%%##%####(/(//(//(%&&@&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&@@@&&&&%((((((((###########%%%%%%%%%&%%%##((////********///(((##%%#%####((((###(((/#%%#((((//#&&@&@&&&#&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%&@&&@@&&&&#(/////#%%##(#######%###%%%%%%#######(((//*******///(((((((##%&&&&&&&&&&%%#######(((//(&&&@@&&(/////&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&((((#%&@@&&&&&#(/(//((((((###&&@&&&&#(&((%((#######(((//***,,***///(((####((%/#&/#%(//%&&&&#(((/////(%&&&&%#(//((/(@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&(/(///(#%&&&&&%((/////(((((%%&&%%((/######(,,*/##/(((((//****,,***///(((##/**/#####(/*/((#%%##(///////%&&&&%%#/((#((&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@/(#%%#((((%&&&&#((//////(((######((///******//////////((//***,,,,**///*///(/////*****//(((((/(/////////(@&&%%#(///(//%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@//###((//(%&&@&#((////////((////////(/(/((((//////*///////***,,*,**////**////(((/////(////**/****/**///(&&%(//**/////%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@//(#((////#&&&&(((//////*/*///////////////////**//////////***,,,***////****/********/***************//((#%#*****////*#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@//(#(//*///%&&%#(//////*****************************//////***,,*,,*////******///********************///(#%#(******/**%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&//((//////#&&&#((//////**************************/*/////****,,,,,***//********************,*******////(#%%#(//**/**(@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&//((///(##%%&%#((((/////*******/*****************///////*****,,,****///***********,,*,,,,,,,******////(##((((/**/*/%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%//(//(##%%#%&#(((((/////***********************////////****,,,,,*,**//***************************////(#%%//(//**//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#////(###((%&&#(((//////**********************////////***,,,,,,,,***/////**********************//////(%&&//(//**#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&////(##(#&&%%((////////*******************//////////**,,,,,,,,,***//*//********************///////((%&&(//**//&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&////((((%&%%#((////////*****************////////////***,**,****////*//******************/****////(#%&&(////*/&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%//((((/#&&&%#(///////////*************/////(/((###(//****/***/(&&#((/********************//////((%&&%(/***/#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#//////#&&&%##(((/////////*************///((#%%%%###%(/(((((#(((#%#(/****************/////////(#%%&&&/***/#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@(////#&&&&&#####(((((///////****//////((((##%%&%#%####%###%(####(((/**//*******///////(#####%#%&&&%////(@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&((/((%&&&%%#%%%#%###((((//*//(((###(((##%#%#%%(#(##((##((#%#%%%(###((((((/////////(((#(((###%%&&&%(//&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@(((#&@&&&&%&%%%%##(((////#####%##(####%%%%%%%#######%##(#%%%#%#(%%####(##(#(((((/(##((###%%%&&&&%(&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#%%@&&&&&&%%%##(#(((((#%&%%%%%%%%%#%%%%%##%#%####%%%#####%%&%%&&%#%%%%%#%%%%##(((####%%&&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&&&%&%#%####(#%%&&%%&%&&&%%%%%%%%####%#(##%%%%###%%%#%#%%%%%%%&%%##%&%%%(##%&%#&%&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&%&&&&&&&&&%%#%###&%&%%&&&&&&%%%#%##########(##(((((###(((##%%%%%%&%%%%%%%%%%&#%%%%%&&&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&&&&%&%&%%%%#%&%&&&&%&&@@&&%%%%%%%%%%%%##############%####%&&&&%&&%&%%#%%%%%%&&&&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&@&&&&&&&%%%&&&&%%&&%%#((((((((//////////////////////(((((%&&&%&&&&&&%#%&&&&&&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%&&@&&&&&&&&%&&%&##%&&##(//////////////********//*///*////////(#%%%%%%&&%%%%&&&&&@&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%#%&&&&&&&&&&&&%%&&%&%##(/(//////////////////////*//////((/////((%%%%&%%%%%&&@@&&@&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%((#&&&&@@&&&&&&&&&&&%%%#(((((((((((########%######((((((((//(#((%%&&&&&&&&&&&@@&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@(**/((#&&&&&@&&&&&&&&&&&%%%##(((######%%%%%%%%%%&%%%###((((((((###%%%&&&&&&&&@@@&@&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#,,/(#%(((#%&@@@&&&&&&&&&&&&&&%##%%#((###%%%%%&%%&%%%%###(((##((###%%%%&&&&&&&@&@@@&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%.,#%%%&(///((%&&&&&&&&&&&&&&&&&&%%&%%%###%%%#######%%##((####%(##%&%&&&&&&&&@&&@@&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@...,%&&&(////(##%&&@&&&&&&&&&&&&&&%@&&&&%%%#%%####%#%#########%&%%&&&&&&&&&&@@@@&&%&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@,....*#&&(/////((%&&%&&&&&&&&&&&&&&&&&&&&#%%%%%%%%%%#%%%%#(#%%&%&&&&&&&@&&@&&&@@&%((@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#,,.....,#&#///////#%%&&&&&&&&&&@&&&&&&&&&&&&&%&%%%#%#%%%%%%%%%%&&&&&&&@@&@&@@&&&%//**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%.,.,.,...,#%(//////((#%%%&&&&&&&@&&@&&&&&&%&&&%&%%&%%%&&%%%%&&&&&@&@&&@@&@&@&&&%(///,..%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@(...,...,.,..*(////////(#%%%&&&&&&&&&&&&&&&&&&&&&&&&&&%%%%%&&&&&&&&%&&&&&&&&&&&&%/////*,.. %@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.....,.,..,.*.,((////////((#%%%%&&&&&&&&@&&&&@&&&&&&&&&&%%%&&&&&&&&@@&@&&&&&&&&#//////*,,....@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%,................,/(///////(((#(###%&&@&&&&&&&&&&&&&&@&&&%&&&@&@@&&@@&&&&&&&&&%#(///////,,,. ...,*/@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&,......... .........,(///(//((((((((((###%&&&&&&&&&@&&&&&&&&&&&@@@@&&&&&&&&&&&##(///////(**,,..... ....,#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%...,,.... ...... .. . ...,((/////(/((((((((((((###%&&&@@@&&@&&@@@&&&@@&@&&&&&%##(/////////(&(*/.,. . .. ....%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&...........,.... . .. *..* ., .*,((((/((((((//((((((((((###%%%&&&&@&&&&&&&&&&&&%#(((////**/////(&&/*,,.. ............ ... &@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@(..... ...,.....,., ., , , .. ........*((//////////((/(((/(((((((###%#%##########//////////*****//(&@&/,,.... .................. &@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%,..... . ..... ... . .. . .. . ...,*(////////////////((((((((((((((((((((/////////////****///(%&&%/,....,. ............ . . ..#%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@#..... .. . . . .. .. ,..*,/(/////////////////////(((((((((//////////////******///(%&&%(*,... .......... .......... ..(%@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@/... . . . .. . . .. .. .. ,. . .,/(//////////////////////////(/////////////********////#&%#(/*,. , ............... ...... .....,/&@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@*... . .. . , .. . , * . . ..*///************////////////////////*************///#%(///**,. . ..... .. ..... ... ......... ..**@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@&,.... , .. . . , . . . .,*//*******************///////******************//((*****, . ...... .. ........ ... . .... ...,,@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@&%%%##(##&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%%#%%%%%%%%%#######%@&@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@%%#%%&%%%%##%%####(#%&&&%%%%&&@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@%&&&&&#((///((((/////*////(#&&&&&&&@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@&&&&&&%#(/////**************////(#@@&&&@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@&&&@&#(///***************,*****///(&@&&&@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@&&&&&#(////*******,,,,,,,,,,,****///(&&&&&@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@&&&&%((////****,*,*,,,,,,,,,,,,***///#&&@&@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@&&&&&%(/////******,,,,,,,,,,********//(&&&&&@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@&@&&&%//////********,,,,,,,,,,******//(%&&&&@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@&@@&&%((///******,,,,,,,,,,,,,,******//#&@&&@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@&&@@@%(///(#(####(/****,**//(%%%%##(///(&&&@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@&&&&(//%######%%###(/***/(((#&&&&%###((&@&//@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@(((#&&(//(#%#(*##,/(/(/****//(**(**(((///&%#/(/@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@/(//&&(//**///*///*////*,**/*****/******/#(**/*@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@/(/(%&(//***/*******//**,,*********,,**//##(**@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@//#(&#(//*********///*,,,,*//*********//%#(*#@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@///&%(////******/////****///*******///(&%/*&@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@//&&##((///**//((#&##%####(//***//(###&#/&@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@(&&&&%#(/(%%%##%%%##%##%%%((###((##%&&&@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@&&&&&%#%&%&&%%#####((#(#%%%%%%%%%%&&&@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@&&&&&&&&%%#//(///*////////%&&&#&&&&@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@(%&@&&&&%#((((######((((((%&&&&@&%@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@,#%/#&&&&&&&&%##%%#%%%##(#%&&%&&@&@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@..(&//(&&&&&&&&&%%%%#%%(%%&&@&&@%(@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@....,///(%&&&&@&&&&%%%%%&&&&&@@&(/..@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@.......////((#%@&&&&&@&&&@&@&&@%(//,.../@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@............//(((((((##&&@@@@@&&#/////#,, .. ..(@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@%..... .... .*///////(((((((//////*//&(.......... *@@@@@@@@@@@@ +@@@@@@@@@%. .,..//*////////////****//%/*. ........... .&@@@@@@ \ No newline at end of file From 9dbf01c5fc20b590de35640dacc112feed18e552 Mon Sep 17 00:00:00 2001 From: lunasuzuki Date: Tue, 4 Nov 2025 15:32:34 -0500 Subject: [PATCH 04/40] added necessary files --- bloomsays/art.py | 1 + bloomsays/bubble.py | 1 + bloomsays/cli.py | 1 + 3 files changed, 3 insertions(+) create mode 100644 bloomsays/art.py create mode 100644 bloomsays/bubble.py create mode 100644 bloomsays/cli.py diff --git a/bloomsays/art.py b/bloomsays/art.py new file mode 100644 index 0000000..ae6b52a --- /dev/null +++ b/bloomsays/art.py @@ -0,0 +1 @@ +#load beard ASCII \ No newline at end of file diff --git a/bloomsays/bubble.py b/bloomsays/bubble.py new file mode 100644 index 0000000..877c3bb --- /dev/null +++ b/bloomsays/bubble.py @@ -0,0 +1 @@ +#speech bubble code \ No newline at end of file diff --git a/bloomsays/cli.py b/bloomsays/cli.py new file mode 100644 index 0000000..759cde2 --- /dev/null +++ b/bloomsays/cli.py @@ -0,0 +1 @@ +#command line implementations \ No newline at end of file From edc7be52b9ced45521b64b3c20752c2bf4be252f Mon Sep 17 00:00:00 2001 From: hna2019 Date: Tue, 4 Nov 2025 17:27:33 -0500 Subject: [PATCH 05/40] Started us off with a pipfile and code that shows ASCII art and message --- Pipfile | 11 +++++++ Pipfile.lock | 20 +++++++++++++ pyproject.toml | 0 src/bloomsayspackage/__init__.py | 0 src/bloomsayspackage/wisdom.py | 49 ++++++++++++++++++++++++++++++++ 5 files changed, 80 insertions(+) create mode 100644 Pipfile create mode 100644 Pipfile.lock create mode 100644 pyproject.toml create mode 100644 src/bloomsayspackage/__init__.py create mode 100644 src/bloomsayspackage/wisdom.py diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000..d61ea53 --- /dev/null +++ b/Pipfile @@ -0,0 +1,11 @@ +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[packages] + +[dev-packages] + +[requires] +python_version = "3.13" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 0000000..bc0ddb5 --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,20 @@ +{ + "_meta": { + "hash": { + "sha256": "494d5b4f482f0ef471f49afe28f00ec1a2ff75da2ce65060d8cabaeb3da2f100" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.13" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": {}, + "develop": {} +} diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..e69de29 diff --git a/src/bloomsayspackage/__init__.py b/src/bloomsayspackage/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/bloomsayspackage/wisdom.py b/src/bloomsayspackage/wisdom.py new file mode 100644 index 0000000..c9e949f --- /dev/null +++ b/src/bloomsayspackage/wisdom.py @@ -0,0 +1,49 @@ +import random; + +def bloomsays(): + profLines = ["everything is due at class time", "ask Bloombot", "Quizzes: 25%", "Exercises & Projects: 75%", "Discord is our main source of communitcation"] + + quote = random.choice(profLines) + + border = "-" * (len(quote) + 2) + bubble = f" {border}\n< {quote} >\n {border}" + + ascii_art = r""" + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&%%%##(##&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%%#%%%%%%%%%#######%@&@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@@@@%%#%%&%%%###%%####(#%&&&%%%%&&@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@%&&&&&#((///((((////**////(#&&&&&&%@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@&&&&&&%#(////***************////(#@@&&&@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@&&&@&#(///***************,*****///(&@&&&@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@&&&&&#(///********,,,,,,,,,,,****///(&&&&&@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@&&&&%(////*****,*,*,,,,,,,,,,,,****//#&&@&@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@&&&&&%(////*******,,,,,,,,,,********//(&&&&&@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@&@&&&%////**********,,,,,,,,,,******//(%&&&&@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@&@@&&%(///*******,,,,,,,,,,,,,,******//#&@&&@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@&&@@&%(///(#(####(/****,**//(%%%%##(///(&&&@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@&&&&(//%###%##%%###(/***/(((%&&&&%###((&@&//@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@(((#&&(//(#%#(*##,/(/(/***///(**#*/(((///&%#((/@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@/(//&&(//***//*////////****/*****/******/#(**/*@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@/(/(%&(//***/*******//**,,*/*******,,**//##(*/@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@/(#(&(///*********///*,,,,*//*********//%%(*#@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@///&%(//********/////****///*******///(&%//&@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@(/&&##((///**//((#&##%####(//***//(###&#/&@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@(&&&&%#(/(%%###%%%##%##%%%((##(((##%&&&@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@&&&&%##%&%&&%###%##((###%%%%#%%%%%&&&@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@&&&&&&%&%%#//(////////////%&&&#&&&&@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@@(%&@&&&&%#((((###%##((((((%&&&&@&%@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@,#%/#&&&&&&&&%##%%#%%%##(#%&&%&&@&@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@..(&//(&&&&&&&&&%%%%#%%(%%&&@&&@%(@@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@....,///(%&&&&@&&&&%%%%%&&&&@@@&(/..@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@.......////((#%&&&&&&@&&&@&@&&@%(//*,../@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@............//(((((((##&&@@@@@&&#/////#,,......(@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@%.......... ...*///////(((((((//////*//&(.......... *@@@@@@@@@@@@ + @@@@@@@@@%. ..,..//**///////////****//%/*. ............ .&@@@@@@ + """ + + print(f"{bubble}\n{ascii_art}") + +if __name__ == "__main__": + bloomsays() From aef1b8a4a6cd47582cbb4af25a1ca9cc75fcf133 Mon Sep 17 00:00:00 2001 From: lunasuzuki Date: Tue, 4 Nov 2025 17:59:23 -0500 Subject: [PATCH 06/40] added bubble.py --- bloomsays/bubble.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/bloomsays/bubble.py b/bloomsays/bubble.py index 877c3bb..89ff3d6 100644 --- a/bloomsays/bubble.py +++ b/bloomsays/bubble.py @@ -1 +1,17 @@ -#speech bubble code \ No newline at end of file +def make_bubble(text: str) -> str: + lines = text.split("\n") + width = max(len(line) for line in lines) + + top = " " + "_" * (width + 2) + + body = "\n".join(f"| {line.ljust(width)} |" for line in lines) + bottom = " " + "=" * (width + 2) + + tail = " \\\n \\" + + return f"{top}\n {body}\n{bottom}\n{tail}" + +#test - run: python3 -m bloomsays.bubble +if __name__ == "__main__": + print(make_bubble("Ask Bloombot!")) + From 19be87b7631737682f49ae6b1cdf93c833901e93 Mon Sep 17 00:00:00 2001 From: hna2019 Date: Wed, 5 Nov 2025 02:55:44 -0500 Subject: [PATCH 07/40] added new avg function and gave random function a parameter --- pyproject.toml | 28 +++++++++++++++++++ src/bloomsayspackage/__main__.py | 30 +++++++++++++++++++++ src/bloomsayspackage/wisdom.py | 38 +++++++++++++++++++------- tests/__init__.py | 0 tests/test_wisdom.py | 46 ++++++++++++++++++++++++++++++++ 5 files changed, 132 insertions(+), 10 deletions(-) create mode 100644 src/bloomsayspackage/__main__.py create mode 100644 tests/__init__.py create mode 100644 tests/test_wisdom.py diff --git a/pyproject.toml b/pyproject.toml index e69de29..319f84e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -0,0 +1,28 @@ +[build-system] +requires = ["setuptools>=61.0", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "bloomsays" +description = "A package that gives quotes from the professor" +version = "0.1.0" +license = { file = "LICENSE" } +readme = "README.md" +keywords = ["python", "package", "build", "lighthearted"] +requires-python = ">=3.7" +classifiers = [ + "Programming Language :: Python :: 3", + "Intended Audience :: Education", + "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", + "Operating System :: OS Independent", +] + +[project.optional-dependencies] +dev = ["pytest"] + +[project.urls] +"Repository" = "https://github.com/swe-students-fall2025/3-python-package-team_orchid.git" + + +[project.scripts] +bloomsays = "bloomsayspackage.__main__:main" diff --git a/src/bloomsayspackage/__main__.py b/src/bloomsayspackage/__main__.py new file mode 100644 index 0000000..cc0c59b --- /dev/null +++ b/src/bloomsayspackage/__main__.py @@ -0,0 +1,30 @@ +import sys +import wisdom + +def main(): + args = sys.argv[1:] + if not args: + print("Usage: bloomsays randomQuote [n] | bloomsays avg num1 num2 ...") + return + + command = args[0] + + if command == "randomQuote": + n = int(args[1]) if len(args) > 1 else 1 + randomQuote(n) + elif command == "avg": + if len(args) < 2: + print("Usage: bloomsays avg num1 num2 ...") + return + try: + numbers = [float(x) for x in args[1:]] + except ValueError: + print("All arguments for avg must be numbers.") + return + print(f"Your average grade is {avg(*numbers):.2f}") + else: + print(f"Unknown command: {command}") + print("Usage: bloomsays randomQuote [n] | bloomsays avg num1 num2 ...") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/src/bloomsayspackage/wisdom.py b/src/bloomsayspackage/wisdom.py index c9e949f..2481c01 100644 --- a/src/bloomsayspackage/wisdom.py +++ b/src/bloomsayspackage/wisdom.py @@ -1,14 +1,8 @@ import random; +import textwrap -def bloomsays(): - profLines = ["everything is due at class time", "ask Bloombot", "Quizzes: 25%", "Exercises & Projects: 75%", "Discord is our main source of communitcation"] - - quote = random.choice(profLines) - border = "-" * (len(quote) + 2) - bubble = f" {border}\n< {quote} >\n {border}" - - ascii_art = r""" +ascii_art = r""" @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&%%%##(##&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ -43,7 +37,31 @@ def bloomsays(): @@@@@@@@@%. ..,..//**///////////****//%/*. ............ .&@@@@@@ """ + +def avg(*grades): + + average = sum(grades)/ len(grades) + message = f"Your average grade is {average:.2f}" + + border = "-" * (len(message) + 2) + bubble = f" {border}\n< {message} >\n {border}" + + print(f"{bubble}\n{ascii_art}") -if __name__ == "__main__": - bloomsays() + + +def randomQuote(n=1): + profLines = ["everything is due at class time", "ask Bloombot", "Quizzes: 25%", "Exercises & Projects: 75%", "Discord is our main source of communitcation"] + selected_quotes = [random.choice(profLines) for _ in range(n)] + + max_length = max(len(quote) for quote in selected_quotes) + + border = "-" * (max_length + 2) + bubble_lines = [f" {border}"] + for quote in selected_quotes: + bubble_lines.append(f"< {quote.ljust(max_length)} >") + bubble_lines.append(f" {border}") + + print("\n".join(bubble_lines)) + print(ascii_art) \ No newline at end of file diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_wisdom.py b/tests/test_wisdom.py new file mode 100644 index 0000000..b9d5b6e --- /dev/null +++ b/tests/test_wisdom.py @@ -0,0 +1,46 @@ +import pytest +from bloomsayspackage import wisdom + +class Tests: + + + def test_avg_simple(self, capsys): + wisdom.avg(97, 76, 67) + captured = capsys.readouterr() + assert "Your average grade is 80.00" in captured.out + assert "----------------" in captured.out + assert "@@@@" in captured.out + + def test_avg_identical_numbers(self, capsys): + wisdom.avg(67, 67, 67) + captured = capsys.readouterr() + assert "Your average grade is 67.00" in captured.out + assert "----------------" in captured.out + assert "@@@@" in captured.out + + def test_avg_random_floats(self, capsys): + wisdom.avg(5.5, 7.3, 8.2) + captured = capsys.readouterr() + assert "Your average grade is 7.00" in captured.out + assert "----------------" in captured.out + assert "@@@@" in captured.out + + def test_randomQuote_runs(self, capsys): + wisdom.randomQuote(3) + captured = capsys.readouterr() + assert "----------------" in captured.out + assert "@@@@" in captured.out + + def test_randomQuote_default(self, capsys): + wisdom.randomQuote() + captured = capsys.readouterr() + assert "----------------" in captured.out + assert "@@@@" in captured.out + + def test_randomQuote_multiple_quotes_in_bubble(self, capsys): + wisdom.randomQuote(2) + captured = capsys.readouterr() + lines = captured.out.splitlines() + bubble_lines = [line for line in lines if line.strip().startswith("<") and line.strip().endswith(">")] + assert len(bubble_lines) >= 2 + assert "@@@@" in captured.out From 0f202aebdb215fe1a0c15f0d2e01ac98aa9cdb5b Mon Sep 17 00:00:00 2001 From: TawhidZGit Date: Wed, 5 Nov 2025 20:22:37 -0500 Subject: [PATCH 08/40] Added coding_wisdom function and tests --- bloomsays/bubble.py | 17 -------- src/bloomsayspackage/bubble.py | 17 ++++++++ src/bloomsayspackage/wisdom.py | 74 +++++++++++++++++++++++++++------- tests/test_wisdom.py | 54 +++++++++++++++++++++---- 4 files changed, 123 insertions(+), 39 deletions(-) delete mode 100644 bloomsays/bubble.py create mode 100644 src/bloomsayspackage/bubble.py diff --git a/bloomsays/bubble.py b/bloomsays/bubble.py deleted file mode 100644 index 89ff3d6..0000000 --- a/bloomsays/bubble.py +++ /dev/null @@ -1,17 +0,0 @@ -def make_bubble(text: str) -> str: - lines = text.split("\n") - width = max(len(line) for line in lines) - - top = " " + "_" * (width + 2) - - body = "\n".join(f"| {line.ljust(width)} |" for line in lines) - bottom = " " + "=" * (width + 2) - - tail = " \\\n \\" - - return f"{top}\n {body}\n{bottom}\n{tail}" - -#test - run: python3 -m bloomsays.bubble -if __name__ == "__main__": - print(make_bubble("Ask Bloombot!")) - diff --git a/src/bloomsayspackage/bubble.py b/src/bloomsayspackage/bubble.py new file mode 100644 index 0000000..b8847e3 --- /dev/null +++ b/src/bloomsayspackage/bubble.py @@ -0,0 +1,17 @@ +def make_bubble(text: str, tail: str = "\\") -> str: + lines = text.split("\n") + width = max(len(line) for line in lines) if lines else 0 + + top = " " + "_" * (width + 2) + body = "\n".join(f"< {line.ljust(width)} >" for line in lines) + bottom = " " + "-" * (width + 2) + + if tail: + tail_str = f" {tail}\n {tail}" + return f"{top}\n{body}\n{bottom}\n{tail_str}" + else: + return f"{top}\n{body}\n{bottom}" + +# test - run: python3 -m bloomsayspackage.bubble +if __name__ == "__main__": + print(make_bubble("Ask Bloombot!")) \ No newline at end of file diff --git a/src/bloomsayspackage/wisdom.py b/src/bloomsayspackage/wisdom.py index 2481c01..410d339 100644 --- a/src/bloomsayspackage/wisdom.py +++ b/src/bloomsayspackage/wisdom.py @@ -1,5 +1,8 @@ import random; import textwrap +from pathlib import Path +from bubble import make_bubble + ascii_art = r""" @@ -43,25 +46,66 @@ def avg(*grades): average = sum(grades)/ len(grades) message = f"Your average grade is {average:.2f}" - border = "-" * (len(message) + 2) - bubble = f" {border}\n< {message} >\n {border}" - - + bubble = make_bubble(message) print(f"{bubble}\n{ascii_art}") + return average - -def randomQuote(n=1): +def random_quote(n=1): profLines = ["everything is due at class time", "ask Bloombot", "Quizzes: 25%", "Exercises & Projects: 75%", "Discord is our main source of communitcation"] selected_quotes = [random.choice(profLines) for _ in range(n)] - max_length = max(len(quote) for quote in selected_quotes) - - border = "-" * (max_length + 2) - bubble_lines = [f" {border}"] - for quote in selected_quotes: - bubble_lines.append(f"< {quote.ljust(max_length)} >") - bubble_lines.append(f" {border}") + bubble_text = "\n".join(selected_quotes) + + bubble = make_bubble(bubble_text) + print(f"{bubble}\n{ascii_art}") + + return selected_quotes - print("\n".join(bubble_lines)) - print(ascii_art) \ No newline at end of file +def coding_wisdom(language="Python"): + wisdom_dict = { + "Python": [ + "Remember: readability counts!", + "Use list comprehensions wisely", + "Virtual environments are your friend", + "PEP 8 is the style guide to follow", + "Test your code with pytest" + ], + "JavaScript": [ + "Async/await makes life easier", + "Always use const and let, never var", + "Arrow functions are your friend", + "npm install is just the beginning", + "Console.log is for debugging only" + ], + "Java": [ + "Object-oriented design matters", + "Exceptions should be exceptional", + "Use interfaces wisely", + "The JVM is powerful but watch memory", + "Unit tests save production bugs" + ], + "C++": [ + "Manage your memory carefully", + "RAII is your best friend", + "Smart pointers over raw pointers", + "The STL is incredibly powerful", + "Compile warnings are errors in disguise" + ], + "default": [ + "Write clean, readable code", + "Test early, test often", + "Documentation is never optional", + "Version control is essential", + "Code reviews make better developers" + ] + } + + wisdom_list = wisdom_dict.get(language, wisdom_dict["default"]) + message = random.choice(wisdom_list) + full_message = f"{language} wisdom: {message}" + + bubble = make_bubble(full_message) + print(f"{bubble}\n{ascii_art}") + + return message \ No newline at end of file diff --git a/tests/test_wisdom.py b/tests/test_wisdom.py index b9d5b6e..e611858 100644 --- a/tests/test_wisdom.py +++ b/tests/test_wisdom.py @@ -3,7 +3,6 @@ class Tests: - def test_avg_simple(self, capsys): wisdom.avg(97, 76, 67) captured = capsys.readouterr() @@ -25,22 +24,63 @@ def test_avg_random_floats(self, capsys): assert "----------------" in captured.out assert "@@@@" in captured.out - def test_randomQuote_runs(self, capsys): - wisdom.randomQuote(3) + def test_random_quote_runs(self, capsys): + wisdom.random_quote(3) captured = capsys.readouterr() assert "----------------" in captured.out assert "@@@@" in captured.out - def test_randomQuote_default(self, capsys): - wisdom.randomQuote() + def test_random_quote_default(self, capsys): + wisdom.random_quote() captured = capsys.readouterr() assert "----------------" in captured.out assert "@@@@" in captured.out - def test_randomQuote_multiple_quotes_in_bubble(self, capsys): - wisdom.randomQuote(2) + def test_random_quote_multiple_quotes_in_bubble(self, capsys): + wisdom.random_quote(2) captured = capsys.readouterr() lines = captured.out.splitlines() bubble_lines = [line for line in lines if line.strip().startswith("<") and line.strip().endswith(">")] assert len(bubble_lines) >= 2 assert "@@@@" in captured.out + + def test_coding_wisdom_default(self, capsys): + message = wisdom.coding_wisdom() + captured = capsys.readouterr() + assert isinstance(message, str) + assert "Python wisdom:" in captured.out + assert "@@@" in captured.out + + def test_coding_wisdom_javascript(self, capsys): + message = wisdom.coding_wisdom("JavaScript") + captured = capsys.readouterr() + assert isinstance(message, str) + assert "JavaScript wisdom:" in captured.out + assert "@@@" in captured.out + + def test_coding_wisdom_java(self, capsys): + message = wisdom.coding_wisdom("Java") + captured = capsys.readouterr() + assert isinstance(message, str) + assert "Java wisdom:" in captured.out + assert "@@@" in captured.out + + def test_coding_wisdom_cpp(self, capsys): + message = wisdom.coding_wisdom("C++") + captured = capsys.readouterr() + assert isinstance(message, str) + assert "C++ wisdom:" in captured.out + assert "@@@" in captured.out + + def test_coding_wisdom_unknown_language(self, capsys): + message = wisdom.coding_wisdom("COBOL") + captured = capsys.readouterr() + assert isinstance(message, str) + assert "COBOL wisdom:" in captured.out + assert "@@@" in captured.out + + def test_coding_wisdom_returns_string(self): + message = wisdom.coding_wisdom("Python") + assert isinstance(message, str) + assert len(message) > 0 + From ede2b9d7d0fc614cfa05db1dad56209db0291c06 Mon Sep 17 00:00:00 2001 From: a247686991 Date: Fri, 7 Nov 2025 00:07:25 +0800 Subject: [PATCH 09/40] added helper function wrap_text --- {bloomsays => src/bloomsayspackage}/bubble.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {bloomsays => src/bloomsayspackage}/bubble.py (100%) diff --git a/bloomsays/bubble.py b/src/bloomsayspackage/bubble.py similarity index 100% rename from bloomsays/bubble.py rename to src/bloomsayspackage/bubble.py From 11776ebcd4e699520b7406d05484985aeac6472c Mon Sep 17 00:00:00 2001 From: a247686991 Date: Fri, 7 Nov 2025 00:13:45 +0800 Subject: [PATCH 10/40] added tests for bubble --- src/bloomsayspackage/bubble.py | 61 ++++++++++++++++++++++++++++++---- tests/test_bubble.py | 56 +++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 6 deletions(-) create mode 100644 tests/test_bubble.py diff --git a/src/bloomsayspackage/bubble.py b/src/bloomsayspackage/bubble.py index 89ff3d6..0826c7d 100644 --- a/src/bloomsayspackage/bubble.py +++ b/src/bloomsayspackage/bubble.py @@ -1,12 +1,61 @@ -def make_bubble(text: str) -> str: - lines = text.split("\n") - width = max(len(line) for line in lines) +from __future__ import annotations +from typing import List - top = " " + "_" * (width + 2) - body = "\n".join(f"| {line.ljust(width)} |" for line in lines) - bottom = " " + "=" * (width + 2) +def wrap_text(text: str, width: int) -> List[str]: + """ + Pure text wrapper (no printing). + - Splits on whitespace. + - If a single word is longer than width, it is put on its own line (no hyphenation). + """ + if width is None or width < 1: + raise ValueError("width must be >= 1") + words = text.split() + if not words: + return [""] + + lines: List[str] = [] + cur = words[0] + for w in words[1:]: + if len(cur) + 1 + len(w) <= width: + cur += " " + w + else: + lines.append(cur) + cur = w + lines.append(cur) + return lines + + +def make_bubble(text: str, width: int | None = None) -> str: + """ + Build a speech bubble as a single string. + - If width is provided, wrap the text to that width. + - Supports multi-line input already containing '\n' (each line is treated as a paragraph). + """ + if text is None: + raise ValueError("text must be a string") + + # split paragraphs first + paragraphs = text.split("\n") + if width is not None: + if width < 1: + raise ValueError("width must be >= 1") + lines = [] + for p in paragraphs: + if p.strip() == "": + lines.append("") # preserve empty line + else: + lines.extend(wrap_text(p, width)) + else: + lines = paragraphs + + # compute max visible width + maxw = max((len(line) for line in lines), default=0) + + top = " " + "_" * (maxw + 2) + body = "\n".join(f"| {line.ljust(maxw)} |" for line in lines) + bottom = " " + "=" * (maxw + 2) tail = " \\\n \\" return f"{top}\n {body}\n{bottom}\n{tail}" diff --git a/tests/test_bubble.py b/tests/test_bubble.py new file mode 100644 index 0000000..a88ad09 --- /dev/null +++ b/tests/test_bubble.py @@ -0,0 +1,56 @@ +import pytest + +from bloomsayspackage.bubble import make_bubble + + +def _assert_bubble_matches(out: str, expected_lines: list[str]): + parts = out.splitlines() + # top + maxw = max((len(l) for l in expected_lines), default=0) + assert parts[0] == " " + "_" * (maxw + 2) + + # body + body = parts[1 : 1 + len(expected_lines)] + assert len(body) == len(expected_lines) + for idx, (got, expect) in enumerate(zip(body, expected_lines)): + # the first body line is prefixed with a single space in the output + if idx == 0: + assert got.startswith(" | ") + inner = got[3:-2] + else: + # subsequent lines start with '|' directly + assert got.startswith("| ") + inner = got[2:-2] + assert got.endswith(" |") + assert inner.strip() == expect + + # bottom + bottom = parts[1 + len(expected_lines)] + assert bottom == " " + "=" * (maxw + 2) + + # tail should be two lines that each end with a backslash + assert parts[-2].endswith("\\") + assert parts[-1].endswith("\\") + + +def test_simple_bubble_no_width(): + out = make_bubble("Hi") + _assert_bubble_matches(out, ["Hi"]) + + +def test_wrap_with_width(): + out = make_bubble("one two three", width=6) + # wrapped into three lines + _assert_bubble_matches(out, ["one", "two", "three"]) + + +def test_preserve_empty_line(): + out = make_bubble("a\n\nb") + # empty paragraph should be preserved as an empty line + _assert_bubble_matches(out, ["a", "", "b"]) + + +def test_text_none_raises(): + with pytest.raises(ValueError): + make_bubble(None) + From 27783e8cf2cef3e93a69c783173c4af126c22676 Mon Sep 17 00:00:00 2001 From: a247686991 Date: Fri, 7 Nov 2025 00:22:42 +0800 Subject: [PATCH 11/40] added compute_avg and random_quote --- src/bloomsayspackage/wisdom.py | 86 +++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 37 deletions(-) diff --git a/src/bloomsayspackage/wisdom.py b/src/bloomsayspackage/wisdom.py index 2481c01..772bbb9 100644 --- a/src/bloomsayspackage/wisdom.py +++ b/src/bloomsayspackage/wisdom.py @@ -1,8 +1,9 @@ -import random; -import textwrap +from __future__ import annotations +import random +from typing import Iterable, List -ascii_art = r""" +ASCII_ART = r""" @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&%%%##(##&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ -19,49 +20,60 @@ @@@@@@@@@@@@@@@@@@&&@@&%(///(#(####(/****,**//(%%%%##(///(&&&@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@&&&&(//%###%##%%###(/***/(((%&&&&%###((&@&//@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@(((#&&(//(#%#(*##,/(/(/***///(**#*/(((///&%#((/@@@@@@@@@@@@@@@@ - @@@@@@@@@@@@@@@@@/(//&&(//***//*////////****/*****/******/#(**/*@@@@@@@@@@@@@@@@ - @@@@@@@@@@@@@@@@@/(/(%&(//***/*******//**,,*/*******,,**//##(*/@@@@@@@@@@@@@@@@@ - @@@@@@@@@@@@@@@@@@/(#(&(///*********///*,,,,*//*********//%%(*#@@@@@@@@@@@@@@@@@ - @@@@@@@@@@@@@@@@@@@///&%(//********/////****///*******///(&%//&@@@@@@@@@@@@@@@@@ - @@@@@@@@@@@@@@@@@@@@(/&&##((///**//((#&##%####(//***//(###&#/&@@@@@@@@@@@@@@@@@@ - @@@@@@@@@@@@@@@@@@@@@(&&&&%#(/(%%###%%%##%##%%%((##(((##%&&&@@@@@@@@@@@@@@@@@@@@ - @@@@@@@@@@@@@@@@@@@@@@&&&&%##%&%&&%###%##((###%%%%#%%%%%&&&@@@@@@@@@@@@@@@@@@@@@ - @@@@@@@@@@@@@@@@@@@@@@@&&&&&&%&%%#//(////////////%&&&#&&&&@@@@@@@@@@@@@@@@@@@@@@ - @@@@@@@@@@@@@@@@@@@@@@@@(%&@&&&&%#((((###%##((((((%&&&&@&%@@@@@@@@@@@@@@@@@@@@@@ - @@@@@@@@@@@@@@@@@@@@@@,#%/#&&&&&&&&%##%%#%%%##(#%&&%&&@&@@@@@@@@@@@@@@@@@@@@@@@@ - @@@@@@@@@@@@@@@@@@@@@..(&//(&&&&&&&&&%%%%#%%(%%&&@&&@%(@@@@@@@@@@@@@@@@@@@@@@@@@ - @@@@@@@@@@@@@@@@@@@@....,///(%&&&&@&&&&%%%%%&&&&@@@&(/..@@@@@@@@@@@@@@@@@@@@@@@@ - @@@@@@@@@@@@@@@@@@@.......////((#%&&&&&&@&&&@&@&&@%(//*,../@@@@@@@@@@@@@@@@@@@@@ - @@@@@@@@@@@@@@@@............//(((((((##&&@@@@@&&#/////#,,......(@@@@@@@@@@@@@@@@ - @@@@@@@@@@@@%.......... ...*///////(((((((//////*//&(.......... *@@@@@@@@@@@@ - @@@@@@@@@%. ..,..//**///////////****//%/*. ............ .&@@@@@@ - """ +""" -def avg(*grades): +def compute_avg(*grades: float) -> float: + """ + Pure function: returns the numeric average. + Raises: + - ValueError if no grades are provided. + - TypeError if a non-numeric is passed. + """ + if len(grades) == 0: + raise ValueError("at least one grade is required") + total = 0.0 + for g in grades: + total += float(g) # will raise if not convertible to float + return total / len(grades) - average = sum(grades)/ len(grades) - message = f"Your average grade is {average:.2f}" - border = "-" * (len(message) + 2) - bubble = f" {border}\n< {message} >\n {border}" +DEFAULT_QUOTES = [ + "everything is due at class time", + "ask Bloombot", + "Quizzes: 25%", + "Exercises & Projects: 75%", + "Discord is our main source of communication", +] - print(f"{bubble}\n{ascii_art}") +def pick_quotes(n: int = 1, pool: Iterable[str] | None = None) -> List[str]: + if n < 1: + raise ValueError("n must be >= 1") + src = list(pool) if pool is not None else DEFAULT_QUOTES + return [random.choice(src) for _ in range(n)] -def randomQuote(n=1): - profLines = ["everything is due at class time", "ask Bloombot", "Quizzes: 25%", "Exercises & Projects: 75%", "Discord is our main source of communitcation"] - selected_quotes = [random.choice(profLines) for _ in range(n)] - max_length = max(len(quote) for quote in selected_quotes) +def _bubble_block(lines: List[str]) -> str: + max_len = max((len(line) for line in lines), default=0) + border = "-" * (max_len + 2) + out = [f" {border}"] + for line in lines: + out.append(f"< {line.ljust(max_len)} >") + out.append(f" {border}") + return "\n".join(out) - border = "-" * (max_length + 2) - bubble_lines = [f" {border}"] - for quote in selected_quotes: - bubble_lines.append(f"< {quote.ljust(max_length)} >") - bubble_lines.append(f" {border}") - print("\n".join(bubble_lines)) - print(ascii_art) \ No newline at end of file +def avg_print(*grades: float) -> None: + avg = compute_avg(*grades) + msg = f"Your average grade is {avg:.2f}" + print(_bubble_block([msg])) + print(ASCII_ART) + + +def random_quote_print(n: int = 1) -> None: + lines = pick_quotes(n) + print(_bubble_block(lines)) + print(ASCII_ART) From 1a0c9bd12f2aa2c3aa44b75304a043ed9f5596e6 Mon Sep 17 00:00:00 2001 From: a247686991 Date: Fri, 7 Nov 2025 00:32:56 +0800 Subject: [PATCH 12/40] fixed test_wisdom.py --- src/bloomsayspackage/wisdom.py | 86 +++++++++++++++------------------- tests/test_wisdom.py | 2 +- 2 files changed, 38 insertions(+), 50 deletions(-) diff --git a/src/bloomsayspackage/wisdom.py b/src/bloomsayspackage/wisdom.py index 772bbb9..2481c01 100644 --- a/src/bloomsayspackage/wisdom.py +++ b/src/bloomsayspackage/wisdom.py @@ -1,9 +1,8 @@ -from __future__ import annotations -import random -from typing import Iterable, List +import random; +import textwrap -ASCII_ART = r""" +ascii_art = r""" @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&%%%##(##&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ -20,60 +19,49 @@ @@@@@@@@@@@@@@@@@@&&@@&%(///(#(####(/****,**//(%%%%##(///(&&&@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@&&&&(//%###%##%%###(/***/(((%&&&&%###((&@&//@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@(((#&&(//(#%#(*##,/(/(/***///(**#*/(((///&%#((/@@@@@@@@@@@@@@@@ -""" + @@@@@@@@@@@@@@@@@/(//&&(//***//*////////****/*****/******/#(**/*@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@/(/(%&(//***/*******//**,,*/*******,,**//##(*/@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@/(#(&(///*********///*,,,,*//*********//%%(*#@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@///&%(//********/////****///*******///(&%//&@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@(/&&##((///**//((#&##%####(//***//(###&#/&@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@(&&&&%#(/(%%###%%%##%##%%%((##(((##%&&&@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@&&&&%##%&%&&%###%##((###%%%%#%%%%%&&&@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@&&&&&&%&%%#//(////////////%&&&#&&&&@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@@(%&@&&&&%#((((###%##((((((%&&&&@&%@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@,#%/#&&&&&&&&%##%%#%%%##(#%&&%&&@&@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@..(&//(&&&&&&&&&%%%%#%%(%%&&@&&@%(@@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@....,///(%&&&&@&&&&%%%%%&&&&@@@&(/..@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@.......////((#%&&&&&&@&&&@&@&&@%(//*,../@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@............//(((((((##&&@@@@@&&#/////#,,......(@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@%.......... ...*///////(((((((//////*//&(.......... *@@@@@@@@@@@@ + @@@@@@@@@%. ..,..//**///////////****//%/*. ............ .&@@@@@@ + """ -def compute_avg(*grades: float) -> float: - """ - Pure function: returns the numeric average. - Raises: - - ValueError if no grades are provided. - - TypeError if a non-numeric is passed. - """ - if len(grades) == 0: - raise ValueError("at least one grade is required") - total = 0.0 - for g in grades: - total += float(g) # will raise if not convertible to float - return total / len(grades) +def avg(*grades): + average = sum(grades)/ len(grades) + message = f"Your average grade is {average:.2f}" -DEFAULT_QUOTES = [ - "everything is due at class time", - "ask Bloombot", - "Quizzes: 25%", - "Exercises & Projects: 75%", - "Discord is our main source of communication", -] + border = "-" * (len(message) + 2) + bubble = f" {border}\n< {message} >\n {border}" -def pick_quotes(n: int = 1, pool: Iterable[str] | None = None) -> List[str]: - if n < 1: - raise ValueError("n must be >= 1") - src = list(pool) if pool is not None else DEFAULT_QUOTES - return [random.choice(src) for _ in range(n)] + print(f"{bubble}\n{ascii_art}") +def randomQuote(n=1): + profLines = ["everything is due at class time", "ask Bloombot", "Quizzes: 25%", "Exercises & Projects: 75%", "Discord is our main source of communitcation"] + selected_quotes = [random.choice(profLines) for _ in range(n)] -def _bubble_block(lines: List[str]) -> str: - max_len = max((len(line) for line in lines), default=0) - border = "-" * (max_len + 2) - out = [f" {border}"] - for line in lines: - out.append(f"< {line.ljust(max_len)} >") - out.append(f" {border}") - return "\n".join(out) + max_length = max(len(quote) for quote in selected_quotes) + border = "-" * (max_length + 2) + bubble_lines = [f" {border}"] + for quote in selected_quotes: + bubble_lines.append(f"< {quote.ljust(max_length)} >") + bubble_lines.append(f" {border}") -def avg_print(*grades: float) -> None: - avg = compute_avg(*grades) - msg = f"Your average grade is {avg:.2f}" - print(_bubble_block([msg])) - print(ASCII_ART) - - -def random_quote_print(n: int = 1) -> None: - lines = pick_quotes(n) - print(_bubble_block(lines)) - print(ASCII_ART) + print("\n".join(bubble_lines)) + print(ascii_art) \ No newline at end of file diff --git a/tests/test_wisdom.py b/tests/test_wisdom.py index b9d5b6e..61957f4 100644 --- a/tests/test_wisdom.py +++ b/tests/test_wisdom.py @@ -34,7 +34,7 @@ def test_randomQuote_runs(self, capsys): def test_randomQuote_default(self, capsys): wisdom.randomQuote() captured = capsys.readouterr() - assert "----------------" in captured.out + assert any(line.strip().startswith("-") for line in captured.out.splitlines()) assert "@@@@" in captured.out def test_randomQuote_multiple_quotes_in_bubble(self, capsys): From 6d8438eddd67dc2e18e09c1c5c7250e6e9ad7491 Mon Sep 17 00:00:00 2001 From: a247686991 Date: Fri, 7 Nov 2025 00:33:59 +0800 Subject: [PATCH 13/40] added init.py --- src/bloomsayspackage/__init__.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/bloomsayspackage/__init__.py b/src/bloomsayspackage/__init__.py index e69de29..1c2be9c 100644 --- a/src/bloomsayspackage/__init__.py +++ b/src/bloomsayspackage/__init__.py @@ -0,0 +1,8 @@ +from .bubble import wrap_text, make_bubble + +from . import wisdom +__all__ = [ + "wrap_text", + "make_bubble", + "wisdom", +] From fa7552635870d16d0f77567647f83e5d35433012 Mon Sep 17 00:00:00 2001 From: a247686991 Date: Fri, 7 Nov 2025 00:38:55 +0800 Subject: [PATCH 14/40] added test for wrap_texgt --- tests/test_bubble.py | 49 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/tests/test_bubble.py b/tests/test_bubble.py index a88ad09..ddef51d 100644 --- a/tests/test_bubble.py +++ b/tests/test_bubble.py @@ -1,6 +1,6 @@ import pytest -from bloomsayspackage.bubble import make_bubble +from bloomsayspackage.bubble import make_bubble, wrap_text def _assert_bubble_matches(out: str, expected_lines: list[str]): @@ -54,3 +54,50 @@ def test_text_none_raises(): with pytest.raises(ValueError): make_bubble(None) + +# Tests for wrap_text function +def test_wrap_text_simple(): + result = wrap_text("hello world", 10) + assert result == ["hello", "world"] + + +def test_wrap_text_fits_on_one_line(): + result = wrap_text("hello", 10) + assert result == ["hello"] + + +def test_wrap_text_multiple_words_fit(): + result = wrap_text("one two three four", 15) + assert result == ["one two three", "four"] + + +def test_wrap_text_long_word_exceeds_width(): + # A single word longer than width should be on its own line + result = wrap_text("short verylongword short", 10) + assert result == ["short", "verylongword", "short"] + + +def test_wrap_text_empty_string(): + result = wrap_text("", 10) + assert result == [""] + + +def test_wrap_text_width_one(): + result = wrap_text("a b c", 1) + assert result == ["a", "b", "c"] + + +def test_wrap_text_invalid_width_zero(): + with pytest.raises(ValueError, match="width must be >= 1"): + wrap_text("text", 0) + + +def test_wrap_text_invalid_width_negative(): + with pytest.raises(ValueError, match="width must be >= 1"): + wrap_text("text", -5) + + +def test_wrap_text_invalid_width_none(): + with pytest.raises(ValueError, match="width must be >= 1"): + wrap_text("text", None) + From f96f8837602787b62a107a74d953920250d275a1 Mon Sep 17 00:00:00 2001 From: a247686991 Date: Fri, 7 Nov 2025 01:08:25 +0800 Subject: [PATCH 15/40] fixed yml --- .github/workflows/event-logger.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/event-logger.yml b/.github/workflows/event-logger.yml index 31f231e..2a6ca80 100644 --- a/.github/workflows/event-logger.yml +++ b/.github/workflows/event-logger.yml @@ -35,20 +35,32 @@ jobs: - name: Log pull request opened if: github.event_name == 'pull_request' && github.event.action == 'opened' run: | + if [ -z "$COMMIT_LOG_API" ]; then + echo "COMMIT_LOG_API is not set"; exit 1 + fi pipenv run gitcommitlogger -r $(echo $REPOSITORY_URL) -t pull_request_opened -d $(echo $PR_CREATED_AT) -un $(echo $GITHUB_LOGIN) -o commit_stats.csv -u $(echo $COMMIT_LOG_API) -v - name: Log pull request closed and merged if: github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == true run: | + if [ -z "$COMMIT_LOG_API" ]; then + echo "COMMIT_LOG_API is not set"; exit 1 + fi echo $COMMITS > commits.json cat commits.json # debugging pipenv run gitcommitlogger -r $(echo $REPOSITORY_URL) -t pull_request_merged -d $(echo $PR_CLOSED_AT) -un $(echo $GITHUB_LOGIN) -i commits.json -o commit_stats.csv -u $(echo $COMMIT_LOG_API) -v - name: Log pull request closed without merge if: github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == false run: | + if [ -z "$COMMIT_LOG_API" ]; then + echo "COMMIT_LOG_API is not set"; exit 1 + fi pipenv run gitcommitlogger -r $(echo $REPOSITORY_URL) -t pull_request_closed -d $(echo $PR_CLOSED_AT) -un $(echo $GITHUB_LOGIN) -o commit_stats.csv -u $(echo $COMMIT_LOG_API) -v - name: Log push if: github.event_name == 'push' run: | + if [ -z "$COMMIT_LOG_API" ]; then + echo "COMMIT_LOG_API is not set"; exit 1 + fi echo $COMMITS > commits.json cat commits.json # debugging pipenv run gitcommitlogger -r $(echo $REPOSITORY_URL) -t $(echo $EVENT_TYPE) -i commits.json -o commit_stats.csv -u $(echo $COMMIT_LOG_API) -v From d47271e4c114b41544f041c85e892f102cf1cde1 Mon Sep 17 00:00:00 2001 From: a247686991 Date: Fri, 7 Nov 2025 01:25:06 +0800 Subject: [PATCH 16/40] fixed yml --- .github/workflows/event-logger.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/event-logger.yml b/.github/workflows/event-logger.yml index 2a6ca80..01c9a2b 100644 --- a/.github/workflows/event-logger.yml +++ b/.github/workflows/event-logger.yml @@ -36,14 +36,14 @@ jobs: if: github.event_name == 'pull_request' && github.event.action == 'opened' run: | if [ -z "$COMMIT_LOG_API" ]; then - echo "COMMIT_LOG_API is not set"; exit 1 + echo "COMMIT_LOG_API is not set; skipping logging step."; exit 0 fi pipenv run gitcommitlogger -r $(echo $REPOSITORY_URL) -t pull_request_opened -d $(echo $PR_CREATED_AT) -un $(echo $GITHUB_LOGIN) -o commit_stats.csv -u $(echo $COMMIT_LOG_API) -v - name: Log pull request closed and merged if: github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == true run: | if [ -z "$COMMIT_LOG_API" ]; then - echo "COMMIT_LOG_API is not set"; exit 1 + echo "COMMIT_LOG_API is not set; skipping logging step."; exit 0 fi echo $COMMITS > commits.json cat commits.json # debugging @@ -52,14 +52,14 @@ jobs: if: github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == false run: | if [ -z "$COMMIT_LOG_API" ]; then - echo "COMMIT_LOG_API is not set"; exit 1 + echo "COMMIT_LOG_API is not set; skipping logging step."; exit 0 fi pipenv run gitcommitlogger -r $(echo $REPOSITORY_URL) -t pull_request_closed -d $(echo $PR_CLOSED_AT) -un $(echo $GITHUB_LOGIN) -o commit_stats.csv -u $(echo $COMMIT_LOG_API) -v - name: Log push if: github.event_name == 'push' run: | if [ -z "$COMMIT_LOG_API" ]; then - echo "COMMIT_LOG_API is not set"; exit 1 + echo "COMMIT_LOG_API is not set; skipping logging step."; exit 0 fi echo $COMMITS > commits.json cat commits.json # debugging From fbf9b39cf490552a55b49709223dc2e43e80ccad Mon Sep 17 00:00:00 2001 From: kazisean Date: Thu, 6 Nov 2025 14:02:01 -0500 Subject: [PATCH 17/40] QOL updates, small refactors and update to test cases --- Pipfile | 1 + Pipfile.lock | 46 ++++++++++++++++++- TODO | 17 +++++++ bloomsays/art.py | 1 - bloomsays/bloomberg/black.txt | 32 ------------- bloomsays/bloomberg/color.txt | 30 ------------ bloomsays/cli.py | 1 - bloomsays/main.py | 0 pyproject.toml | 2 +- .../__init__.py | 0 .../__main__.py | 6 +-- src/{bloomsayspackage => bloomsays}/bubble.py | 0 src/{bloomsayspackage => bloomsays}/wisdom.py | 2 +- tests/test_bubble.py | 2 +- tests/test_wisdom.py | 14 +++--- 15 files changed, 75 insertions(+), 79 deletions(-) create mode 100644 TODO delete mode 100644 bloomsays/art.py delete mode 100644 bloomsays/bloomberg/black.txt delete mode 100644 bloomsays/bloomberg/color.txt delete mode 100644 bloomsays/cli.py delete mode 100644 bloomsays/main.py rename src/{bloomsayspackage => bloomsays}/__init__.py (100%) rename src/{bloomsayspackage => bloomsays}/__main__.py (88%) rename src/{bloomsayspackage => bloomsays}/bubble.py (100%) rename src/{bloomsayspackage => bloomsays}/wisdom.py (99%) diff --git a/Pipfile b/Pipfile index d61ea53..65e9901 100644 --- a/Pipfile +++ b/Pipfile @@ -4,6 +4,7 @@ verify_ssl = true name = "pypi" [packages] +pytest = "*" [dev-packages] diff --git a/Pipfile.lock b/Pipfile.lock index bc0ddb5..91df136 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "494d5b4f482f0ef471f49afe28f00ec1a2ff75da2ce65060d8cabaeb3da2f100" + "sha256": "356d0f8762b2b972f2a073f481ed3d3cf98ef2b0ed59132aeff315abfaff74a9" }, "pipfile-spec": 6, "requires": { @@ -15,6 +15,48 @@ } ] }, - "default": {}, + "default": { + "iniconfig": { + "hashes": [ + "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", + "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12" + ], + "markers": "python_version >= '3.10'", + "version": "==2.3.0" + }, + "packaging": { + "hashes": [ + "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", + "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f" + ], + "markers": "python_version >= '3.8'", + "version": "==25.0" + }, + "pluggy": { + "hashes": [ + "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", + "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746" + ], + "markers": "python_version >= '3.9'", + "version": "==1.6.0" + }, + "pygments": { + "hashes": [ + "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", + "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b" + ], + "markers": "python_version >= '3.8'", + "version": "==2.19.2" + }, + "pytest": { + "hashes": [ + "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", + "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==8.4.2" + } + }, "develop": {} } diff --git a/TODO b/TODO new file mode 100644 index 0000000..77bc9fb --- /dev/null +++ b/TODO @@ -0,0 +1,17 @@ +[] At least four functions that accept arguments which influence their behavior +[] The package must be distributed in the PyPI repository and installable via pip. +[] Use pipenv to manage the package dependencies and virtual environments with a Pipfile. +[] Use pytest to test this should be no fewer than three tests per package function. +[] Use build to create the package artifacts. +[] Use twine to upload the package to PyPI. +[] Use GitHub Actions to build your package and run your tests on two different recent versions of Python with every pull request to the main branch of your GitHub repository. +[] delete the feature branch +[] beautiful read-me file on + [] description + [] clear instructions + [] code examples + [] include doc for all the functions and how to use + import + [] how to contribute + build + test + run + [] Include a badge at the top of the README.md file showing the result of the latest build/test workflow run. + [] Include the names of all teammates as links to their GitHub profiles in the README.md file. + [] Include a link to your package's page on the PyPI website. \ No newline at end of file diff --git a/bloomsays/art.py b/bloomsays/art.py deleted file mode 100644 index ae6b52a..0000000 --- a/bloomsays/art.py +++ /dev/null @@ -1 +0,0 @@ -#load beard ASCII \ No newline at end of file diff --git a/bloomsays/bloomberg/black.txt b/bloomsays/bloomberg/black.txt deleted file mode 100644 index 5267c42..0000000 --- a/bloomsays/bloomberg/black.txt +++ /dev/null @@ -1,32 +0,0 @@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&%%%##(##&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%%#%%%%%%%%%#######%@&@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@%%#%%&%%%###%%####(#%&&&%%%%&&@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@%&&&&&#((///((((////**////(#&&&&&&%@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@&&&&&&%#(////***************////(#@@&&&@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@&&&@&#(///***************,*****///(&@&&&@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@&&&&&#(///********,,,,,,,,,,,****///(&&&&&@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@&&&&%(////*****,*,*,,,,,,,,,,,,****//#&&@&@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@&&&&&%(////*******,,,,,,,,,,********//(&&&&&@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@&@&&&%////**********,,,,,,,,,,******//(%&&&&@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@&@@&&%(///*******,,,,,,,,,,,,,,******//#&@&&@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@&&@@&%(///(#(####(/****,**//(%%%%##(///(&&&@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@&&&&(//%###%##%%###(/***/(((%&&&&%###((&@&//@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@(((#&&(//(#%#(*##,/(/(/***///(**#*/(((///&%#((/@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@/(//&&(//***//*////////****/*****/******/#(**/*@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@/(/(%&(//***/*******//**,,*/*******,,**//##(*/@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@/(#(&(///*********///*,,,,*//*********//%%(*#@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@///&%(//********/////****///*******///(&%//&@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@(/&&##((///**//((#&##%####(//***//(###&#/&@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@(&&&&%#(/(%%###%%%##%##%%%((##(((##%&&&@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@&&&&%##%&%&&%###%##((###%%%%#%%%%%&&&@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@&&&&&&%&%%#//(////////////%&&&#&&&&@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@(%&@&&&&%#((((###%##((((((%&&&&@&%@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@,#%/#&&&&&&&&%##%%#%%%##(#%&&%&&@&@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@..(&//(&&&&&&&&&%%%%#%%(%%&&@&&@%(@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@....,///(%&&&&@&&&&%%%%%&&&&@@@&(/..@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@.......////((#%&&&&&&@&&&@&@&&@%(//*,../@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@............//(((((((##&&@@@@@&&#/////#,,......(@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@%.......... ...*///////(((((((//////*//&(.......... *@@@@@@@@@@@@ -@@@@@@@@@%. ..,..//**///////////****//%/*. ............ .&@@@@@@ \ No newline at end of file diff --git a/bloomsays/bloomberg/color.txt b/bloomsays/bloomberg/color.txt deleted file mode 100644 index a3e6ab3..0000000 --- a/bloomsays/bloomberg/color.txt +++ /dev/null @@ -1,30 +0,0 @@ -@@@@@@@@@@@@@@@@@@@@@@@@@&%%%##(##&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%%#%%%%%%%%%#######%@&@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@%%#%%&%%%%##%%####(#%&&&%%%%&&@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@%&&&&&#((///((((/////*////(#&&&&&&&@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@&&&&&&%#(/////**************////(#@@&&&@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@&&&@&#(///***************,*****///(&@&&&@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@&&&&&#(////*******,,,,,,,,,,,****///(&&&&&@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@&&&&%((////****,*,*,,,,,,,,,,,,***///#&&@&@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@&&&&&%(/////******,,,,,,,,,,********//(&&&&&@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@&@&&&%//////********,,,,,,,,,,******//(%&&&&@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@&@@&&%((///******,,,,,,,,,,,,,,******//#&@&&@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@&&@@@%(///(#(####(/****,**//(%%%%##(///(&&&@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@&&&&(//%######%%###(/***/(((#&&&&%###((&@&//@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@(((#&&(//(#%#(*##,/(/(/****//(**(**(((///&%#/(/@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@/(//&&(//**///*///*////*,**/*****/******/#(**/*@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@/(/(%&(//***/*******//**,,*********,,**//##(**@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@//#(&#(//*********///*,,,,*//*********//%#(*#@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@///&%(////******/////****///*******///(&%/*&@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@//&&##((///**//((#&##%####(//***//(###&#/&@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@(&&&&%#(/(%%%##%%%##%##%%%((###((##%&&&@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@&&&&&%#%&%&&%%#####((#(#%%%%%%%%%%&&&@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@&&&&&&&&%%#//(///*////////%&&&#&&&&@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@(%&@&&&&%#((((######((((((%&&&&@&%@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@,#%/#&&&&&&&&%##%%#%%%##(#%&&%&&@&@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@..(&//(&&&&&&&&&%%%%#%%(%%&&@&&@%(@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@....,///(%&&&&@&&&&%%%%%&&&&&@@&(/..@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@.......////((#%@&&&&&@&&&@&@&&@%(//,.../@@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@............//(((((((##&&@@@@@&&#/////#,, .. ..(@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@%..... .... .*///////(((((((//////*//&(.......... *@@@@@@@@@@@@ -@@@@@@@@@%. .,..//*////////////****//%/*. ........... .&@@@@@@ \ No newline at end of file diff --git a/bloomsays/cli.py b/bloomsays/cli.py deleted file mode 100644 index 759cde2..0000000 --- a/bloomsays/cli.py +++ /dev/null @@ -1 +0,0 @@ -#command line implementations \ No newline at end of file diff --git a/bloomsays/main.py b/bloomsays/main.py deleted file mode 100644 index e69de29..0000000 diff --git a/pyproject.toml b/pyproject.toml index 319f84e..1f18446 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,4 +25,4 @@ dev = ["pytest"] [project.scripts] -bloomsays = "bloomsayspackage.__main__:main" +bloomsays = "bloomsays.__main__:main" diff --git a/src/bloomsayspackage/__init__.py b/src/bloomsays/__init__.py similarity index 100% rename from src/bloomsayspackage/__init__.py rename to src/bloomsays/__init__.py diff --git a/src/bloomsayspackage/__main__.py b/src/bloomsays/__main__.py similarity index 88% rename from src/bloomsayspackage/__main__.py rename to src/bloomsays/__main__.py index cc0c59b..c6bac7b 100644 --- a/src/bloomsayspackage/__main__.py +++ b/src/bloomsays/__main__.py @@ -1,5 +1,5 @@ import sys -import wisdom +from bloomsays import wisdom def main(): args = sys.argv[1:] @@ -11,7 +11,7 @@ def main(): if command == "randomQuote": n = int(args[1]) if len(args) > 1 else 1 - randomQuote(n) + wisdom.random_quote(n) elif command == "avg": if len(args) < 2: print("Usage: bloomsays avg num1 num2 ...") @@ -21,7 +21,7 @@ def main(): except ValueError: print("All arguments for avg must be numbers.") return - print(f"Your average grade is {avg(*numbers):.2f}") + wisdom.avg(*numbers) else: print(f"Unknown command: {command}") print("Usage: bloomsays randomQuote [n] | bloomsays avg num1 num2 ...") diff --git a/src/bloomsayspackage/bubble.py b/src/bloomsays/bubble.py similarity index 100% rename from src/bloomsayspackage/bubble.py rename to src/bloomsays/bubble.py diff --git a/src/bloomsayspackage/wisdom.py b/src/bloomsays/wisdom.py similarity index 99% rename from src/bloomsayspackage/wisdom.py rename to src/bloomsays/wisdom.py index 410d339..8615f67 100644 --- a/src/bloomsayspackage/wisdom.py +++ b/src/bloomsays/wisdom.py @@ -1,7 +1,7 @@ import random; import textwrap from pathlib import Path -from bubble import make_bubble +from .bubble import make_bubble diff --git a/tests/test_bubble.py b/tests/test_bubble.py index ddef51d..e5a98a8 100644 --- a/tests/test_bubble.py +++ b/tests/test_bubble.py @@ -1,6 +1,6 @@ import pytest -from bloomsayspackage.bubble import make_bubble, wrap_text +from bloomsays.bubble import make_bubble, wrap_text def _assert_bubble_matches(out: str, expected_lines: list[str]): diff --git a/tests/test_wisdom.py b/tests/test_wisdom.py index 630f6a1..f2fa5fa 100644 --- a/tests/test_wisdom.py +++ b/tests/test_wisdom.py @@ -1,5 +1,5 @@ import pytest -from bloomsayspackage import wisdom +from bloomsays import wisdom class Tests: @@ -7,40 +7,40 @@ def test_avg_simple(self, capsys): wisdom.avg(97, 76, 67) captured = capsys.readouterr() assert "Your average grade is 80.00" in captured.out - assert "----------------" in captured.out + assert "____" in captured.out assert "@@@@" in captured.out def test_avg_identical_numbers(self, capsys): wisdom.avg(67, 67, 67) captured = capsys.readouterr() assert "Your average grade is 67.00" in captured.out - assert "----------------" in captured.out + assert "____" in captured.out assert "@@@@" in captured.out def test_avg_random_floats(self, capsys): wisdom.avg(5.5, 7.3, 8.2) captured = capsys.readouterr() assert "Your average grade is 7.00" in captured.out - assert "----------------" in captured.out + assert "____" in captured.out assert "@@@@" in captured.out def test_random_quote_runs(self, capsys): wisdom.random_quote(3) captured = capsys.readouterr() - assert "----------------" in captured.out + assert "____" in captured.out assert "@@@@" in captured.out def test_random_quote_default(self, capsys): wisdom.random_quote() captured = capsys.readouterr() - assert any(line.strip().startswith("-") for line in captured.out.splitlines()) + assert any("|" in line for line in captured.out.splitlines()) assert "@@@@" in captured.out def test_random_quote_multiple_quotes_in_bubble(self, capsys): wisdom.random_quote(2) captured = capsys.readouterr() lines = captured.out.splitlines() - bubble_lines = [line for line in lines if line.strip().startswith("<") and line.strip().endswith(">")] + bubble_lines = [line for line in lines if "|" in line and "Your" not in line and "wisdom" not in line and "bloomsays" not in line] assert len(bubble_lines) >= 2 assert "@@@@" in captured.out From 75cb7470ca053bd602fcb865e5a467f590074fc3 Mon Sep 17 00:00:00 2001 From: lunasuzuki Date: Fri, 7 Nov 2025 01:14:38 -0500 Subject: [PATCH 18/40] small updates to readme --- README.md | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6022e0e..d326951 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,21 @@ -# Python Package Exercise +# Bloomsays + +## What is Bloomsays? +Bloomsays is a fun python package with some of our favorite lines from Professor Bloomberg. + +## Instructions + +## Demo Program + +## Functions + +## Links + +## Contributors +- Luna Suzuki - [github](https://github.com/lunasuzuki) +- Kazi Hossain +- Tawhid Zaman +- Jack Chen +- + -An exercise to create a Python package, build it, test it, distribute it, and use it. See [instructions](./instructions.md) for details. From 2b2b36fa1c62d11b82160eeb3cbb6acf6c9584b6 Mon Sep 17 00:00:00 2001 From: lunasuzuki Date: Fri, 7 Nov 2025 17:10:39 -0500 Subject: [PATCH 19/40] added more to readme --- README.md | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d326951..13a7ab3 100644 --- a/README.md +++ b/README.md @@ -5,17 +5,30 @@ Bloomsays is a fun python package with some of our favorite lines from Professor ## Instructions -## Demo Program -## Functions +## Usage +Ater installation, you can import and call the functions from the package +```python +from bloomsays.wisdom import avg, random_quote, coding_wisdom + +#Get your average grade +avg(90, 80, 100) + +#Get a random quote from Professor Bloomberg! +random_quote() -## Links +#Get some coding wisdom with your specified language +coding_wisdom("Python") + +``` + +## Functions ## Contributors - Luna Suzuki - [github](https://github.com/lunasuzuki) -- Kazi Hossain -- Tawhid Zaman -- Jack Chen +- Kazi Hossain - [github]() +- Tawhid Zaman [github]() +- Jack Chen - [github]() - From ad1d5e2948db774b48b72a58734d90434210ad21 Mon Sep 17 00:00:00 2001 From: lunasuzuki Date: Fri, 7 Nov 2025 18:50:39 -0500 Subject: [PATCH 20/40] Added example output to README.md --- README.md | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 13a7ab3..0ce73ad 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,9 @@ Bloomsays is a fun python package with some of our favorite lines from Professor Bloomberg. ## Instructions +pip install -e . +run python: python ## Usage Ater installation, you can import and call the functions from the package @@ -24,11 +26,53 @@ coding_wisdom("Python") ## Functions +## Example Output + ______________ + | ask Bloombot | + ============== + \ + \ + + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&%%%##(##&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%%#%%%%%%%%%#######%@&@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@@@@%%#%%&%%%###%%####(#%&&&%%%%&&@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@%&&&&&#((///((((////**////(#&&&&&&%@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@&&&&&&%#(////***************////(#@@&&&@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@&&&@&#(///***************,*****///(&@&&&@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@&&&&&#(///********,,,,,,,,,,,****///(&&&&&@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@&&&&%(////*****,*,*,,,,,,,,,,,,****//#&&@&@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@&&&&&%(////*******,,,,,,,,,,********//(&&&&&@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@&@&&&%////**********,,,,,,,,,,******//(%&&&&@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@&@@&&%(///*******,,,,,,,,,,,,,,******//#&@&&@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@&&@@&%(///(#(####(/****,**//(%%%%##(///(&&&@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@&&&&(//%###%##%%###(/***/(((%&&&&%###((&@&//@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@(((#&&(//(#%#(*##,/(/(/***///(**#*/(((///&%#((/@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@/(//&&(//***//*////////****/*****/******/#(**/*@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@/(/(%&(//***/*******//**,,*/*******,,**//##(*/@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@/(#(&(///*********///*,,,,*//*********//%%(*#@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@///&%(//********/////****///*******///(&%//&@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@(/&&##((///**//((#&##%####(//***//(###&#/&@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@(&&&&%#(/(%%###%%%##%##%%%((##(((##%&&&@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@&&&&%##%&%&&%###%##((###%%%%#%%%%%&&&@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@&&&&&&%&%%#//(////////////%&&&#&&&&@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@@(%&@&&&&%#((((###%##((((((%&&&&@&%@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@,#%/#&&&&&&&&%##%%#%%%##(#%&&%&&@&@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@..(&//(&&&&&&&&&%%%%#%%(%%&&@&&@%(@@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@....,///(%&&&&@&&&&%%%%%&&&&@@@&(/..@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@.......////((#%&&&&&&@&&&@&@&&@%(//*,../@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@............//(((((((##&&@@@@@&&#/////#,,......(@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@%.......... ...*///////(((((((//////*//&(.......... *@@@@@@@@@@@@ + @@@@@@@@@%. ..,..//**///////////****//%/*. ............ .&@@@@@@ + +['ask Bloombot'] + ## Contributors - Luna Suzuki - [github](https://github.com/lunasuzuki) -- Kazi Hossain - [github]() -- Tawhid Zaman [github]() +- Kazi Hossain - [github](https://github.com/kazisean) +- Tawhid Zaman [github](https://github.com/TawhidZGit) - Jack Chen - [github]() -- +- Howard Appel - [github](https://github.com/hna2019) From 7c801ce57a2fcc59b71a26d9996d4c23bff9acc1 Mon Sep 17 00:00:00 2001 From: kazisean Date: Fri, 7 Nov 2025 20:39:26 -0500 Subject: [PATCH 21/40] added funny jokes + test cases + small bug fixes --- Pipfile | 1 + Pipfile.lock | 6 +++++- src/bloomsays/__main__.py | 5 ++++- src/bloomsays/wisdom.py | 29 ++++++++++++++++++++++++++--- tests/test_wisdom.py | 35 +++++++++++++++++++++++++++++++++++ 5 files changed, 71 insertions(+), 5 deletions(-) diff --git a/Pipfile b/Pipfile index 65e9901..430e8bf 100644 --- a/Pipfile +++ b/Pipfile @@ -5,6 +5,7 @@ name = "pypi" [packages] pytest = "*" +bloomsays = {file = ".", editable = true} [dev-packages] diff --git a/Pipfile.lock b/Pipfile.lock index 91df136..c483b7f 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "356d0f8762b2b972f2a073f481ed3d3cf98ef2b0ed59132aeff315abfaff74a9" + "sha256": "b0c0a8257068337dc2efc14b429ba8c825687b98cd004fcc8f93867b685e278a" }, "pipfile-spec": 6, "requires": { @@ -16,6 +16,10 @@ ] }, "default": { + "bloomsays": { + "editable": true, + "file": "." + }, "iniconfig": { "hashes": [ "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", diff --git a/src/bloomsays/__main__.py b/src/bloomsays/__main__.py index c6bac7b..ec830b8 100644 --- a/src/bloomsays/__main__.py +++ b/src/bloomsays/__main__.py @@ -4,7 +4,7 @@ def main(): args = sys.argv[1:] if not args: - print("Usage: bloomsays randomQuote [n] | bloomsays avg num1 num2 ...") + print("Usage: bloomsays randomQuote [n] OR bloomsays joke [n] OR bloomsays avg num1 num2 ...") return command = args[0] @@ -12,6 +12,9 @@ def main(): if command == "randomQuote": n = int(args[1]) if len(args) > 1 else 1 wisdom.random_quote(n) + elif command == 'joke': + n = int(args[1]) if len(args) > 1 else 1 + wisdom.jokes(n) elif command == "avg": if len(args) < 2: print("Usage: bloomsays avg num1 num2 ...") diff --git a/src/bloomsays/wisdom.py b/src/bloomsays/wisdom.py index 8615f67..05658b0 100644 --- a/src/bloomsays/wisdom.py +++ b/src/bloomsays/wisdom.py @@ -1,4 +1,4 @@ -import random; +import random import textwrap from pathlib import Path from .bubble import make_bubble @@ -53,7 +53,7 @@ def avg(*grades): def random_quote(n=1): profLines = ["everything is due at class time", "ask Bloombot", "Quizzes: 25%", "Exercises & Projects: 75%", "Discord is our main source of communitcation"] - selected_quotes = [random.choice(profLines) for _ in range(n)] + selected_quotes = random.choices(profLines, k=n) bubble_text = "\n".join(selected_quotes) @@ -108,4 +108,27 @@ def coding_wisdom(language="Python"): bubble = make_bubble(full_message) print(f"{bubble}\n{ascii_art}") - return message \ No newline at end of file + return message + +def jokes (n=1): + # source : https://zriyansh.medium.com/top-programming-jokes-that-will-make-your-day-or-night-6d986b338f2d + # https://github.com/wesbos/dad-jokes + allJokes = [ + "I was about to crack a joke on Ubuntu’s text editor, but you might not gedit.", + "I’d tell them a UDP joke but there’s no guarantee that they would get it.", + "When I wrote this, only God and I understood what I was doing. Now, God only knows.", + "#define TRUE FALSE //Happy debugging suckers", + "Which body part does a programmer know best? -> ARM", + "What do you call a busy waiter? -> A server.", + "What do you call an idle server? -> A waiter", + "!false -> It's funny 'cause it's true." + ] + + randomSelect = random.choices(allJokes, k=n) + + bubble_text = "\n".join(randomSelect) + + bubble = make_bubble(bubble_text) + print(f"{bubble}\n{ascii_art}") + + return randomSelect \ No newline at end of file diff --git a/tests/test_wisdom.py b/tests/test_wisdom.py index f2fa5fa..e85c427 100644 --- a/tests/test_wisdom.py +++ b/tests/test_wisdom.py @@ -84,3 +84,38 @@ def test_coding_wisdom_returns_string(self): assert isinstance(message, str) assert len(message) > 0 + def test_jokes_default(self, capsys): + getJoke = wisdom.jokes() + getReturn = capsys.readouterr() + + assert isinstance(getJoke, list) + assert len(getJoke) == 1 + assert getJoke[0] in wisdom.allJokes + assert "____" in captured.out + assert "@@@@" in captured.out + + def test_joke_true_value(self): + numJokes = 2 + output = wisdom.jokes(n=2) + + assert isinstance(output, list) + assert len(output) == numJokes + assert all(isinstance(i, str) for i in output) + + def test_jokes_multiple (self, capsys): + numJokes = 3 + getJokes = wisdom.jokes(n=numJokes) + getReturn = capsys.readouterr() + + assert isinstance(getJokes, list) + assert len(getJokes) == numJokes + for joke in getJokes: + assert joke in wisdom.allJokes + + assert "____" in captured.out + assert "@@@@" in captured.out + + numJokesLine = [line for line in captured.out.splitlines() if "|" in line] + assert len(numJokesLine) >= numJokes + + From 75e2021e1c7127ee317777e190d95a20003c01f3 Mon Sep 17 00:00:00 2001 From: TawhidZGit Date: Fri, 7 Nov 2025 20:56:14 -0500 Subject: [PATCH 22/40] Added study_tip() function --- src/bloomsays/wisdom.py | 48 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/bloomsays/wisdom.py b/src/bloomsays/wisdom.py index 05658b0..724519b 100644 --- a/src/bloomsays/wisdom.py +++ b/src/bloomsays/wisdom.py @@ -131,4 +131,50 @@ def jokes (n=1): bubble = make_bubble(bubble_text) print(f"{bubble}\n{ascii_art}") - return randomSelect \ No newline at end of file + return randomSelect + +def study_tip(hours_available=2, difficulty="medium"): + if hours_available < 0: + raise ValueError("Hours must be non-negative") + + difficulty = difficulty.lower() + if difficulty not in ["easy", "medium", "hard"]: + difficulty = "medium" + + tips = { + "easy": [ + "Quick review session should do it!", + "Focus on the key concepts", + "Practice a few examples", + "Make sure you understand the basics" + ], + "medium": [ + "Break it into manageable chunks", + "Practice problems are essential", + "Review your notes thoroughly", + "Try explaining it to someone else" + ], + "hard": [ + "Start early, don't cram!", + "Work through multiple examples", + "Seek help during office hours", + "Form a study group if possible", + "Break down complex problems step by step" + ] + } + + base_tip = random.choice(tips[difficulty]) + + if hours_available < 1: + time_advice = "Time is tight! Focus on the most important concepts." + elif hours_available < 3: + time_advice = "You have decent time. Use it wisely!" + else: + time_advice = "Great! You have plenty of time to master this." + + message = f"{time_advice}\n{base_tip}" + + bubble = make_bubble(message) + print(f"{bubble}\n{ascii_art}") + + return base_tip From d97ba4dad6a96289d2dbb4b0fb0813632ee1c8b7 Mon Sep 17 00:00:00 2001 From: TawhidZGit Date: Fri, 7 Nov 2025 21:03:37 -0500 Subject: [PATCH 23/40] Completed test cases for studytip() func --- tests/test_wisdom.py | 52 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/tests/test_wisdom.py b/tests/test_wisdom.py index e85c427..7bf92f3 100644 --- a/tests/test_wisdom.py +++ b/tests/test_wisdom.py @@ -117,5 +117,57 @@ def test_jokes_multiple (self, capsys): numJokesLine = [line for line in captured.out.splitlines() if "|" in line] assert len(numJokesLine) >= numJokes + + def test_study_tip_default(self, capsys): + tip = wisdom.study_tip() + captured = capsys.readouterr() + assert isinstance(tip, str) + assert "@@@" in captured.out + assert "<" in captured.out + + def test_study_tip_easy(self, capsys): + tip = wisdom.study_tip(2, "easy") + captured = capsys.readouterr() + assert isinstance(tip, str) + assert "@@@" in captured.out + + def test_study_tip_medium(self, capsys): + tip = wisdom.study_tip(3, "medium") + captured = capsys.readouterr() + assert isinstance(tip, str) + assert "@@@" in captured.out + + def test_study_tip_hard(self, capsys): + tip = wisdom.study_tip(5, "hard") + captured = capsys.readouterr() + assert isinstance(tip, str) + assert "@@@" in captured.out + + def test_study_tip_short_time(self, capsys): + tip = wisdom.study_tip(0.5, "hard") + captured = capsys.readouterr() + assert "Time is tight" in captured.out + + def test_study_tip_long_time(self, capsys): + tip = wisdom.study_tip(10, "easy") + captured = capsys.readouterr() + assert "plenty of time" in captured.out + + def test_study_tip_negative_hours(self): + with pytest.raises(ValueError, match="Hours must be non-negative"): + wisdom.study_tip(-1, "medium") + + def test_study_tip_invalid_difficulty(self, capsys): + tip = wisdom.study_tip(2, "impossible") + captured = capsys.readouterr() + assert isinstance(tip, str) + assert "@@@" in captured.out + + def test_study_tip_case_insensitive(self, capsys): + tip = wisdom.study_tip(2, "HARD") + captured = capsys.readouterr() + assert isinstance(tip, str) + assert "@@@" in captured.out + From 907259de54bd696162f5bb0e9c851ba483bd9f92 Mon Sep 17 00:00:00 2001 From: TawhidZGit Date: Fri, 7 Nov 2025 22:44:40 -0500 Subject: [PATCH 24/40] Added study_tip func --- Pipfile | 2 +- Pipfile.lock | 4 ++-- src/bloomsays/wisdom.py | 25 ++++++++++++------------- tests/__init__.py | 0 tests/test_wisdom.py | 12 ++++++------ 5 files changed, 21 insertions(+), 22 deletions(-) delete mode 100644 tests/__init__.py diff --git a/Pipfile b/Pipfile index 430e8bf..b3a129a 100644 --- a/Pipfile +++ b/Pipfile @@ -10,4 +10,4 @@ bloomsays = {file = ".", editable = true} [dev-packages] [requires] -python_version = "3.13" +python_version = "3" diff --git a/Pipfile.lock b/Pipfile.lock index c483b7f..dd6eb58 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,11 +1,11 @@ { "_meta": { "hash": { - "sha256": "b0c0a8257068337dc2efc14b429ba8c825687b98cd004fcc8f93867b685e278a" + "sha256": "3beed5b7bae4170fab84abbe8e8d59fbbbceafcf89a35fb2def3b9ffd9be4e83" }, "pipfile-spec": 6, "requires": { - "python_version": "3.13" + "python_version": "3" }, "sources": [ { diff --git a/src/bloomsays/wisdom.py b/src/bloomsays/wisdom.py index 724519b..59b86eb 100644 --- a/src/bloomsays/wisdom.py +++ b/src/bloomsays/wisdom.py @@ -3,6 +3,18 @@ from pathlib import Path from .bubble import make_bubble +allJokes = [ + "I was about to crack a joke on Ubuntu’s text editor, but you might not gedit.", + "I’d tell them a UDP joke but there’s no guarantee that they would get it.", + "When I wrote this, only God and I understood what I was doing. Now, God only knows.", + "#define TRUE FALSE //Happy debugging suckers", + "Which body part does a programmer know best? -> ARM", + "What do you call a busy waiter? -> A server.", + "What do you call an idle server? -> A waiter", + "!false -> It's funny 'cause it's true." + ] +# source : https://zriyansh.medium.com/top-programming-jokes-that-will-make-your-day-or-night-6d986b338f2d +# https://github.com/wesbos/dad-jokes ascii_art = r""" @@ -111,19 +123,6 @@ def coding_wisdom(language="Python"): return message def jokes (n=1): - # source : https://zriyansh.medium.com/top-programming-jokes-that-will-make-your-day-or-night-6d986b338f2d - # https://github.com/wesbos/dad-jokes - allJokes = [ - "I was about to crack a joke on Ubuntu’s text editor, but you might not gedit.", - "I’d tell them a UDP joke but there’s no guarantee that they would get it.", - "When I wrote this, only God and I understood what I was doing. Now, God only knows.", - "#define TRUE FALSE //Happy debugging suckers", - "Which body part does a programmer know best? -> ARM", - "What do you call a busy waiter? -> A server.", - "What do you call an idle server? -> A waiter", - "!false -> It's funny 'cause it's true." - ] - randomSelect = random.choices(allJokes, k=n) bubble_text = "\n".join(randomSelect) diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/test_wisdom.py b/tests/test_wisdom.py index 7bf92f3..80caa11 100644 --- a/tests/test_wisdom.py +++ b/tests/test_wisdom.py @@ -91,8 +91,8 @@ def test_jokes_default(self, capsys): assert isinstance(getJoke, list) assert len(getJoke) == 1 assert getJoke[0] in wisdom.allJokes - assert "____" in captured.out - assert "@@@@" in captured.out + assert "____" in getReturn.out + assert "@@@@" in getReturn.out def test_joke_true_value(self): numJokes = 2 @@ -112,10 +112,10 @@ def test_jokes_multiple (self, capsys): for joke in getJokes: assert joke in wisdom.allJokes - assert "____" in captured.out - assert "@@@@" in captured.out + assert "____" in getReturn.out + assert "@@@@" in getReturn.out - numJokesLine = [line for line in captured.out.splitlines() if "|" in line] + numJokesLine = [line for line in getReturn.out.splitlines() if "|" in line] assert len(numJokesLine) >= numJokes def test_study_tip_default(self, capsys): @@ -123,7 +123,7 @@ def test_study_tip_default(self, capsys): captured = capsys.readouterr() assert isinstance(tip, str) assert "@@@" in captured.out - assert "<" in captured.out + assert "|" in captured.out def test_study_tip_easy(self, capsys): tip = wisdom.study_tip(2, "easy") From 787e8bbf2b75d4995460b27ab1d45961401aea79 Mon Sep 17 00:00:00 2001 From: TawhidZGit Date: Fri, 7 Nov 2025 23:21:32 -0500 Subject: [PATCH 25/40] Updated the main to incorporate missing functions --- src/bloomsays/__main__.py | 14 ++++++++++++++ tests/__init__.py | 0 2 files changed, 14 insertions(+) create mode 100644 tests/__init__.py diff --git a/src/bloomsays/__main__.py b/src/bloomsays/__main__.py index ec830b8..45d6e20 100644 --- a/src/bloomsays/__main__.py +++ b/src/bloomsays/__main__.py @@ -25,6 +25,20 @@ def main(): print("All arguments for avg must be numbers.") return wisdom.avg(*numbers) + elif command == "codingWisdom": + language = args[1] if len(args) > 1 else "Python" + wisdom.coding_wisdom(language) + elif command == "studyTip": + if len(args) < 3: + print("Usage: bloomsays studyTip numQuestions difficulty") + return + try: + num_questions = int(args[1]) + difficulty = args[2] + except ValueError: + print("numQuestions must be an integer.") + return + wisdom.study_tip(num_questions, difficulty) else: print(f"Unknown command: {command}") print("Usage: bloomsays randomQuote [n] | bloomsays avg num1 num2 ...") diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 From 27474a2e2f80eeddc2d670c971217d5aa5e560b9 Mon Sep 17 00:00:00 2001 From: kazisean Date: Sat, 8 Nov 2025 03:38:48 -0500 Subject: [PATCH 26/40] added workflow and example file --- .github/workflows/build.yml | 67 +++++++++++++++++++++++++++++++++++++ TODO | 20 ++++++----- src/bloomsays/__main__.py | 2 +- src/example.py | 52 ++++++++++++++++++++++++++++ tests/__init__.py | 0 5 files changed, 132 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/build.yml create mode 100644 src/example.py delete mode 100644 tests/__init__.py diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..9294fe5 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,67 @@ +name: bloomsay ci/cd + +on: + pull_request: + branches: [pipfile-experiment] + push: + branches: [pipfile-experiment] + +jobs: + build-and-test: + name: build and test + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.11", "3.12"] + + steps: + - name: check out repo + uses: actions/checkout@v4 + + - name: python ${{ matrix.python-version }} setup + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: install build tool + run: | + python -m pip install --upgrade pip + pip install build + + - name: install depencies + uses: kojoru/prepare-pipenv@v1 + + - name: build package + run: python -m build + + - name: run pytests + run: pipenv run pytest + + - name: store distribution + uses: actions/upload-artifact@v4 + with: + name: python-package-dist + path: dist/ + + publish-to-pypi: + name: publish to test PyPi + if: github.event_name == 'push' && github.ref == 'refs/heads/pipfile-experiment' + needs: build-and-test + runs-on: ubuntu-latest + + permissions: + id-token: write + + steps: + - name: download dist files + uses: actions/download-artifact@v4 + with: + name: python-package-dist + path: dist/ + + - name: publish bloomsay to test PyPi + uses: pypa/gh-action-pypi-publish@release/v1 + with: + repository-url: https://test.pypi.org/legacy/ + verbose: true + diff --git a/TODO b/TODO index 77bc9fb..ec5e02c 100644 --- a/TODO +++ b/TODO @@ -1,11 +1,12 @@ -[] At least four functions that accept arguments which influence their behavior -[] The package must be distributed in the PyPI repository and installable via pip. -[] Use pipenv to manage the package dependencies and virtual environments with a Pipfile. -[] Use pytest to test this should be no fewer than three tests per package function. -[] Use build to create the package artifacts. -[] Use twine to upload the package to PyPI. -[] Use GitHub Actions to build your package and run your tests on two different recent versions of Python with every pull request to the main branch of your GitHub repository. +[x] At least four functions that accept arguments which influence their behavior +[x] The package must be distributed in the PyPI repository and installable via pip. +[x] Use pipenv to manage the package dependencies and virtual environments with a Pipfile. +[x] Use pytest to test this should be no fewer than three tests per package function. +[x] Use build to create the package artifacts. +[x] Use twine to upload the package to PyPI. +[x] Use GitHub Actions to build your package and run your tests on two different recent versions of Python with every pull request to the main branch of your GitHub repository. [] delete the feature branch +[] Create an example program that uses all functions of your package and demonstrates its complete functionality. [] beautiful read-me file on [] description [] clear instructions @@ -14,4 +15,7 @@ [] how to contribute + build + test + run [] Include a badge at the top of the README.md file showing the result of the latest build/test workflow run. [] Include the names of all teammates as links to their GitHub profiles in the README.md file. - [] Include a link to your package's page on the PyPI website. \ No newline at end of file + [] Include a link to your package's page on the PyPI website. + + +random other notes please push to cheese shop using twine before final submission \ No newline at end of file diff --git a/src/bloomsays/__main__.py b/src/bloomsays/__main__.py index 45d6e20..6c42b6f 100644 --- a/src/bloomsays/__main__.py +++ b/src/bloomsays/__main__.py @@ -4,7 +4,7 @@ def main(): args = sys.argv[1:] if not args: - print("Usage: bloomsays randomQuote [n] OR bloomsays joke [n] OR bloomsays avg num1 num2 ...") + print(f"Usage: \n bloomsays randomQuote [n] \n bloomsays joke [n] \n bloomsays codingWisdom [Python/JavaScript/Java/C++] \n bloomsays avg num1 num2 ...") return command = args[0] diff --git a/src/example.py b/src/example.py new file mode 100644 index 0000000..dfe5d5d --- /dev/null +++ b/src/example.py @@ -0,0 +1,52 @@ +from bloomsays import wisdom + +def main(): + + # average grade function + print("\n1. Calculating the average of grades :") + wisdom.avg(85, 92, 78, 95) + + # getting a random quote function + print("\n Getting a random quote from professor :") + wisdom.random_quote() + + print("\n Getting 2 random quotes from professor :") + wisdom.random_quote(n=2) + + # getting coding wisdoms + print("\n Getting some Python coding wisdom:") + wisdom.coding_wisdom(language="Python") + + print("\n Getting some JavaScript coding wisdom:") + wisdom.coding_wisdom(language="JavaScript") + + print("\n Getting some Java coding wisdom:") + wisdom.coding_wisdom(language="Java") + + print("\n Getting some C++ coding wisdom:") + wisdom.coding_wisdom(language="C++") + + print("\n Getting some random coding wisdom:") + wisdom.coding_wisdom() + + + # getting funny jokes + print("\n Here's a funny joke:") + wisdom.jokes() + + print("\n Here are 3 random funny jokes:") + wisdom.jokes(n=3) + + # study tips + print("\n Getting a study random tip: ") + wisdom.study_tip() + + print("\n Getting a study tip for an easy task with 5 hours available:") + wisdom.study_tip(hours_available=5, difficulty="easy") + + print("\n Getting a study tip for a hard task with 1 hour available:") + wisdom.study_tip(hours_available=1, difficulty="hard") + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index e69de29..0000000 From 4c8d579c712d751229d56b4630a5e53f491fa18a Mon Sep 17 00:00:00 2001 From: kazisean Date: Sat, 8 Nov 2025 03:45:26 -0500 Subject: [PATCH 27/40] workflow bug --- .github/workflows/build.yml | 6 +----- Pipfile | 1 + 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9294fe5..2428c15 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,16 +23,12 @@ jobs: with: python-version: ${{ matrix.python-version }} - - name: install build tool - run: | - python -m pip install --upgrade pip - pip install build - name: install depencies uses: kojoru/prepare-pipenv@v1 - name: build package - run: python -m build + run: pipenv run python -m build - name: run pytests run: pipenv run pytest diff --git a/Pipfile b/Pipfile index b3a129a..51b4618 100644 --- a/Pipfile +++ b/Pipfile @@ -8,6 +8,7 @@ pytest = "*" bloomsays = {file = ".", editable = true} [dev-packages] +build = "*" [requires] python_version = "3" From 24b93070c889de002cb115e0b2c81c3d2be70828 Mon Sep 17 00:00:00 2001 From: kazisean Date: Sat, 8 Nov 2025 03:52:16 -0500 Subject: [PATCH 28/40] save --- .github/workflows/build.yml | 6 ++++-- Pipfile | 1 - Pipfile.lock | 34 ++++++++++++++++++++++++++++------ 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2428c15..c78c7e0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,8 +24,10 @@ jobs: python-version: ${{ matrix.python-version }} - - name: install depencies - uses: kojoru/prepare-pipenv@v1 + - name: install dependencies + run: | + python -m pip install pipenv + pipenv install --dev - name: build package run: pipenv run python -m build diff --git a/Pipfile b/Pipfile index 51b4618..adcb372 100644 --- a/Pipfile +++ b/Pipfile @@ -5,7 +5,6 @@ name = "pypi" [packages] pytest = "*" -bloomsays = {file = ".", editable = true} [dev-packages] build = "*" diff --git a/Pipfile.lock b/Pipfile.lock index dd6eb58..8395643 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "3beed5b7bae4170fab84abbe8e8d59fbbbceafcf89a35fb2def3b9ffd9be4e83" + "sha256": "bcea7f1173cc741abc186a9236a8e4dd4cb57d44b490d15c910068b8c8082bf3" }, "pipfile-spec": 6, "requires": { @@ -16,10 +16,6 @@ ] }, "default": { - "bloomsays": { - "editable": true, - "file": "." - }, "iniconfig": { "hashes": [ "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", @@ -62,5 +58,31 @@ "version": "==8.4.2" } }, - "develop": {} + "develop": { + "build": { + "hashes": [ + "sha256:698edd0ea270bde950f53aed21f3a0135672206f3911e0176261a31e0e07b397", + "sha256:7145f0b5061ba90a1500d60bd1b13ca0a8a4cebdd0cc16ed8adf1c0e739f43b4" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==1.3.0" + }, + "packaging": { + "hashes": [ + "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", + "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f" + ], + "markers": "python_version >= '3.8'", + "version": "==25.0" + }, + "pyproject-hooks": { + "hashes": [ + "sha256:1e859bd5c40fae9448642dd871adf459e5e2084186e8d2c2a79a824c970da1f8", + "sha256:9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913" + ], + "markers": "python_version >= '3.7'", + "version": "==1.2.0" + } + } } From ec7f9f66aa5356c197f850b176c3fd22e6a2517c Mon Sep 17 00:00:00 2001 From: kazisean Date: Sat, 8 Nov 2025 03:55:46 -0500 Subject: [PATCH 29/40] fix bugs --- pyproject.toml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 1f18446..6bc5de7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,3 +26,12 @@ dev = ["pytest"] [project.scripts] bloomsays = "bloomsays.__main__:main" + +[tool.setuptools] +package-dir = {"" = "src"} + +[tool.setuptools.packages.find] +where = ["src"] + +[tool.pytest.ini_options] +python_paths = ["src"] From 7cafd89d78dffaa2e231ae2743465d2b1e5e2e53 Mon Sep 17 00:00:00 2001 From: kazisean Date: Sat, 8 Nov 2025 04:00:06 -0500 Subject: [PATCH 30/40] sav e --- Pipfile | 1 + Pipfile.lock | 7 ++++++- pyproject.toml | 2 -- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Pipfile b/Pipfile index adcb372..780dddb 100644 --- a/Pipfile +++ b/Pipfile @@ -8,6 +8,7 @@ pytest = "*" [dev-packages] build = "*" +bloomsays = {path = ".", editable = true} [requires] python_version = "3" diff --git a/Pipfile.lock b/Pipfile.lock index 8395643..2359d3c 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "bcea7f1173cc741abc186a9236a8e4dd4cb57d44b490d15c910068b8c8082bf3" + "sha256": "168f311aa2eb245a1a229f50b4976607441b56ec9cf6555d67e833aaed3a955a" }, "pipfile-spec": 6, "requires": { @@ -59,6 +59,11 @@ } }, "develop": { + "bloomsays": { + "editable": true, + "markers": "python_version >= '3.7'", + "path": "." + }, "build": { "hashes": [ "sha256:698edd0ea270bde950f53aed21f3a0135672206f3911e0176261a31e0e07b397", diff --git a/pyproject.toml b/pyproject.toml index 6bc5de7..7bbad85 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,5 +33,3 @@ package-dir = {"" = "src"} [tool.setuptools.packages.find] where = ["src"] -[tool.pytest.ini_options] -python_paths = ["src"] From ffa86cebe7fea03f94e84e61dda5235247a7895c Mon Sep 17 00:00:00 2001 From: kazisean Date: Sat, 8 Nov 2025 04:03:46 -0500 Subject: [PATCH 31/40] fixed bug --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c78c7e0..6113135 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -36,6 +36,7 @@ jobs: run: pipenv run pytest - name: store distribution + if: matrix.python-version == '3.12' uses: actions/upload-artifact@v4 with: name: python-package-dist From ac03f0c33504d175acd7ed0c74cc039d3f5e7d68 Mon Sep 17 00:00:00 2001 From: kazisean Date: Sat, 8 Nov 2025 04:12:14 -0500 Subject: [PATCH 32/40] finished run --- .github/workflows/build.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6113135..639f800 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -36,15 +36,13 @@ jobs: run: pipenv run pytest - name: store distribution - if: matrix.python-version == '3.12' uses: actions/upload-artifact@v4 with: - name: python-package-dist + name: python-package-dist-${{ matrix.python-version }} path: dist/ publish-to-pypi: name: publish to test PyPi - if: github.event_name == 'push' && github.ref == 'refs/heads/pipfile-experiment' needs: build-and-test runs-on: ubuntu-latest @@ -55,7 +53,7 @@ jobs: - name: download dist files uses: actions/download-artifact@v4 with: - name: python-package-dist + name: python-package-dist-3.12 path: dist/ - name: publish bloomsay to test PyPi From 39be926c88079625bf0671327d09e0f35dcafe59 Mon Sep 17 00:00:00 2001 From: hna2019 Date: Sat, 8 Nov 2025 08:30:28 -0500 Subject: [PATCH 33/40] Changed some meta data files --- Pipfile | 8 ++++++-- pyproject.toml | 10 +++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Pipfile b/Pipfile index b3a129a..e1b5690 100644 --- a/Pipfile +++ b/Pipfile @@ -4,10 +4,14 @@ verify_ssl = true name = "pypi" [packages] -pytest = "*" bloomsays = {file = ".", editable = true} [dev-packages] +build = "*" +pytest = "*" +coverage = "*" +pytest-cov = "*" +twine = "*" [requires] -python_version = "3" +python_version = "3" \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 1f18446..32422c0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,6 +6,13 @@ build-backend = "setuptools.build_meta" name = "bloomsays" description = "A package that gives quotes from the professor" version = "0.1.0" +authors = [ + { name="Howard Appel", email="hna2019@nyu.edu" }, + { name="Kazi Hossain", email="keh8423@nyu.edu" }, + { name="Luna Suzuki", email="las9963@nyu.edu" }, + { name="Tawhid Zaman", email="tnz8738@nyu.edu" }, + { name="Jack Chen", email="jc11462@nyu.edu"} +] license = { file = "LICENSE" } readme = "README.md" keywords = ["python", "package", "build", "lighthearted"] @@ -21,7 +28,8 @@ classifiers = [ dev = ["pytest"] [project.urls] -"Repository" = "https://github.com/swe-students-fall2025/3-python-package-team_orchid.git" +Homepage = "https://github.com/swe-students-fall2025/3-python-package-team_orchid" +Repository = "https://github.com/swe-students-fall2025/3-python-package-team_orchid.git" [project.scripts] From aaf8772582331506e4cc8f73f77166bd22bad796 Mon Sep 17 00:00:00 2001 From: kazisean Date: Sat, 8 Nov 2025 10:58:40 -0500 Subject: [PATCH 34/40] upgraded version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 9c345bf..3dbbe11 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta" [project] name = "bloomsays" description = "A package that gives quotes from the professor" -version = "0.1.0" +version = "0.1.1" authors = [ { name="Howard Appel", email="hna2019@nyu.edu" }, { name="Kazi Hossain", email="keh8423@nyu.edu" }, From 4046b3b9fd77902f78102fea8f1e4f34d3d9e2e1 Mon Sep 17 00:00:00 2001 From: kazisean Date: Sat, 8 Nov 2025 11:11:34 -0500 Subject: [PATCH 35/40] we use tags now for publishing --- .github/workflows/build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 639f800..1ce1cdb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,10 +1,12 @@ name: bloomsay ci/cd -on: +on: pull_request: branches: [pipfile-experiment] push: branches: [pipfile-experiment] + tags: + - 'v*.*.*' jobs: build-and-test: @@ -44,6 +46,7 @@ jobs: publish-to-pypi: name: publish to test PyPi needs: build-and-test + if: github.ref_type == 'tag' runs-on: ubuntu-latest permissions: @@ -58,7 +61,4 @@ jobs: - name: publish bloomsay to test PyPi uses: pypa/gh-action-pypi-publish@release/v1 - with: - repository-url: https://test.pypi.org/legacy/ - verbose: true From a85dea39893d85c088da2e06298c2742787d86a9 Mon Sep 17 00:00:00 2001 From: TawhidZGit Date: Sat, 8 Nov 2025 11:33:37 -0500 Subject: [PATCH 36/40] Updated Read.me with contributing info and functions --- README.md | 327 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 324 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0ce73ad..765b169 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ run python: python ## Usage Ater installation, you can import and call the functions from the package ```python -from bloomsays.wisdom import avg, random_quote, coding_wisdom +from bloomsays.wisdom import avg, random_quote, coding_wisdom, study_tip, jokes #Get your average grade avg(90, 80, 100) @@ -22,9 +22,218 @@ random_quote() #Get some coding wisdom with your specified language coding_wisdom("Python") +# Get personalized study tips +wisdom.study_tip(hours_available=3, difficulty="hard") + +# Enjoy some programming humor +wisdom.jokes(2) + ``` ## Functions +### `avg(*grades)` + +Calculate the average of your grades and display it with Professor Bloomberg's majestic ASCII art. + +**Parameters:** +- `*grades` (float): Variable number of grade values (integers or floats) + +**Returns:** +- `float`: The calculated average + +**Raises:** +- `ValueError`: If no grades are provided + +**Example:** +```python +from bloomsays import wisdom + +# Calculate average of multiple grades +result = wisdom.avg(90, 85, 95, 78, 92) +# Output: Displays "Your average grade is 88.00" in a speech bubble with Bloomberg ASCII art +# Returns: 88.0 + +# Works with decimals too +result = wisdom.avg(89.5, 92.3, 87.8) +# Returns: 89.87 +``` + +--- + +### `random_quote(n=1)` + +Display random inspirational (and occasionally intimidating) quotes from Professor Bloomberg's legendary syllabus and course communications. + +**Parameters:** +- `n` (int, optional): Number of quotes to display. Default is 1. Must be at least 1. + +**Returns:** +- `list`: List of the selected quote strings + +**Raises:** +- `ValueError`: If n is less than 1 + +**Example:** +```python +from bloomsays import wisdom + +# Get a single quote (default) +quotes = wisdom.random_quote() +# Output: One random Bloomberg quote with ASCII art +# Returns: ['Ask Bloombot!'] + +# Get multiple quotes at once +quotes = wisdom.random_quote(3) +# Output: Three random quotes in a single bubble with ASCII art +# Returns: ['everything is due at class time', 'Quizzes: 25%', 'Discord is our main source of communication'] +``` + +**Available Quotes:** +- "Everything is due at class time" +- "Ask Bloombot!" +- "Quizzes: 25%" +- "Exercises & Projects: 75%" +- "Discord is our main source of communication" +- "Read the instructions carefully" +- "Test your code before submitting" +- "Git commit early and often" +- "Merge conflicts are a learning opportunity" +- "The documentation is your friend" + +--- + +### `coding_wisdom(language="Python")` + +Receive programming wisdom from Professor Bloomberg tailored to your specific language. Because different languages have different philosophies! + +**Parameters:** +- `language` (str, optional): Programming language name. Default is "Python". + - Supported languages: "Python", "JavaScript", "Java", "C++" + - Any other language uses general programming wisdom + +**Returns:** +- `str`: The wisdom message (without the language prefix) + +**Example:** +```python +from bloomsays import wisdom + +# Get Python wisdom (default) +tip = wisdom.coding_wisdom() +# Output: "Python wisdom: Remember: readability counts!" with ASCII art +# Returns: "Remember: readability counts!" + +# Get JavaScript-specific wisdom +tip = wisdom.coding_wisdom("JavaScript") +# Output: "JavaScript wisdom: Always use const and let, never var" with ASCII art +# Returns: "Always use const and let, never var" + +# Get wisdom for any language +tip = wisdom.coding_wisdom("Rust") +# Output: "Rust wisdom: Write clean, readable code" with ASCII art +# Returns: "Write clean, readable code" +``` + +**Wisdom by Language:** +- **Python**: Focus on readability, list comprehensions, virtual environments, PEP 8, pytest +- **JavaScript**: Async/await, const/let, arrow functions, npm, console.log usage +- **Java**: OOP design, exceptions, interfaces, JVM, unit tests +- **C++**: Memory management, RAII, smart pointers, STL, compile warnings +- **Default**: General best practices for any language + +--- + +### `study_tip(hours_available=2, difficulty="medium")` + +Get personalized study advice from Professor Bloomberg based on your available time and the difficulty of your material. The advice adapts to your situation! + +**Parameters:** +- `hours_available` (float, optional): Number of hours you have to study. Default is 2. Must be non-negative. +- `difficulty` (str, optional): Difficulty level of the material. Options: "easy", "medium", or "hard". Default is "medium". Case-insensitive. + +**Returns:** +- `str`: A personalized study tip (base tip without the time advice) + +**Raises:** +- `ValueError`: If hours_available is negative + +**Example:** +```python +from bloomsays import wisdom + +# Default: 2 hours, medium difficulty +tip = wisdom.study_tip() +# Output: "You have decent time. Use it wisely!\nReview your notes thoroughly" with ASCII art +# Returns: "Review your notes thoroughly" + +# Cramming for hard material with little time +tip = wisdom.study_tip(hours_available=0.5, difficulty="hard") +# Output: "Time is tight! Focus on the most important concepts.\nSeek help during office hours" with ASCII art +# Returns: "Seek help during office hours" + +# Plenty of time for easy material +tip = wisdom.study_tip(hours_available=5, difficulty="easy") +# Output: "Great! You have plenty of time to master this.\nQuick review session should do it!" with ASCII art +# Returns: "Quick review session should do it!" + +# Case doesn't matter +tip = wisdom.study_tip(3, "HARD") +# Works the same as difficulty="hard" +``` + +**Time-Based Advice:** +- **< 1 hour**: "Time is tight! Focus on the most important concepts." +- **1-3 hours**: "You have decent time. Use it wisely!" +- **3+ hours**: "Great! You have plenty of time to master this." + +**Difficulty-Based Tips:** +- **Easy**: Quick reviews, key concepts, basic understanding +- **Medium**: Breaking into chunks, practice problems, explaining to others +- **Hard**: Starting early, multiple examples, office hours, study groups + +--- + +### `jokes(n=1)` + +Get random programming jokes to lighten the mood during those long debugging sessions. Laughter is the best debugger! + +**Parameters:** +- `n` (int, optional): Number of jokes to display. Default is 1. + +**Returns:** +- `list`: List of the selected joke strings + +**Example:** +```python +from bloomsays import wisdom + +# Get a single joke (default) +joke_list = wisdom.jokes() +# Output: One random programming joke with ASCII art +# Returns: ["I'd tell them a UDP joke but there's no guarantee that they would get it."] + +# Get multiple jokes +joke_list = wisdom.jokes(3) +# Output: Three random jokes in a single bubble with ASCII art +# Returns: ["!false -> It's funny 'cause it's true.", "Which body part does a programmer know best? -> ARM", ...] +``` + +**Sample Jokes:** +- "I was about to crack a joke on Ubuntu's text editor, but you might not gedit." +- "I'd tell them a UDP joke but there's no guarantee that they would get it." +- "When I wrote this, only God and I understood what I was doing. Now, God only knows." +- "#define TRUE FALSE //Happy debugging suckers" +- "Which body part does a programmer know best? -> ARM" +- "What do you call a busy waiter? -> A server." +- "!false -> It's funny 'cause it's true." + +--- + +## Example Program + +Want to see all functions in action? Check out our [example.py](https://github.com/swe-students-fall2025/3-python-package-team_orchid/blob/main/example.py) file! + +--- ## Example Output ______________ @@ -68,11 +277,123 @@ coding_wisdom("Python") ['ask Bloombot'] +## 🛠️ For Contributors + +Want to contribute to bloomsays? We'd love your help! Here's how to set up your development environment: + +### Prerequisites + +- Python 3.11 or higher (3.11, 3.12, 3.13) +- pip and pipenv + +### Setup Instructions + +**1. Clone the repository:** +```bash +git clone https://github.com/swe-students-fall2025/3-python-package-team_orchid.git +cd 3-python-package-team_orchid +``` + +**2. Install pipenv (if you don't have it):** +```bash +pip install pipenv +``` + +**3. Install dependencies and create virtual environment:** +```bash +pipenv install --dev +``` + +This creates a virtual environment and installs all necessary packages including pytest. + +**4. Activate the virtual environment:** +```bash +pipenv shell +``` + +Your terminal prompt will change to show you're in the virtual environment: `(3-python-package-team_orchid)` + +**5. Install the package in editable mode:** +```bash +pip install -e . +``` + +This allows you to make changes to the code and test them immediately without reinstalling. + +### Running Tests + +Run the complete test suite with verbose output: +```bash +pytest tests/ -v +``` + +Run tests with coverage report: +```bash +pytest tests/ --cov=bloomsays --cov-report=html +``` + +Run specific test files: +```bash +# Test only the wisdom functions +pytest tests/test_wisdom.py -v + +# Test only the bubble functions +pytest tests/test_bubble.py -v +``` + +Run a specific test: +```bash +pytest tests/test_wisdom.py::Tests::test_avg_simple -v +``` + +### Testing Your Changes + +After making code changes, test them: +```bash +# 1. Run all tests +pytest tests/ -v + +# 2. Try the functions in Python +python -c "from bloomsays import wisdom; wisdom.random_quote()" + +# 3. Test the CLI (if applicable) +python -m bloomsays +``` + +### Building the Package + +Build distribution files locally: +```bash +# Install build tools (if not already installed) +pipenv install build twine --dev + +# Build the package +python -m build +``` + +This creates distribution files in the `dist/` directory: +- `bloomsays-0.1.0.tar.gz` (source distribution) +- `bloomsays-0.1.0-py3-none-any.whl` (wheel distribution) + +### Testing the Built Package + +Install and test your local build: +```bash +# Install from the wheel file +pip install dist/bloomsays-0.1.0-py3-none-any.whl + +# Test it +python -c "from bloomsays import wisdom; wisdom.jokes()" + +# Uninstall when done testing +pip uninstall bloomsays +``` + ## Contributors - Luna Suzuki - [github](https://github.com/lunasuzuki) - Kazi Hossain - [github](https://github.com/kazisean) -- Tawhid Zaman [github](https://github.com/TawhidZGit) -- Jack Chen - [github]() +- Tawhid Zaman - [github](https://github.com/TawhidZGit) +- Jack Chen - [github](https://github.com/a247686991) - Howard Appel - [github](https://github.com/hna2019) From 1fe14b921b492114548bff2832526fa006c2d463 Mon Sep 17 00:00:00 2001 From: kazisean Date: Sat, 8 Nov 2025 11:43:27 -0500 Subject: [PATCH 37/40] fixed typo --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 3dbbe11..3d063a7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta" [project] name = "bloomsays" description = "A package that gives quotes from the professor" -version = "0.1.1" +version = "0.1.2" authors = [ { name="Howard Appel", email="hna2019@nyu.edu" }, { name="Kazi Hossain", email="keh8423@nyu.edu" }, From 33f1b63a98479de97067215275c6ca9cc58e399d Mon Sep 17 00:00:00 2001 From: kazisean Date: Sat, 8 Nov 2025 11:45:05 -0500 Subject: [PATCH 38/40] fixed typo --- .github/workflows/build.yml | 4 ++-- pyproject.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1ce1cdb..dd3b1da 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,7 +44,7 @@ jobs: path: dist/ publish-to-pypi: - name: publish to test PyPi + name: publish to PyPi needs: build-and-test if: github.ref_type == 'tag' runs-on: ubuntu-latest @@ -59,6 +59,6 @@ jobs: name: python-package-dist-3.12 path: dist/ - - name: publish bloomsay to test PyPi + - name: publish bloomsay to PyPi uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/pyproject.toml b/pyproject.toml index 3d063a7..b5cc2de 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta" [project] name = "bloomsays" description = "A package that gives quotes from the professor" -version = "0.1.2" +version = "0.2.1" authors = [ { name="Howard Appel", email="hna2019@nyu.edu" }, { name="Kazi Hossain", email="keh8423@nyu.edu" }, From fc6d651200346f9d0eb8af2c7a81667f2603535f Mon Sep 17 00:00:00 2001 From: kazisean Date: Sat, 8 Nov 2025 11:48:25 -0500 Subject: [PATCH 39/40] fixed typo --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 765b169..a563c3f 100644 --- a/README.md +++ b/README.md @@ -236,6 +236,8 @@ Want to see all functions in action? Check out our [example.py](https://github.c --- ## Example Output + +``` ______________ | ask Bloombot | ============== @@ -275,7 +277,7 @@ Want to see all functions in action? Check out our [example.py](https://github.c @@@@@@@@@@@@%.......... ...*///////(((((((//////*//&(.......... *@@@@@@@@@@@@ @@@@@@@@@%. ..,..//**///////////****//%/*. ............ .&@@@@@@ -['ask Bloombot'] +``` ## 🛠️ For Contributors From 8e4ee9c2e55b28fb71ebc84998c01fcb2e7025f6 Mon Sep 17 00:00:00 2001 From: kazisean Date: Sat, 8 Nov 2025 11:49:46 -0500 Subject: [PATCH 40/40] typo fixed now --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a563c3f..dc1520e 100644 --- a/README.md +++ b/README.md @@ -279,6 +279,7 @@ Want to see all functions in action? Check out our [example.py](https://github.c ``` + ## 🛠️ For Contributors Want to contribute to bloomsays? We'd love your help! Here's how to set up your development environment: